Merge changes from topic "vpn-dialog"
am: 19bb1a0b99
Change-Id: I168072aa2bfdb9ed7630cf50547cb9732fb29280
This commit is contained in:
@@ -2173,10 +2173,14 @@
|
||||
<string name="config_customAdbPublicKeyConfirmationSecondaryUserComponent"
|
||||
>com.android.systemui/com.android.systemui.usb.UsbDebuggingSecondaryUserActivity</string>
|
||||
|
||||
<!-- Name of the CustomDialog that is used for VPN -->
|
||||
<string name="config_customVpnConfirmDialogComponent"
|
||||
<!-- Name of the dialog that is used to request the user's consent to VPN connection -->
|
||||
<string name="config_customVpnConfirmDialogComponent" translatable="false"
|
||||
>com.android.vpndialogs/com.android.vpndialogs.ConfirmDialog</string>
|
||||
|
||||
<!-- Name of the dialog that is used to inform the user that always-on VPN is disconnected -->
|
||||
<string name="config_customVpnAlwaysOnDisconnectedDialogComponent" translatable="false"
|
||||
>com.android.vpndialogs/com.android.vpndialogs.AlwaysOnDisconnectedDialog</string>
|
||||
|
||||
<!-- Apps that are authorized to access shared accounts, overridden by product overlays -->
|
||||
<string name="config_appsAuthorizedForSharedAccounts" translatable="false">;com.android.settings;</string>
|
||||
|
||||
|
||||
@@ -3463,16 +3463,21 @@
|
||||
<!-- The text of the notification when VPN is active with a session name. -->
|
||||
<string name="vpn_text_long">Connected to <xliff:g id="session" example="office">%s</xliff:g>. Tap to manage the network.</string>
|
||||
|
||||
<!-- Notification title when connecting to lockdown VPN. -->
|
||||
<!-- Notification title when connecting to always-on VPN, a VPN that's set to always stay
|
||||
connected. -->
|
||||
<string name="vpn_lockdown_connecting">Always-on VPN connecting\u2026</string>
|
||||
<!-- Notification title when connected to lockdown VPN. -->
|
||||
<!-- Notification title when connected to always-on VPN, a VPN that's set to always stay
|
||||
connected. -->
|
||||
<string name="vpn_lockdown_connected">Always-on VPN connected</string>
|
||||
<!-- Notification title when not connected to lockdown VPN. -->
|
||||
<string name="vpn_lockdown_disconnected">Always-on VPN disconnected</string>
|
||||
<!-- Notification title when error connecting to lockdown VPN. -->
|
||||
<!-- Notification title when not connected to always-on VPN, a VPN that's set to always stay
|
||||
connected. -->
|
||||
<string name="vpn_lockdown_disconnected">Disconnected from always-on VPN</string>
|
||||
<!-- Notification title when error connecting to always-on VPN, a VPN that's set to always stay
|
||||
connected. -->
|
||||
<string name="vpn_lockdown_error">Always-on VPN error</string>
|
||||
<!-- Notification body that indicates user can touch to configure lockdown VPN connection. -->
|
||||
<string name="vpn_lockdown_config">Tap to set up</string>
|
||||
<!-- Notification body that indicates user can touch to configure always-on VPN, a VPN that's
|
||||
set to always stay connected. -->
|
||||
<string name="vpn_lockdown_config">Change network or VPN settings</string>
|
||||
|
||||
<!-- Localized strings for WebView -->
|
||||
<!-- Label for button in a WebView that will open a chooser to choose a file to upload -->
|
||||
|
||||
@@ -2009,6 +2009,7 @@
|
||||
<java-symbol type="string" name="config_customAdbPublicKeyConfirmationComponent" />
|
||||
<java-symbol type="string" name="config_customAdbPublicKeyConfirmationSecondaryUserComponent" />
|
||||
<java-symbol type="string" name="config_customVpnConfirmDialogComponent" />
|
||||
<java-symbol type="string" name="config_customVpnAlwaysOnDisconnectedDialogComponent" />
|
||||
<java-symbol type="string" name="config_defaultNetworkScorerPackageName" />
|
||||
<java-symbol type="string" name="config_persistentDataPackageName" />
|
||||
|
||||
|
||||
@@ -23,9 +23,10 @@
|
||||
<uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
|
||||
|
||||
<application android:label="VpnDialogs"
|
||||
android:allowBackup="false" >
|
||||
android:allowBackup="false">
|
||||
|
||||
<activity android:name=".ConfirmDialog"
|
||||
android:theme="@android:style/Theme.Material.Light.Dialog.Alert">
|
||||
android:theme="@android:style/Theme.Material.Light.Dialog.Alert">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
@@ -33,12 +34,21 @@
|
||||
</activity>
|
||||
|
||||
<activity android:name=".ManageDialog"
|
||||
android:theme="@android:style/Theme.Material.Light.Dialog.Alert"
|
||||
android:noHistory="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
</intent-filter>
|
||||
android:theme="@android:style/Theme.Material.Light.Dialog.Alert"
|
||||
android:noHistory="true"
|
||||
android:excludeFromRecents="true"
|
||||
android:permission="android.permission.NETWORK_SETTINGS"
|
||||
android:exported="true">
|
||||
</activity>
|
||||
|
||||
<activity android:name=".AlwaysOnDisconnectedDialog"
|
||||
android:label="@string/always_on_disconnected_title"
|
||||
android:theme="@android:style/Theme.Material.Light.Dialog.Alert"
|
||||
android:noHistory="true"
|
||||
android:excludeFromRecents="true"
|
||||
android:permission="android.permission.NETWORK_SETTINGS"
|
||||
android:exported="true">
|
||||
</activity>
|
||||
|
||||
</application>
|
||||
</manifest>
|
||||
|
||||
25
packages/VpnDialogs/res/layout/always_on_disconnected.xml
Normal file
25
packages/VpnDialogs/res/layout/always_on_disconnected.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2017 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="24dp">
|
||||
<TextView android:id="@+id/message"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
</ScrollView>
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
<!-- Dialog title to identify the request from a VPN application. [CHAR LIMIT=60] -->
|
||||
<string name="prompt">Connection request</string>
|
||||
|
||||
<!-- Dialog message to warn about the risk of using a VPN application. [CHAR LIMIT=NONE] -->
|
||||
<string name="warning"><xliff:g id="app">%s</xliff:g> wants to set up a VPN connection
|
||||
that allows it to monitor network traffic. Only accept if you trust the source.
|
||||
@@ -31,11 +30,6 @@
|
||||
|
||||
<!-- Dialog title for built-in VPN. [CHAR LIMIT=40] -->
|
||||
<string name="legacy_title">VPN is connected</string>
|
||||
<!-- Button label to configure the current VPN session. [CHAR LIMIT=20] -->
|
||||
<string name="configure">Configure</string>
|
||||
<!-- Button label to disconnect the current VPN session. [CHAR LIMIT=20] -->
|
||||
<string name="disconnect">Disconnect</string>
|
||||
|
||||
<!-- Label for the name of the current VPN session. [CHAR LIMIT=20] -->
|
||||
<string name="session">Session:</string>
|
||||
<!-- Label for the duration of the current VPN session. [CHAR LIMIT=20] -->
|
||||
@@ -44,10 +38,55 @@
|
||||
<string name="data_transmitted">Sent:</string>
|
||||
<!-- Label for the network usage of data received over VPN. [CHAR LIMIT=20] -->
|
||||
<string name="data_received">Received:</string>
|
||||
|
||||
<!-- Formatted string for the network usage over VPN. [CHAR LIMIT=40] -->
|
||||
<string name="data_value_format">
|
||||
<xliff:g id="number">%1$s</xliff:g> bytes /
|
||||
<xliff:g id="number">%2$s</xliff:g> packets
|
||||
</string>
|
||||
|
||||
<!-- This string is the title of a dialog. The dialog shows up for Android users when always-on
|
||||
VPN, a VPN that's set to always stay connected, loses its connection. [CHAR LIMIT=60] -->
|
||||
<string name="always_on_disconnected_title">Can\'t connect to always-on VPN</string>
|
||||
<!-- This message is part of a dialog. The dialog shows up for users when always-on VPN, a VPN
|
||||
that's set to always stay connected, loses its connection. Until the phone can reconnect to
|
||||
the VPN, it'll automatically connect to a public network if possible. This text is followed
|
||||
by a clickable link that leads to VPN settings. [CHAR LIMIT=NONE] -->
|
||||
<string name="always_on_disconnected_message">
|
||||
<xliff:g id="vpn_app" example="Foo VPN App">%1$s</xliff:g> is set up to stay connected all
|
||||
the time, but it can\'t connect right now. Your phone will use a public network until it can
|
||||
reconnect to <xliff:g id="vpn_app" example="Foo VPN App">%1$s</xliff:g>.
|
||||
</string>
|
||||
<!-- This message is part of a dialog. The dialog shows up for users when always-on VPN, a VPN
|
||||
that's set to always stay connected, loses its connection while in the lockdown mode.
|
||||
Until the phone can reconnect to the VPN, it won't be able to connect to the Internet. This
|
||||
text is followed by a clickable link that leads to VPN settings. [CHAR LIMIT=NONE] -->
|
||||
<string name="always_on_disconnected_message_lockdown">
|
||||
<xliff:g id="vpn_app" example="Foo VPN App">%1$s</xliff:g> is set up to stay connected all
|
||||
the time, but it can\'t connect right now. You won\'t have a connection until the VPN can
|
||||
reconnect.
|
||||
</string>
|
||||
<!-- This is a space separating the body text and the "Change VPN settings" link that follows
|
||||
it. [CHAR LIMIT=5] -->
|
||||
<string name="always_on_disconnected_message_separator">" "</string>
|
||||
<!-- This is a clickable link appended at the end of the body text of a dialog. The dialog shows
|
||||
up for users when always-on VPN, a VPN that's set to always stay connected, loses its
|
||||
connection. This link takes the user to the VPN page in Settings. -->
|
||||
<string name="always_on_disconnected_message_settings_link">Change VPN settings</string>
|
||||
|
||||
<!-- This is the label of a button in a dialog. The button takes the user to the VPN settings
|
||||
screen. [CHAR LIMIT=20] -->
|
||||
<string name="configure">Configure</string>
|
||||
<!-- This is the label of a button in a dialog. The button lets the user disconnect from the
|
||||
current VPN connection. [CHAR LIMIT=20] -->
|
||||
<string name="disconnect">Disconnect</string>
|
||||
<!-- This button is part of a dialog, and it opens the user's VPN app. The dialog shows up for
|
||||
users when always-on VPN, a VPN that's set to always stay connected, loses its connection.
|
||||
Until the phone can reconnect to the VPN, it may automatically connect to a public network.
|
||||
If it doesn't, the user won't have a connection until the VPN reconnects. [CHAR LIMIT=20]
|
||||
-->
|
||||
<string name="open_app">Open app</string>
|
||||
<!-- This is the label of a button in a dialog. The button lets the user dismiss the dialog
|
||||
without any consequences. [CHAR LIMIT=20] -->
|
||||
<string name="dismiss">Dismiss</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.vpndialogs;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.IConnectivityManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.text.style.ClickableSpan;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.app.AlertActivity;
|
||||
import com.android.internal.net.VpnConfig;
|
||||
|
||||
public class AlwaysOnDisconnectedDialog extends AlertActivity
|
||||
implements DialogInterface.OnClickListener{
|
||||
|
||||
private static final String TAG = "VpnDisconnected";
|
||||
|
||||
private IConnectivityManager mService;
|
||||
private int mUserId;
|
||||
private String mVpnPackage;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
mService = IConnectivityManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
|
||||
mUserId = UserHandle.myUserId();
|
||||
mVpnPackage = getAlwaysOnVpnPackage();
|
||||
if (mVpnPackage == null) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
View view = View.inflate(this, R.layout.always_on_disconnected, null);
|
||||
TextView messageView = view.findViewById(R.id.message);
|
||||
messageView.setText(getMessage(getIntent().getBooleanExtra("lockdown", false)));
|
||||
messageView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
|
||||
mAlertParams.mTitle = getString(R.string.always_on_disconnected_title);
|
||||
mAlertParams.mPositiveButtonText = getString(R.string.open_app);
|
||||
mAlertParams.mPositiveButtonListener = this;
|
||||
mAlertParams.mNegativeButtonText = getString(R.string.dismiss);
|
||||
mAlertParams.mNegativeButtonListener = this;
|
||||
mAlertParams.mCancelable = false;
|
||||
mAlertParams.mView = view;
|
||||
setupAlert();
|
||||
|
||||
getWindow().setCloseOnTouchOutside(false);
|
||||
getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
switch (which) {
|
||||
case BUTTON_POSITIVE:
|
||||
PackageManager pm = getPackageManager();
|
||||
final Intent intent = pm.getLaunchIntentForPackage(mVpnPackage);
|
||||
if (intent != null) {
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
startActivity(intent);
|
||||
}
|
||||
finish();
|
||||
break;
|
||||
case BUTTON_NEGATIVE:
|
||||
finish();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private String getAlwaysOnVpnPackage() {
|
||||
try {
|
||||
return mService.getAlwaysOnVpnPackage(mUserId);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Can't getAlwaysOnVpnPackage()", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private CharSequence getVpnLabel() {
|
||||
try {
|
||||
return VpnConfig.getVpnLabel(this, mVpnPackage);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.w(TAG, "Can't getVpnLabel() for " + mVpnPackage, e);
|
||||
return mVpnPackage;
|
||||
}
|
||||
}
|
||||
|
||||
private CharSequence getMessage(boolean isLockdown) {
|
||||
final SpannableStringBuilder message = new SpannableStringBuilder();
|
||||
final int baseMessageResId = isLockdown
|
||||
? R.string.always_on_disconnected_message_lockdown
|
||||
: R.string.always_on_disconnected_message;
|
||||
message.append(getString(baseMessageResId, getVpnLabel()));
|
||||
message.append(getString(R.string.always_on_disconnected_message_separator));
|
||||
message.append(getString(R.string.always_on_disconnected_message_settings_link),
|
||||
new VpnSpan(), 0 /*flags*/);
|
||||
return message;
|
||||
}
|
||||
|
||||
private class VpnSpan extends ClickableSpan {
|
||||
@Override
|
||||
public void onClick(View unused) {
|
||||
final Intent intent = new Intent(Settings.ACTION_VPN_SETTINGS);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,12 +54,6 @@ public class ManageDialog extends AlertActivity implements
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
if (getCallingPackage() != null) {
|
||||
Log.e(TAG, getCallingPackage() + " cannot start this activity");
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
mService = IConnectivityManager.Stub.asInterface(
|
||||
|
||||
@@ -1416,7 +1416,11 @@ public class Vpn {
|
||||
notificationManager.cancelAsUser(TAG, SystemMessage.NOTE_VPN_DISCONNECTED, user);
|
||||
return;
|
||||
}
|
||||
final Intent intent = new Intent(Settings.ACTION_VPN_SETTINGS);
|
||||
final Intent intent = new Intent();
|
||||
intent.setComponent(ComponentName.unflattenFromString(mContext.getString(
|
||||
R.string.config_customVpnAlwaysOnDisconnectedDialogComponent)));
|
||||
intent.putExtra("lockdown", mLockdown);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
final PendingIntent configIntent = mSystemServices.pendingIntentGetActivityAsUser(
|
||||
intent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT, user);
|
||||
final Notification.Builder builder =
|
||||
|
||||
@@ -32,6 +32,7 @@ import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.net.NetworkInfo.DetailedState;
|
||||
import android.net.UidRange;
|
||||
import android.net.VpnService;
|
||||
@@ -46,6 +47,7 @@ import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.net.VpnConfig;
|
||||
|
||||
import org.mockito.Answers;
|
||||
@@ -116,6 +118,9 @@ public class VpnTest extends AndroidTestCase {
|
||||
when(mContext.getSystemService(eq(Context.APP_OPS_SERVICE))).thenReturn(mAppOps);
|
||||
when(mContext.getSystemService(eq(Context.NOTIFICATION_SERVICE)))
|
||||
.thenReturn(mNotificationManager);
|
||||
when(mContext.getString(R.string.config_customVpnAlwaysOnDisconnectedDialogComponent))
|
||||
.thenReturn(Resources.getSystem().getString(
|
||||
R.string.config_customVpnAlwaysOnDisconnectedDialogComponent));
|
||||
|
||||
// Used by {@link Notification.Builder}
|
||||
ApplicationInfo applicationInfo = new ApplicationInfo();
|
||||
|
||||
Reference in New Issue
Block a user