Activity for messaging installed CA certs, and icon in Settings.

Add the MonitoringCertInfoActivity, used by Settings, QuickSettings
and notification to explain about CA certs enabling network traffic
monitoring.
Add a button on the Security item in Settings when a cert is installed.

Bug: 10633199

Change-Id: Ic753fe22b66c30d837a9ba471a0632a07bb7471f
This commit is contained in:
Maggie Benthall
2013-09-05 15:33:58 -04:00
parent b8e39041a5
commit 9d6c40e56d
11 changed files with 297 additions and 27 deletions

View File

@@ -854,6 +854,18 @@
android:resource="@id/security_settings" />
</activity>
<activity android:name="MonitoringCertInfoActivity"
android:label="@string/ssl_ca_cert_dialog_title"
android:theme="@style/Transparent"
android:taskAffinity=""
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="com.android.settings.MONITORING_CERT_INFO" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name="Settings$TrustedCredentialsSettingsActivity"
android:label="@string/trusted_credentials"
android:taskAffinity=""

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2013 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.
-->
<!-- Layout of a header item in PreferenceActivity. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:descendantFocusability="blocksDescendants"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="48dp"
android:background="?android:attr/activatedBackgroundIndicator"
android:gravity="center_vertical"
android:paddingEnd="?android:attr/scrollbarSize">
<LinearLayout
android:layout_width="@dimen/header_icon_width"
android:layout_marginStart="6dip"
android:layout_marginEnd="6dip"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</LinearLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="2dip"
android:layout_marginEnd="6dip"
android:layout_marginTop="6dip"
android:layout_marginBottom="6dip"
android:layout_weight="1">
<TextView android:id="@+android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"
android:ellipsize="marquee"
android:fadingEdge="horizontal" />
<TextView android:id="@+android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@android:id/title"
android:layout_alignStart="@android:id/title"
android:textAppearance="?android:attr/textAppearanceSmall"
android:ellipsize="end"
android:maxLines="2" />
</RelativeLayout>
<View
android:id="@+id/divider"
style="@style/VertDivider"
android:layout_marginTop="6dp"
android:layout_marginBottom="6dp" />
<ImageButton android:id="@+id/buttonWidget"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="8dip"
android:focusable="false"
style="?android:attr/borderlessButtonStyle"
android:clickable="true" />
</LinearLayout>

View File

@@ -46,6 +46,7 @@
<dimen name="divider_height">3dip</dimen>
<dimen name="divider_margin_top">6dip</dimen>
<dimen name="divider_margin_bottom">7dip</dimen>
<dimen name="vert_divider_width">1dip</dimen>
<!-- Size of icons in the top-level of settings -->
<dimen name="header_icon_width">28dp</dimen>

View File

@@ -4580,6 +4580,22 @@
<string name="selinux_status_permissive">Permissive</string>
<string name="selinux_status_enforcing">Enforcing</string>
<!-- Notification of installed CA Certs --> <skip/>
<!-- Shows up when there is a user SSL CA Cert installed on the
device. Indicates to the user that SSL traffic can be intercepted. [CHAR LIMIT=NONE] -->
<string name="ssl_ca_cert_warning">Network may be monitored</string>
<!-- Button to close the SSL CA cert warning dialog box. [CHAR LIMIT=NONE] -->
<string name="done_button">Done</string>
<!-- Title of Dialog warning users of SSL monitoring. [CHAR LIMIT=NONE] -->
<string name="ssl_ca_cert_dialog_title">Network monitoring</string>
<!-- Text of message to show to users whose administrator has installed a SSL CA Cert. [CHAR LIMIT=NONE] -->
<string name="ssl_ca_cert_info_message">This device is managed by: <xliff:g id="managing_domain">%s</xliff:g>.\n\nYour administrator is capable of monitoring your network activity, including emails, apps, and secure websites.\n\nFor more information, contact your administrator.</string>
<!-- Text of warning to show to users that have a SSL CA Cert installed. [CHAR LIMIT=NONE] -->
<string name="ssl_ca_cert_warning_message">A third party is capable of monitoring your network\nactivity, including emails, apps, and secure websites.\n\nA trusted credential installed on your device is making this possible.</string>
<!-- Label on button that will take the user to the Trusted Credentials settings page. [CHAR LIMIT=NONE]-->
<string name="ssl_ca_cert_settings_button">Check trusted credentials</string>
<!-- User settings -->
<skip/>

View File

@@ -117,6 +117,14 @@
<item name="android:scrollbarStyle">outsideOverlay</item>
</style>
<style name="VertDivider">
<item name="android:layout_width">@dimen/vert_divider_width</item>
<item name="android:layout_height">fill_parent</item>
<item name="android:background">@color/divider_color</item>
<item name="android:focusable">false</item>
<item name="android:clickable">false</item>
</style>
<!-- We'd like to have this as 16dip hight including paddingTop/paddingBottom to
be consistent with ProgressBar -->
<style name="TopDivider">

View File

@@ -0,0 +1,94 @@
/*
* Copyright (C) 2013 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.settings;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.os.Bundle;
import android.os.RemoteException;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
/**
* Activity that shows a dialog explaining that a CA cert is allowing someone to monitor network
* traffic.
*/
public class MonitoringCertInfoActivity extends Activity implements OnClickListener {
private boolean hasDeviceOwner = false;
@Override
protected void onCreate(Bundle savedStates) {
super.onCreate(savedStates);
DevicePolicyManager dpm =
(DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.ssl_ca_cert_dialog_title);
builder.setCancelable(true);
hasDeviceOwner = dpm.getDeviceOwner() != null;
int buttonLabel;
if (hasDeviceOwner) {
// Institutional case. Show informational message.
String message = this.getResources().getString(R.string.ssl_ca_cert_info_message,
dpm.getDeviceOwnerName());
builder.setMessage(message);
buttonLabel = R.string.done_button;
} else {
// Consumer case. Show scary warning.
builder.setIcon(android.R.drawable.stat_notify_error);
builder.setMessage(R.string.ssl_ca_cert_warning_message);
buttonLabel = R.string.ssl_ca_cert_settings_button;
}
builder.setPositiveButton(buttonLabel, this);
final Dialog dialog = builder.create();
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
try {
WindowManagerGlobal.getWindowManagerService().dismissKeyguard();
} catch (RemoteException e) {
}
dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override public void onCancel(DialogInterface dialog) {
finish();
}
});
dialog.show();
}
@Override
public void onClick(DialogInterface dialog, int which) {
if (hasDeviceOwner) {
finish();
} else {
Intent intent =
new Intent(android.provider.Settings.ACTION_TRUSTED_CREDENTIALS_USER);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
}
}
}

View File

@@ -19,6 +19,7 @@ package com.android.settings;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.OnAccountsUpdateListener;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -48,6 +49,7 @@ import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.Switch;
@@ -745,17 +747,21 @@ public class Settings extends PreferenceActivity
static final int HEADER_TYPE_CATEGORY = 0;
static final int HEADER_TYPE_NORMAL = 1;
static final int HEADER_TYPE_SWITCH = 2;
private static final int HEADER_TYPE_COUNT = HEADER_TYPE_SWITCH + 1;
static final int HEADER_TYPE_BUTTON = 3;
private static final int HEADER_TYPE_COUNT = HEADER_TYPE_BUTTON + 1;
private final WifiEnabler mWifiEnabler;
private final BluetoothEnabler mBluetoothEnabler;
private AuthenticatorHelper mAuthHelper;
private DevicePolicyManager mDevicePolicyManager;
private static class HeaderViewHolder {
ImageView icon;
TextView title;
TextView summary;
Switch switch_;
ImageButton button_;
View divider_;
}
private LayoutInflater mInflater;
@@ -765,6 +771,8 @@ public class Settings extends PreferenceActivity
return HEADER_TYPE_CATEGORY;
} else if (header.id == R.id.wifi_settings || header.id == R.id.bluetooth_settings) {
return HEADER_TYPE_SWITCH;
} else if (header.id == R.id.security_settings) {
return HEADER_TYPE_BUTTON;
} else {
return HEADER_TYPE_NORMAL;
}
@@ -797,7 +805,7 @@ public class Settings extends PreferenceActivity
}
public HeaderAdapter(Context context, List<Header> objects,
AuthenticatorHelper authenticatorHelper) {
AuthenticatorHelper authenticatorHelper, DevicePolicyManager dpm) {
super(context, 0, objects);
mAuthHelper = authenticatorHelper;
@@ -807,6 +815,7 @@ public class Settings extends PreferenceActivity
// Switches inflated from their layouts. Must be done before adapter is set in super
mWifiEnabler = new WifiEnabler(context, new Switch(context));
mBluetoothEnabler = new BluetoothEnabler(context, new Switch(context));
mDevicePolicyManager = dpm;
}
@Override
@@ -836,6 +845,18 @@ public class Settings extends PreferenceActivity
holder.switch_ = (Switch) view.findViewById(R.id.switchWidget);
break;
case HEADER_TYPE_BUTTON:
view = mInflater.inflate(R.layout.preference_header_button_item, parent,
false);
holder.icon = (ImageView) view.findViewById(R.id.icon);
holder.title = (TextView)
view.findViewById(com.android.internal.R.id.title);
holder.summary = (TextView)
view.findViewById(com.android.internal.R.id.summary);
holder.button_ = (ImageButton) view.findViewById(R.id.buttonWidget);
holder.divider_ = view.findViewById(R.id.divider);
break;
case HEADER_TYPE_NORMAL:
view = mInflater.inflate(
R.layout.preference_header_item, parent,
@@ -866,12 +887,49 @@ public class Settings extends PreferenceActivity
} else {
mBluetoothEnabler.setSwitch(holder.switch_);
}
// No break, fall through on purpose to update common fields
updateCommonHeaderView(header, holder);
break;
case HEADER_TYPE_BUTTON:
if (header.id == R.id.security_settings) {
boolean hasCert = DevicePolicyManager.hasAnyCaCertsInstalled();
if (hasCert) {
holder.button_.setVisibility(View.VISIBLE);
holder.divider_.setVisibility(View.VISIBLE);
boolean isManaged = mDevicePolicyManager.getDeviceOwner() != null;
if (isManaged) {
holder.button_.setImageResource(R.drawable.ic_qs_certificate_info);
} else {
holder.button_.setImageResource(
android.R.drawable.stat_notify_error);
}
holder.button_.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(
android.provider.Settings.ACTION_MONITORING_CERT_INFO);
getContext().startActivity(intent);
}
});
} else {
holder.button_.setVisibility(View.GONE);
holder.divider_.setVisibility(View.GONE);
}
}
updateCommonHeaderView(header, holder);
break;
//$FALL-THROUGH$
case HEADER_TYPE_NORMAL:
if (header.extras != null &&
header.extras.containsKey(ManageAccountsSettings.KEY_ACCOUNT_TYPE)) {
updateCommonHeaderView(header, holder);
break;
}
return view;
}
private void updateCommonHeaderView(Header header, HeaderViewHolder holder) {
if (header.extras != null
&& header.extras.containsKey(ManageAccountsSettings.KEY_ACCOUNT_TYPE)) {
String accType = header.extras.getString(
ManageAccountsSettings.KEY_ACCOUNT_TYPE);
Drawable icon = mAuthHelper.getDrawableForType(getContext(), accType);
@@ -892,10 +950,6 @@ public class Settings extends PreferenceActivity
} else {
holder.summary.setVisibility(View.GONE);
}
break;
}
return view;
}
private void setHeaderIcon(HeaderViewHolder holder, Drawable icon) {
@@ -963,7 +1017,9 @@ public class Settings extends PreferenceActivity
if (adapter == null) {
super.setListAdapter(null);
} else {
super.setListAdapter(new HeaderAdapter(this, getHeaders(), mAuthenticatorHelper));
DevicePolicyManager dpm =
(DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
super.setListAdapter(new HeaderAdapter(this, getHeaders(), mAuthenticatorHelper, dpm));
}
}