DO NOT MERGE Rework Device Monitoring Dialog in Quicksettings
am: 2f512047c2
Change-Id: If56eee8a498435aaa059990eceea9555897e11b9
This commit is contained in:
@@ -24,6 +24,6 @@ Copyright (C) 2016 The Android Open Source Project
|
|||||||
android:tint="#4DFFFFFF" >
|
android:tint="#4DFFFFFF" >
|
||||||
<path
|
<path
|
||||||
android:fillColor="#FFFFFFFF"
|
android:fillColor="#FFFFFFFF"
|
||||||
android:pathData="M7,18v-2h6v2H7z M7,14v-2h10v2H7z M8.5,9 12,5.5 15.5,9 13,9 13,13 11,13 11,9z"/>
|
android:pathData="M2,24v-4h12v4H2z M2,16v-4h20v4H2z M5,7 12,0 19,7 14,7 14,15 10,15 10,7z"/>
|
||||||
|
|
||||||
</vector>
|
</vector>
|
||||||
|
|||||||
117
packages/SystemUI/res/layout/quick_settings_footer_dialog.xml
Normal file
117
packages/SystemUI/res/layout/quick_settings_footer_dialog.xml
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2016 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:id="@+id/scrollView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clipToPadding="false">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingTop="?android:attr/dialogPreferredPadding"
|
||||||
|
android:paddingRight="?android:attr/dialogPreferredPadding"
|
||||||
|
android:paddingLeft="?android:attr/dialogPreferredPadding"
|
||||||
|
android:paddingBottom="?android:attr/dialogPreferredPadding"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/device_owner_warning"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
style="@android:style/TextAppearance.Material.Subhead"
|
||||||
|
android:textColor="?android:attr/textColorPrimaryInverse"
|
||||||
|
/>
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/vpn_icon"
|
||||||
|
android:layout_width="@dimen/qs_footer_dialog_icon_size"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingTop="?android:attr/dialogPreferredPadding"
|
||||||
|
android:layout_marginStart="@dimen/qs_footer_dialog_icon_margin"
|
||||||
|
android:layout_marginEnd="@dimen/qs_footer_dialog_icon_margin"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
android:src="@drawable/ic_qs_vpn"
|
||||||
|
android:tint="?android:attr/textColorPrimaryInverse"
|
||||||
|
android:adjustViewBounds="true"/>
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/vpn_subtitle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingTop="?android:attr/dialogPreferredPadding"
|
||||||
|
android:text="@string/monitoring_subtitle_vpn"
|
||||||
|
style="@android:style/TextAppearance.Material.Title"
|
||||||
|
android:textColor="?android:attr/textColorPrimaryInverse"
|
||||||
|
/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/vpn_warning"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@null"
|
||||||
|
style="@android:style/TextAppearance.Material.Subhead"
|
||||||
|
android:textColor="?android:attr/textColorPrimaryInverse"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/network_logging_icon"
|
||||||
|
android:layout_width="@dimen/qs_footer_dialog_icon_size"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingTop="?android:attr/dialogPreferredPadding"
|
||||||
|
android:layout_marginStart="@dimen/qs_footer_dialog_icon_margin"
|
||||||
|
android:layout_marginEnd="@dimen/qs_footer_dialog_icon_margin"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
android:src="@drawable/ic_qs_network_logging"
|
||||||
|
android:tint="?android:attr/textColorPrimaryInverse"
|
||||||
|
android:alpha="@dimen/qs_footer_dialog_network_logging_icon_alpha"
|
||||||
|
android:adjustViewBounds="true"/>
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/network_logging_subtitle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingTop="?android:attr/dialogPreferredPadding"
|
||||||
|
android:text="@string/monitoring_subtitle_network_logging"
|
||||||
|
style="@android:style/TextAppearance.Material.Title"
|
||||||
|
android:textColor="?android:attr/textColorPrimaryInverse"
|
||||||
|
/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/network_logging_warning"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/monitoring_description_network_logging"
|
||||||
|
style="@android:style/TextAppearance.Material.Subhead"
|
||||||
|
android:textColor="?android:attr/textColorPrimaryInverse"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
@@ -212,6 +212,13 @@
|
|||||||
<!-- How far the expanded QS panel peeks from the header in collapsed state. -->
|
<!-- How far the expanded QS panel peeks from the header in collapsed state. -->
|
||||||
<dimen name="qs_peek_height">0dp</dimen>
|
<dimen name="qs_peek_height">0dp</dimen>
|
||||||
|
|
||||||
|
<!-- How large the icons in the quick settings footer dialog are -->
|
||||||
|
<dimen name="qs_footer_dialog_icon_size">24sp</dimen>
|
||||||
|
<!-- Left and right margin of the icons -->
|
||||||
|
<dimen name="qs_footer_dialog_icon_margin">8sp</dimen>
|
||||||
|
<!-- Alpha value of network logging icon -->
|
||||||
|
<item name="qs_footer_dialog_network_logging_icon_alpha" format="float" type="dimen">0.3</item>
|
||||||
|
|
||||||
<!-- Zen mode panel: condition item button padding -->
|
<!-- Zen mode panel: condition item button padding -->
|
||||||
<dimen name="zen_mode_condition_detail_button_padding">8dp</dimen>
|
<dimen name="zen_mode_condition_detail_button_padding">8dp</dimen>
|
||||||
|
|
||||||
|
|||||||
@@ -1013,6 +1013,13 @@
|
|||||||
<!-- Monitoring dialog title for normal devices [CHAR LIMIT=35]-->
|
<!-- Monitoring dialog title for normal devices [CHAR LIMIT=35]-->
|
||||||
<string name="monitoring_title">Network monitoring</string>
|
<string name="monitoring_title">Network monitoring</string>
|
||||||
|
|
||||||
|
<!-- STOPSHIP(b/33655277) Monitoring strings still need to be finalized and approved -->
|
||||||
|
<!-- Monitoring dialog subtitle for the section describing VPN [CHAR LIMIT=TODO]-->
|
||||||
|
<string name="monitoring_subtitle_vpn">VPN</string>
|
||||||
|
|
||||||
|
<!-- Monitoring dialog subtitle for the section describing network logging [CHAR LIMIT=TODO]-->
|
||||||
|
<string name="monitoring_subtitle_network_logging">Network Logging</string>
|
||||||
|
|
||||||
<!-- Monitoring dialog disable vpn button [CHAR LIMIT=30] -->
|
<!-- Monitoring dialog disable vpn button [CHAR LIMIT=30] -->
|
||||||
<string name="disable_vpn">Disable VPN</string>
|
<string name="disable_vpn">Disable VPN</string>
|
||||||
|
|
||||||
@@ -1022,6 +1029,19 @@
|
|||||||
<!-- Monitoring dialog device owner body text [CHAR LIMIT=400] -->
|
<!-- Monitoring dialog device owner body text [CHAR LIMIT=400] -->
|
||||||
<string name="monitoring_description_device_owned">Your device is managed by <xliff:g id="organization">%1$s</xliff:g>.\n\nYour administrator can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information. For more information, contact your administrator.</string>
|
<string name="monitoring_description_device_owned">Your device is managed by <xliff:g id="organization">%1$s</xliff:g>.\n\nYour administrator can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information. For more information, contact your administrator.</string>
|
||||||
|
|
||||||
|
<!-- Monitoring dialog: Part of text body explaining that a VPN is connected and what it can do, for devices managed by a Device Owner app [CHAR LIMIT=130] -->
|
||||||
|
<string name="monitoring_description_do_body_vpn">You\'re connected to <xliff:g id="vpn_app">%1$s</xliff:g>, which can monitor your network activity, including emails, apps, and websites.</string>
|
||||||
|
|
||||||
|
<!-- Monitoring dialog: Space that separates the VPN body text and the "Open VPN Settings" link that follows it. [CHAR LIMIT=5] -->
|
||||||
|
<string name="monitoring_description_vpn_settings_separator">" "</string>
|
||||||
|
|
||||||
|
<!-- Monitoring dialog: Link to open the VPN settings page [CHAR LIMIT=TODO] -->
|
||||||
|
<string name="monitoring_description_vpn_settings">Open VPN Settings</string>
|
||||||
|
|
||||||
|
<!-- Monitoring dialog: Network logging text [CHAR LIMIT=TODO] -->
|
||||||
|
<string name="monitoring_description_network_logging">Your admin has turned on network logging, which monitors traffic on your device.\n\nFor more information contact your admin.</string>
|
||||||
|
|
||||||
|
|
||||||
<!-- Monitoring dialog VPN text [CHAR LIMIT=400] -->
|
<!-- Monitoring dialog VPN text [CHAR LIMIT=400] -->
|
||||||
<string name="monitoring_description_vpn">You gave an app permission to set up a VPN connection.\n\nThis app can monitor your device and network activity, including emails, apps, and websites.</string>
|
<string name="monitoring_description_vpn">You gave an app permission to set up a VPN connection.\n\nThis app can monitor your device and network activity, including emails, apps, and websites.</string>
|
||||||
|
|
||||||
|
|||||||
@@ -24,9 +24,14 @@ import android.os.Handler;
|
|||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.UserHandle;
|
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.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
@@ -159,24 +164,60 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void createDialog() {
|
private void createDialog() {
|
||||||
String deviceOwner = mSecurityController.getDeviceOwnerName();
|
final String deviceOwnerPackage = mSecurityController.getDeviceOwnerName();
|
||||||
String profileOwner = mSecurityController.getProfileOwnerName();
|
final String profileOwnerPackage = mSecurityController.getProfileOwnerName();
|
||||||
String primaryVpn = mSecurityController.getPrimaryVpnName();
|
final boolean isNetworkLoggingEnabled = mSecurityController.isNetworkLoggingEnabled();
|
||||||
String profileVpn = mSecurityController.getProfileVpnName();
|
final String primaryVpn = mSecurityController.getPrimaryVpnName();
|
||||||
boolean managed = mSecurityController.hasProfileOwner();
|
final String profileVpn = mSecurityController.getProfileVpnName();
|
||||||
boolean isBranded = deviceOwner == null && mSecurityController.isVpnBranded();
|
boolean hasProfileOwner = mSecurityController.hasProfileOwner();
|
||||||
|
boolean isBranded = deviceOwnerPackage == null && mSecurityController.isVpnBranded();
|
||||||
|
|
||||||
mDialog = new SystemUIDialog(mContext);
|
mDialog = new SystemUIDialog(mContext);
|
||||||
if (!isBranded) {
|
if (!isBranded) {
|
||||||
mDialog.setTitle(getTitle(deviceOwner));
|
mDialog.setTitle(getTitle(deviceOwnerPackage));
|
||||||
}
|
}
|
||||||
mDialog.setMessage(getMessage(deviceOwner, profileOwner, primaryVpn, profileVpn, managed,
|
CharSequence msg = getMessage(deviceOwnerPackage, profileOwnerPackage, primaryVpn,
|
||||||
isBranded));
|
profileVpn, hasProfileOwner, isBranded);
|
||||||
|
if (deviceOwnerPackage == null) {
|
||||||
|
mDialog.setMessage(msg);
|
||||||
|
} else {
|
||||||
|
View dialogView = LayoutInflater.from(mContext)
|
||||||
|
.inflate(R.layout.quick_settings_footer_dialog, null, false);
|
||||||
|
mDialog.setView(dialogView);
|
||||||
|
TextView deviceOwnerWarning =
|
||||||
|
(TextView) dialogView.findViewById(R.id.device_owner_warning);
|
||||||
|
deviceOwnerWarning.setText(msg);
|
||||||
|
// Make the link "learn more" clickable.
|
||||||
|
deviceOwnerWarning.setMovementMethod(new LinkMovementMethod());
|
||||||
|
if (primaryVpn == null) {
|
||||||
|
dialogView.findViewById(R.id.vpn_icon).setVisibility(View.GONE);
|
||||||
|
dialogView.findViewById(R.id.vpn_subtitle).setVisibility(View.GONE);
|
||||||
|
dialogView.findViewById(R.id.vpn_warning).setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
final SpannableStringBuilder message = new SpannableStringBuilder();
|
||||||
|
message.append(mContext.getString(R.string.monitoring_description_do_body_vpn,
|
||||||
|
primaryVpn));
|
||||||
|
message.append(mContext.getString(
|
||||||
|
R.string.monitoring_description_vpn_settings_separator));
|
||||||
|
message.append(mContext.getString(R.string.monitoring_description_vpn_settings),
|
||||||
|
new VpnSpan(), 0);
|
||||||
|
|
||||||
|
TextView vpnWarning = (TextView) dialogView.findViewById(R.id.vpn_warning);
|
||||||
|
vpnWarning.setText(message);
|
||||||
|
// Make the link "Open VPN Settings" clickable.
|
||||||
|
vpnWarning.setMovementMethod(new LinkMovementMethod());
|
||||||
|
}
|
||||||
|
if (!isNetworkLoggingEnabled) {
|
||||||
|
dialogView.findViewById(R.id.network_logging_icon).setVisibility(View.GONE);
|
||||||
|
dialogView.findViewById(R.id.network_logging_subtitle).setVisibility(View.GONE);
|
||||||
|
dialogView.findViewById(R.id.network_logging_warning).setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mDialog.setButton(DialogInterface.BUTTON_POSITIVE, getPositiveButton(isBranded), this);
|
mDialog.setButton(DialogInterface.BUTTON_POSITIVE, getPositiveButton(isBranded), this);
|
||||||
if (mSecurityController.isVpnEnabled() && !mSecurityController.isVpnRestricted()) {
|
|
||||||
mDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getSettingsButton(), this);
|
|
||||||
}
|
|
||||||
mDialog.show();
|
mDialog.show();
|
||||||
|
mDialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getSettingsButton() {
|
private String getSettingsButton() {
|
||||||
@@ -187,22 +228,15 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene
|
|||||||
return mContext.getString(isBranded ? android.R.string.ok : R.string.quick_settings_done);
|
return mContext.getString(isBranded ? android.R.string.ok : R.string.quick_settings_done);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getMessage(String deviceOwner, String profileOwner, String primaryVpn,
|
protected CharSequence getMessage(String deviceOwnerPackage, String profileOwnerPackage,
|
||||||
String profileVpn, boolean primaryUserIsManaged, boolean isBranded) {
|
String primaryVpn, String profileVpn, boolean hasProfileOwner, boolean isBranded) {
|
||||||
// Show a special warning when the device has device owner, but --
|
if (deviceOwnerPackage != null) {
|
||||||
// TODO See b/25779452 -- device owner doesn't actually have monitoring power.
|
|
||||||
if (deviceOwner != null) {
|
|
||||||
if (primaryVpn != null) {
|
|
||||||
return mContext.getString(R.string.monitoring_description_vpn_app_device_owned,
|
|
||||||
deviceOwner, primaryVpn);
|
|
||||||
} else {
|
|
||||||
return mContext.getString(R.string.monitoring_description_device_owned,
|
return mContext.getString(R.string.monitoring_description_device_owned,
|
||||||
deviceOwner);
|
deviceOwnerPackage);
|
||||||
}
|
|
||||||
} else if (primaryVpn != null) {
|
} else if (primaryVpn != null) {
|
||||||
if (profileVpn != null) {
|
if (profileVpn != null) {
|
||||||
return mContext.getString(R.string.monitoring_description_app_personal_work,
|
return mContext.getString(R.string.monitoring_description_app_personal_work,
|
||||||
profileOwner, profileVpn, primaryVpn);
|
profileOwnerPackage, profileVpn, primaryVpn);
|
||||||
} else {
|
} else {
|
||||||
if (isBranded) {
|
if (isBranded) {
|
||||||
return mContext.getString(R.string.branded_monitoring_description_app_personal,
|
return mContext.getString(R.string.branded_monitoring_description_app_personal,
|
||||||
@@ -214,10 +248,10 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene
|
|||||||
}
|
}
|
||||||
} else if (profileVpn != null) {
|
} else if (profileVpn != null) {
|
||||||
return mContext.getString(R.string.monitoring_description_app_work,
|
return mContext.getString(R.string.monitoring_description_app_work,
|
||||||
profileOwner, profileVpn);
|
profileOwnerPackage, profileVpn);
|
||||||
} else if (profileOwner != null && primaryUserIsManaged) {
|
} else if (profileOwnerPackage != null && hasProfileOwner) {
|
||||||
return mContext.getString(R.string.monitoring_description_device_owned,
|
return mContext.getString(R.string.monitoring_description_device_owned,
|
||||||
profileOwner);
|
profileOwnerPackage);
|
||||||
} else {
|
} else {
|
||||||
// No device owner, no personal VPN, no work VPN, no user owner. Why are we here?
|
// No device owner, no personal VPN, no work VPN, no user owner. Why are we here?
|
||||||
return null;
|
return null;
|
||||||
@@ -286,4 +320,13 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected class VpnSpan extends ClickableSpan {
|
||||||
|
@Override
|
||||||
|
public void onClick(View widget) {
|
||||||
|
final Intent intent = new Intent(Settings.ACTION_VPN_SETTINGS);
|
||||||
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
|
mDialog.dismiss();
|
||||||
|
mContext.startActivity(intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user