Merge "Add WebView provider setting to developer settings."
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 43fe796..3bbc667 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -2646,5 +2646,15 @@
android:value="com.android.settings.applications.WriteSettingsDetails" />
</activity>
+ <activity android:name="ShowAdminSupportDetailsDialog"
+ android:theme="@style/Transparent"
+ android:excludeFromRecents="true">
+
+ <intent-filter>
+ <action android:name="android.app.action.SHOW_ADMIN_SUPPORT_DETAILS" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
</application>
</manifest>
diff --git a/res/drawable/ic_settings_lock_outline.xml b/res/drawable/ic_settings_lock_outline.xml
new file mode 100644
index 0000000..1c4202c
--- /dev/null
+++ b/res/drawable/ic_settings_lock_outline.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 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.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="22.0"
+ android:tint="?android:attr/colorAccent">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M12 17c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm6-9h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zM8.9 6c0-1.71 1.39-3.1 3.1-3.1s3.1 1.39 3.1 3.1v2H8.9V6zM18 20H6V10h12v10z" />
+</vector>
diff --git a/res/layout/admin_support_details_dialog.xml b/res/layout/admin_support_details_dialog.xml
new file mode 100644
index 0000000..0d857df
--- /dev/null
+++ b/res/layout/admin_support_details_dialog.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="@dimen/admin_details_dialog_padding"
+ android:orientation="vertical">
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:paddingBottom="@dimen/admin_details_dialog_padding">
+ <ImageView
+ android:layout_width="@dimen/admin_details_dialog_icon_size"
+ android:layout_height="@dimen/admin_details_dialog_icon_size"
+ android:src="@drawable/ic_settings_lock_outline"
+ android:scaleType="fitCenter"
+ android:contentDescription="@null" />
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingStart="@dimen/admin_details_dialog_padding"
+ android:text="@string/disabled_by_policy_title"
+ android:textAppearance="@android:style/TextAppearance.Material.Title" />
+ </LinearLayout>
+
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:fadeScrollbars="false">
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+ <TextView android:id="@+id/disabled_by_admin_msg"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textColor="?android:attr/textColorSecondary" />
+ <TextView android:id="@+id/admin_support_msg"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textColor="?android:attr/textColorSecondary" />
+ <TextView android:id="@+id/admins_policies_list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="@dimen/admin_details_dialog_link_padding_top"
+ android:text="@string/list_of_administrators"
+ android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textColor="?android:attr/colorAccent"
+ android:clickable="true"
+ android:background="?android:attr/selectableItemBackground" />
+ </LinearLayout>
+ </ScrollView>
+</LinearLayout>
\ No newline at end of file
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 62c34ea..2381ed8 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -114,4 +114,8 @@
<attr name="android:entries" />
<attr name="android:entryValues" />
</declare-styleable>
+
+ <declare-styleable name="RestrictedPreference">
+ <attr name="userRestriction" format="string"/>
+ </declare-styleable>
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 481cc73..86030ff 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -250,6 +250,15 @@
<dimen name="shortcut_size">40dp</dimen>
<dimen name="badge_size">10dp</dimen>
+ <!-- Lock icon for preferences locked by admin -->
+ <dimen name="restricted_lock_icon_size">16dp</dimen>
+ <dimen name="restricted_lock_icon_padding">4dp</dimen>
+
+ <!-- Admin support contact details dialog. -->
+ <dimen name="admin_details_dialog_padding">24dp</dimen>
+ <dimen name="admin_details_dialog_icon_size">48dp</dimen>
+ <dimen name="admin_details_dialog_link_padding_top">36dp</dimen>
+
<!-- Button bar padding for unmount button. -->
<dimen name="unmount_button_padding">8dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a1a1901..7120163 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3660,7 +3660,7 @@
<!-- Title for the accessibility preference to speak passwords. [CHAR LIMIT=35] -->
<string name="accessibility_toggle_speak_password_preference_title">Speak passwords</string>
<!-- Title for the accessibility preference for enabling/disabling large icons for mouse/trackpad pointers. [CHAR LIMIT=35] -->
- <string name="accessibility_toggle_large_pointer_icon_title">Large mouse/trackpad pointer icons</string>
+ <string name="accessibility_toggle_large_pointer_icon_title">Large mouse pointer</string>
<!-- Title for accessibility preference to choose long-press delay i.e. timeout before it is detected. [CHAR LIMIT=35] -->
<string name="accessibility_long_press_timeout_preference_title">Touch & hold delay</string>
<!-- Title for the accessibility preference to configure display color inversion. [CHAR LIMIT=NONE] -->
@@ -6684,4 +6684,11 @@
<!-- Summary of device info page [CHAR LIMIT=NONE] -->
<string name="about_summary">Android <xliff:g id="version" example="6.0">%1$s</xliff:g></string>
+
+ <!-- TODO: Update these strings with the finalized ones. -->
+ <string name="disabled_by_policy_title">Disabled by policy</string>
+ <string name="disabled_by_admin_msg">Disabled by your <xliff:g id="organisation_name" example="organisation">%s</xliff:g>\'s administrator.</string>
+ <string name="default_organisation_name">organisation</string>
+ <string name="default_admin_support_msg">Contact them to learn more.</string>
+ <string name="list_of_administrators">List of administrators</string>
</resources>
diff --git a/res/xml/privacy_settings.xml b/res/xml/privacy_settings.xml
index 721a3bf..e014420 100644
--- a/res/xml/privacy_settings.xml
+++ b/res/xml/privacy_settings.xml
@@ -54,10 +54,11 @@
android:fragment="com.android.settings.ResetNetwork" />
<!-- Factory reset -->
- <PreferenceScreen
+ <com.android.settings.RestrictedPreference
android:key="factory_reset"
android:title="@string/master_clear_title"
settings:keywords="@string/keywords_factory_data_reset"
+ settings:userRestriction="no_factory_reset"
android:fragment="com.android.settings.MasterClear" />
</PreferenceScreen>
diff --git a/res/xml/security_settings_misc.xml b/res/xml/security_settings_misc.xml
index 62b6fa3..41daa02 100644
--- a/res/xml/security_settings_misc.xml
+++ b/res/xml/security_settings_misc.xml
@@ -52,7 +52,7 @@
android:persistent="false"
android:fragment="com.android.settings.DeviceAdminSettings"/>
- <SwitchPreference android:key="toggle_install_applications"
+ <com.android.settings.RestrictedSwitchPreference android:key="toggle_install_applications"
android:title="@string/install_applications"
android:summaryOff="@string/install_unknown_applications"
android:summaryOn="@string/install_unknown_applications"
diff --git a/src/com/android/settings/AirplaneModeVoiceActivity.java b/src/com/android/settings/AirplaneModeVoiceActivity.java
index e0649e4..21bfef2 100644
--- a/src/com/android/settings/AirplaneModeVoiceActivity.java
+++ b/src/com/android/settings/AirplaneModeVoiceActivity.java
@@ -16,7 +16,9 @@
package com.android.settings;
+import android.content.Context;
import android.content.Intent;
+import android.net.ConnectivityManager;
import android.provider.Settings;
import android.util.Log;
@@ -31,9 +33,10 @@
protected boolean onVoiceSettingInteraction(Intent intent) {
if (intent.hasExtra(Settings.EXTRA_AIRPLANE_MODE_ENABLED)) {
- Settings.Global.putInt(getContentResolver(),
- Settings.Global.AIRPLANE_MODE_ON,
- intent.getBooleanExtra(Settings.EXTRA_AIRPLANE_MODE_ENABLED, false) ? 1 : 0);
+ ConnectivityManager mgr = (ConnectivityManager) getSystemService(
+ Context.CONNECTIVITY_SERVICE);
+ mgr.setAirplaneMode(intent.getBooleanExtra(
+ Settings.EXTRA_AIRPLANE_MODE_ENABLED, false));
} else {
Log.v(TAG, "Missing airplane mode extra");
}
diff --git a/src/com/android/settings/PrivacySettings.java b/src/com/android/settings/PrivacySettings.java
index 2344a33..0735b11 100644
--- a/src/com/android/settings/PrivacySettings.java
+++ b/src/com/android/settings/PrivacySettings.java
@@ -291,10 +291,6 @@
nonVisibleKeys.add(CONFIGURE_ACCOUNT);
}
if (UserManager.get(context).hasUserRestriction(
- UserManager.DISALLOW_FACTORY_RESET)) {
- nonVisibleKeys.add(FACTORY_RESET);
- }
- if (UserManager.get(context).hasUserRestriction(
UserManager.DISALLOW_NETWORK_RESET)) {
nonVisibleKeys.add(NETWORK_RESET);
}
diff --git a/src/com/android/settings/RestrictedPreference.java b/src/com/android/settings/RestrictedPreference.java
new file mode 100644
index 0000000..7903f93
--- /dev/null
+++ b/src/com/android/settings/RestrictedPreference.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2015 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.content.ComponentName;
+import android.content.Context;
+import android.os.UserHandle;
+import android.support.v4.content.res.TypedArrayUtils;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceManager;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.util.AttributeSet;
+
+/**
+ * Preference class that supports being disabled by a user restriction
+ * set by a device admin.
+ */
+public class RestrictedPreference extends Preference {
+ RestrictedPreferenceHelper mHelper;
+
+ public RestrictedPreference(Context context, AttributeSet attrs,
+ int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ mHelper = new RestrictedPreferenceHelper(context, this, attrs);
+ }
+
+ public RestrictedPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public RestrictedPreference(Context context, AttributeSet attrs) {
+ this(context, attrs, TypedArrayUtils.getAttr(context, R.attr.preferenceStyle,
+ android.R.attr.preferenceStyle));
+ }
+
+ public RestrictedPreference(Context context) {
+ this(context, null);
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+ mHelper.onBindViewHolder(holder);
+ }
+
+ @Override
+ public void performClick() {
+ if (!mHelper.performClick()) {
+ super.performClick();
+ }
+ }
+
+ @Override
+ protected void onAttachedToHierarchy(PreferenceManager preferenceManager) {
+ mHelper.onAttachedToHierarchy();
+ super.onAttachedToHierarchy(preferenceManager);
+ }
+
+ public void checkRestrictionAndSetDisabled(String userRestriction) {
+ mHelper.checkRestrictionAndSetDisabled(userRestriction, UserHandle.myUserId());
+ }
+
+ public void checkRestrictionAndSetDisabled(String userRestriction, int userId) {
+ mHelper.checkRestrictionAndSetDisabled(userRestriction, userId);
+ }
+
+ public void setDisabledByAdmin(boolean disabled) {
+ mHelper.setDisabledByAdmin(disabled, null, UserHandle.USER_NULL);
+ }
+
+ public void setDisabledByAdmin(boolean disabled, ComponentName admin, int userId) {
+ if (mHelper.setDisabledByAdmin(disabled, admin, userId)) {
+ notifyChanged();
+ }
+ }
+
+ public boolean isDisabledByAdmin() {
+ return mHelper.isDisabledByAdmin();
+ }
+}
diff --git a/src/com/android/settings/RestrictedPreferenceHelper.java b/src/com/android/settings/RestrictedPreferenceHelper.java
new file mode 100644
index 0000000..0918887
--- /dev/null
+++ b/src/com/android/settings/RestrictedPreferenceHelper.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2015 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.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.View;
+import android.widget.TextView;
+
+/**
+ * Helper class for managing settings preferences that can be disabled
+ * by device admins via user restrictions.
+ *
+ **/
+public class RestrictedPreferenceHelper {
+ private final Context mContext;
+ private final Preference mPreference;
+ private final Drawable mRestrictedPadlock;
+ private final int mRestrictedPadlockPadding;
+ private final DevicePolicyManager mDevicePolicyManager;
+
+ private boolean mDisabledByAdmin;
+ private ComponentName mEnforcedAdmin;
+ private int mUserId = UserHandle.USER_NULL;
+ private String mAttrUserRestriction = null;
+
+ RestrictedPreferenceHelper(Context context, Preference preference,
+ AttributeSet attrs) {
+ mContext = context;
+ mPreference = preference;
+
+ mRestrictedPadlock = mContext.getDrawable(R.drawable.ic_settings_lock_outline);
+ final int iconSize = mContext.getResources().getDimensionPixelSize(
+ R.dimen.restricted_lock_icon_size);
+ mRestrictedPadlock.setBounds(0, 0, iconSize, iconSize);
+ mRestrictedPadlockPadding = mContext.getResources().getDimensionPixelSize(
+ R.dimen.restricted_lock_icon_padding);
+
+ mDevicePolicyManager = (DevicePolicyManager) mContext.getSystemService(
+ Context.DEVICE_POLICY_SERVICE);
+
+ mAttrUserRestriction = attrs.getAttributeValue(
+ R.styleable.RestrictedPreference_userRestriction);
+ final TypedArray attributes = context.obtainStyledAttributes(attrs,
+ R.styleable.RestrictedPreference);
+ final TypedValue userRestriction =
+ attributes.peekValue(R.styleable.RestrictedPreference_userRestriction);
+ CharSequence data = null;
+ if (userRestriction != null && userRestriction.type == TypedValue.TYPE_STRING) {
+ if (userRestriction.resourceId != 0) {
+ data = context.getText(userRestriction.resourceId);
+ } else {
+ data = userRestriction.string;
+ }
+ }
+ mAttrUserRestriction = data == null ? null : data.toString();
+ }
+
+ /**
+ * Modify PreferenceViewHolder to add padlock if restriction is disabled.
+ */
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ final TextView titleView = (TextView) holder.findViewById(android.R.id.title);
+ if (titleView != null) {
+ if (mDisabledByAdmin) {
+ titleView.setCompoundDrawablesRelative(null, null, mRestrictedPadlock, null);
+ titleView.setCompoundDrawablePadding(mRestrictedPadlockPadding);
+ holder.itemView.setEnabled(true);
+ } else {
+ titleView.setCompoundDrawablesRelative(null, null, null, null);
+ }
+ }
+ }
+
+ /**
+ * Check if the preference is disabled if so handle the click by informing the user.
+ *
+ * @return true if the method handled the click.
+ */
+ public boolean performClick() {
+ if (mDisabledByAdmin) {
+ Intent intent = new Intent(mContext, ShowAdminSupportDetailsDialog.class);
+ if (mEnforcedAdmin != null) {
+ intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mEnforcedAdmin);
+ }
+ if (mUserId != UserHandle.USER_NULL) {
+ intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
+ }
+ mContext.startActivity(intent);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Disable / enable if we have been passed the restriction in the xml.
+ */
+ protected void onAttachedToHierarchy() {
+ if (mAttrUserRestriction != null) {
+ checkRestrictionAndSetDisabled(mAttrUserRestriction, UserHandle.myUserId());
+ }
+ }
+
+ /**
+ * Set the user restriction that is used to disable this preference.
+ *
+ * @param userRestriction constant from {@link android.os.UserManager}
+ * @param userId user to check the restriction for.
+ */
+ public void checkRestrictionAndSetDisabled(String userRestriction, int userId) {
+ ComponentName deviceOwner = mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser();
+ int deviceOwnerUserId = mDevicePolicyManager.getDeviceOwnerUserId();
+ boolean enforcedByDeviceOwner = false;
+ if (deviceOwner != null && deviceOwnerUserId != UserHandle.USER_NULL) {
+ enforcedByDeviceOwner = isEnforcedByAdmin(
+ deviceOwner, userRestriction, deviceOwnerUserId);
+ }
+
+ ComponentName profileOwner = mDevicePolicyManager.getProfileOwnerAsUser(userId);
+ boolean enforcedByProfileOwner = false;
+ if (profileOwner != null && userId != UserHandle.USER_NULL) {
+ enforcedByProfileOwner = isEnforcedByAdmin(
+ profileOwner, userRestriction, userId);
+ }
+
+ if (!enforcedByDeviceOwner && !enforcedByProfileOwner) {
+ setDisabledByAdmin(false, null, UserHandle.USER_NULL);
+ return;
+ }
+
+ if (enforcedByDeviceOwner && enforcedByProfileOwner) {
+ setDisabledByAdmin(true, null, UserHandle.USER_NULL);
+ } else if (enforcedByDeviceOwner) {
+ setDisabledByAdmin(true, deviceOwner, deviceOwnerUserId);
+ } else {
+ setDisabledByAdmin(true, profileOwner, userId);
+ }
+ }
+
+ private boolean isEnforcedByAdmin(ComponentName admin, String userRestriction, int userId) {
+ Bundle enforcedRestrictions = mDevicePolicyManager.getUserRestrictions(admin, userId);
+ if (enforcedRestrictions != null
+ && enforcedRestrictions.getBoolean(userRestriction, false)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Disable this preference.
+ *
+ * @param disabled true if preference should be disabled.
+ * @param admin Device admin that disabled the preference.
+ * @param userId userId the device admin is installed for.
+ * @return true if the disabled state was changed.
+ */
+ public boolean setDisabledByAdmin(boolean disabled, ComponentName admin, int userId) {
+ if (mDisabledByAdmin != disabled) {
+ mDisabledByAdmin = disabled;
+ mEnforcedAdmin = admin;
+ mUserId = userId;
+ mPreference.setEnabled(!disabled);
+ return true;
+ }
+ return false;
+ }
+
+ public boolean isDisabledByAdmin() {
+ return mDisabledByAdmin;
+ }
+}
diff --git a/src/com/android/settings/RestrictedSwitchPreference.java b/src/com/android/settings/RestrictedSwitchPreference.java
new file mode 100644
index 0000000..526bd42
--- /dev/null
+++ b/src/com/android/settings/RestrictedSwitchPreference.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2015 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.content.ComponentName;
+import android.content.Context;
+import android.os.UserHandle;
+import android.support.v4.content.res.TypedArrayUtils;
+import android.support.v7.preference.PreferenceManager;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.support.v14.preference.SwitchPreference;
+import android.util.AttributeSet;
+
+/**
+ * Version of SwitchPreference that can be disabled by a device admin
+ * using a user restriction.
+ */
+public class RestrictedSwitchPreference extends SwitchPreference {
+ RestrictedPreferenceHelper mHelper;
+
+ public RestrictedSwitchPreference(Context context, AttributeSet attrs,
+ int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ mHelper = new RestrictedPreferenceHelper(context, this, attrs);
+ }
+
+ public RestrictedSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public RestrictedSwitchPreference(Context context, AttributeSet attrs) {
+ this(context, attrs, TypedArrayUtils.getAttr(context, R.attr.switchPreferenceStyle,
+ android.R.attr.switchPreferenceStyle));
+ }
+
+ public RestrictedSwitchPreference(Context context) {
+ this(context, null);
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+ mHelper.onBindViewHolder(holder);
+ }
+
+ @Override
+ public void performClick() {
+ if (!mHelper.performClick()) {
+ super.performClick();
+ }
+ }
+
+ @Override
+ protected void onAttachedToHierarchy(PreferenceManager preferenceManager) {
+ mHelper.onAttachedToHierarchy();
+ super.onAttachedToHierarchy(preferenceManager);
+ }
+
+ public void checkRestrictionAndSetDisabled(String userRestriction) {
+ mHelper.checkRestrictionAndSetDisabled(userRestriction, UserHandle.myUserId());
+ }
+
+ public void checkRestrictionAndSetDisabled(String userRestriction, int userId) {
+ mHelper.checkRestrictionAndSetDisabled(userRestriction, userId);
+ }
+
+ public void setDisabledByAdmin(boolean disabled) {
+ mHelper.setDisabledByAdmin(disabled, null, UserHandle.USER_NULL);
+ }
+
+ public void setDisabledByAdmin(boolean disabled, ComponentName admin, int userId) {
+ if (mHelper.setDisabledByAdmin(disabled, admin, userId)) {
+ notifyChanged();
+ }
+ }
+
+ public boolean isDisabledByAdmin() {
+ return mHelper.isDisabledByAdmin();
+ }
+}
diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java
index 838fcf3..fbe0f1c 100644
--- a/src/com/android/settings/SecuritySettings.java
+++ b/src/com/android/settings/SecuritySettings.java
@@ -129,7 +129,7 @@
private KeyStore mKeyStore;
private Preference mResetCredentials;
- private SwitchPreference mToggleAppInstallation;
+ private RestrictedSwitchPreference mToggleAppInstallation;
private DialogInterface mWarnInstallApps;
private SwitchPreference mPowerButtonInstantlyLocks;
@@ -313,15 +313,19 @@
// Application install
PreferenceGroup deviceAdminCategory = (PreferenceGroup)
root.findPreference(KEY_DEVICE_ADMIN_CATEGORY);
- mToggleAppInstallation = (SwitchPreference) findPreference(
+ mToggleAppInstallation = (RestrictedSwitchPreference) findPreference(
KEY_TOGGLE_INSTALL_APPLICATIONS);
mToggleAppInstallation.setChecked(isNonMarketAppsAllowed());
// Side loading of apps.
// Disable for restricted profiles. For others, check if policy disallows it.
mToggleAppInstallation.setEnabled(!um.getUserInfo(MY_USER_ID).isRestricted());
- if (um.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES)
- || um.hasUserRestriction(UserManager.DISALLOW_INSTALL_APPS)) {
- mToggleAppInstallation.setEnabled(false);
+ if (mToggleAppInstallation.isEnabled()) {
+ mToggleAppInstallation.checkRestrictionAndSetDisabled(
+ UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
+ if (!mToggleAppInstallation.isDisabledByAdmin()) {
+ mToggleAppInstallation.checkRestrictionAndSetDisabled(
+ UserManager.DISALLOW_INSTALL_APPS);
+ }
}
// Advanced Security features
diff --git a/src/com/android/settings/ShowAdminSupportDetailsDialog.java b/src/com/android/settings/ShowAdminSupportDetailsDialog.java
new file mode 100644
index 0000000..42e8f05
--- /dev/null
+++ b/src/com/android/settings/ShowAdminSupportDetailsDialog.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2015 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.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextView;
+
+public class ShowAdminSupportDetailsDialog extends Activity
+ implements DialogInterface.OnDismissListener {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ View rootView = LayoutInflater.from(this).inflate(
+ R.layout.admin_support_details_dialog, null);
+ setAdminSupportDetails(rootView);
+
+ new AlertDialog.Builder(this)
+ .setView(rootView)
+ .setPositiveButton(R.string.okay, null)
+ .setOnDismissListener(this)
+ .show();
+ }
+
+ private void setAdminSupportDetails(View root) {
+ CharSequence adminDisabledMsg = getString(R.string.disabled_by_admin_msg,
+ getString(R.string.default_organisation_name));
+ TextView textView = (TextView) root.findViewById(R.id.disabled_by_admin_msg);
+ textView.setText(adminDisabledMsg);
+
+ CharSequence adminSupportDetails = getString(R.string.default_admin_support_msg);
+ textView = (TextView) root.findViewById(R.id.admin_support_msg);
+ textView.setText(adminSupportDetails);
+
+ root.findViewById(R.id.admins_policies_list).setOnClickListener(
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Intent intent = new Intent();
+ intent.setClass(ShowAdminSupportDetailsDialog.this,
+ Settings.DeviceAdminSettingsActivity.class);
+ startActivity(intent);
+ finish();
+ }
+ });
+ }
+
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ finish();
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/notification/ImportanceSeekBarPreference.java b/src/com/android/settings/notification/ImportanceSeekBarPreference.java
index fdba42c..ec77467 100644
--- a/src/com/android/settings/notification/ImportanceSeekBarPreference.java
+++ b/src/com/android/settings/notification/ImportanceSeekBarPreference.java
@@ -33,7 +33,6 @@
SeekBar.OnSeekBarChangeListener {
private static final String TAG = "ImportanceSeekBarPref";
- public static final int IMPORTANCE_PROGRESS_OFFSET = 2;
private Callback mCallback;
private TextView mSummaryTextView;
private String mSummary;
@@ -89,8 +88,6 @@
}
private String getProgressSummary(int progress) {
- // Map progress 0-4 values to Importance's -2-2.
- progress = progress - IMPORTANCE_PROGRESS_OFFSET;
switch (progress) {
case NotificationListenerService.Ranking.IMPORTANCE_NONE:
return getContext().getString(
diff --git a/src/com/android/settings/notification/TopicNotificationSettings.java b/src/com/android/settings/notification/TopicNotificationSettings.java
index 71196b7..e847e34 100644
--- a/src/com/android/settings/notification/TopicNotificationSettings.java
+++ b/src/com/android/settings/notification/TopicNotificationSettings.java
@@ -135,13 +135,11 @@
mTopicRow.importance == NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED
? NotificationListenerService.Ranking.IMPORTANCE_DEFAULT
: mTopicRow.importance;
- mImportance.setProgress(
- importance + ImportanceSeekBarPreference.IMPORTANCE_PROGRESS_OFFSET);
+ mImportance.setProgress(importance);
mImportance.setCallback(new ImportanceSeekBarPreference.Callback() {
@Override
public void onImportanceChanged(int progress) {
- mBackend.setImportance(mTopicRow.pkg, mTopicRow.uid, mTopicRow.topic,
- progress - ImportanceSeekBarPreference.IMPORTANCE_PROGRESS_OFFSET);
+ mBackend.setImportance(mTopicRow.pkg, mTopicRow.uid, mTopicRow.topic, progress);
}
});
mPriority.setChecked(mTopicRow.priority);