Merge "Add logging to Bluetooth settings."
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index b3db932..23dc206 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1506,19 +1506,13 @@
</activity>
<activity android:name="Settings$EnterprisePrivacySettingsActivity"
- android:label="@string/enterprise_privacy_settings_title"
- android:icon="@drawable/ic_settings_about"
- android:taskAffinity="com.android.settings"
- android:parentActivityName="Settings">
+ android:label="@string/enterprise_privacy_settings_title"
+ android:taskAffinity="com.android.settings"
+ android:parentActivityName="Settings$SecuritySettingsActivity">
<intent-filter>
<action android:name="android.settings.ENTERPRISE_PRIVACY_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
- <intent-filter android:priority="-1">
- <action android:name="com.android.settings.action.SETTINGS" />
- </intent-filter>
- <meta-data android:name="com.android.settings.category"
- android:value="com.android.settings.category.ia.system" />
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.enterprise.EnterprisePrivacySettings" />
</activity>
@@ -2832,6 +2826,19 @@
android:value="com.android.settings.applications.ManageApplications" />
</activity>
+
+ <activity android:name="Settings$AppWriteSettingsActivity"
+ android:label="@string/write_settings_title"
+ android:taskAffinity="">
+ <intent-filter android:priority="1">
+ <action android:name="android.settings.action.MANAGE_WRITE_SETTINGS" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:scheme="package" />
+ </intent-filter>
+ <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+ android:value="com.android.settings.applications.WriteSettingsDetails" />
+ </activity>
+
<activity android:name="Settings$ManageExternalSourcesActivity"
android:label="@string/install_other_apps"
android:taskAffinity="">
@@ -2843,16 +2850,16 @@
android:value="com.android.settings.applications.ManageApplications" />
</activity>
- <activity android:name="Settings$AppWriteSettingsActivity"
- android:label="@string/write_settings_title"
- android:taskAffinity="">
+ <activity android:name="Settings$ManageAppExternalSourcesActivity"
+ android:label="@string/install_other_apps"
+ android:taskAffinity="">
<intent-filter android:priority="1">
- <action android:name="android.settings.action.MANAGE_WRITE_SETTINGS" />
+ <action android:name="android.settings.action.MANAGE_EXTERNAL_SOURCES" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="package" />
</intent-filter>
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
- android:value="com.android.settings.applications.WriteSettingsDetails" />
+ android:value="com.android.settings.applications.ExternalSourcesDetails" />
</activity>
<activity android:name="ShowAdminSupportDetailsDialog"
diff --git a/res/layout/app_details.xml b/res/layout/app_details.xml
index 00d4cca..15cb38a 100644
--- a/res/layout/app_details.xml
+++ b/res/layout/app_details.xml
@@ -18,7 +18,7 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/app_snippet"
- style="@style/EntityHeader"
+ style="@style/AppInfoHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|top"
@@ -79,7 +79,7 @@
<TextView
android:id="@+id/app_detail_title"
- style="@style/TextAppearance.EntityHeaderTitle"
+ style="@style/TextAppearance.AppInfoTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="false"
@@ -89,24 +89,22 @@
<TextView
android:id="@+id/install_type"
+ style="@style/TextAppearance.AppInfoSummary"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:singleLine="true"
- android:ellipsize="marquee"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
- android:textColor="?android:attr/textColorSecondary"/>
+ android:ellipsize="marquee"/>
<TextView
android:id="@+id/app_detail_summary"
+ style="@style/TextAppearance.AppInfoSummary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:singleLine="true"
- android:ellipsize="marquee"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
- android:textColor="?android:attr/textColorSecondary"/>
+ android:ellipsize="marquee"/>
</LinearLayout>
diff --git a/res/layout/app_preferred_settings.xml b/res/layout/app_preferred_settings.xml
index d0041a1..1f3b497 100644
--- a/res/layout/app_preferred_settings.xml
+++ b/res/layout/app_preferred_settings.xml
@@ -14,36 +14,27 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-<ScrollView
+<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:clipToPadding="false"
- android:scrollbarStyle="@integer/preference_scrollbar_style">
+ android:layout_height="wrap_content"
+ android:paddingStart="@dimen/preference_no_icon_padding_start"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:paddingBottom="5dip"
+ android:orientation="vertical">
- <LinearLayout
- android:layout_width="match_parent"
+ <TextView android:id="@+id/auto_launch"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:layout_alignParentStart="true"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="6dip" />
+
+ <Button
+ android:id="@+id/clear_activities_button"
+ android:layout_marginStart="-4dip"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:paddingStart="?android:attr/listPreferredItemPaddingStart"
- android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
- android:paddingBottom="5dip"
- android:orientation="vertical">
+ android:text="@string/clear_activities" />
- <TextView android:id="@+id/auto_launch"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:layout_alignParentStart="true"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingTop="6dip" />
-
- <Button
- android:id="@+id/clear_activities_button"
- android:layout_marginStart="-4dip"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/clear_activities" />
-
- </LinearLayout>
-
-</ScrollView>
+</LinearLayout>
diff --git a/res/layout/date_time_custom_list_item_2.xml b/res/layout/date_time_custom_list_item_2.xml
index ed32fb7..4902758 100644
--- a/res/layout/date_time_custom_list_item_2.xml
+++ b/res/layout/date_time_custom_list_item_2.xml
@@ -15,29 +15,28 @@
-->
<!-- Based on simple_list_item_2.xml in framework -->
-<TwoLineListItem xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeight"
- android:mode="twoLine"
+ android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
->
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:orientation="vertical"
+ android:paddingStart="@dimen/preference_no_icon_padding_start"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
- <TextView android:id="@android:id/text1"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="16dip"
- android:layout_marginStart="10dip"
- android:textAppearance="?android:attr/textAppearanceMedium"
- />
+ <TextView
+ android:id="@android:id/text1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceListItem" />
- <TextView android:id="@android:id/text2"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="10dip"
- android:layout_below="@android:id/text1"
- android:layout_alignStart="@android:id/text1"
- android:textAppearance="?android:attr/textAppearanceSmall"
- />
+ <TextView
+ android:id="@android:id/text2"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+ android:textColor="?android:attr/textColorSecondary" />
-</TwoLineListItem>
+</LinearLayout>
diff --git a/res/layout/expand_preference.xml b/res/layout/expand_preference.xml
index 1392d65..d5fe031 100644
--- a/res/layout/expand_preference.xml
+++ b/res/layout/expand_preference.xml
@@ -56,9 +56,7 @@
android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceListItem"
- android:textColor="?android:attr/colorAccent"
android:ellipsize="marquee"/>
<TextView
diff --git a/res/layout/preference_footer.xml b/res/layout/preference_footer.xml
index e336ac1..1df4f70 100644
--- a/res/layout/preference_footer.xml
+++ b/res/layout/preference_footer.xml
@@ -20,7 +20,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
- android:gravity="center_vertical"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:background="?android:attr/selectableItemBackground"
@@ -31,15 +30,15 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="60dp"
- android:gravity="start|center_vertical"
+ android:gravity="start|top"
android:orientation="horizontal"
android:paddingEnd="12dp"
- android:paddingTop="4dp"
+ android:paddingTop="20dp"
android:paddingBottom="4dp">
- <com.android.internal.widget.PreferenceImageView
+ <ImageView
android:id="@android:id/icon"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
+ android:layout_height="wrap_content" />
</LinearLayout>
<com.android.settingslib.widget.LinkTextView
@@ -50,6 +49,6 @@
android:paddingTop="16dp"
android:maxLines="10"
android:textColor="?android:attr/textColorSecondary"
- android:ellipsize="marquee"/>
+ android:ellipsize="marquee" />
</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/storage_summary_donut.xml b/res/layout/storage_summary_donut.xml
index eadb6e5..9fd4860 100644
--- a/res/layout/storage_summary_donut.xml
+++ b/res/layout/storage_summary_donut.xml
@@ -56,15 +56,6 @@
android:textAlignment="viewStart"
android:textAppearance="@android:style/TextAppearance.Material.Body1" />
- <TextView
- android:id="@+id/storage_manager_indicator"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginStart="4dp"
- android:layout_marginEnd="4dp"
- android:textAlignment="viewStart"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"/>
-
<Button
android:id="@+id/deletion_helper_button"
android:layout_width="wrap_content"
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index d099cdc..d4f9d90 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -92,6 +92,8 @@
<attr name="apnPreferenceStyle" format="reference" />
+ <attr name="footerPreferenceStyle" format="reference" />
+
<!-- For Search -->
<declare-styleable name="Preference">
<attr name="keywords" format="string" />
diff --git a/res/values/strings.xml b/res/values/strings.xml
index c9a1bf7..d64018d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4299,6 +4299,11 @@
<!-- Display time remaining until battery is charged [CHAR_LIMIT=60] -->
<string name="power_charge_remaining"><xliff:g id="until_charged">%1$s</xliff:g> to charge</string>
+ <!-- Title for the background activity setting, which allows a user to control whether an app can run in the background [CHAR_LIMIT=40] -->
+ <string name="background_activity_title">Background activity</string>
+ <!-- Summary for the background activity [CHAR_LIMIT=120] -->
+ <string name="background_activity_summary">Allow the app to run in the background</string>
+
<!-- Title for the screen usage in power use UI [CHAR_LIMIT=40] -->
<string name="device_screen_usage">Screen usage</string>
<!-- Title for the screen consumption in power use UI(i.e. Screen consumption: 30% of battery usage) [CHAR_LIMIT=40] -->
@@ -8066,6 +8071,9 @@
<!-- Summary text for the assist gesture [CHAR LIMIT=160]-->
<string name="assist_gesture_summary"></string>
+ <!-- Title text for the assist gesture sensitivity setting [CHAR LIMIT=NONE]-->
+ <string name="assist_gesture_sensitivity_title">Sensitivity</string>
+
<!-- Switch text for each gesture setting state -->
<string name="gesture_setting_on">On</string>
<string name="gesture_setting_off">Off</string>
@@ -8114,64 +8122,58 @@
<!-- Enterprise Privacy --> <skip />
- <!-- Title of setting on main settings screen. This will take the user to a screen with information about his/her privacy on a managed device. Shown on enterprise-managed devices only. -->
- <string name="enterprise_privacy_settings">Privacy</string>
+ <!-- Title of setting on security settings screen. This will take the user to a screen with information about admin powers and their impact on the user's privacy on a managed device. Shown on enterprise-managed devices only. -->
+ <string name="enterprise_privacy_settings">Device management</string>
+ <!-- Summary for Enterprise Privacy settings, explaining what the user can expect to find under it [CHAR LIMIT=NONE]-->
+ <string name="enterprise_privacy_settings_summary">View all settings applied by your admin</string>
<!-- Enterprise Privacy settings activity title -->
- <string name="enterprise_privacy_settings_title">Privacy</string>
- <!-- Enterprise Privacy settings activity header, summarizing the powers that the admin has. [CHAR LIMIT=NONE] -->
- <string name="enterprise_privacy_header">To provide access to your work data, your organization may change settings and install software on your device, which could cause some of your personal content to be visible to your admin. Contact your organization\'s admin for more details.</string>
- <!-- Title for the 'What types of information can your organization see?' preference category. [CHAR LIMIT=60] -->
- <string name="enterprise_privacy_exposure_category">What types of information can your organization see?</string>
- <!-- Title for the 'What changes affect what your organization can see?' preference category. [CHAR LIMIT=60] -->
- <string name="enterprise_privacy_exposure_changes_category">What changes affect what your organization can see?</string>
- <!-- Title for the 'What actions may impact your access to this device?' preference category. [CHAR LIMIT=60] -->
- <string name="enterprise_privacy_device_access_category">What actions may impact your access to this device?</string>
+ <string name="enterprise_privacy_settings_title">Device management</string>
+ <!-- Enterprise Privacy settings activity footer, summarizing the powers that the admin has. [CHAR LIMIT=NONE] -->
+ <string name="enterprise_privacy_footer">To provide access to your work data, your organization may change settings and install software on your device. \n\nFor more details, contact your organization\'s admin.</string>
+ <!-- Title for the 'Types of information your organization can see' preference category. [CHAR LIMIT=60] -->
+ <string name="enterprise_privacy_exposure_category">Types of information your organization can see</string>
+ <!-- Title for the 'Changes made by your organization’s admin' preference category. [CHAR LIMIT=60] -->
+ <string name="enterprise_privacy_exposure_changes_category">Changes made by your organization\'s admin</string>
+ <!-- Title for the 'Your access to this device' preference category. [CHAR LIMIT=60] -->
+ <string name="enterprise_privacy_device_access_category">Your access to this device</string>
<!-- Label explaining that the admin can see data associated with his/her work account. [CHAR LIMIT=NONE] -->
<string name="enterprise_privacy_enterprise_data">Data associated with your work account, such as email and calendar</string>
- <!-- Label explaining that the admin can see all apps installed on the device. [CHAR LIMIT=NONE] -->
- <string name="enterprise_privacy_number_installed_packages_default">List of all apps on your device</string>
- <!-- Label explaining that the admin can see all apps installed on the device. [CHAR LIMIT=NONE] -->
- <plurals name="enterprise_privacy_number_installed_packages">
- <item quantity="one">List of all <xliff:g id="count">%d</xliff:g> app on your device</item>
- <item quantity="other">List of all <xliff:g id="count">%d</xliff:g> apps on your device</item>
+ <!-- Label explaining that the admin can see apps installed on the device. [CHAR LIMIT=NONE] -->
+ <string name="enterprise_privacy_installed_packages">List of apps on your device</string>
+ <!-- Summary indicating the number of apps that a label (e.g. installed apps or apps granted a particular permission) refers to. [CHAR LIMIT=NONE] -->
+ <plurals name="enterprise_privacy_number_packages">
+ <item quantity="one"><xliff:g id="count">%d</xliff:g> app</item>
+ <item quantity="other"><xliff:g id="count">%d</xliff:g> apps</item>
+ </plurals>
+ <!-- Summary indicating the number of apps that a label (e.g. installed apps or apps granted a particular permission) refers to. [CHAR LIMIT=NONE] -->
+ <plurals name="enterprise_privacy_number_packages_actionable">
+ <item quantity="one"><xliff:g id="count">%d</xliff:g> app. Tap to view.</item>
+ <item quantity="other"><xliff:g id="count">%d</xliff:g> apps. Tap to view.</item>
</plurals>
<!-- Label explaining that the admin can see app usage statistics. [CHAR LIMIT=NONE] -->
- <string name="enterprise_privacy_usage_stats">Usage (time spent and amount of data used) of each app on your device</string>
+ <string name="enterprise_privacy_usage_stats">Time and data spent in each app on your device</string>
<!-- Label explaining that the admin can retrieve network logs on the device. [CHAR LIMIT=NONE] -->
- <string name="enterprise_privacy_network_logs">Traffic logs on your device</string>
+ <string name="enterprise_privacy_network_logs">Network traffic logs on your device</string>
<!-- Label explaining that the admin can request bug reports on the device. [CHAR LIMIT=NONE] -->
- <string name="enterprise_privacy_bug_reports">Your most recent bug report</string>
+ <string name="enterprise_privacy_bug_reports">Most recent bug report</string>
<!-- Label explaining that the admin can retrieve security on from the device. [CHAR LIMIT=NONE] -->
- <string name="enterprise_privacy_security_logs">Your most recent security log</string>
- <!-- Label indicating that the date at which the admin last took a particular action was "never" (i.e. the admin never took the action so far). -->
- <string name="enterprise_privacy_never">Never</string>
- <!-- Label indicating how many apps were installed on the device by the admin. [CHAR LIMIT=NONE] -->
- <plurals name="enterprise_privacy_number_enterprise_installed_packages">
- <item quantity="one"><xliff:g id="count">%d</xliff:g> app installed by your admin</item>
- <item quantity="other"><xliff:g id="count">%d</xliff:g> apps installed by your admin</item>
- </plurals>
- <!-- Label indicating how many apps were granted permission to access the device's location by the admin. [CHAR LIMIT=NONE] -->
- <plurals name="enterprise_privacy_number_location_access_packages">
- <item quantity="one"><xliff:g id="count">%d</xliff:g> app allowed access to your location by your admin</item>
- <item quantity="other"><xliff:g id="count">%d</xliff:g> apps allowed access to your location by your admin</item>
- </plurals>
- <!-- Label indicating how many apps were granted permission to access the microphone by the admin. [CHAR LIMIT=NONE] -->
- <plurals name="enterprise_privacy_number_microphone_access_packages">
- <item quantity="one"><xliff:g id="count">%d</xliff:g> app allowed access to your microphone by your admin</item>
- <item quantity="other"><xliff:g id="count">%d</xliff:g> apps allowed access to your microphone by your admin</item>
- </plurals>
- <!-- Label indicating how many apps were granted permission to access the camera by the admin. [CHAR LIMIT=NONE] -->
- <plurals name="enterprise_privacy_number_camera_access_packages">
- <item quantity="one"><xliff:g id="count">%d</xliff:g> app allowed access to your camera by your admin</item>
- <item quantity="other"><xliff:g id="count">%d</xliff:g> apps allowed access to your camera by your admin</item>
- </plurals>
- <!-- Label indicating how many apps were set as default defaults for common actions (e.g. open browser, send e-mail) by the admin. [CHAR LIMIT=NONE] -->
- <plurals name="enterprise_privacy_number_enterprise_set_default_apps">
- <item quantity="one"><xliff:g id="count">%d</xliff:g> default app set by your admin</item>
- <item quantity="other"><xliff:g id="count">%d</xliff:g> default apps set by your admin</item>
- </plurals>
+ <string name="enterprise_privacy_security_logs">Most recent security log</string>
+ <!-- Label indicating that the the admin never took a given action so far (e.g. did not retrieve security logs or request bug reports). -->
+ <string name="enterprise_privacy_none">None</string>
+ <!-- Label indicating that the admin installed one or more apps on the device. -->
+ <string name="enterprise_privacy_enterprise_installed_packages">Apps installed</string>
+ <!-- Label indicating that the admin granted one or more apps access to the device's location. [CHAR LIMIT=NONE] -->
+ <string name="enterprise_privacy_location_access">Apps allowed to access your location</string>
+ <!-- Label indicating that the admin granted one or more apps access to the microphone. [CHAR LIMIT=NONE] -->
+ <string name="enterprise_privacy_microphone_access">Apps allowed to access your microphone</string>
+ <!-- Label indicating that the admin granted one or more apps access to the camera. [CHAR LIMIT=NONE] -->
+ <string name="enterprise_privacy_camera_access">Apps allowed to access your camera</string>
+ <!-- Label indicating that the admin set one or more apps as defaults for common actions (e.g. open browser, send e-mail). [CHAR LIMIT=NONE] -->
+ <string name="enterprise_privacy_enterprise_set_default_apps">Default apps set</string>
<!-- Label explaining that the current input method was set by the admin. [CHAR LIMIT=NONE] -->
- <string name="enterprise_privacy_input_method">Default keyboard set to <xliff:g id="app_label" example="Example Keyboard">%s</xliff:g> by your admin</string>
+ <string name="enterprise_privacy_input_method">Default keyboard</string>
+ <!-- Summary indicating the input method set by the admin. [CHAR LIMIT=NONE] -->
+ <string name="enterprise_privacy_input_method_name">Set to <xliff:g id="app_label" example="Example Keyboard">%s</xliff:g></string>
<!-- Label explaining that an always-on VPN was set by the admin for the entire device. [CHAR LIMIT=NONE] -->
<string name="enterprise_privacy_always_on_vpn_device">Always-on VPN turned on</string>
<!-- Label explaining that an always-on VPN was set by the admin in the personal profile. [CHAR LIMIT=NONE] -->
@@ -8180,22 +8182,46 @@
<string name="enterprise_privacy_always_on_vpn_work">Always-on VPN turned on in your work profile</string>
<!-- Label explaining that a global HTTP proxy was set by the admin. [CHAR LIMIT=NONE] -->
<string name="enterprise_privacy_global_http_proxy">Global HTTP proxy set</string>
+ <!-- Label explaining that the admin installed trusted CA certificates for the current user. [CHAR LIMIT=NONE] -->
+ <plurals name="enterprise_privacy_ca_certs_user">
+ <item quantity="one">Trusted CA Certificate installed</item>
+ <item quantity="other">Trusted CA Certificates installed</item>
+ </plurals>
+ <!-- Label explaining that the admin installed trusted CA certificates for the personal profile. [CHAR LIMIT=NONE] -->
+ <plurals name="enterprise_privacy_ca_certs_personal">
+ <item quantity="one">Trusted CA Certificate installed in the personal profile</item>
+ <item quantity="other">Trusted CA Certificates installed in the personal profile</item>
+ </plurals>
+ <!-- Summary indicating the number of trusted CA certificates installed by the admin. [CHAR LIMIT=NONE] -->
+ <plurals name="enterprise_privacy_number_ca_certs">
+ <item quantity="one"><xliff:g id="count">%d</xliff:g> certificate</item>
+ <item quantity="other"><xliff:g id="count">%d</xliff:g> certificates</item>
+ </plurals>
+ <!-- Summary indicating the number of trusted CA certificates installed by the admin. [CHAR LIMIT=NONE] -->
+ <plurals name="enterprise_privacy_number_ca_certs_actionable">
+ <item quantity="one"><xliff:g id="count">%d</xliff:g> certificate. Tap to view.</item>
+ <item quantity="other"><xliff:g id="count">%d</xliff:g> certificates. Tap to view.</item>
+ </plurals>
+ <!-- Label explaining that the admin installed trusted CA certificates for the work profile. [CHAR LIMIT=NONE] -->
+ <plurals name="enterprise_privacy_ca_certs_work">
+ <item quantity="one">Trusted CA Certificate installed in the work profile</item>
+ <item quantity="other">Trusted CA Certificates installed in the work profile</item>
+ </plurals>
<!-- Label explaining that the admin can lock the device and change the user's password. [CHAR LIMIT=NONE] -->
- <string name="enterprise_privacy_lock_device">Admin can lock device and reset password</string>
+ <string name="enterprise_privacy_lock_device">Admin can lock the device and reset password</string>
<!-- Label explaining that the admin can wipe the device remotely. [CHAR LIMIT=NONE] -->
<string name="enterprise_privacy_wipe_device">Admin can delete all device data</string>
- <!-- Label explaining that the admin configured the device to wipe itself when the password is mistyped this many times. [CHAR LIMIT=NONE] -->
- <plurals name="enterprise_privacy_failed_password_wipe_device">
- <item quantity="one">Admin set maximum password attempts to <xliff:g id="count">%d</xliff:g> before deleting all device data</item>
- <item quantity="other">Admin set maximum password attempts to <xliff:g id="count">%d</xliff:g> before deleting all device data</item>
- </plurals>
- <!-- Label explaining that the admin configured the work profile to wipe itself when the password is mistyped this many times. [CHAR LIMIT=NONE] -->
- <plurals name="enterprise_privacy_failed_password_wipe_work">
- <item quantity="one">Admin set maximum password attempts to <xliff:g id="count">%d</xliff:g> before deleting work profile data</item>
- <item quantity="other">Admin set maximum password attempts to <xliff:g id="count">%d</xliff:g> before deleting work profile data</item>
+ <!-- Label explaining that the admin configured the device to wipe itself when the password is mistyped too many times. [CHAR LIMIT=NONE] -->
+ <string name="enterprise_privacy_failed_password_wipe_device">Failed password attempts before deleting all device data</string>
+ <!-- Label explaining that the admin configured the work profile to wipe itself when the password is mistyped too many times. [CHAR LIMIT=NONE] -->
+ <string name="enterprise_privacy_failed_password_wipe_work">Failed password attempts before deleting work profile data</string>
+ <!-- Summary indicating the number of mistyped passwords after which the device or work profile wipes itself. [CHAR LIMIT=NONE] -->
+ <plurals name="enterprise_privacy_number_failed_password_wipe">
+ <item quantity="one"><xliff:g id="count">%d</xliff:g> attempt</item>
+ <item quantity="other"><xliff:g id="count">%d</xliff:g> attempts</item>
</plurals>
<!-- Message indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=NONE] -->
- <string name="do_disclosure_generic">This device is managed.</string>
+ <string name="do_disclosure_generic">This device is managed by your organization.</string>
<!-- Message indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=NONE] -->
<string name="do_disclosure_with_name">This device is managed by <xliff:g id="organization_name" example="Foo, Inc.">%s</xliff:g>.</string>
<!-- Message indicating that the device is enterprise-managed: Space that separates the main text and the "learn more" link that follows it. [CHAR LIMIT=NONE] -->
@@ -8219,7 +8245,7 @@
<string name="storage_files">Files</string>
<!-- Main settings screen item's title to go into the storage settings screen [CHAR LIMIT=25] -->
- <string name="storage_settings_2" >Phone Storage</string>
+ <string name="storage_settings_2">Phone storage</string>
<!-- Summary of a single storage volume used space. [CHAR LIMIT=24] -->
<string name="storage_size_large_alternate"><xliff:g id="number" example="128">^1</xliff:g><small> <xliff:g id="unit" example="KB">^2</xliff:g></small></string>
@@ -8228,18 +8254,6 @@
<!-- The percent of storage used by a storage volume. Exposed inside of a donut graph. [CHAR LIMIT=4]-->
<string name="storage_percent_used"><xliff:g id="percent" example="50%">%1$s</xliff:g>%%</string>
- <!-- Indicates if the automatic storage manager is enabled or not. [CHAR_LIMIT=40] -->
- <string name="storage_manager_indicator">Storage Manager: <xliff:g id="status" example="on">^1</xliff:g></string>
-
- <!-- Off status for the automatic storage manager. [CHAR_LIMIT=10] -->
- <string name="storage_manager_indicator_off">Off</string>
-
- <!-- On status for the automatic storage manager. [CHAR_LIMIT=10] -->
- <string name="storage_manager_indicator_on">On</string>
-
- <!-- Added as the value of a header field indicating this is an instant app (as opposed to installed normally) -->
- <string name="install_type_instant">Instant app</string>
-
<!-- Title of games app storage screen [CHAR LIMIT=30] -->
<string name="game_storage_settings">Games</string>
@@ -8268,4 +8282,16 @@
<!-- Temporary reboot string, will be removed -->
<string name="change_theme_reboot" translatable="false">Changing the theme requires a restart.</string>
+ <!-- Indicates if the automatic storage manager is enabled or not. [CHAR_LIMIT=40] -->
+ <string name="storage_manager_indicator">Storage Manager: <xliff:g id="status" example="on">^1</xliff:g></string>
+
+ <!-- Off status for the automatic storage manager. [CHAR_LIMIT=10] -->
+ <string name="storage_manager_indicator_off">Off</string>
+
+ <!-- On status for the automatic storage manager. [CHAR_LIMIT=10] -->
+ <string name="storage_manager_indicator_on">On</string>
+
+ <!-- Added as the value of a header field indicating this is an instant app (as opposed to installed normally) -->
+ <string name="install_type_instant">Instant app</string>
+
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 2692508..d193c30 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -428,6 +428,19 @@
<item name="android:textSize">24sp</item>
</style>
+ <style name="AppInfoHeader" parent="EntityHeader">
+ <item name="android:background">?android:attr/colorAccent</item>
+ </style>
+
+ <style name="TextAppearance.AppInfoTitle" parent="TextAppearance.EntityHeaderTitle">
+ <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
+ </style>
+
+ <style name="TextAppearance.AppInfoSummary"
+ parent="@android:style/TextAppearance.Material.Body1">
+ <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
+ </style>
+
<style name="AppActionPrimaryButton" parent="android:Widget.Material.Button.Colored"/>
<style name="LockPatternStyle">
diff --git a/res/values/styles_preference.xml b/res/values/styles_preference.xml
index e7c2852..8271df4 100644
--- a/res/values/styles_preference.xml
+++ b/res/values/styles_preference.xml
@@ -38,6 +38,11 @@
<item name="android:layout">@layout/apn_preference_layout</item>
</style>
+ <style name="FooterPreference" parent="SettingsPreference">
+ <item name="android:layout">@layout/preference_footer</item>
+ <item name="allowDividerAbove">true</item>
+ </style>
+
<style name="EditTextPreference"
parent="@style/Preference.DialogPreference.EditTextPreference.Material">
<item name="allowDividerAbove">false</item>
diff --git a/res/values/themes.xml b/res/values/themes.xml
index f49ea2c..99e2133 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -81,6 +81,7 @@
<!-- Parent path frameworks/support/v14/preference/res/values/themes.xml -->
<item name="android:scrollbars">vertical</item>
<item name="apnPreferenceStyle">@style/ApnPreference</item>
+ <item name="footerPreferenceStyle">@style/FooterPreference</item>
<item name="dialogPreferenceStyle">@style/SettingsDialogPreference</item>
<item name="dropdownPreferenceStyle">@style/SettingsDropdownPreference</item>
<item name="editTextPreferenceStyle">@style/EditTextPreference</item>
diff --git a/res/xml/app_default_settings.xml b/res/xml/app_default_settings.xml
index a382bc9..e96c070 100644
--- a/res/xml/app_default_settings.xml
+++ b/res/xml/app_default_settings.xml
@@ -67,7 +67,7 @@
android:key="default_autofill"
android:title="@string/autofill_app"
android:summary="@string/app_list_preference_none"
- android:fragment="com.android.settings.applications.defaultapps.DefaultAutoFillPicker"
+ android:fragment="com.android.settings.applications.defaultapps.DefaultAutofillPicker"
settings:keywords="@string/autofill_keywords"
android:order="-14"/>
diff --git a/res/xml/assist_gesture_settings.xml b/res/xml/assist_gesture_settings.xml
index c0a3810..52ee247 100644
--- a/res/xml/assist_gesture_settings.xml
+++ b/res/xml/assist_gesture_settings.xml
@@ -29,4 +29,10 @@
android:title="@string/assist_gesture_title"
android:summary="@string/assist_gesture_summary" />
+ <com.android.settings.SeekBarPreference
+ android:key="gesture_assist_sensitivity"
+ android:title="@string/assist_gesture_sensitivity_title"
+ android:defaultValue="2"
+ android:max="4" />
+
</PreferenceScreen>
diff --git a/res/xml/date_time_prefs.xml b/res/xml/date_time_prefs.xml
index 34d48f1..7859119 100644
--- a/res/xml/date_time_prefs.xml
+++ b/res/xml/date_time_prefs.xml
@@ -44,7 +44,7 @@
/>
<Preference
- android:fragment="com.android.settings.ZonePicker"
+ android:fragment="com.android.settings.datetime.ZonePicker"
android:key="timezone"
android:title="@string/date_time_set_timezone"
android:summary="GMT-8:00"
diff --git a/res/xml/device_info_status.xml b/res/xml/device_info_status.xml
index 1b173f1..9a57af9 100644
--- a/res/xml/device_info_status.xml
+++ b/res/xml/device_info_status.xml
@@ -14,64 +14,76 @@
limitations under the License.
-->
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
- android:title="@string/device_status_activity_title">
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:title="@string/device_status_activity_title">
- <com.android.settings.CopyablePreference android:key="battery_status"
+ <Preference
+ android:key="battery_status"
android:enabled="false"
android:shouldDisableView="false"
android:title="@string/battery_status_title"
- android:summary="@string/device_info_not_available"
- android:persistent="false" />
- <com.android.settings.CopyablePreference android:key="battery_level"
+ android:summary="@string/device_info_not_available" />
+ <Preference
+ android:key="battery_level"
android:enabled="false"
android:shouldDisableView="false"
android:title="@string/battery_level_title"
android:summary="@string/device_info_not_available"
android:persistent="false" />
- <Preference android:key="sim_status"
+ <Preference
+ android:key="sim_status"
android:title="@string/sim_status_title"
android:persistent="false">
- <intent android:targetPackage="com.android.settings"
+ <intent
+ android:targetPackage="com.android.settings"
android:targetClass="com.android.settings.Settings$SimStatusActivity" />
</Preference>
- <Preference android:key="imei_info"
+ <Preference
+ android:key="imei_info"
android:title="@string/imei_information_title"
android:persistent="false">
- <intent android:targetPackage="com.android.settings"
+ <intent
+ android:targetPackage="com.android.settings"
android:targetClass="com.android.settings.Settings$ImeiInformationActivity" />
</Preference>
- <com.android.settings.CopyablePreference android:key="wifi_ip_address"
+ <Preference
+ android:key="wifi_ip_address"
android:enabled="false"
android:shouldDisableView="false"
android:title="@string/wifi_advanced_ip_address_title"
android:summary="@string/device_info_not_available"
android:persistent="false" />
- <com.android.settings.CopyablePreference android:key="wifi_mac_address"
+ <Preference
+ android:key="wifi_mac_address"
android:enabled="false"
android:shouldDisableView="false"
android:title="@string/status_wifi_mac_address"
android:summary="@string/device_info_not_available"
android:persistent="false" />
- <com.android.settings.CopyablePreference android:key="bt_address"
+ <Preference
+ android:key="bt_address"
android:enabled="false"
android:shouldDisableView="false"
android:title="@string/status_bt_address"
android:summary="@string/device_info_not_available"
android:persistent="false" />
- <com.android.settings.CopyablePreference android:key="serial_number"
+ <Preference
+ android:key="serial_number"
android:enabled="false"
android:shouldDisableView="false"
android:title="@string/status_serial_number"
android:summary="@string/device_info_not_available"
android:persistent="false" />
- <com.android.settings.CopyablePreference android:key="up_time"
+ <Preference
+ android:key="up_time"
android:enabled="false"
android:shouldDisableView="false"
android:title="@string/status_up_time"
android:summary="@string/device_info_not_available"
android:persistent="false" />
- <com.android.settings.CopyablePreference android:key="wimax_mac_address"
+ <Preference
+ android:key="wimax_mac_address"
android:enabled="false"
android:shouldDisableView="false"
android:title="@string/status_wimax_mac_address"
diff --git a/res/xml/enterprise_privacy_settings.xml b/res/xml/enterprise_privacy_settings.xml
index 992c753..f08b9f2 100644
--- a/res/xml/enterprise_privacy_settings.xml
+++ b/res/xml/enterprise_privacy_settings.xml
@@ -19,83 +19,75 @@
android:key="enterprise_privacy_settings"
android:title="@string/enterprise_privacy_settings_title">
- <!-- Header -->
- <Preference android:key="enterprise_privacy_header"
- android:summary="@string/enterprise_privacy_header"
- android:selectable="false"/>
-
<PreferenceCategory android:title="@string/enterprise_privacy_exposure_category">
<com.android.settings.DividerPreference
android:key="enterprise_data"
android:layout_height="wrap_content"
android:title="@string/enterprise_privacy_enterprise_data"
- settings:allowDividerBelow="true"
settings:multiLine="true"/>
<com.android.settings.DividerPreference
- android:key="number_installed_packages"
- android:title="@string/enterprise_privacy_number_installed_packages_default"
- settings:allowDividerBelow="true"
+ android:key="installed_packages"
+ android:title="@string/enterprise_privacy_installed_packages"
settings:multiLine="true"/>
<com.android.settings.DividerPreference
android:key="usage_stats"
android:title="@string/enterprise_privacy_usage_stats"
- settings:allowDividerBelow="true"
settings:multiLine="true"/>
<com.android.settings.DividerPreference
android:key="network_logs"
android:title="@string/enterprise_privacy_network_logs"
- settings:allowDividerBelow="true"
settings:multiLine="true"/>
<com.android.settings.DividerPreference
android:key="bug_reports"
android:title="@string/enterprise_privacy_bug_reports"
- settings:allowDividerBelow="true"
settings:multiLine="true"/>
<com.android.settings.DividerPreference
android:key="security_logs"
android:title="@string/enterprise_privacy_security_logs"
- settings:allowDividerBelow="true"
settings:multiLine="true"/>
</PreferenceCategory>
<PreferenceCategory android:title="@string/enterprise_privacy_exposure_changes_category">
<com.android.settings.DividerPreference
android:key="number_enterprise_installed_packages"
- settings:allowDividerBelow="true"
+ android:title="@string/enterprise_privacy_enterprise_installed_packages"
settings:multiLine="true"/>
<com.android.settings.DividerPreference
android:key="enterprise_privacy_number_location_access_packages"
- settings:allowDividerBelow="true"
+ android:title="@string/enterprise_privacy_location_access"
settings:multiLine="true"/>
<com.android.settings.DividerPreference
android:key="enterprise_privacy_number_microphone_access_packages"
- settings:allowDividerBelow="true"
+ android:title="@string/enterprise_privacy_microphone_access"
settings:multiLine="true"/>
<com.android.settings.DividerPreference
android:key="enterprise_privacy_number_camera_access_packages"
- settings:allowDividerBelow="true"
+ android:title="@string/enterprise_privacy_camera_access"
settings:multiLine="true"/>
<com.android.settings.DividerPreference
android:key="number_enterprise_set_default_apps"
- settings:allowDividerBelow="true"
+ android:title="@string/enterprise_privacy_enterprise_set_default_apps"
settings:multiLine="true"/>
<com.android.settings.DividerPreference
android:key="always_on_vpn_primary_user"
- settings:allowDividerBelow="true"
settings:multiLine="true"/>
<com.android.settings.DividerPreference
android:key="always_on_vpn_managed_profile"
android:title="@string/enterprise_privacy_always_on_vpn_work"
- settings:allowDividerBelow="true"
settings:multiLine="true"/>
<com.android.settings.DividerPreference
android:key="input_method"
- settings:allowDividerBelow="true"
+ android:title="@string/enterprise_privacy_input_method"
settings:multiLine="true"/>
<com.android.settings.DividerPreference
android:key="global_http_proxy"
android:title="@string/enterprise_privacy_global_http_proxy"
- settings:allowDividerBelow="true"
+ settings:multiLine="true"/>
+ <com.android.settings.DividerPreference
+ android:key="ca_certs_current_user"
+ settings:multiLine="true"/>
+ <com.android.settings.DividerPreference
+ android:key="ca_certs_managed_profile"
settings:multiLine="true"/>
</PreferenceCategory>
@@ -103,20 +95,20 @@
<com.android.settings.DividerPreference
android:key="lock_device"
android:title="@string/enterprise_privacy_lock_device"
- settings:allowDividerBelow="true"
settings:multiLine="true"/>
<com.android.settings.DividerPreference
android:key="wipe_device"
android:title="@string/enterprise_privacy_wipe_device"
- settings:allowDividerBelow="true"
settings:multiLine="true"/>
<com.android.settings.DividerPreference
android:key="failed_password_wipe_primary_user"
- settings:allowDividerBelow="true"
settings:multiLine="true"/>
<com.android.settings.DividerPreference
android:key="failed_password_wipe_managed_profile"
- settings:allowDividerBelow="true"
settings:multiLine="true"/>
</PreferenceCategory>
+
+ <com.android.settings.widget.FooterPreference
+ android:title="@string/enterprise_privacy_footer"
+ android:selectable="false"/>
</PreferenceScreen>
diff --git a/res/xml/ia_sound_settings.xml b/res/xml/ia_sound_settings.xml
index 27fcdda..a34d875 100644
--- a/res/xml/ia_sound_settings.xml
+++ b/res/xml/ia_sound_settings.xml
@@ -151,4 +151,41 @@
android:targetClass="com.android.cellbroadcastreceiver.CellBroadcastSettings" />
</com.android.settingslib.RestrictedPreference>
+ <com.android.settings.WorkOnlyCategory
+ android:key="sound_work_settings_section"
+ android:title="@string/sound_work_settings">
+
+ <!-- Use the same sounds of the work profile -->
+ <SwitchPreference
+ android:key="work_use_personal_sounds"
+ android:title="@string/work_use_personal_sounds_title"
+ android:summary="@string/work_use_personal_sounds_summary"
+ android:disableDependentsState="true" />
+
+ <!-- Work phone ringtone -->
+ <com.android.settings.DefaultRingtonePreference
+ android:key="work_ringtone"
+ android:title="@string/work_ringtone_title"
+ android:dialogTitle="@string/work_alarm_ringtone_title"
+ android:ringtoneType="ringtone"
+ android:dependency="work_use_personal_sounds" />
+
+ <!-- Default work notification ringtone -->
+ <com.android.settings.DefaultRingtonePreference
+ android:key="work_notification_ringtone"
+ android:title="@string/work_notification_ringtone_title"
+ android:dialogTitle="@string/work_alarm_ringtone_title"
+ android:ringtoneType="notification"
+ android:dependency="work_use_personal_sounds" />
+
+ <!-- Default work alarm ringtone -->
+ <com.android.settings.DefaultRingtonePreference
+ android:key="work_alarm_ringtone"
+ android:title="@string/work_alarm_ringtone_title"
+ android:dialogTitle="@string/work_alarm_ringtone_title"
+ android:persistent="false"
+ android:ringtoneType="alarm"
+ android:dependency="work_use_personal_sounds" />
+
+ </com.android.settings.WorkOnlyCategory>
</PreferenceScreen>
diff --git a/res/xml/installed_app_launch_settings.xml b/res/xml/installed_app_launch_settings.xml
index 7342cc0..ac77be1 100644
--- a/res/xml/installed_app_launch_settings.xml
+++ b/res/xml/installed_app_launch_settings.xml
@@ -37,8 +37,7 @@
android:title="@string/app_launch_other_defaults_title">
<com.android.settings.applications.ClearDefaultsPreference
- android:key="app_launch_clear_defaults"
- />
+ android:key="app_launch_clear_defaults" />
</PreferenceCategory>
diff --git a/res/xml/power_usage_details.xml b/res/xml/power_usage_details.xml
index 724aae8..86aa4f5 100644
--- a/res/xml/power_usage_details.xml
+++ b/res/xml/power_usage_details.xml
@@ -26,6 +26,11 @@
android:key="controls_parent"
android:title="@string/controls_subtitle">
+ <SwitchPreference
+ android:key="background_activity"
+ android:title="@string/background_activity_title"
+ android:summary="@string/background_activity_summary"/>
+
<Preference
android:key="high_power"
android:title="@string/high_power_apps" />
diff --git a/res/xml/security_settings_misc.xml b/res/xml/security_settings_misc.xml
index 04272df..155f21a 100644
--- a/res/xml/security_settings_misc.xml
+++ b/res/xml/security_settings_misc.xml
@@ -43,6 +43,12 @@
android:persistent="false"
android:fragment="com.android.settings.DeviceAdminSettings"/>
+ <Preference android:key="enterprise_privacy"
+ android:title="@string/enterprise_privacy_settings"
+ android:summary="@string/enterprise_privacy_settings_summary"
+ android:persistent="false"
+ android:fragment="com.android.settings.enterprise.EnterprisePrivacySettings"/>
+
</PreferenceCategory>
<Preference android:key="sim_lock_settings"
diff --git a/res/xml/sound_work_settings.xml b/res/xml/sound_work_settings.xml
deleted file mode 100644
index b63ec75..0000000
--- a/res/xml/sound_work_settings.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-<?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.
--->
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
- android:title="@string/sound_work_settings"
- android:key="sound_work_settings">
-
- <PreferenceCategory
- android:key="sound_work_settings_section"
- android:title="@string/sound_work_settings">
-
- <!-- Use the same sounds of the work profile -->
- <SwitchPreference
- android:key="work_use_personal_sounds"
- android:title="@string/work_use_personal_sounds_title"
- android:summary="@string/work_use_personal_sounds_summary"
- android:disableDependentsState="true" />
-
- <!-- Work phone ringtone -->
- <com.android.settings.DefaultRingtonePreference
- android:key="work_ringtone"
- android:title="@string/work_ringtone_title"
- android:dialogTitle="@string/work_alarm_ringtone_title"
- android:ringtoneType="ringtone"
- android:dependency="work_use_personal_sounds" />
-
- <!-- Default work notification ringtone -->
- <com.android.settings.DefaultRingtonePreference
- android:key="work_notification_ringtone"
- android:title="@string/work_notification_ringtone_title"
- android:dialogTitle="@string/work_alarm_ringtone_title"
- android:ringtoneType="notification"
- android:dependency="work_use_personal_sounds" />
-
- <!-- Default work alarm ringtone -->
- <com.android.settings.DefaultRingtonePreference
- android:key="work_alarm_ringtone"
- android:title="@string/work_alarm_ringtone_title"
- android:dialogTitle="@string/work_alarm_ringtone_title"
- android:persistent="false"
- android:ringtoneType="alarm"
- android:dependency="work_use_personal_sounds" />
-
- </PreferenceCategory>
-
-</PreferenceScreen>
diff --git a/res/xml/storage_dashboard_fragment.xml b/res/xml/storage_dashboard_fragment.xml
index fedc77f..78ccbbf 100644
--- a/res/xml/storage_dashboard_fragment.xml
+++ b/res/xml/storage_dashboard_fragment.xml
@@ -21,45 +21,38 @@
<com.android.settings.deviceinfo.storage.StorageSummaryDonutPreference
android:key="pref_summary"
android:order="0" />
+ <com.android.settings.widget.MasterSwitchPreference
+ android:fragment="com.android.settings.deletionhelper.AutomaticStorageManagerSettings"
+ android:key="toggle_asm"
+ android:title="@string/automatic_storage_manager_preference_title"
+ android:icon="@drawable/ic_settings_storage"
+ android:order="1" />
<com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate
android:key="pref_photos_videos"
android:title="@string/storage_photos_videos"
- android:order="1" >
- </com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate>
+ android:order="2" />
<com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate
android:key="pref_music_audio"
android:title="@string/storage_music_audio"
- android:order="2" >
- </com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate>
+ android:order="3" />
<com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate
android:key="pref_games"
android:title="@string/storage_games"
- android:order="3" >
- </com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate>
+ android:order="4" />
<com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate
android:key="pref_other_apps"
android:title="@string/storage_other_apps"
- android:order="4" >
- </com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate>
+ android:order="5" />
<com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate
android:key="pref_files"
android:title="@string/storage_files"
- android:order="5" >
- </com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate>
+ android:order="6" />
<com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate
android:key="pref_system"
android:title="@string/storage_detail_system"
- android:order="100" >
- </com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate>
+ android:order="100" />
<PreferenceCategory
android:key="pref_secondary_users"
android:title="@string/storage_other_users"
android:order="200" />
- <Preference
- android:key="manage_storage"
- android:title="@string/storage_menu_manage"
- android:icon="@drawable/ic_settings_storage"
- android:fragment="com.android.settings.deletionhelper.AutomaticStorageManagerSettings"
- android:order="300" >
- </Preference>
</PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/user_and_accounts_settings.xml b/res/xml/user_and_accounts_settings.xml
index bc3ac6c..6280980 100644
--- a/res/xml/user_and_accounts_settings.xml
+++ b/res/xml/user_and_accounts_settings.xml
@@ -23,7 +23,8 @@
<Preference
android:key="emergency_info"
android:title="@string/emergency_info_title"
- android:order="100"/>
+ android:order="100"
+ settings:allowDividerAbove="true"/>
<PreferenceCategory
android:key="account_configuration_header"
diff --git a/src/com/android/settings/CopyablePreference.java b/src/com/android/settings/CopyablePreference.java
deleted file mode 100644
index 03147c2..0000000
--- a/src/com/android/settings/CopyablePreference.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.ClipboardManager;
-import android.content.Context;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceViewHolder;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.View.OnLongClickListener;
-import android.widget.Toast;
-
-public class CopyablePreference extends Preference {
-
- public CopyablePreference(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public CopyablePreference(Context context) {
- this(context, null);
- }
-
- @Override
- public void onBindViewHolder(PreferenceViewHolder holder) {
- super.onBindViewHolder(holder);
- holder.setDividerAllowedAbove(true);
- holder.setDividerAllowedBelow(true);
- holder.itemView.setLongClickable(true);
- holder.itemView.setOnLongClickListener(new OnLongClickListener() {
- @Override
- public boolean onLongClick(View v) {
- copyPreference(getContext(), CopyablePreference.this);
- return true;
- }
- });
- }
-
- public CharSequence getCopyableText() {
- return getSummary();
- }
-
- public static void copyPreference(Context context, CopyablePreference pref) {
- ClipboardManager cm =
- (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
- cm.setText(pref.getCopyableText());
- Toast.makeText(context, com.android.internal.R.string.text_copied, Toast.LENGTH_SHORT)
- .show();
- }
-}
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 2b486aa..f2d6452 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -131,6 +131,7 @@
public static class ManageExternalSourcesActivity extends SettingsActivity {
/* empty */ }
+ public static class ManageAppExternalSourcesActivity extends SettingsActivity { /* empty */ }
public static class WifiCallingSuggestionActivity extends SettingsActivity { /* empty */ }
public static class ZenModeAutomationSuggestionActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 7d6cf77..7a4d5f8 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -67,6 +67,7 @@
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.DynamicIndexableContentMonitor;
import com.android.settings.search2.SearchFeatureProvider;
+import com.android.settings.wfd.WifiDisplaySettings;
import com.android.settings.widget.SwitchBar;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.SettingsDrawerActivity;
@@ -947,6 +948,10 @@
FeatureFactory.getFactory(this).getEnterprisePrivacyFeatureProvider(this)
.hasDeviceOwner(), isAdmin);
+ setTileEnabled(new ComponentName(packageName,
+ Settings.WifiDisplaySettingsActivity.class.getName()),
+ WifiDisplaySettings.isAvailable(this), isAdmin);
+
if (UserHandle.MU_ENABLED && !isAdmin) {
// When on restricted users, disable all extra categories (but only the settings ones).
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 350ab9c..f267640 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -302,13 +302,6 @@
return formatPercentage(getBatteryLevel(batteryChangedIntent));
}
- public static void forcePrepareCustomPreferencesList(
- ViewGroup parent, View child, ListView list, boolean ignoreSidePadding) {
- list.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
- list.setClipToPadding(false);
- prepareCustomPreferencesList(parent, child, list, ignoreSidePadding);
- }
-
/**
* Prepare a custom preferences layout, moving padding to {@link ListView}
* when outside scrollbars are requested. Usually used to display
diff --git a/src/com/android/settings/applications/AdvancedAppSettings.java b/src/com/android/settings/applications/AdvancedAppSettings.java
index c68e19f..b8ebeb4 100644
--- a/src/com/android/settings/applications/AdvancedAppSettings.java
+++ b/src/com/android/settings/applications/AdvancedAppSettings.java
@@ -20,7 +20,7 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
-import com.android.settings.applications.defaultapps.DefaultAutoFillPreferenceController;
+import com.android.settings.applications.defaultapps.DefaultAutofillPreferenceController;
import com.android.settings.applications.defaultapps.DefaultBrowserPreferenceController;
import com.android.settings.applications.defaultapps.DefaultEmergencyPreferenceController;
import com.android.settings.applications.defaultapps.DefaultHomePreferenceController;
@@ -61,7 +61,7 @@
controllers.add(new DefaultSmsPreferenceController(context));
controllers.add(new DefaultEmergencyPreferenceController(context));
controllers.add(new DefaultHomePreferenceController(context));
- controllers.add(new DefaultAutoFillPreferenceController(context));
+ controllers.add(new DefaultAutofillPreferenceController(context));
return controllers;
}
diff --git a/src/com/android/settings/applications/ClearDefaultsPreference.java b/src/com/android/settings/applications/ClearDefaultsPreference.java
index e9c5a0e..0de2676 100644
--- a/src/com/android/settings/applications/ClearDefaultsPreference.java
+++ b/src/com/android/settings/applications/ClearDefaultsPreference.java
@@ -24,6 +24,7 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
+import android.support.v4.content.res.TypedArrayUtils;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceViewHolder;
import android.text.SpannableString;
@@ -68,7 +69,9 @@
}
public ClearDefaultsPreference(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
+ this(context, attrs, TypedArrayUtils.getAttr(context,
+ android.support.v7.preference.R.attr.preferenceStyle,
+ android.R.attr.preferenceStyle));
}
public ClearDefaultsPreference(Context context) {
diff --git a/src/com/android/settings/applications/ExternalSourcesDetails.java b/src/com/android/settings/applications/ExternalSourcesDetails.java
index af9251c..6441437 100644
--- a/src/com/android/settings/applications/ExternalSourcesDetails.java
+++ b/src/com/android/settings/applications/ExternalSourcesDetails.java
@@ -15,6 +15,9 @@
*/
package com.android.settings.applications;
+import static android.app.Activity.RESULT_CANCELED;
+import static android.app.Activity.RESULT_OK;
+
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import android.app.AlertDialog;
@@ -26,6 +29,7 @@
import android.support.v7.preference.Preference.OnPreferenceChangeListener;
import com.android.settings.R;
+import com.android.settings.Settings;
import com.android.settings.applications.AppStateInstallAppsBridge.InstallAppsState;
import com.android.settingslib.applications.ApplicationsState.AppEntry;
@@ -67,6 +71,10 @@
final boolean checked = (Boolean) newValue;
if (preference == mSwitchPref) {
if (mInstallAppsState != null && checked != mInstallAppsState.canInstallApps()) {
+ if (Settings.ManageAppExternalSourcesActivity.class.getName().equals(
+ getIntent().getComponent().getClassName())) {
+ setResult(checked ? RESULT_OK : RESULT_CANCELED);
+ }
setCanInstallApps(checked);
refreshUi();
}
@@ -97,9 +105,13 @@
protected boolean refreshUi() {
mInstallAppsState = mAppBridge.createInstallAppsStateFor(mPackageName,
mPackageInfo.applicationInfo.uid);
-
- final boolean canWrite = mInstallAppsState.canInstallApps();
- mSwitchPref.setChecked(canWrite);
+ if (!mInstallAppsState.isPotentialAppSource()) {
+ // Invalid app entry. Should not allow changing permission
+ mSwitchPref.setEnabled(false);
+ return true;
+ }
+ final boolean canInstallApps = mInstallAppsState.canInstallApps();
+ mSwitchPref.setChecked(canInstallApps);
return true;
}
diff --git a/src/com/android/settings/applications/assist/GestureAssistPreferenceController.java b/src/com/android/settings/applications/assist/GestureAssistPreferenceController.java
deleted file mode 100644
index bd85a03..0000000
--- a/src/com/android/settings/applications/assist/GestureAssistPreferenceController.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.settings.applications.assist;
-
-import android.content.Context;
-
-import com.android.settings.core.PreferenceController;
-import com.android.settings.gestures.AssistGestureFeatureProvider;
-import com.android.settings.overlay.FeatureFactory;
-
-public class GestureAssistPreferenceController extends PreferenceController {
-
- private static final String KEY_ASSIST_GESTURE = "gesture_assist";
-
- private AssistGestureFeatureProvider mFeatureProvider;
-
- public GestureAssistPreferenceController(Context context) {
- super(context);
- mFeatureProvider = FeatureFactory.getFactory(context)
- .getAssistGestureFeatureProvider();
- }
-
- @Override
- public boolean isAvailable() {
- return mFeatureProvider.isSupported(mContext);
- }
-
- @Override
- public String getPreferenceKey() {
- return KEY_ASSIST_GESTURE;
- }
-}
diff --git a/src/com/android/settings/applications/assist/ManageAssist.java b/src/com/android/settings/applications/assist/ManageAssist.java
index a54f0ff..824c0b1 100644
--- a/src/com/android/settings/applications/assist/ManageAssist.java
+++ b/src/com/android/settings/applications/assist/ManageAssist.java
@@ -24,6 +24,7 @@
import com.android.settings.core.PreferenceController;
import com.android.settings.core.lifecycle.Lifecycle;
import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.gestures.AssistGesturePreferenceController;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
@@ -70,7 +71,7 @@
Lifecycle lifecycle) {
final List<PreferenceController> controllers = new ArrayList<>();
controllers.add(new DefaultAssistPreferenceController(context));
- controllers.add(new GestureAssistPreferenceController(context));
+ controllers.add(new AssistGesturePreferenceController(context, lifecycle));
controllers.add(new AssistContextPreferenceController(context, lifecycle));
controllers.add(new AssistScreenshotPreferenceController(context, lifecycle));
controllers.add(new AssistFlashScreenPreferenceController(context, lifecycle));
diff --git a/src/com/android/settings/applications/defaultapps/DefaultAutoFillPicker.java b/src/com/android/settings/applications/defaultapps/DefaultAutofillPicker.java
similarity index 62%
rename from src/com/android/settings/applications/defaultapps/DefaultAutoFillPicker.java
rename to src/com/android/settings/applications/defaultapps/DefaultAutofillPicker.java
index b8190cd..e3a7a2b 100644
--- a/src/com/android/settings/applications/defaultapps/DefaultAutoFillPicker.java
+++ b/src/com/android/settings/applications/defaultapps/DefaultAutofillPicker.java
@@ -23,7 +23,8 @@
import android.content.pm.ServiceInfo;
import android.provider.Settings;
import android.service.autofill.AutoFillService;
-import android.service.autofill.AutoFillServiceInfo;
+import android.service.autofill.AutofillService;
+import android.service.autofill.AutofillServiceInfo;
import android.text.TextUtils;
import com.android.internal.logging.nano.MetricsProto;
@@ -32,10 +33,12 @@
import java.util.ArrayList;
import java.util.List;
-public class DefaultAutoFillPicker extends DefaultAppPickerFragment {
+public class DefaultAutofillPicker extends DefaultAppPickerFragment {
- static final String SETTING = Settings.Secure.AUTO_FILL_SERVICE;
- static final Intent AUTO_FILL_PROBE = new Intent(AutoFillService.SERVICE_INTERFACE);
+ static final String SETTING = Settings.Secure.AUTOFILL_SERVICE;
+ // TODO(b/35956626): remove once clients migrated
+ static final Intent OLD_AUTO_FILL_PROBE = new Intent(AutoFillService.OLD_SERVICE_INTERFACE);
+ static final Intent AUTOFILL_PROBE = new Intent(AutofillService.SERVICE_INTERFACE);
@Override
public int getMetricsCategory() {
@@ -51,11 +54,17 @@
protected List<DefaultAppInfo> getCandidates() {
final List<DefaultAppInfo> candidates = new ArrayList<>();
final List<ResolveInfo> resolveInfos = mPm.getPackageManager()
- .queryIntentServices(AUTO_FILL_PROBE, PackageManager.GET_META_DATA);
+ .queryIntentServices(AUTOFILL_PROBE, PackageManager.GET_META_DATA);
for (ResolveInfo info : resolveInfos) {
candidates.add(new DefaultAppInfo(mUserId, new ComponentName(
info.serviceInfo.packageName, info.serviceInfo.name)));
}
+ final List<ResolveInfo> oldResolveInfos = mPm.getPackageManager()
+ .queryIntentServices(OLD_AUTO_FILL_PROBE, PackageManager.GET_META_DATA);
+ for (ResolveInfo info : oldResolveInfos) {
+ candidates.add(new DefaultAppInfo(mUserId, new ComponentName(
+ info.serviceInfo.packageName, info.serviceInfo.name)));
+ }
return candidates;
}
@@ -82,13 +91,12 @@
/**
* Provides Intent to setting activity for the specified auto-fill service.
*/
- static final class AutoFillSettingIntentProvider
- implements SettingIntentProvider {
+ static final class AutofillSettingIntentProvider implements SettingIntentProvider {
private final String mSelectedKey;
private final PackageManager mPackageManager;
- public AutoFillSettingIntentProvider(PackageManager packageManager, String key) {
+ public AutofillSettingIntentProvider(PackageManager packageManager, String key) {
mSelectedKey = key;
mPackageManager = packageManager;
}
@@ -96,14 +104,33 @@
@Override
public Intent getIntent() {
final List<ResolveInfo> resolveInfos = mPackageManager.queryIntentServices(
- AUTO_FILL_PROBE, PackageManager.GET_META_DATA);
+ AUTOFILL_PROBE, PackageManager.GET_META_DATA);
for (ResolveInfo resolveInfo : resolveInfos) {
final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
final String flattenKey = new ComponentName(
serviceInfo.packageName, serviceInfo.name).flattenToString();
if (TextUtils.equals(mSelectedKey, flattenKey)) {
- final String settingsActivity = new AutoFillServiceInfo(
+ final String settingsActivity = new AutofillServiceInfo(
+ mPackageManager, serviceInfo)
+ .getSettingsActivity();
+ if (TextUtils.isEmpty(settingsActivity)) {
+ return null;
+ }
+ return new Intent(Intent.ACTION_MAIN).setComponent(
+ new ComponentName(serviceInfo.packageName, settingsActivity));
+ }
+ }
+
+ final List<ResolveInfo> oldResolveInfos = mPackageManager.queryIntentServices(
+ OLD_AUTO_FILL_PROBE, PackageManager.GET_META_DATA);
+
+ for (ResolveInfo resolveInfo : oldResolveInfos) {
+ final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
+ final String flattenKey = new ComponentName(
+ serviceInfo.packageName, serviceInfo.name).flattenToString();
+ if (TextUtils.equals(mSelectedKey, flattenKey)) {
+ final String settingsActivity = new AutofillServiceInfo(
mPackageManager, serviceInfo)
.getSettingsActivity();
if (TextUtils.isEmpty(settingsActivity)) {
diff --git a/src/com/android/settings/applications/defaultapps/DefaultAutoFillPreferenceController.java b/src/com/android/settings/applications/defaultapps/DefaultAutofillPreferenceController.java
similarity index 85%
rename from src/com/android/settings/applications/defaultapps/DefaultAutoFillPreferenceController.java
rename to src/com/android/settings/applications/defaultapps/DefaultAutofillPreferenceController.java
index b7f3b77..c536dbb 100644
--- a/src/com/android/settings/applications/defaultapps/DefaultAutoFillPreferenceController.java
+++ b/src/com/android/settings/applications/defaultapps/DefaultAutofillPreferenceController.java
@@ -22,9 +22,9 @@
import android.provider.Settings;
import android.text.TextUtils;
-public class DefaultAutoFillPreferenceController extends DefaultAppPreferenceController {
+public class DefaultAutofillPreferenceController extends DefaultAppPreferenceController {
- public DefaultAutoFillPreferenceController(Context context) {
+ public DefaultAutofillPreferenceController(Context context) {
super(context);
}
@@ -43,8 +43,8 @@
if (info == null) {
return null;
}
- final DefaultAutoFillPicker.AutoFillSettingIntentProvider intentProvider =
- new DefaultAutoFillPicker.AutoFillSettingIntentProvider(
+ final DefaultAutofillPicker.AutofillSettingIntentProvider intentProvider =
+ new DefaultAutofillPicker.AutofillSettingIntentProvider(
mPackageManager.getPackageManager(), info.getKey());
return intentProvider.getIntent();
}
@@ -52,7 +52,7 @@
@Override
protected DefaultAppInfo getDefaultAppInfo() {
final String flattenComponent = Settings.Secure.getString(mContext.getContentResolver(),
- DefaultAutoFillPicker.SETTING);
+ DefaultAutofillPicker.SETTING);
if (!TextUtils.isEmpty(flattenComponent)) {
DefaultAppInfo appInfo = new DefaultAppInfo(
mUserId, ComponentName.unflattenFromString(flattenComponent));
diff --git a/src/com/android/settings/bluetooth/BluetoothProgressCategory.java b/src/com/android/settings/bluetooth/BluetoothProgressCategory.java
index a36c98b..ec948e0 100644
--- a/src/com/android/settings/bluetooth/BluetoothProgressCategory.java
+++ b/src/com/android/settings/bluetooth/BluetoothProgressCategory.java
@@ -48,7 +48,6 @@
}
private void init() {
- setIcon(R.drawable.ic_settings_bluetooth);
setEmptyTextRes(R.string.bluetooth_no_devices_found);
}
}
diff --git a/src/com/android/settings/core/DynamicAvailabilityPreferenceController.java b/src/com/android/settings/core/DynamicAvailabilityPreferenceController.java
new file mode 100644
index 0000000..9323aa3
--- /dev/null
+++ b/src/com/android/settings/core/DynamicAvailabilityPreferenceController.java
@@ -0,0 +1,59 @@
+/*
+ * 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.settings.core;
+
+import android.content.Context;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.core.lifecycle.Lifecycle;
+import com.android.settings.core.lifecycle.LifecycleObserver;
+import com.android.settings.core.lifecycle.events.OnResume;
+
+public abstract class DynamicAvailabilityPreferenceController extends PreferenceController
+ implements LifecycleObserver, OnResume {
+
+ private Preference mPreference;
+ private PreferenceScreen mScreen;
+
+ public DynamicAvailabilityPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context);
+ if (lifecycle != null) {
+ lifecycle.addObserver(this);
+ }
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ mScreen = screen;
+ mPreference = screen.findPreference(getPreferenceKey());
+ super.displayPreference(screen);
+ }
+
+ @Override
+ public void onResume() {
+ if (!isAvailable()) {
+ removePreference(mScreen, getPreferenceKey());
+ return;
+ }
+
+ updateState(mPreference);
+ if (mScreen.findPreference(getPreferenceKey()) == null) {
+ mScreen.addPreference(mPreference);
+ }
+ }
+}
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index 59c5014..2a3c5d3 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -50,6 +50,7 @@
import com.android.settings.applications.AdvancedAppSettings;
import com.android.settings.applications.AppAndNotificationDashboardFragment;
import com.android.settings.applications.DrawOverlayDetails;
+import com.android.settings.applications.ExternalSourcesDetails;
import com.android.settings.applications.InstalledAppDetails;
import com.android.settings.applications.ManageApplications;
import com.android.settings.applications.ManageDomainUrls;
@@ -214,6 +215,7 @@
ProcessStatsSummary.class.getName(),
DrawOverlayDetails.class.getName(),
WriteSettingsDetails.class.getName(),
+ ExternalSourcesDetails.class.getName(),
AdvancedAppSettings.class.getName(),
WallpaperTypeSettings.class.getName(),
VrListenerSettings.class.getName(),
diff --git a/src/com/android/settings/datausage/DataUsageMeteredSettings.java b/src/com/android/settings/datausage/DataUsageMeteredSettings.java
index 1982887..ce2bc8d 100644
--- a/src/com/android/settings/datausage/DataUsageMeteredSettings.java
+++ b/src/com/android/settings/datausage/DataUsageMeteredSettings.java
@@ -114,7 +114,8 @@
}
private Preference buildWifiPref(WifiConfiguration config) {
- final String networkId = config.SSID;
+ final String networkId = config.isPasspoint() ?
+ config.providerFriendlyName : config.SSID;
final NetworkTemplate template = NetworkTemplate.buildTemplateWifi(networkId);
final MeteredPreference pref = new MeteredPreference(getPrefContext(), template);
pref.setTitle(removeDoubleQuotes(networkId));
diff --git a/src/com/android/settings/ZonePicker.java b/src/com/android/settings/datetime/ZonePicker.java
similarity index 89%
rename from src/com/android/settings/ZonePicker.java
rename to src/com/android/settings/datetime/ZonePicker.java
index f6d6a6c..2d58dd8 100644
--- a/src/com/android/settings/ZonePicker.java
+++ b/src/com/android/settings/datetime/ZonePicker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settings;
+package com.android.settings.datetime;
import android.annotation.NonNull;
import android.app.Activity;
@@ -33,8 +33,9 @@
import android.widget.TextView;
import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.core.instrumentation.VisibilityLoggerMixin;
+import com.android.settings.R;
import com.android.settings.core.instrumentation.Instrumentable;
+import com.android.settings.core.instrumentation.VisibilityLoggerMixin;
import com.android.settingslib.datetime.ZoneGetter;
import java.util.Collections;
@@ -52,11 +53,6 @@
*/
public class ZonePicker extends ListFragment implements Instrumentable {
- public interface ZoneSelectionListener {
- // You can add any argument if you really need it...
- void onZoneSelected(TimeZone tz);
- }
-
private static final int MENU_TIMEZONE = Menu.FIRST+1;
private static final int MENU_ALPHABETICAL = Menu.FIRST;
private final VisibilityLoggerMixin mVisibilityLoggerMixin =
@@ -67,8 +63,6 @@
private SimpleAdapter mTimezoneSortedAdapter;
private SimpleAdapter mAlphabeticalAdapter;
- private ZoneSelectionListener mListener;
-
/**
* Constructs an adapter with TimeZone list. Sorted by TimeZone in default.
*
@@ -148,15 +142,6 @@
return -1;
}
- /**
- * @param item one of items in adapters. The adapter should be constructed by
- * {@link #constructTimezoneAdapter(Context, boolean)}.
- * @return TimeZone object corresponding to the item.
- */
- public static TimeZone obtainTimeZoneFromItem(Object item) {
- return TimeZone.getTimeZone((String)((Map<?, ?>)item).get(ZoneGetter.KEY_ID));
- }
-
@Override
public void onAttach(Context context) {
super.onAttach(context);
@@ -185,8 +170,8 @@
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = super.onCreateView(inflater, container, savedInstanceState);
- final ListView list = (ListView) view.findViewById(android.R.id.list);
- Utils.forcePrepareCustomPreferencesList(container, view, list, false);
+ final ListView list = view.findViewById(android.R.id.list);
+ prepareCustomPreferencesList(list);
return view;
}
@@ -233,8 +218,10 @@
}
}
- public void setZoneSelectionListener(ZoneSelectionListener listener) {
- mListener = listener;
+ static void prepareCustomPreferencesList(ListView list) {
+ list.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
+ list.setClipToPadding(false);
+ list.setDivider(null);
}
private void setSorting(boolean sortByTimezone) {
@@ -259,12 +246,9 @@
final Activity activity = getActivity();
final AlarmManager alarm = (AlarmManager) activity.getSystemService(Context.ALARM_SERVICE);
alarm.setTimeZone(tzId);
- final TimeZone tz = TimeZone.getTimeZone(tzId);
- if (mListener != null) {
- mListener.onZoneSelected(tz);
- } else {
- getActivity().onBackPressed();
- }
+
+ getActivity().onBackPressed();
+
}
@Override
diff --git a/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java b/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java
index bff0882..4d4cfe8 100644
--- a/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java
+++ b/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java
@@ -18,6 +18,7 @@
import android.app.Activity;
import android.app.AlertDialog;
+import android.app.FragmentManager;
import android.content.ContentResolver;
import android.content.Intent;
import android.os.Bundle;
diff --git a/src/com/android/settings/deviceinfo/ManageStoragePreferenceController.java b/src/com/android/settings/deviceinfo/ManageStoragePreferenceController.java
deleted file mode 100644
index 769b69b..0000000
--- a/src/com/android/settings/deviceinfo/ManageStoragePreferenceController.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.
- */
-package com.android.settings.deviceinfo;
-
-import android.content.Context;
-
-import com.android.settings.R;
-import com.android.settings.core.PreferenceController;
-
-public class ManageStoragePreferenceController extends PreferenceController {
-
- public static final String KEY_MANAGE_STORAGE = "manage_storage";
-
- public ManageStoragePreferenceController(Context context) {
- super(context);
- }
-
- @Override
- public String getPreferenceKey() {
- return KEY_MANAGE_STORAGE;
- }
-
- @Override
- public boolean isAvailable() {
- return mContext.getResources().getBoolean(R.bool.config_storage_manager_settings_enabled);
- }
-}
-
diff --git a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
index 92703e3..133c56c 100644
--- a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
+++ b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
@@ -35,6 +35,7 @@
import com.android.settings.applications.UserManagerWrapperImpl;
import com.android.settings.core.PreferenceController;
import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.deviceinfo.storage.AutomaticStorageManagementSwitchPreferenceController;
import com.android.settings.deviceinfo.storage.SecondaryUserController;
import com.android.settings.deviceinfo.storage.StorageAsyncLoader;
import com.android.settings.deviceinfo.storage.StorageItemPreferenceController;
@@ -146,7 +147,11 @@
mSecondaryUsers = SecondaryUserController.getSecondaryUserControllers(context, userManager);
controllers.addAll(mSecondaryUsers);
- controllers.add(new ManageStoragePreferenceController(context));
+ final AutomaticStorageManagementSwitchPreferenceController asmController =
+ new AutomaticStorageManagementSwitchPreferenceController(
+ context, mMetricsFeatureProvider, getFragmentManager());
+ getLifecycle().addObserver(asmController);
+ controllers.add(asmController);
return controllers;
}
@@ -189,7 +194,6 @@
null /* volume */, new StorageManagerVolumeProvider(sm)));
controllers.addAll(SecondaryUserController.getSecondaryUserControllers(
context, userManager));
- controllers.add(new ManageStoragePreferenceController(context));
return controllers;
}
diff --git a/src/com/android/settings/deviceinfo/StorageSettings.java b/src/com/android/settings/deviceinfo/StorageSettings.java
index c062a56..b2bad3a 100644
--- a/src/com/android/settings/deviceinfo/StorageSettings.java
+++ b/src/com/android/settings/deviceinfo/StorageSettings.java
@@ -234,8 +234,8 @@
final Bundle args = new Bundle();
args.putString(VolumeInfo.EXTRA_VOLUME_ID, VolumeInfo.ID_PRIVATE_INTERNAL);
Intent intent = Utils.onBuildStartFragmentIntent(getActivity(),
- StorageDashboardFragment.class.getName(), args, null, R.string.apps_storage,
- null, false, getMetricsCategory());
+ StorageDashboardFragment.class.getName(), args, null,
+ R.string.storage_settings_2, null, false, getMetricsCategory());
intent.putExtra(SettingsDrawerActivity.EXTRA_SHOW_MENU, true);
getActivity().startActivity(intent);
finish();
@@ -280,7 +280,7 @@
if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) {
startFragment(this, StorageDashboardFragment.class.getCanonicalName(),
- -1, 0, args);
+ R.string.storage_settings_2, 0, args);
} else {
// TODO: Go to the StorageDashboardFragment once it fully handles all of the
// SD card cases and other private internal storage cases.
diff --git a/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceController.java b/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceController.java
new file mode 100644
index 0000000..a8ca5b9
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceController.java
@@ -0,0 +1,100 @@
+/**
+ * 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.settings.deviceinfo.storage;
+
+import android.app.FragmentManager;
+import android.content.Context;
+import android.os.SystemProperties;
+import android.provider.Settings;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.core.PreferenceController;
+import com.android.settings.core.instrumentation.MetricsFeatureProvider;
+import com.android.settings.core.lifecycle.LifecycleObserver;
+import com.android.settings.core.lifecycle.events.OnResume;
+import com.android.settings.deletionhelper.ActivationWarningFragment;
+import com.android.settings.widget.MasterSwitchController;
+import com.android.settings.widget.MasterSwitchPreference;
+import com.android.settings.widget.SwitchWidgetController;
+
+public class AutomaticStorageManagementSwitchPreferenceController extends PreferenceController
+ implements LifecycleObserver, OnResume, SwitchWidgetController.OnSwitchChangeListener {
+ private static final String KEY_TOGGLE_ASM = "toggle_asm";
+ @VisibleForTesting
+ static final String STORAGE_MANAGER_ENABLED_BY_DEFAULT_PROPERTY = "ro.storage_manager.enabled";
+
+ private MasterSwitchPreference mSwitch;
+ private MasterSwitchController mSwitchController;
+ private final MetricsFeatureProvider mMetricsFeatureProvider;
+ private final FragmentManager mFragmentManager;
+
+ public AutomaticStorageManagementSwitchPreferenceController(Context context,
+ MetricsFeatureProvider metricsFeatureProvider, FragmentManager fragmentManager) {
+ super(context);
+ mMetricsFeatureProvider = metricsFeatureProvider;
+ mFragmentManager = fragmentManager;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mSwitch = (MasterSwitchPreference) screen.findPreference(KEY_TOGGLE_ASM);
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_TOGGLE_ASM;
+ }
+
+ @Override
+ public void onResume() {
+ boolean isStorageManagerEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED, 0) != 0;
+ mSwitch.setChecked(isStorageManagerEnabled);
+
+ if (mSwitch != null) {
+ mSwitchController = new MasterSwitchController(mSwitch);
+ mSwitchController.setListener(this);
+ mSwitchController.startListening();
+ }
+ }
+
+ @Override
+ public boolean onSwitchToggled(boolean isChecked) {
+ mMetricsFeatureProvider.action(mContext,
+ MetricsEvent.ACTION_TOGGLE_STORAGE_MANAGER, isChecked);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED,
+ isChecked ? 1 : 0);
+
+ boolean storageManagerEnabledByDefault = SystemProperties.getBoolean(
+ STORAGE_MANAGER_ENABLED_BY_DEFAULT_PROPERTY, false);
+ if (isChecked && !storageManagerEnabledByDefault) {
+ ActivationWarningFragment fragment = ActivationWarningFragment.newInstance();
+ fragment.show(mFragmentManager, ActivationWarningFragment.TAG);
+ }
+
+ return true;
+ }
+}
diff --git a/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreference.java b/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreference.java
index 8b6bac0..44d3d44 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreference.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreference.java
@@ -80,23 +80,6 @@
if (deletionHelperButton != null) {
deletionHelperButton.setOnClickListener(this);
}
-
- final TextView storageManagerText =
- (TextView) view.findViewById(R.id.storage_manager_indicator);
- if (storageManagerText != null) {
- Context context = getContext();
- final SpannableString templateSs = new SpannableString(
- context.getString(R.string.storage_manager_indicator));
- boolean isStorageManagerEnabled = Settings.Secure.getInt(context.getContentResolver(),
- Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED, 0) != 0;
- String value = isStorageManagerEnabled ?
- context.getString(R.string.storage_manager_indicator_on) :
- context.getString(R.string.storage_manager_indicator_off);
- Locale locale = storageManagerText.getTextLocale();
- final SpannableString ss = new SpannableString(value.toUpperCase(locale));
- ss.setSpan(new BoldLinkSpan(), 0, value.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- storageManagerText.setText(TextUtils.expandTemplate(templateSs, ss));
- }
}
@Override
diff --git a/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceController.java
index a962669..c4613ed 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceController.java
@@ -17,7 +17,6 @@
package com.android.settings.deviceinfo.storage;
import android.content.Context;
-import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
@@ -26,7 +25,6 @@
import com.android.settings.R;
import com.android.settings.core.PreferenceController;
-import com.android.settingslib.deviceinfo.StorageManagerVolumeProvider;
import com.android.settingslib.deviceinfo.StorageVolumeProvider;
/**
diff --git a/src/com/android/settings/display/ThemePreferenceController.java b/src/com/android/settings/display/ThemePreferenceController.java
index e66e7ce..a8d47d6 100644
--- a/src/com/android/settings/display/ThemePreferenceController.java
+++ b/src/com/android/settings/display/ThemePreferenceController.java
@@ -15,15 +15,19 @@
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_THEME;
-import android.app.AlertDialog;
-import android.app.UiModeManager;
import android.content.Context;
-import android.content.DialogInterface.OnClickListener;
+import android.content.om.IOverlayManager;
+import android.content.om.OverlayInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference;
-
import android.text.TextUtils;
+
import com.android.settings.R;
import com.android.settings.core.PreferenceController;
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
@@ -31,17 +35,27 @@
import libcore.util.Objects;
+import java.util.List;
+
public class ThemePreferenceController extends PreferenceController implements
Preference.OnPreferenceChangeListener {
private static final String KEY_THEME = "theme";
- private final UiModeManager mUiModeManager;
private final MetricsFeatureProvider mMetricsFeatureProvider;
+ private final OverlayManager mOverlayService;
+ private final PackageManager mPackageManager;
public ThemePreferenceController(Context context) {
+ this(context, ServiceManager.getService(Context.OVERLAY_SERVICE) != null
+ ? new OverlayManager() : null);
+ }
+
+ @VisibleForTesting
+ ThemePreferenceController(Context context, OverlayManager overlayManager) {
super(context);
- mUiModeManager = context.getSystemService(UiModeManager.class);
+ mOverlayService = overlayManager;
+ mPackageManager = context.getPackageManager();
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
}
@@ -61,12 +75,18 @@
@Override
public void updateState(Preference preference) {
ListPreference pref = (ListPreference) preference;
- String[] options = getAvailableThemes();
- for (int i = 0; i < options.length; i++) {
- options[i] = nullToDefault(options[i]);
+ String[] pkgs = getAvailableThemes();
+ CharSequence[] labels = new CharSequence[pkgs.length];
+ for (int i = 0; i < pkgs.length; i++) {
+ try {
+ labels[i] = mPackageManager.getApplicationInfo(pkgs[i], 0)
+ .loadLabel(mPackageManager);
+ } catch (NameNotFoundException e) {
+ labels[i] = pkgs[i];
+ }
}
- pref.setEntries(options);
- pref.setEntryValues(options);
+ pref.setEntries(labels);
+ pref.setEntryValues(pkgs);
String theme = getCurrentTheme();
if (TextUtils.isEmpty(theme)) {
theme = mContext.getString(R.string.default_theme);
@@ -77,49 +97,76 @@
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (Objects.equal(newValue, mUiModeManager.getTheme())) {
+ String current = getTheme();
+ if (Objects.equal(newValue, current)) {
return true;
}
- // TODO: STOPSHIP Don't require reboot and remove this prompt.
- OnClickListener onConfirm = (d, i) -> {
- mUiModeManager.setTheme(defaultToNull((String) newValue));
- ((ListPreference) preference).setValue((String) newValue);
- };
- new AlertDialog.Builder(mContext)
- .setTitle(R.string.change_theme_reboot)
- .setPositiveButton(com.android.internal.R.string.global_action_restart, onConfirm)
- .setNegativeButton(android.R.string.cancel, null)
- .show();
- return false;
+ try {
+ mOverlayService.setEnabledExclusive((String) newValue, true, UserHandle.myUserId());
+ } catch (RemoteException e) {
+ return false;
+ }
+ return true;
+ }
+
+ private String getTheme() {
+ try {
+ List<OverlayInfo> infos = mOverlayService.getOverlayInfosForTarget("android",
+ UserHandle.myUserId());
+ for (int i = 0, size = infos.size(); i < size; i++) {
+ if (infos.get(i).isEnabled()) {
+ return infos.get(i).packageName;
+ }
+ }
+ } catch (RemoteException e) {
+ }
+ return null;
}
@Override
public boolean isAvailable() {
+ if (mOverlayService == null) return false;
String[] themes = getAvailableThemes();
return themes != null && themes.length > 1;
}
+
@VisibleForTesting
String getCurrentTheme() {
- return mUiModeManager.getTheme();
+ return getTheme();
}
@VisibleForTesting
String[] getAvailableThemes() {
- return mUiModeManager.getAvailableThemes();
+ try {
+ List<OverlayInfo> infos = mOverlayService.getOverlayInfosForTarget("android",
+ UserHandle.myUserId());
+ String[] pkgs = new String[infos.size()];
+ for (int i = 0, size = infos.size(); i < size; i++) {
+ pkgs[i] = infos.get(i).packageName;
+ }
+ return pkgs;
+ } catch (RemoteException e) {
+ }
+ return new String[0];
}
- private String nullToDefault(String input) {
- if (TextUtils.isEmpty(input)) {
- return mContext.getString(R.string.default_theme);
- }
- return input;
- }
+ public static class OverlayManager {
+ private final IOverlayManager mService;
- private String defaultToNull(String input) {
- if (mContext.getString(R.string.default_theme).equals(input)) {
- return null;
+ public OverlayManager() {
+ mService = IOverlayManager.Stub.asInterface(
+ ServiceManager.getService(Context.OVERLAY_SERVICE));
}
- return input;
+
+ public void setEnabledExclusive(String pkg, boolean enabled, int userId)
+ throws RemoteException {
+ mService.setEnabledExclusive(pkg, enabled, userId);
+ }
+
+ public List<OverlayInfo> getOverlayInfosForTarget(String target, int userId)
+ throws RemoteException {
+ return mService.getOverlayInfosForTarget(target, userId);
+ }
}
}
diff --git a/src/com/android/settings/enterprise/AdminActionPreferenceControllerBase.java b/src/com/android/settings/enterprise/AdminActionPreferenceControllerBase.java
index 6b72573..f6bd4c1 100644
--- a/src/com/android/settings/enterprise/AdminActionPreferenceControllerBase.java
+++ b/src/com/android/settings/enterprise/AdminActionPreferenceControllerBase.java
@@ -40,7 +40,7 @@
public void updateState(Preference preference) {
final Date timestamp = getAdminActionTimestamp();
preference.setSummary(timestamp == null ?
- mContext.getString(R.string.enterprise_privacy_never) :
+ mContext.getString(R.string.enterprise_privacy_none) :
DateUtils.formatDateTime(mContext, timestamp.getTime(),
DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE));
}
diff --git a/src/com/android/settings/enterprise/AdminGrantedCameraPermissionPreferenceController.java b/src/com/android/settings/enterprise/AdminGrantedCameraPermissionPreferenceController.java
index a2137ff..35648c8 100644
--- a/src/com/android/settings/enterprise/AdminGrantedCameraPermissionPreferenceController.java
+++ b/src/com/android/settings/enterprise/AdminGrantedCameraPermissionPreferenceController.java
@@ -17,8 +17,6 @@
import android.Manifest;
import android.content.Context;
-import com.android.settings.R;
-
public class AdminGrantedCameraPermissionPreferenceController extends
AdminGrantedPermissionsPreferenceControllerBase {
@@ -26,8 +24,7 @@
= "enterprise_privacy_number_camera_access_packages";
public AdminGrantedCameraPermissionPreferenceController(Context context) {
- super(context, new String[] {Manifest.permission.CAMERA},
- R.plurals.enterprise_privacy_number_camera_access_packages);
+ super(context, new String[] {Manifest.permission.CAMERA});
}
@Override
diff --git a/src/com/android/settings/enterprise/AdminGrantedLocationPermissionsPreferenceController.java b/src/com/android/settings/enterprise/AdminGrantedLocationPermissionsPreferenceController.java
index 0453b53..f570558 100644
--- a/src/com/android/settings/enterprise/AdminGrantedLocationPermissionsPreferenceController.java
+++ b/src/com/android/settings/enterprise/AdminGrantedLocationPermissionsPreferenceController.java
@@ -17,8 +17,6 @@
import android.Manifest;
import android.content.Context;
-import com.android.settings.R;
-
public class AdminGrantedLocationPermissionsPreferenceController extends
AdminGrantedPermissionsPreferenceControllerBase {
@@ -27,8 +25,7 @@
public AdminGrantedLocationPermissionsPreferenceController(Context context) {
super(context, new String[] {Manifest.permission.ACCESS_COARSE_LOCATION,
- Manifest.permission.ACCESS_FINE_LOCATION},
- R.plurals.enterprise_privacy_number_location_access_packages);
+ Manifest.permission.ACCESS_FINE_LOCATION});
}
@Override
diff --git a/src/com/android/settings/enterprise/AdminGrantedMicrophonePermissionPreferenceController.java b/src/com/android/settings/enterprise/AdminGrantedMicrophonePermissionPreferenceController.java
index 3adde92..842235d 100644
--- a/src/com/android/settings/enterprise/AdminGrantedMicrophonePermissionPreferenceController.java
+++ b/src/com/android/settings/enterprise/AdminGrantedMicrophonePermissionPreferenceController.java
@@ -17,8 +17,6 @@
import android.Manifest;
import android.content.Context;
-import com.android.settings.R;
-
public class AdminGrantedMicrophonePermissionPreferenceController extends
AdminGrantedPermissionsPreferenceControllerBase {
@@ -26,8 +24,7 @@
= "enterprise_privacy_number_microphone_access_packages";
public AdminGrantedMicrophonePermissionPreferenceController(Context context) {
- super(context, new String[] {Manifest.permission.RECORD_AUDIO},
- R.plurals.enterprise_privacy_number_microphone_access_packages);
+ super(context, new String[] {Manifest.permission.RECORD_AUDIO});
}
@Override
diff --git a/src/com/android/settings/enterprise/AdminGrantedPermissionsPreferenceControllerBase.java b/src/com/android/settings/enterprise/AdminGrantedPermissionsPreferenceControllerBase.java
index 2ca5451..2b972a5 100644
--- a/src/com/android/settings/enterprise/AdminGrantedPermissionsPreferenceControllerBase.java
+++ b/src/com/android/settings/enterprise/AdminGrantedPermissionsPreferenceControllerBase.java
@@ -18,6 +18,7 @@
import android.content.res.Resources;
import android.support.v7.preference.Preference;
+import com.android.settings.R;
import com.android.settings.applications.ApplicationFeatureProvider;
import com.android.settings.core.PreferenceController;
import com.android.settings.overlay.FeatureFactory;
@@ -25,14 +26,11 @@
public abstract class AdminGrantedPermissionsPreferenceControllerBase extends PreferenceController {
private final String[] mPermissions;
- private final int mStringResourceId;
private final ApplicationFeatureProvider mFeatureProvider;
- public AdminGrantedPermissionsPreferenceControllerBase(Context context, String[] permissions,
- int stringResourceId) {
+ public AdminGrantedPermissionsPreferenceControllerBase(Context context, String[] permissions) {
super(context);
mPermissions = permissions;
- mStringResourceId = stringResourceId;
mFeatureProvider = FeatureFactory.getFactory(context)
.getApplicationFeatureProvider(context);
}
@@ -45,8 +43,8 @@
preference.setVisible(false);
} else {
preference.setVisible(true);
- preference.setTitle(mContext.getResources().getQuantityString(
- mStringResourceId, num, num));
+ preference.setSummary(mContext.getResources().getQuantityString(
+ R.plurals.enterprise_privacy_number_packages, num, num));
}
});
}
diff --git a/src/com/android/settings/enterprise/CaCertsCurrentUserPreferenceController.java b/src/com/android/settings/enterprise/CaCertsCurrentUserPreferenceController.java
new file mode 100644
index 0000000..c8ea551
--- /dev/null
+++ b/src/com/android/settings/enterprise/CaCertsCurrentUserPreferenceController.java
@@ -0,0 +1,60 @@
+/*
+ * 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.settings.enterprise;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.R;
+import com.android.settings.core.PreferenceController;
+import com.android.settings.overlay.FeatureFactory;
+
+public class CaCertsCurrentUserPreferenceController extends PreferenceController {
+
+ private static final String CA_CERTS_CURRENT_USER = "ca_certs_current_user";
+ private final EnterprisePrivacyFeatureProvider mFeatureProvider;
+
+ public CaCertsCurrentUserPreferenceController(Context context) {
+ super(context);
+ mFeatureProvider = FeatureFactory.getFactory(context)
+ .getEnterprisePrivacyFeatureProvider(context);
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ final int certs = mFeatureProvider.getNumberOfOwnerInstalledCaCertsInCurrentUser();
+ if (certs == 0) {
+ preference.setVisible(false);
+ return;
+ }
+ preference.setTitle(mContext.getResources().getQuantityString(
+ mFeatureProvider.isInCompMode() ? R.plurals.enterprise_privacy_ca_certs_personal :
+ R.plurals.enterprise_privacy_ca_certs_user, certs));
+ preference.setSummary(mContext.getResources().getQuantityString(
+ R.plurals.enterprise_privacy_number_ca_certs, certs, certs));
+ preference.setVisible(true);
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return CA_CERTS_CURRENT_USER;
+ }
+}
diff --git a/src/com/android/settings/enterprise/CaCertsManagedProfilePreferenceController.java b/src/com/android/settings/enterprise/CaCertsManagedProfilePreferenceController.java
new file mode 100644
index 0000000..33224ae
--- /dev/null
+++ b/src/com/android/settings/enterprise/CaCertsManagedProfilePreferenceController.java
@@ -0,0 +1,59 @@
+/*
+ * 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.settings.enterprise;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.R;
+import com.android.settings.core.PreferenceController;
+import com.android.settings.overlay.FeatureFactory;
+
+public class CaCertsManagedProfilePreferenceController extends PreferenceController {
+
+ private static final String KEY_CA_CERTS_MANAGED_PROFILE = "ca_certs_managed_profile";
+ private final EnterprisePrivacyFeatureProvider mFeatureProvider;
+
+ public CaCertsManagedProfilePreferenceController(Context context) {
+ super(context);
+ mFeatureProvider = FeatureFactory.getFactory(context)
+ .getEnterprisePrivacyFeatureProvider(context);
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ final int certs = mFeatureProvider.getNumberOfOwnerInstalledCaCertsInManagedProfile();
+ if (certs == 0) {
+ preference.setVisible(false);
+ return;
+ }
+ preference.setTitle(mContext.getResources().getQuantityString(
+ R.plurals.enterprise_privacy_ca_certs_work, certs));
+ preference.setSummary(mContext.getResources().getQuantityString(
+ R.plurals.enterprise_privacy_number_ca_certs, certs, certs));
+ preference.setVisible(true);
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_CA_CERTS_MANAGED_PROFILE;
+ }
+}
diff --git a/src/com/android/settings/enterprise/DevicePolicyManagerWrapper.java b/src/com/android/settings/enterprise/DevicePolicyManagerWrapper.java
index 29f315c..7fae8bb 100644
--- a/src/com/android/settings/enterprise/DevicePolicyManagerWrapper.java
+++ b/src/com/android/settings/enterprise/DevicePolicyManagerWrapper.java
@@ -16,10 +16,13 @@
package com.android.settings.enterprise;
+import android.annotation.NonNull;
import android.content.ComponentName;
import android.os.UserHandle;
import android.support.annotation.Nullable;
+import java.util.List;
+
/**
* This interface replicates a subset of the android.app.admin.DevicePolicyManager (DPM). The
* interface exists so that we can use a thin wrapper around the DPM in production code and a mock
@@ -97,4 +100,12 @@
* @see android.app.admin.DevicePolicyManager#isCurrentInputMethodSetByOwner
*/
boolean isCurrentInputMethodSetByOwner();
+
+
+ /**
+ * Calls {@code DevicePolicyManager.getOwnerInstalledCaCerts()}.
+ *
+ * @see android.app.admin.DevicePolicyManager#getOwnerInstalledCaCerts
+ */
+ List<String> getOwnerInstalledCaCerts(@NonNull UserHandle user);
}
diff --git a/src/com/android/settings/enterprise/DevicePolicyManagerWrapperImpl.java b/src/com/android/settings/enterprise/DevicePolicyManagerWrapperImpl.java
index 0fdcb9c..76264b4 100644
--- a/src/com/android/settings/enterprise/DevicePolicyManagerWrapperImpl.java
+++ b/src/com/android/settings/enterprise/DevicePolicyManagerWrapperImpl.java
@@ -16,11 +16,14 @@
package com.android.settings.enterprise;
+import android.annotation.NonNull;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.os.UserHandle;
import android.support.annotation.Nullable;
+import java.util.List;
+
public class DevicePolicyManagerWrapperImpl implements DevicePolicyManagerWrapper {
private final DevicePolicyManager mDpm;
@@ -78,4 +81,9 @@
public boolean isCurrentInputMethodSetByOwner() {
return mDpm.isCurrentInputMethodSetByOwner();
}
+
+ @Override
+ public List<String> getOwnerInstalledCaCerts(@NonNull UserHandle user) {
+ return mDpm.getOwnerInstalledCaCerts(user);
+ }
}
diff --git a/src/com/android/settings/enterprise/EnterpriseInstalledPackagesPreferenceController.java b/src/com/android/settings/enterprise/EnterpriseInstalledPackagesPreferenceController.java
index 1fbb04a..9b4be3a 100644
--- a/src/com/android/settings/enterprise/EnterpriseInstalledPackagesPreferenceController.java
+++ b/src/com/android/settings/enterprise/EnterpriseInstalledPackagesPreferenceController.java
@@ -44,9 +44,8 @@
preference.setVisible(false);
} else {
preference.setVisible(true);
- preference.setTitle(mContext.getResources().getQuantityString(
- R.plurals.enterprise_privacy_number_enterprise_installed_packages,
- num, num));
+ preference.setSummary(mContext.getResources().getQuantityString(
+ R.plurals.enterprise_privacy_number_packages, num, num));
}
});
}
diff --git a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java
index 30b74f5..792c3ac 100644
--- a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java
+++ b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java
@@ -88,4 +88,16 @@
* Owner or Profile Owner in that user. Otherwise, returns {@code null}.
*/
String getImeLabelIfOwnerSet();
+
+ /**
+ * Returns the number of CA certificates that the Device Owner or Profile Owner installed in
+ * the current user.
+ */
+ int getNumberOfOwnerInstalledCaCertsInCurrentUser();
+
+ /**
+ * Returns the number of CA certificates that the Profile Owner installed in the current user's
+ * managed profile (if any).
+ */
+ int getNumberOfOwnerInstalledCaCertsInManagedProfile();
}
diff --git a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java
index 49d87a5..3b8251c 100644
--- a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java
+++ b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java
@@ -178,6 +178,22 @@
}
}
+ @Override
+ public int getNumberOfOwnerInstalledCaCertsInCurrentUser() {
+ final List<String> certs = mDpm.getOwnerInstalledCaCerts(new UserHandle(MY_USER_ID));
+ return certs != null ? certs.size() : 0;
+ }
+
+ @Override
+ public int getNumberOfOwnerInstalledCaCertsInManagedProfile() {
+ final int userId = getManagedProfileUserId();
+ if (userId == UserHandle.USER_NULL) {
+ return 0;
+ }
+ final List<String> certs = mDpm.getOwnerInstalledCaCerts(new UserHandle(userId));
+ return certs != null ? certs.size() : 0;
+ }
+
protected static class EnterprisePrivacySpan extends ClickableSpan {
private final Context mContext;
diff --git a/src/com/android/settings/enterprise/EnterprisePrivacySettings.java b/src/com/android/settings/enterprise/EnterprisePrivacySettings.java
index 3929bbd..140a05c 100644
--- a/src/com/android/settings/enterprise/EnterprisePrivacySettings.java
+++ b/src/com/android/settings/enterprise/EnterprisePrivacySettings.java
@@ -63,6 +63,8 @@
controllers.add(new AlwaysOnVpnPrimaryUserPreferenceController(context));
controllers.add(new AlwaysOnVpnManagedProfilePreferenceController(context));
controllers.add(new GlobalHttpProxyPreferenceController(context));
+ controllers.add(new CaCertsCurrentUserPreferenceController(context));
+ controllers.add(new CaCertsManagedProfilePreferenceController(context));
controllers.add(new FailedPasswordWipePrimaryUserPreferenceController(context));
controllers.add(new FailedPasswordWipeManagedProfilePreferenceController(context));
controllers.add(new ImePreferenceController(context));
diff --git a/src/com/android/settings/enterprise/EnterpriseSetDefaultAppsPreferenceController.java b/src/com/android/settings/enterprise/EnterpriseSetDefaultAppsPreferenceController.java
index 23627cd..08a72e3 100644
--- a/src/com/android/settings/enterprise/EnterpriseSetDefaultAppsPreferenceController.java
+++ b/src/com/android/settings/enterprise/EnterpriseSetDefaultAppsPreferenceController.java
@@ -68,9 +68,8 @@
preference.setVisible(false);
} else {
preference.setVisible(true);
- preference.setTitle(mContext.getResources().getQuantityString(
- R.plurals.enterprise_privacy_number_enterprise_set_default_apps,
- num, num));
+ preference.setSummary(mContext.getResources().getQuantityString(
+ R.plurals.enterprise_privacy_number_packages, num, num));
}
}
diff --git a/src/com/android/settings/enterprise/FailedPasswordWipeManagedProfilePreferenceController.java b/src/com/android/settings/enterprise/FailedPasswordWipeManagedProfilePreferenceController.java
index 2eac0a9..5a0e7c8 100644
--- a/src/com/android/settings/enterprise/FailedPasswordWipeManagedProfilePreferenceController.java
+++ b/src/com/android/settings/enterprise/FailedPasswordWipeManagedProfilePreferenceController.java
@@ -15,8 +15,6 @@
import android.content.Context;
-import com.android.settings.R;
-
public class FailedPasswordWipeManagedProfilePreferenceController
extends FailedPasswordWipePreferenceControllerBase {
@@ -24,7 +22,7 @@
= "failed_password_wipe_managed_profile";
public FailedPasswordWipeManagedProfilePreferenceController(Context context) {
- super(context, R.plurals.enterprise_privacy_failed_password_wipe_work);
+ super(context);
}
@Override
diff --git a/src/com/android/settings/enterprise/FailedPasswordWipePreferenceControllerBase.java b/src/com/android/settings/enterprise/FailedPasswordWipePreferenceControllerBase.java
index 7cdd8da..ee4aecf 100644
--- a/src/com/android/settings/enterprise/FailedPasswordWipePreferenceControllerBase.java
+++ b/src/com/android/settings/enterprise/FailedPasswordWipePreferenceControllerBase.java
@@ -18,17 +18,16 @@
import android.content.res.Resources;
import android.support.v7.preference.Preference;
+import com.android.settings.R;
import com.android.settings.core.PreferenceController;
import com.android.settings.overlay.FeatureFactory;
public abstract class FailedPasswordWipePreferenceControllerBase extends PreferenceController {
- private final int mStringResourceId;
protected final EnterprisePrivacyFeatureProvider mFeatureProvider;
- public FailedPasswordWipePreferenceControllerBase(Context context, int stringResourceId) {
+ public FailedPasswordWipePreferenceControllerBase(Context context) {
super(context);
- mStringResourceId = stringResourceId;
mFeatureProvider = FeatureFactory.getFactory(context)
.getEnterprisePrivacyFeatureProvider(context);
}
@@ -42,8 +41,9 @@
preference.setVisible(false);
} else {
preference.setVisible(true);
- preference.setTitle(mContext.getResources().getQuantityString(
- mStringResourceId, failedPasswordsBeforeWipe, failedPasswordsBeforeWipe));
+ preference.setSummary(mContext.getResources().getQuantityString(
+ R.plurals.enterprise_privacy_number_failed_password_wipe,
+ failedPasswordsBeforeWipe, failedPasswordsBeforeWipe));
}
}
diff --git a/src/com/android/settings/enterprise/FailedPasswordWipePrimaryUserPreferenceController.java b/src/com/android/settings/enterprise/FailedPasswordWipePrimaryUserPreferenceController.java
index 91bdf9b..44c6383 100644
--- a/src/com/android/settings/enterprise/FailedPasswordWipePrimaryUserPreferenceController.java
+++ b/src/com/android/settings/enterprise/FailedPasswordWipePrimaryUserPreferenceController.java
@@ -15,8 +15,6 @@
import android.content.Context;
-import com.android.settings.R;
-
public class FailedPasswordWipePrimaryUserPreferenceController
extends FailedPasswordWipePreferenceControllerBase {
@@ -24,7 +22,7 @@
= "failed_password_wipe_primary_user";
public FailedPasswordWipePrimaryUserPreferenceController(Context context) {
- super(context, R.plurals.enterprise_privacy_failed_password_wipe_device);
+ super(context);
}
@Override
diff --git a/src/com/android/settings/enterprise/ImePreferenceController.java b/src/com/android/settings/enterprise/ImePreferenceController.java
index 18dfac7..3c0cc26 100644
--- a/src/com/android/settings/enterprise/ImePreferenceController.java
+++ b/src/com/android/settings/enterprise/ImePreferenceController.java
@@ -40,8 +40,8 @@
preference.setVisible(false);
return;
}
- preference.setTitle(mContext.getResources().getString(
- R.string.enterprise_privacy_input_method, ownerSetIme));
+ preference.setSummary(mContext.getResources().getString(
+ R.string.enterprise_privacy_input_method_name, ownerSetIme));
preference.setVisible(true);
}
diff --git a/src/com/android/settings/enterprise/InstalledPackagesPreferenceController.java b/src/com/android/settings/enterprise/InstalledPackagesPreferenceController.java
index 91ac4c2..4252429 100644
--- a/src/com/android/settings/enterprise/InstalledPackagesPreferenceController.java
+++ b/src/com/android/settings/enterprise/InstalledPackagesPreferenceController.java
@@ -24,7 +24,7 @@
public class InstalledPackagesPreferenceController extends PreferenceController {
- private static final String KEY_NUMBER_INSTALLED_PACKAGES = "number_installed_packages";
+ private static final String KEY_INSTALLED_PACKAGES = "installed_packages";
private final ApplicationFeatureProvider mFeatureProvider;
public InstalledPackagesPreferenceController(Context context) {
@@ -38,8 +38,12 @@
mFeatureProvider.calculateNumberOfInstalledApps(
ApplicationFeatureProvider.IGNORE_INSTALL_REASON,
(num) -> {
- preference.setTitle(mContext.getResources().getQuantityString(
- R.plurals.enterprise_privacy_number_installed_packages, num, num));
+ if (num == 0) {
+ preference.setSummary("");
+ } else {
+ preference.setSummary(mContext.getResources().getQuantityString(
+ R.plurals.enterprise_privacy_number_packages, num, num));
+ }
});
}
@@ -50,6 +54,6 @@
@Override
public String getPreferenceKey() {
- return KEY_NUMBER_INSTALLED_PACKAGES;
+ return KEY_INSTALLED_PACKAGES;
}
}
diff --git a/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceController.java b/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceController.java
new file mode 100644
index 0000000..0f08398
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceController.java
@@ -0,0 +1,106 @@
+/*
+ * 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.settings.fuelgauge;
+
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.support.annotation.VisibleForTesting;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.util.Log;
+import com.android.settings.core.PreferenceController;
+
+/**
+ * Controller to control whether an app can run in the background
+ */
+public class BackgroundActivityPreferenceController extends PreferenceController implements
+ Preference.OnPreferenceChangeListener {
+
+ private static final String TAG = "BgActivityPrefContr";
+ private static final String KEY_BACKGROUND_ACTIVITY = "background_activity";
+
+ private final PackageManager mPackageManager;
+ private final AppOpsManager mAppOpsManager;
+ private final String[] mPackages;
+ private final int mUid;
+
+ private String mTargetPackage;
+
+ public BackgroundActivityPreferenceController(Context context, int uid) {
+ super(context);
+ mPackageManager = context.getPackageManager();
+ mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
+ mUid = uid;
+ mPackages = mPackageManager.getPackagesForUid(mUid);
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ final int mode = mAppOpsManager
+ .checkOpNoThrow(AppOpsManager.OP_RUN_IN_BACKGROUND, mUid, mTargetPackage);
+
+ if (mode == AppOpsManager.MODE_ERRORED) {
+ preference.setEnabled(false);
+ } else {
+ ((SwitchPreference) preference).setChecked(mode != AppOpsManager.MODE_IGNORED);
+ }
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (mPackages == null) {
+ return false;
+ }
+ for (final String packageName : mPackages) {
+ if (isLegacyApp(packageName)) {
+ mTargetPackage = packageName;
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_BACKGROUND_ACTIVITY;
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ boolean switchOn = (Boolean) newValue;
+ mAppOpsManager.setUidMode(AppOpsManager.OP_RUN_IN_BACKGROUND, mUid,
+ switchOn ? AppOpsManager.MODE_DEFAULT : AppOpsManager.MODE_IGNORED);
+
+ return true;
+ }
+
+ @VisibleForTesting
+ boolean isLegacyApp(final String packageName) {
+ try {
+ ApplicationInfo info = mPackageManager.getApplicationInfo(packageName,
+ PackageManager.GET_META_DATA);
+
+ return info.targetSdkVersion < Build.VERSION_CODES.O;
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, "Cannot find package: " + packageName, e);
+ }
+
+ return false;
+ }
+}
diff --git a/src/com/android/settings/fuelgauge/PowerUsageDetail.java b/src/com/android/settings/fuelgauge/PowerUsageDetail.java
index 94fc3b5..956b279 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageDetail.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageDetail.java
@@ -34,7 +34,6 @@
import android.os.Bundle;
import android.os.Process;
import android.os.UserHandle;
-import android.provider.SearchIndexableResource;
import android.support.v14.preference.PreferenceFragment;
import android.support.v7.preference.Preference;
import android.support.v7.preference.Preference.OnPreferenceClickListener;
@@ -67,7 +66,7 @@
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
-import java.util.Arrays;
+import java.util.ArrayList;
import java.util.List;
public class PowerUsageDetail extends PowerUsageBase implements Button.OnClickListener {
@@ -396,7 +395,11 @@
@Override
protected List<PreferenceController> getPreferenceControllers(Context context) {
- return null;
+ final List<PreferenceController> controllers = new ArrayList<>();
+ final int uid = getArguments().getInt(EXTRA_UID, 0);
+ controllers.add(new BackgroundActivityPreferenceController(context, uid));
+
+ return controllers;
}
@Override
diff --git a/src/com/android/settings/gestures/AssistGesturePreferenceController.java b/src/com/android/settings/gestures/AssistGesturePreferenceController.java
index 99d38b6..f0ba888 100644
--- a/src/com/android/settings/gestures/AssistGesturePreferenceController.java
+++ b/src/com/android/settings/gestures/AssistGesturePreferenceController.java
@@ -17,29 +17,90 @@
package com.android.settings.gestures;
import android.content.Context;
+import android.net.Uri;
import android.provider.Settings;
import android.support.v7.preference.Preference;
-import android.util.ArrayMap;
+import android.support.v7.preference.PreferenceScreen;
+import com.android.settings.applications.assist.AssistSettingObserver;
import com.android.settings.core.lifecycle.Lifecycle;
+import com.android.settings.core.lifecycle.events.OnPause;
+import com.android.settings.core.lifecycle.events.OnResume;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.search2.InlineSwitchPayload;
-import com.android.settings.search2.ResultPayload;
-public class AssistGesturePreferenceController extends GesturePreferenceController {
+import java.util.Arrays;
+import java.util.List;
+
+public class AssistGesturePreferenceController extends GesturePreferenceController
+ implements OnPause, OnResume {
private static final String PREF_KEY_VIDEO = "gesture_assist_video";
private static final String PREF_KEY_ASSIST_GESTURE = "gesture_assist";
+ private final AssistGestureFeatureProvider mFeatureProvider;
+ private final SettingObserver mSettingObserver;
+ private boolean mWasAvailable;
+
+ private PreferenceScreen mScreen;
+ private Preference mPreference;
+
public AssistGesturePreferenceController(Context context, Lifecycle lifecycle) {
super(context, lifecycle);
+ mFeatureProvider = FeatureFactory.getFactory(context).getAssistGestureFeatureProvider();
+ mSettingObserver = new SettingObserver();
+ mWasAvailable = isAvailable();
}
@Override
public boolean isAvailable() {
- AssistGestureFeatureProvider provider =
- FeatureFactory.getFactory(mContext).getAssistGestureFeatureProvider();
- return provider.isSupported(mContext);
+ return mFeatureProvider.isSupported(mContext);
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ mScreen = screen;
+ mPreference = screen.findPreference(getPreferenceKey());
+ // Call super last or AbstractPreferenceController might remove the preference from the
+ // screen (if !isAvailable()) before we can save a reference to it.
+ super.displayPreference(screen);
+ }
+
+ @Override
+ public void onResume() {
+ mSettingObserver.register(mContext.getContentResolver(), true /* register */);
+ if (mWasAvailable != isAvailable()) {
+ // Only update the preference visibility if the availability has changed -- otherwise
+ // the preference may be incorrectly added to screens with collapsed sections.
+ updatePreference();
+ mWasAvailable = isAvailable();
+ }
+ }
+
+ @Override
+ public void onPause() {
+ mSettingObserver.register(mContext.getContentResolver(), false /* register */);
+ }
+
+ private void updatePreference() {
+ if (mPreference == null) {
+ return;
+ }
+
+ if (isAvailable()) {
+ if (mScreen.findPreference(getPreferenceKey()) == null) {
+ mScreen.addPreference(mPreference);
+ }
+ } else {
+ mScreen.removePreference(mPreference);
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean enabled = (boolean) newValue;
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.ASSIST_GESTURE_ENABLED, enabled ? 1 : 0);
+ return true;
}
@Override
@@ -53,17 +114,28 @@
}
@Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- final boolean enabled = (boolean) newValue;
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.ASSIST_GESTURE_ENABLED, enabled ? 1 : 0);
- return true;
- }
-
- @Override
protected boolean isSwitchPrefEnabled() {
final int assistGestureEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ASSIST_GESTURE_ENABLED, 1);
return assistGestureEnabled != 0;
}
+
+ class SettingObserver extends AssistSettingObserver {
+
+ private final Uri ASSIST_GESTURE_ENABLED_URI =
+ Settings.Secure.getUriFor(Settings.Secure.ASSIST_GESTURE_ENABLED);
+
+ @Override
+ protected List<Uri> getSettingUris() {
+ return Arrays.asList(ASSIST_GESTURE_ENABLED_URI);
+ }
+
+ @Override
+ public void onSettingChange() {
+ if (mWasAvailable != isAvailable()) {
+ updatePreference();
+ mWasAvailable = isAvailable();
+ }
+ }
+ }
}
diff --git a/src/com/android/settings/gestures/AssistGestureSensitivityPreferenceController.java b/src/com/android/settings/gestures/AssistGestureSensitivityPreferenceController.java
new file mode 100644
index 0000000..5334e62
--- /dev/null
+++ b/src/com/android/settings/gestures/AssistGestureSensitivityPreferenceController.java
@@ -0,0 +1,151 @@
+/*
+ * 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.settings.gestures;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.SeekBarPreference;
+import com.android.settings.core.PreferenceController;
+import com.android.settings.core.lifecycle.Lifecycle;
+import com.android.settings.core.lifecycle.LifecycleObserver;
+import com.android.settings.core.lifecycle.events.OnPause;
+import com.android.settings.core.lifecycle.events.OnResume;
+import com.android.settings.overlay.FeatureFactory;
+
+public class AssistGestureSensitivityPreferenceController extends PreferenceController
+ implements Preference.OnPreferenceChangeListener, LifecycleObserver, OnPause, OnResume {
+
+ private static final String PREF_KEY_ASSIST_GESTURE_SENSITIVITY = "gesture_assist_sensitivity";
+
+ private final AssistGestureFeatureProvider mFeatureProvider;
+ private final SettingObserver mSettingObserver;
+
+ private PreferenceScreen mScreen;
+ private SeekBarPreference mPreference;
+
+ public AssistGestureSensitivityPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context);
+ mFeatureProvider = FeatureFactory.getFactory(context).getAssistGestureFeatureProvider();
+ mSettingObserver = new SettingObserver();
+
+ if (lifecycle != null) {
+ lifecycle.addObserver(this);
+ }
+ }
+
+ @Override
+ public void onResume() {
+ mSettingObserver.register(mContext.getContentResolver(), true /* register */);
+ updatePreference();
+ }
+
+ @Override
+ public void onPause() {
+ mSettingObserver.register(mContext.getContentResolver(), false /* register */);
+ }
+
+ @Override
+ public boolean isAvailable() {
+ // The sensitivity control is contingent on the assist gesture being supported and the
+ // gesture being enabled.
+ final int gestureEnabled = Settings.Secure.getInt(
+ mContext.getContentResolver(),
+ Settings.Secure.ASSIST_GESTURE_ENABLED,
+ 1);
+ return (gestureEnabled == 1) && mFeatureProvider.isSupported(mContext);
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ mScreen = screen;
+ mPreference = (SeekBarPreference) screen.findPreference(getPreferenceKey());
+ // Call super last or AbstractPreferenceController might remove the preference from the
+ // screen (if !isAvailable()) before we can save a reference to it.
+ super.displayPreference(screen);
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ updatePreference();
+ }
+
+ private void updatePreference() {
+ if (mPreference == null) {
+ return;
+ }
+
+ if (isAvailable()) {
+ if (mScreen.findPreference(getPreferenceKey()) == null) {
+ mScreen.addPreference(mPreference);
+ }
+ } else {
+ mScreen.removePreference(mPreference);
+ }
+
+ final int sensitivity = Settings.Secure.getInt(
+ mContext.getContentResolver(),
+ Settings.Secure.ASSIST_GESTURE_SENSITIVITY,
+ mPreference.getProgress());
+ mPreference.setProgress(sensitivity);
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final int sensitivity = (int) newValue;
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.ASSIST_GESTURE_SENSITIVITY, sensitivity);
+ return true;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return PREF_KEY_ASSIST_GESTURE_SENSITIVITY;
+ }
+
+ class SettingObserver extends ContentObserver {
+
+ private final Uri ASSIST_GESTURE_ENABLED_URI =
+ Settings.Secure.getUriFor(Settings.Secure.ASSIST_GESTURE_ENABLED);
+ private final Uri ASSIST_GESTURE_SENSITIVITY_URI =
+ Settings.Secure.getUriFor(Settings.Secure.ASSIST_GESTURE_SENSITIVITY);
+
+ public SettingObserver() {
+ super(null /* handler */);
+ }
+
+ public void register(ContentResolver cr, boolean register) {
+ if (register) {
+ cr.registerContentObserver(ASSIST_GESTURE_ENABLED_URI, false, this);
+ cr.registerContentObserver(ASSIST_GESTURE_SENSITIVITY_URI, false, this);
+ } else {
+ cr.unregisterContentObserver(this);
+ }
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ updatePreference();
+ }
+ }
+}
diff --git a/src/com/android/settings/gestures/AssistGestureSettings.java b/src/com/android/settings/gestures/AssistGestureSettings.java
index 7778720..238b8b6 100644
--- a/src/com/android/settings/gestures/AssistGestureSettings.java
+++ b/src/com/android/settings/gestures/AssistGestureSettings.java
@@ -58,6 +58,7 @@
Lifecycle lifecycle) {
final List<PreferenceController> controllers = new ArrayList<>();
controllers.add(new AssistGesturePreferenceController(context, lifecycle));
+ controllers.add(new AssistGestureSensitivityPreferenceController(context, lifecycle));
return controllers;
}
diff --git a/src/com/android/settings/notification/NotificationStation.java b/src/com/android/settings/notification/NotificationStation.java
index 50bcd95..a357846 100644
--- a/src/com/android/settings/notification/NotificationStation.java
+++ b/src/com/android/settings/notification/NotificationStation.java
@@ -16,8 +16,11 @@
package com.android.settings.notification;
-import android.app.*;
+import android.app.Activity;
+import android.app.ActivityManager;
import android.app.INotificationManager;
+import android.app.Notification;
+import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.IntentSender;
@@ -26,7 +29,12 @@
import android.content.res.Resources;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
-import android.os.*;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.NotificationListenerService.RankingMap;
@@ -45,13 +53,15 @@
import android.widget.TextView;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.CopyablePreference;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.Utils;
-import java.lang.StringBuilder;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
public class NotificationStation extends SettingsPreferenceFragment {
private static final String TAG = NotificationStation.class.getSimpleName();
@@ -533,7 +543,7 @@
return null;
}
- private static class HistoricalNotificationPreference extends CopyablePreference {
+ private static class HistoricalNotificationPreference extends Preference {
private final HistoricalNotificationInfo mInfo;
public HistoricalNotificationPreference(Context context, HistoricalNotificationInfo info) {
@@ -574,14 +584,6 @@
}
@Override
- public CharSequence getCopyableText() {
- return new SpannableStringBuilder(mInfo.title)
- .append(" [").append(new Date(mInfo.timestamp).toString())
- .append("]\n").append(mInfo.pkgname)
- .append("\n").append(mInfo.extra);
- }
-
- @Override
public void performClick() {
// Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
// Uri.fromParts("package", mInfo.pkg, null));
diff --git a/src/com/android/settings/notification/WorkSoundPreferenceController.java b/src/com/android/settings/notification/WorkSoundPreferenceController.java
index 5ffb30b..a4d7b8d 100644
--- a/src/com/android/settings/notification/WorkSoundPreferenceController.java
+++ b/src/com/android/settings/notification/WorkSoundPreferenceController.java
@@ -25,7 +25,6 @@
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
-import android.media.AudioSystem;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
@@ -38,7 +37,6 @@
import android.support.v7.preference.PreferenceGroup;
import android.support.v7.preference.PreferenceScreen;
import android.support.v7.preference.TwoStatePreference;
-import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -53,7 +51,7 @@
import com.android.settings.core.lifecycle.events.OnResume;
public class WorkSoundPreferenceController extends PreferenceController implements
- OnPreferenceChangeListener, LifecycleObserver, OnResume, OnPause {
+ OnPreferenceChangeListener, LifecycleObserver, OnResume, OnPause {
private static final String TAG = "WorkSoundPrefController";
private static final String KEY_WORK_CATEGORY = "sound_work_settings_section";
@@ -62,27 +60,28 @@
private static final String KEY_WORK_NOTIFICATION_RINGTONE = "work_notification_ringtone";
private static final String KEY_WORK_ALARM_RINGTONE = "work_alarm_ringtone";
+ private final boolean mVoiceCapable;
+ private final UserManager mUserManager;
+ private final SoundSettings mParent;
+ private final AudioHelper mHelper;
+
private PreferenceGroup mWorkPreferenceCategory;
private TwoStatePreference mWorkUsePersonalSounds;
private Preference mWorkPhoneRingtonePreference;
private Preference mWorkNotificationRingtonePreference;
private Preference mWorkAlarmRingtonePreference;
- private boolean mVoiceCapable;
- private UserManager mUserManager;
- private SoundSettings mParent;
- private AudioHelper mHelper;
- private @UserIdInt
- int mManagedProfileId;
+ @UserIdInt
+ private int mManagedProfileId;
public WorkSoundPreferenceController(Context context, SoundSettings parent,
- Lifecycle lifecycle) {
+ Lifecycle lifecycle) {
this(context, parent, lifecycle, new AudioHelper(context));
}
@VisibleForTesting
WorkSoundPreferenceController(Context context, SoundSettings parent, Lifecycle lifecycle,
- AudioHelper helper) {
+ AudioHelper helper) {
super(context);
mUserManager = UserManager.get(context);
mVoiceCapable = Utils.isVoiceCapable(mContext);
@@ -95,7 +94,10 @@
@Override
public void displayPreference(PreferenceScreen screen) {
- // do nothing
+ mWorkPreferenceCategory = (PreferenceGroup) screen.findPreference(KEY_WORK_CATEGORY);
+ if (mWorkPreferenceCategory != null) {
+ mWorkPreferenceCategory.setVisible(isAvailable());
+ }
}
@Override
@@ -106,7 +108,7 @@
mContext.registerReceiver(mManagedProfileReceiver, managedProfileFilter);
mManagedProfileId = mHelper.getManagedProfileId(mUserManager);
- initWorkPreferences();
+ updateWorkPreferences();
}
@Override
@@ -165,7 +167,7 @@
}
Uri ringtoneUri = RingtoneManager.getActualDefaultRingtoneUri(context, type);
return Ringtone.getTitle(context, ringtoneUri, false /* followSettingsUri */,
- true /* allowRemote */);
+ true /* allowRemote */);
}
private Context getManagedProfileContext() {
@@ -175,9 +177,9 @@
return mHelper.createPackageContextAsUser(mManagedProfileId);
}
- private DefaultRingtonePreference initWorkPreference(String key) {
+ private DefaultRingtonePreference initWorkPreference(PreferenceGroup root, String key) {
DefaultRingtonePreference pref =
- (DefaultRingtonePreference) mParent.getPreferenceScreen().findPreference(key);
+ (DefaultRingtonePreference) root.findPreference(key);
pref.setOnPreferenceChangeListener(this);
// Required so that RingtonePickerActivity lists the work profile ringtones
@@ -185,24 +187,18 @@
return pref;
}
- private void initWorkPreferences() {
- if (mManagedProfileId == UserHandle.USER_NULL || !isAvailable()) {
- maybeRemoveWorkPreferences();
+ private void updateWorkPreferences() {
+ if (mWorkPreferenceCategory == null) {
return;
}
-
- if (mWorkPreferenceCategory == null) {
- mParent.addPreferencesFromResource(R.xml.sound_work_settings);
- final PreferenceScreen screen = mParent.getPreferenceScreen();
-
- mWorkPreferenceCategory = (PreferenceGroup) screen.findPreference(KEY_WORK_CATEGORY);
+ final boolean isAvailable = isAvailable();
+ mWorkPreferenceCategory.setVisible(isAvailable);
+ if (!isAvailable) {
+ return;
+ }
+ if (mWorkUsePersonalSounds == null) {
mWorkUsePersonalSounds = (TwoStatePreference)
- screen.findPreference(KEY_WORK_USE_PERSONAL_SOUNDS);
- mWorkPhoneRingtonePreference = initWorkPreference(KEY_WORK_PHONE_RINGTONE);
- mWorkNotificationRingtonePreference = initWorkPreference(
- KEY_WORK_NOTIFICATION_RINGTONE);
- mWorkAlarmRingtonePreference = initWorkPreference(KEY_WORK_ALARM_RINGTONE);
-
+ mWorkPreferenceCategory.findPreference(KEY_WORK_USE_PERSONAL_SOUNDS);
mWorkUsePersonalSounds.setOnPreferenceChangeListener((Preference p, Object value) -> {
if ((boolean) value) {
UnifyWorkDialogFragment.show(mParent);
@@ -212,16 +208,27 @@
return true;
}
});
-
- if (!mVoiceCapable) {
- mWorkPreferenceCategory.removePreference(mWorkPhoneRingtonePreference);
- mWorkPhoneRingtonePreference = null;
- }
+ }
+ if (mWorkPhoneRingtonePreference == null) {
+ mWorkPhoneRingtonePreference = initWorkPreference(mWorkPreferenceCategory,
+ KEY_WORK_PHONE_RINGTONE);
+ }
+ if (mWorkNotificationRingtonePreference == null) {
+ mWorkNotificationRingtonePreference = initWorkPreference(mWorkPreferenceCategory,
+ KEY_WORK_NOTIFICATION_RINGTONE);
+ }
+ if (mWorkAlarmRingtonePreference == null) {
+ mWorkAlarmRingtonePreference = initWorkPreference(mWorkPreferenceCategory,
+ KEY_WORK_ALARM_RINGTONE);
+ }
+ if (!mVoiceCapable) {
+ mWorkPreferenceCategory.removePreference(mWorkPhoneRingtonePreference);
+ mWorkPhoneRingtonePreference = null;
}
- Context managedProfileContext = getManagedProfileContext();
+ final Context managedProfileContext = getManagedProfileContext();
if (Settings.Secure.getIntForUser(managedProfileContext.getContentResolver(),
- Settings.Secure.SYNC_PARENT_SOUNDS, 0, mManagedProfileId) == 1) {
+ Settings.Secure.SYNC_PARENT_SOUNDS, 0, mManagedProfileId) == 1) {
enableWorkSyncSettings();
} else {
disableWorkSyncSettings();
@@ -237,13 +244,10 @@
mWorkUsePersonalSounds.setChecked(true);
if (mWorkPhoneRingtonePreference != null) {
- mWorkPhoneRingtonePreference.setSummary(
- com.android.settings.R.string.work_sound_same_as_personal);
+ mWorkPhoneRingtonePreference.setSummary(R.string.work_sound_same_as_personal);
}
- mWorkNotificationRingtonePreference.setSummary(
- com.android.settings.R.string.work_sound_same_as_personal);
- mWorkAlarmRingtonePreference.setSummary(
- com.android.settings.R.string.work_sound_same_as_personal);
+ mWorkNotificationRingtonePreference.setSummary(R.string.work_sound_same_as_personal);
+ mWorkAlarmRingtonePreference.setSummary(R.string.work_sound_same_as_personal);
}
private void disableWorkSync() {
@@ -266,36 +270,25 @@
if (mWorkPhoneRingtonePreference != null) {
mWorkPhoneRingtonePreference.setSummary(
- updateRingtoneName(managedProfileContext, RingtoneManager.TYPE_RINGTONE));
+ updateRingtoneName(managedProfileContext, RingtoneManager.TYPE_RINGTONE));
}
mWorkNotificationRingtonePreference.setSummary(
- updateRingtoneName(managedProfileContext, RingtoneManager.TYPE_NOTIFICATION));
+ updateRingtoneName(managedProfileContext, RingtoneManager.TYPE_NOTIFICATION));
mWorkAlarmRingtonePreference.setSummary(
- updateRingtoneName(managedProfileContext, RingtoneManager.TYPE_ALARM));
- }
-
- private void maybeRemoveWorkPreferences() {
- if (mWorkPreferenceCategory == null) {
- return;
- }
- mParent.getPreferenceScreen().removePreference(mWorkPreferenceCategory);
- mWorkPreferenceCategory = null;
- mWorkPhoneRingtonePreference = null;
- mWorkNotificationRingtonePreference = null;
- mWorkAlarmRingtonePreference = null;
+ updateRingtoneName(managedProfileContext, RingtoneManager.TYPE_ALARM));
}
public void onManagedProfileAdded(@UserIdInt int profileId) {
if (mManagedProfileId == UserHandle.USER_NULL) {
mManagedProfileId = profileId;
- initWorkPreferences();
+ updateWorkPreferences();
}
}
public void onManagedProfileRemoved(@UserIdInt int profileId) {
if (mManagedProfileId == profileId) {
mManagedProfileId = mHelper.getManagedProfileId(mUserManager);
- initWorkPreferences();
+ updateWorkPreferences();
}
}
@@ -317,7 +310,7 @@
};
public static class UnifyWorkDialogFragment extends InstrumentedDialogFragment
- implements DialogInterface.OnClickListener {
+ implements DialogInterface.OnClickListener {
private static final String TAG = "UnifyWorkDialogFragment";
private static final int REQUEST_CODE = 200;
@@ -329,12 +322,11 @@
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
- .setTitle(com.android.settings.R.string.work_sync_dialog_title)
- .setMessage(com.android.settings.R.string.work_sync_dialog_message)
- .setPositiveButton(com.android.settings.R.string.work_sync_dialog_yes,
- UnifyWorkDialogFragment.this)
- .setNegativeButton(android.R.string.no, null)
- .create();
+ .setTitle(R.string.work_sync_dialog_title)
+ .setMessage(R.string.work_sync_dialog_message)
+ .setPositiveButton(R.string.work_sync_dialog_yes, UnifyWorkDialogFragment.this)
+ .setNegativeButton(android.R.string.no, null)
+ .create();
}
public static void show(SoundSettings parent) {
diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java
index 362a9c4..561c2c6 100644
--- a/src/com/android/settings/search/SearchIndexableResources.java
+++ b/src/com/android/settings/search/SearchIndexableResources.java
@@ -166,7 +166,7 @@
R.drawable.ic_settings_notifications);
addIndex(SystemDashboardFragment.class, NO_DATA_RES_ID, R.drawable.ic_settings_about);
addIndex(StorageDashboardFragment.class, NO_DATA_RES_ID, R.drawable.ic_settings_storage);
- addIndex(ConnectedDeviceDashboardFragment.class, NO_DATA_RES_ID, R.drawable.ic_bt_laptop);
+ addIndex(ConnectedDeviceDashboardFragment.class, NO_DATA_RES_ID, R.drawable.ic_devices_other);
addIndex(EnterprisePrivacySettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_about);
addIndex(PaymentSettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_nfc_payment);
addIndex(
diff --git a/src/com/android/settings/search2/SearchFeatureProviderImpl.java b/src/com/android/settings/search2/SearchFeatureProviderImpl.java
index b161686..cd9c470 100644
--- a/src/com/android/settings/search2/SearchFeatureProviderImpl.java
+++ b/src/com/android/settings/search2/SearchFeatureProviderImpl.java
@@ -40,7 +40,7 @@
@Override
public boolean isEnabled(Context context) {
- return false;
+ return true;
}
@Override
diff --git a/src/com/android/settings/security/SecurityFeatureProviderImpl.java b/src/com/android/settings/security/SecurityFeatureProviderImpl.java
index 2d782a6..7be2d66 100644
--- a/src/com/android/settings/security/SecurityFeatureProviderImpl.java
+++ b/src/com/android/settings/security/SecurityFeatureProviderImpl.java
@@ -46,9 +46,24 @@
private TrustAgentManager mTrustAgentManager;
+ @VisibleForTesting
+ static final Drawable DEFAULT_ICON = null;
+ @VisibleForTesting
+ static final String DEFAULT_SUMMARY = " ";
+
/** Update preferences with data from associated tiles. */
public void updatePreferences(final Context context, final PreferenceScreen preferenceScreen,
final DashboardCategory dashboardCategory) {
+ if (preferenceScreen == null) {
+ return;
+ }
+ int tilesCount = (dashboardCategory != null) ? dashboardCategory.getTilesCount() : 0;
+ if (tilesCount == 0) {
+ return;
+ }
+
+ initPreferences(context, preferenceScreen, dashboardCategory);
+
// Fetching the summary and icon from the provider introduces latency, so do this on a
// separate thread.
Executors.newSingleThreadExecutor().execute(new Runnable() {
@@ -60,16 +75,33 @@
}
@VisibleForTesting
+ static void initPreferences(Context context, PreferenceScreen preferenceScreen,
+ DashboardCategory dashboardCategory) {
+ int tilesCount = (dashboardCategory != null) ? dashboardCategory.getTilesCount() : 0;
+ for (int i = 0; i < tilesCount; i++) {
+ Tile tile = dashboardCategory.getTile(i);
+ // If the tile does not have a key or appropriate meta data, skip it.
+ if (TextUtils.isEmpty(tile.key) || (tile.metaData == null)) {
+ continue;
+ }
+ Preference matchingPref = preferenceScreen.findPreference(tile.key);
+ // If the tile does not have a matching preference, skip it.
+ if (matchingPref == null) {
+ continue;
+ }
+ // Remove any icons that may be loaded before we inject the final icon.
+ matchingPref.setIcon(DEFAULT_ICON);
+ // Reserve room for the summary. This prevents the title from having to shift when the
+ // final title is injected.
+ matchingPref.setSummary(DEFAULT_SUMMARY);
+ }
+ }
+
+ @VisibleForTesting
void updatePreferencesToRunOnWorkerThread(Context context, PreferenceScreen preferenceScreen,
DashboardCategory dashboardCategory) {
- if (preferenceScreen == null) {
- return;
- }
int tilesCount = (dashboardCategory != null) ? dashboardCategory.getTilesCount() : 0;
- if (tilesCount == 0) {
- return;
- }
Map<String, IContentProvider> providerMap = new ArrayMap<>();
for (int i = 0; i < tilesCount; i++) {
Tile tile = dashboardCategory.getTile(i);
diff --git a/src/com/android/settings/system/FactoryResetPreferenceController.java b/src/com/android/settings/system/FactoryResetPreferenceController.java
new file mode 100644
index 0000000..95a9e54
--- /dev/null
+++ b/src/com/android/settings/system/FactoryResetPreferenceController.java
@@ -0,0 +1,46 @@
+/*
+ * 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.settings.system;
+
+import android.content.Context;
+
+import android.os.UserManager;
+
+import com.android.settings.R;
+import com.android.settings.core.PreferenceController;
+
+public class FactoryResetPreferenceController extends PreferenceController {
+ /** Key of the "Factory reset" preference in {@link R.xml.system_dashboard_fragment}.*/
+ private static final String KEY_FACTORY_RESET = "factory_reset";
+
+ private final UserManager mUm;
+
+ public FactoryResetPreferenceController(Context context, UserManager um) {
+ super(context);
+ mUm = um;
+ }
+
+ /** Hide "Factory reset" settings for secondary users. */
+ @Override
+ public boolean isAvailable() {
+ return mUm.isAdminUser();
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_FACTORY_RESET;
+ }
+}
diff --git a/src/com/android/settings/system/SystemDashboardFragment.java b/src/com/android/settings/system/SystemDashboardFragment.java
index 76ac4a6..d4c63c2 100644
--- a/src/com/android/settings/system/SystemDashboardFragment.java
+++ b/src/com/android/settings/system/SystemDashboardFragment.java
@@ -60,6 +60,7 @@
final List<PreferenceController> controllers = new ArrayList<>();
controllers.add(new SystemUpdatePreferenceController(context, UserManager.get(context)));
controllers.add(new AdditionalSystemUpdatePreferenceController(context));
+ controllers.add(new FactoryResetPreferenceController(context, UserManager.get(context)));
return controllers;
}
diff --git a/src/com/android/settings/webview/WebViewAppPicker.java b/src/com/android/settings/webview/WebViewAppPicker.java
index 586ee36..f1faf9b 100644
--- a/src/com/android/settings/webview/WebViewAppPicker.java
+++ b/src/com/android/settings/webview/WebViewAppPicker.java
@@ -21,7 +21,9 @@
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageItemInfo;
import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
import android.content.Context;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
@@ -60,8 +62,8 @@
getWebViewUpdateServiceWrapper().getValidWebViewApplicationInfos(getContext());
for (ApplicationInfo ai : pkgs) {
packageInfoList.add(createDefaultAppInfo(ai,
- getDisabledReason(getWebViewUpdateServiceWrapper(),
- getContext(), ai.packageName)));
+ getDisabledReason(getWebViewUpdateServiceWrapper(),
+ getContext(), ai.packageName)));
}
return packageInfoList;
}
@@ -107,10 +109,26 @@
return MetricsEvent.WEBVIEW_IMPLEMENTATION;
}
+ private static class WebViewAppInfo extends DefaultAppInfo {
+ public WebViewAppInfo(PackageItemInfo packageItemInfo, String summary, boolean enabled) {
+ super(packageItemInfo, summary, enabled);
+ }
+
+ @Override
+ public CharSequence loadLabel(PackageManager pm) {
+ String versionName = "";
+ try {
+ versionName = pm.getPackageInfo(packageItemInfo.packageName, 0).versionName;
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ return String.format("%s %s", super.loadLabel(pm), versionName);
+ }
+ }
+
+
@VisibleForTesting
- DefaultAppInfo createDefaultAppInfo(
- ApplicationInfo applicationInfo, String disabledReason) {
- return new DefaultAppInfo(applicationInfo, disabledReason,
+ DefaultAppInfo createDefaultAppInfo(PackageItemInfo packageItemInfo, String disabledReason) {
+ return new WebViewAppInfo(packageItemInfo, disabledReason,
TextUtils.isEmpty(disabledReason) /* enabled */);
}
diff --git a/src/com/android/settings/wfd/WifiDisplaySettings.java b/src/com/android/settings/wfd/WifiDisplaySettings.java
index f7c2f6e..0d6b4dc 100755
--- a/src/com/android/settings/wfd/WifiDisplaySettings.java
+++ b/src/com/android/settings/wfd/WifiDisplaySettings.java
@@ -125,9 +125,9 @@
super.onCreate(icicle);
final Context context = getActivity();
- mRouter = (MediaRouter)context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
- mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
- mWifiP2pManager = (WifiP2pManager)context.getSystemService(Context.WIFI_P2P_SERVICE);
+ mRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
+ mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
+ mWifiP2pManager = (WifiP2pManager) context.getSystemService(Context.WIFI_P2P_SERVICE);
mWifiP2pChannel = mWifiP2pManager.initialize(context, Looper.getMainLooper(), null);
addPreferencesFromResource(R.xml.wifi_display_settings);
@@ -211,6 +211,11 @@
return super.onOptionsItemSelected(item);
}
+ public static boolean isAvailable(Context context) {
+ return context.getSystemService(Context.DISPLAY_SERVICE) != null
+ && context.getSystemService(Context.WIFI_P2P_SERVICE) != null;
+ }
+
private void scheduleUpdate(int changes) {
if (mStarted) {
if (mPendingChanges == 0) {
@@ -237,7 +242,7 @@
mWifiDisplayCertificationOn = Settings.Global.getInt(getContentResolver(),
Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON, 0) != 0;
mWpsConfig = Settings.Global.getInt(getContentResolver(),
- Settings.Global.WIFI_DISPLAY_WPS_CONFIG, WpsInfo.INVALID);
+ Settings.Global.WIFI_DISPLAY_WPS_CONFIG, WpsInfo.INVALID);
// The wifi display enabled setting may have changed.
invalidateOptions = true;
@@ -402,12 +407,12 @@
});
mWpsConfig = Settings.Global.getInt(getActivity().getContentResolver(),
Settings.Global.WIFI_DISPLAY_WPS_CONFIG, WpsInfo.INVALID);
- String[] wpsEntries = { "Default", "PBC", "KEYPAD", "DISPLAY" };
+ String[] wpsEntries = {"Default", "PBC", "KEYPAD", "DISPLAY"};
String[] wpsValues = {
- "" + WpsInfo.INVALID,
- "" + WpsInfo.PBC,
- "" + WpsInfo.KEYPAD,
- "" + WpsInfo.DISPLAY };
+ "" + WpsInfo.INVALID,
+ "" + WpsInfo.PBC,
+ "" + WpsInfo.KEYPAD,
+ "" + WpsInfo.DISPLAY};
lp.setKey("wps");
lp.setTitle(R.string.wifi_display_wps_config);
lp.setEntries(wpsEntries);
@@ -430,8 +435,8 @@
return true;
}
});
- String[] lcEntries = { "Auto", "1", "6", "11" };
- String[] lcValues = { "0", "1", "6", "11" };
+ String[] lcEntries = {"Auto", "1", "6", "11"};
+ String[] lcValues = {"0", "1", "6", "11"};
lp.setKey("listening_channel");
lp.setTitle(R.string.wifi_display_listen_channel);
lp.setEntries(lcEntries);
@@ -454,8 +459,8 @@
return true;
}
});
- String[] ocEntries = { "Auto", "1", "6", "11", "36" };
- String[] ocValues = { "0", "1", "6", "11", "36" };
+ String[] ocEntries = {"Auto", "1", "6", "11", "36"};
+ String[] ocValues = {"0", "1", "6", "11", "36"};
lp.setKey("operating_channel");
lp.setTitle(R.string.wifi_display_operating_channel);
lp.setEntries(ocEntries);
@@ -512,14 +517,14 @@
public void onSuccess() {
if (DEBUG) {
Slog.d(TAG, "Successfully " + (enable ? "entered" : "exited")
- +" listen mode.");
+ + " listen mode.");
}
}
@Override
public void onFailure(int reason) {
Slog.e(TAG, "Failed to " + (enable ? "entered" : "exited")
- +" listen mode with reason " + reason + ".");
+ + " listen mode with reason " + reason + ".");
}
});
}
@@ -530,18 +535,18 @@
}
mWifiP2pManager.setWifiP2pChannels(mWifiP2pChannel,
lc, oc, new ActionListener() {
- @Override
- public void onSuccess() {
- if (DEBUG) {
- Slog.d(TAG, "Successfully set wifi p2p channels.");
- }
- }
+ @Override
+ public void onSuccess() {
+ if (DEBUG) {
+ Slog.d(TAG, "Successfully set wifi p2p channels.");
+ }
+ }
- @Override
- public void onFailure(int reason) {
- Slog.e(TAG, "Failed to set wifi p2p channels with reason " + reason + ".");
- }
- });
+ @Override
+ public void onFailure(int reason) {
+ Slog.e(TAG, "Failed to set wifi p2p channels with reason " + reason + ".");
+ }
+ });
}
private void toggleRoute(MediaRouter.RouteInfo route) {
@@ -561,7 +566,7 @@
private void showWifiDisplayOptionsDialog(final WifiDisplay display) {
View view = getActivity().getLayoutInflater().inflate(R.layout.wifi_display_options, null);
- final EditText nameEditText = (EditText)view.findViewById(R.id.name);
+ final EditText nameEditText = (EditText) view.findViewById(R.id.name);
nameEditText.setText(display.getFriendlyDisplayName());
DialogInterface.OnClickListener done = new DialogInterface.OnClickListener() {
@@ -707,7 +712,7 @@
TypedValue value = new TypedValue();
getContext().getTheme().resolveAttribute(android.R.attr.disabledAlpha,
value, true);
- deviceDetails.setImageAlpha((int)(value.getFloat() * 255));
+ deviceDetails.setImageAlpha((int) (value.getFloat() * 255));
deviceDetails.setEnabled(true); // always allow button to be pressed
}
}
diff --git a/src/com/android/settings/widget/FooterPreference.java b/src/com/android/settings/widget/FooterPreference.java
index 4a0d128..9cb9e11 100644
--- a/src/com/android/settings/widget/FooterPreference.java
+++ b/src/com/android/settings/widget/FooterPreference.java
@@ -17,6 +17,7 @@
package com.android.settings.widget;
import android.content.Context;
+import android.support.v4.content.res.TypedArrayUtils;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceViewHolder;
import android.text.method.LinkMovementMethod;
@@ -34,36 +35,24 @@
static final int ORDER_FOOTER = Integer.MAX_VALUE - 1;
static final String KEY_FOOTER = "footer_preference";
- public FooterPreference(Context context, AttributeSet attrs,
- int defStyleAttr, int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- init();
- }
-
- public FooterPreference(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- init();
- }
-
public FooterPreference(Context context, AttributeSet attrs) {
- super(context, attrs);
+ super(context, attrs, TypedArrayUtils.getAttr(
+ context, R.attr.footerPreferenceStyle, android.R.attr.preferenceStyle));
init();
}
public FooterPreference(Context context) {
- super(context);
- init();
+ this(context, null);
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
- TextView title = (TextView) holder.itemView.findViewById(android.R.id.title);
+ TextView title = holder.itemView.findViewById(android.R.id.title);
title.setMovementMethod(new LinkMovementMethod());
}
private void init() {
- setLayoutResource(R.layout.preference_footer);
setIcon(R.drawable.ic_info_outline_24dp);
setKey(KEY_FOOTER);
setOrder(ORDER_FOOTER);
diff --git a/tests/app/AndroidManifest.xml b/tests/app/AndroidManifest.xml
index 1c50700..6659e5f 100644
--- a/tests/app/AndroidManifest.xml
+++ b/tests/app/AndroidManifest.xml
@@ -22,6 +22,9 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
+ <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
+ <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
<application>
<uses-library android:name="android.test.runner" />
diff --git a/tests/app/src/com/android/settings/applications/ExternalSourcesSettingsTest.java b/tests/app/src/com/android/settings/applications/ExternalSourcesSettingsTest.java
new file mode 100644
index 0000000..9114c6f
--- /dev/null
+++ b/tests/app/src/com/android/settings/applications/ExternalSourcesSettingsTest.java
@@ -0,0 +1,200 @@
+/*
+ * 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.settings.applications;
+
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.MODE_DEFAULT;
+import static android.app.AppOpsManager.MODE_ERRORED;
+import static android.app.AppOpsManager.OP_REQUEST_INSTALL_PACKAGES;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.net.Uri;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.LargeTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.Direction;
+
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.Until;
+import android.widget.ListView;
+import android.widget.Switch;
+import android.widget.TextView;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class ExternalSourcesSettingsTest {
+
+ private static final String TAG = ExternalSourcesSettingsTest.class.getSimpleName();
+ private static final String WM_DISMISS_KEYGUARD_COMMAND = "wm dismiss-keyguard";
+ private static final long START_ACTIVITY_TIMEOUT = 5000;
+
+ private Context mContext;
+ private UiDevice mUiDevice;
+ private PackageManager mPackageManager;
+ private AppOpsManager mAppOpsManager;
+ private List<UserInfo> mProfiles;
+ private String mPackageName;
+
+ @Before
+ public void setUp() throws Exception {
+ mContext = InstrumentationRegistry.getTargetContext();
+ mPackageName = InstrumentationRegistry.getContext().getPackageName();
+ mPackageManager = mContext.getPackageManager();
+ mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
+ mProfiles = mContext.getSystemService(UserManager.class).getProfiles(UserHandle.myUserId());
+ resetAppOpModeForAllProfiles();
+ mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ mUiDevice.wakeUp();
+ mUiDevice.executeShellCommand(WM_DISMISS_KEYGUARD_COMMAND);
+ }
+
+ private void resetAppOpModeForAllProfiles() throws Exception {
+ for (UserInfo user : mProfiles) {
+ final int uid = mPackageManager.getPackageUidAsUser(mPackageName, user.id);
+ mAppOpsManager.setMode(OP_REQUEST_INSTALL_PACKAGES, uid, mPackageName, MODE_DEFAULT);
+ }
+ }
+
+ private Intent createManageExternalSourcesListIntent() {
+ final Intent manageExternalSourcesIntent = new Intent();
+ manageExternalSourcesIntent.setAction(Settings.ACTION_MANAGE_EXTERNAL_SOURCES);
+ return manageExternalSourcesIntent;
+ }
+
+ private Intent createManageExternalSourcesAppIntent(String packageName) {
+ final Intent intent = createManageExternalSourcesListIntent();
+ intent.setData(Uri.parse("package:" + packageName));
+ return intent;
+ }
+
+ private String getApplicationLabel(String packageName) throws Exception {
+ final ApplicationInfo info = mPackageManager.getApplicationInfo(packageName, 0);
+ return mPackageManager.getApplicationLabel(info).toString();
+ }
+
+ private UiObject2 findAndVerifySwitchState(boolean checked) {
+ final BySelector switchSelector = By.clazz(Switch.class).res("android:id/switch_widget");
+ final UiObject2 switchPref = mUiDevice.wait(Until.findObject(switchSelector),
+ START_ACTIVITY_TIMEOUT);
+ assertNotNull("Switch not shown", switchPref);
+ assertTrue("Switch in invalid state", switchPref.isChecked() == checked);
+ return switchPref;
+ }
+
+ @Test
+ public void testManageExternalSourcesList() throws Exception {
+ final String testAppLabel = getApplicationLabel(mPackageName);
+
+ mContext.startActivity(createManageExternalSourcesListIntent());
+ final BySelector preferenceListSelector = By.clazz(ListView.class).res("android:id/list");
+ final UiObject2 preferenceList = mUiDevice.wait(Until.findObject(preferenceListSelector),
+ START_ACTIVITY_TIMEOUT);
+ assertNotNull("App list not shown", preferenceList);
+
+ final BySelector appLabelTextViewSelector = By.clazz(TextView.class)
+ .res("android:id/title")
+ .text(testAppLabel);
+ List<UiObject2> listOfMatchingTextViews;
+ do {
+ listOfMatchingTextViews = preferenceList.findObjects(appLabelTextViewSelector);
+ // assuming the number of profiles will be sufficiently small so that all the entries
+ // for the same package will fit in one screen at some time during the scroll.
+ } while (listOfMatchingTextViews.size() != mProfiles.size() &&
+ preferenceList.scroll(Direction.DOWN, 0.2f));
+ assertEquals("Test app not listed for each profile", mProfiles.size(),
+ listOfMatchingTextViews.size());
+
+ for (UiObject2 matchingObject : listOfMatchingTextViews) {
+ matchingObject.click();
+ findAndVerifySwitchState(true);
+ mUiDevice.pressBack();
+ }
+ }
+
+ private void testAppDetailScreenForAppOp(int appOpMode, int userId) throws Exception {
+ final String testAppLabel = getApplicationLabel(mPackageName);
+ final BySelector appDetailTitleSelector = By.clazz(TextView.class)
+ .res("com.android.settings:id/app_detail_title")
+ .text(testAppLabel);
+
+ mAppOpsManager.setMode(OP_REQUEST_INSTALL_PACKAGES,
+ mPackageManager.getPackageUidAsUser(mPackageName, userId), mPackageName, appOpMode);
+ mContext.startActivityAsUser(createManageExternalSourcesAppIntent(mPackageName),
+ UserHandle.of(userId));
+ mUiDevice.wait(Until.findObject(appDetailTitleSelector), START_ACTIVITY_TIMEOUT);
+ findAndVerifySwitchState(appOpMode == MODE_ALLOWED || appOpMode == MODE_DEFAULT);
+ mUiDevice.pressBack();
+ }
+
+ @Test
+ public void testManageExternalSourcesForApp() throws Exception {
+ // App op MODE_DEFAULT is already tested in #testManageExternalSourcesList
+ for (UserInfo user : mProfiles) {
+ testAppDetailScreenForAppOp(MODE_ALLOWED, user.id);
+ testAppDetailScreenForAppOp(MODE_ERRORED, user.id);
+ }
+ }
+
+ private void testSwitchToggle(int fromAppOp, int toAppOp) throws Exception {
+ final int packageUid = mPackageManager.getPackageUid(mPackageName, 0);
+ final boolean initialState = (fromAppOp == MODE_ALLOWED || fromAppOp == MODE_DEFAULT);
+
+ mAppOpsManager.setMode(OP_REQUEST_INSTALL_PACKAGES, packageUid, mPackageName, fromAppOp);
+ mContext.startActivity(createManageExternalSourcesAppIntent(mPackageName));
+ final UiObject2 switchPref = findAndVerifySwitchState(initialState);
+ switchPref.click();
+ Thread.sleep(1000);
+ assertEquals("Toggling switch did not change app op", toAppOp,
+ mAppOpsManager.checkOpNoThrow(OP_REQUEST_INSTALL_PACKAGES, packageUid,
+ mPackageName));
+ mUiDevice.pressBack();
+ }
+
+ @Test
+ public void testIfSwitchTogglesAppOp() throws Exception {
+ testSwitchToggle(MODE_ALLOWED, MODE_ERRORED);
+ testSwitchToggle(MODE_ERRORED, MODE_ALLOWED);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ mUiDevice.pressHome();
+ resetAppOpModeForAllProfiles();
+ }
+}
diff --git a/tests/robotests/src/android/content/om/IOverlayManager.java b/tests/robotests/src/android/content/om/IOverlayManager.java
new file mode 100644
index 0000000..d4f6d10
--- /dev/null
+++ b/tests/robotests/src/android/content/om/IOverlayManager.java
@@ -0,0 +1,26 @@
+/*
+ * 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 android.content.om;
+
+import android.os.IBinder;
+
+public class IOverlayManager {
+
+ public static class Stub {
+ public static IOverlayManager asInterface(IBinder b) {
+ return null;
+ }
+ }
+}
diff --git a/tests/robotests/src/android/content/om/OverlayInfo.java b/tests/robotests/src/android/content/om/OverlayInfo.java
new file mode 100644
index 0000000..cfd3adc
--- /dev/null
+++ b/tests/robotests/src/android/content/om/OverlayInfo.java
@@ -0,0 +1,18 @@
+/*
+ * 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 android.content.om;
+
+public class OverlayInfo {
+}
diff --git a/tests/robotests/src/com/android/settings/ZonePickerTest.java b/tests/robotests/src/com/android/settings/ZonePickerTest.java
index 344eea3..6ab0c2d 100644
--- a/tests/robotests/src/com/android/settings/ZonePickerTest.java
+++ b/tests/robotests/src/com/android/settings/ZonePickerTest.java
@@ -25,6 +25,7 @@
import android.widget.SimpleAdapter;
import android.widget.TextView;
+import com.android.settings.datetime.ZonePicker;
import com.android.settings.testutils.shadow.ShadowLibcoreTimeZoneNames;
import com.android.settings.testutils.shadow.ShadowTimeZoneNames;
diff --git a/tests/robotests/src/com/android/settings/applications/assist/GestureAssistPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/assist/GestureAssistPreferenceControllerTest.java
deleted file mode 100644
index 624a01f..0000000
--- a/tests/robotests/src/com/android/settings/applications/assist/GestureAssistPreferenceControllerTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.settings.applications.assist;
-
-import android.content.Context;
-
-import com.android.settings.SettingsRobolectricTestRunner;
-import com.android.settings.TestConfig;
-import com.android.settings.testutils.FakeFeatureFactory;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Answers;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.annotation.Config;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.when;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class GestureAssistPreferenceControllerTest {
-
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private Context mContext;
- private FakeFeatureFactory mFeatureFactory;
- private GestureAssistPreferenceController mController;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- FakeFeatureFactory.setupForTest(mContext);
- mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
- mController = new GestureAssistPreferenceController(mContext);
- }
-
- @Test
- public void isAvailable_shouldReturnFeatureProviderValue() {
- when(mFeatureFactory.assistGestureFeatureProvider.isSupported(any(Context.class)))
- .thenReturn(true);
- assertThat(mController.isAvailable()).isTrue();
-
- when(mFeatureFactory.assistGestureFeatureProvider.isSupported(any(Context.class)))
- .thenReturn(false);
- assertThat(mController.isAvailable()).isFalse();
- }
-}
diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAutoFillPickerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAutofillPickerTest.java
similarity index 95%
rename from tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAutoFillPickerTest.java
rename to tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAutofillPickerTest.java
index 1ee18cf..1bd611b 100644
--- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAutoFillPickerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAutofillPickerTest.java
@@ -46,7 +46,7 @@
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class DefaultAutoFillPickerTest {
+public class DefaultAutofillPickerTest {
private static final String TEST_APP_KEY = "123";
@@ -56,14 +56,14 @@
private UserManager mUserManager;
@Mock
private PackageManagerWrapper mPackageManager;
- private DefaultAutoFillPicker mPicker;
+ private DefaultAutofillPicker mPicker;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
FakeFeatureFactory.setupForTest(mActivity);
when(mActivity.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
- mPicker = spy(new DefaultAutoFillPicker());
+ mPicker = spy(new DefaultAutofillPicker());
mPicker.onAttach((Context) mActivity);
ReflectionHelpers.setField(mPicker, "mPm", mPackageManager);
diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAutoFillPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAutofillPreferenceControllerTest.java
similarity index 90%
rename from tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAutoFillPreferenceControllerTest.java
rename to tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAutofillPreferenceControllerTest.java
index 1c37368..7bcbcb0 100644
--- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAutoFillPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAutofillPreferenceControllerTest.java
@@ -45,7 +45,7 @@
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class DefaultAutoFillPreferenceControllerTest {
+public class DefaultAutofillPreferenceControllerTest {
@Mock
private Context mContext;
@@ -54,14 +54,14 @@
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private PackageManagerWrapper mPackageManager;
- private DefaultAutoFillPreferenceController mController;
+ private DefaultAutofillPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
- mController = spy(new DefaultAutoFillPreferenceController(mContext));
+ mController = spy(new DefaultAutofillPreferenceController(mContext));
ReflectionHelpers.setField(mController, "mPackageManager", mPackageManager);
}
@@ -82,7 +82,7 @@
public void getDefaultAppInfo_shouldHaveSettingsProvider() {
ReflectionHelpers.setField(mController, "mContext", RuntimeEnvironment.application);
Settings.Secure.putString(RuntimeEnvironment.application.getContentResolver(),
- DefaultAutoFillPicker.SETTING, "com.android.settings/SettingsActivity.class");
+ DefaultAutofillPicker.SETTING, "com.android.settings/SettingsActivity.class");
final DefaultAppInfo info = mController.getDefaultAppInfo();
@@ -91,6 +91,6 @@
mController.getSettingIntent(info);
verify(mPackageManager.getPackageManager()).queryIntentServices(
- DefaultAutoFillPicker.AUTO_FILL_PROBE, PackageManager.GET_META_DATA);
+ DefaultAutofillPicker.AUTOFILL_PROBE, PackageManager.GET_META_DATA);
}
}
diff --git a/tests/robotests/src/com/android/settings/core/DynamicAvailabilityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/core/DynamicAvailabilityPreferenceControllerTest.java
new file mode 100644
index 0000000..38a8356
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/core/DynamicAvailabilityPreferenceControllerTest.java
@@ -0,0 +1,140 @@
+/*
+ * 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.settings.core;
+
+import android.content.Context;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settings.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+ * Tests for {@link DynamicAvailabilityPreferenceController}.
+ */
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public final class DynamicAvailabilityPreferenceControllerTest {
+
+ private final String PREFERENCE_KEY = "preference_key";
+
+ private @Mock Context mContext;
+ private @Mock Preference mPreference;
+ private @Mock PreferenceScreen mScreen;
+ private @Mock Lifecycle mLifecycle;
+
+ private boolean mIsAvailable;
+ private Preference mUpdatedPreference = null;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ when(mPreference.getKey()).thenReturn(PREFERENCE_KEY);
+ when(mScreen.findPreference(PREFERENCE_KEY)).thenReturn(mPreference);
+ when(mScreen.getPreferenceCount()).thenReturn(1);
+ when(mScreen.getPreference(0)).thenReturn(mPreference);
+ }
+
+ @Test
+ public void testAvailableToUnavailable() {
+ mIsAvailable = true;
+
+ final DynamicAvailabilityPreferenceController controller
+ = new DynamicAvailabilityPreferenceControllerTestable(mLifecycle);
+ verify(mLifecycle).addObserver(controller);
+
+ controller.displayPreference(mScreen);
+ verify(mScreen, never()).removePreference(mPreference);
+ verify(mScreen, never()).addPreference(mPreference);
+ assertThat(mUpdatedPreference).isNull();
+
+ controller.onResume();
+ verify(mScreen, never()).removePreference(mPreference);
+ verify(mScreen, never()).addPreference(mPreference);
+ assertThat(mUpdatedPreference).isEqualTo(mPreference);
+
+ mUpdatedPreference = null;
+ mIsAvailable = false;
+ controller.onResume();
+ verify(mScreen).removePreference(mPreference);
+ verify(mScreen, never()).addPreference(mPreference);
+ assertThat(mUpdatedPreference).isNull();
+ }
+
+ @Test
+ public void testUnavailableToAvailable() {
+ mIsAvailable = false;
+
+ final DynamicAvailabilityPreferenceController controller
+ = new DynamicAvailabilityPreferenceControllerTestable(mLifecycle);
+ verify(mLifecycle).addObserver(controller);
+
+ controller.displayPreference(mScreen);
+ verify(mScreen).removePreference(mPreference);
+ verify(mScreen, never()).addPreference(mPreference);
+ assertThat(mUpdatedPreference).isNull();
+
+ reset(mScreen);
+ controller.onResume();
+ verify(mScreen, never()).removePreference(mPreference);
+ verify(mScreen, never()).addPreference(mPreference);
+ assertThat(mUpdatedPreference).isNull();
+
+ mIsAvailable = true;
+ controller.onResume();
+ verify(mScreen, never()).removePreference(mPreference);
+ verify(mScreen).addPreference(mPreference);
+ assertThat(mUpdatedPreference).isEqualTo(mPreference);
+ }
+
+
+ private class DynamicAvailabilityPreferenceControllerTestable
+ extends DynamicAvailabilityPreferenceController {
+ public DynamicAvailabilityPreferenceControllerTestable(Lifecycle lifecycle) {
+ super(DynamicAvailabilityPreferenceControllerTest.this.mContext, lifecycle);
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return mIsAvailable;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ mUpdatedPreference = preference;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return PREFERENCE_KEY;
+ }
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/datetime/ZonePickerTest.java b/tests/robotests/src/com/android/settings/datetime/ZonePickerTest.java
new file mode 100644
index 0000000..4acac70
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/datetime/ZonePickerTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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.settings.datetime;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settings.core.instrumentation.VisibilityLoggerMixin;
+import com.android.settings.testutils.shadow.ShadowZoneGetter;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class ZonePickerTest {
+
+ private Activity mActivity;
+ private ZonePicker mZonePicker;
+
+ @Before
+ public void setUp() {
+ mActivity = Robolectric.setupActivity(Activity.class);
+ mZonePicker = spy(ZonePicker.class);
+ ReflectionHelpers.setField(mZonePicker, "mVisibilityLoggerMixin",
+ mock(VisibilityLoggerMixin.class));
+ }
+
+ @Test
+ @Config(shadows = ShadowZoneGetter.class)
+ public void testLaunch() {
+ // Shouldn't crash
+ mActivity.getFragmentManager()
+ .beginTransaction()
+ .add(mZonePicker, "test_tag")
+ .commit();
+
+ // Should render
+ verify(mZonePicker).onCreateView(
+ any(LayoutInflater.class),
+ any(ViewGroup.class),
+ any(Bundle.class));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/ManageStoragePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/ManageStoragePreferenceControllerTest.java
deleted file mode 100644
index 14c6d72..0000000
--- a/tests/robotests/src/com/android/settings/deviceinfo/ManageStoragePreferenceControllerTest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * 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.
- */
-package com.android.settings.deviceinfo;
-
-
-import android.content.Context;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
-import com.android.settings.SettingsRobolectricTestRunner;
-import com.android.settings.TestConfig;
-import java.util.ArrayList;
-import java.util.List;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Answers;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.annotation.Config;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Answers.RETURNS_DEEP_STUBS;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class ManageStoragePreferenceControllerTest {
-
-
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private Context mContext;
- @Mock(answer = RETURNS_DEEP_STUBS)
- private PreferenceScreen mScreen;
-
- private ManageStoragePreferenceController mController;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mController = new ManageStoragePreferenceController(mContext);
- }
-
- @Test
- public void updateNonIndexableKey_prefUnavaiable_shouldUpdate() {
- final List<String> keys = new ArrayList<>();
- mController.updateNonIndexableKeys(keys);
-
- assertThat(keys).isNotEmpty();
- }
-
- @Test
- public void updateNonIndexableKey_prefAvaiable_shouldNotUpdate() {
- final List<String> keys = new ArrayList<>();
- when(mContext.getResources().getBoolean(
- com.android.settings.R.bool.config_storage_manager_settings_enabled))
- .thenReturn(true);
-
- mController.updateNonIndexableKeys(keys);
-
- assertThat(keys).isEmpty();
- }
-
- @Test
- public void displayPref_prefAvaiable_shouldDisplay() {
- when(mContext.getResources().getBoolean(
- com.android.settings.R.bool.config_storage_manager_settings_enabled))
- .thenReturn(true);
-
- mController.displayPreference(mScreen);
-
- verify(mScreen, never()).removePreference(any(Preference.class));
- }
-
- @Test
- public void displayPref_prefNotAvaiable_shouldNotDisplay() {
- final Preference preference = mock(Preference.class);
- when(mScreen.getPreferenceCount()).thenReturn(1);
- when(mScreen.getPreference(0)).thenReturn(preference);
- when(preference.getKey()).thenReturn(mController.getPreferenceKey());
-
- mController.displayPreference(mScreen);
-
- verify(mScreen).removePreference(any(Preference.class));
- }
-}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceControllerTest.java
new file mode 100644
index 0000000..ee8e7d1
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceControllerTest.java
@@ -0,0 +1,172 @@
+/*
+ * 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.settings.deviceinfo.storage;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settings.core.instrumentation.MetricsFeatureProvider;
+import com.android.settings.deletionhelper.ActivationWarningFragment;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.shadow.SettingsShadowSystemProperties;
+import com.android.settings.widget.MasterSwitchPreference;
+import com.android.settings.overlay.FeatureFactory;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class AutomaticStorageManagementSwitchPreferenceControllerTest {
+
+ @Mock
+ private PreferenceScreen mScreen;
+ @Mock
+ private MasterSwitchPreference mPreference;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private Context mMockContext;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private FragmentManager mFragmentManager;
+
+ private Context mContext;
+ private AutomaticStorageManagementSwitchPreferenceController mController;
+ private MetricsFeatureProvider mMetricsFeature;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application.getApplicationContext();
+ FeatureFactory factory = FeatureFactory.getFactory(mContext);
+ mMetricsFeature = factory.getMetricsFeatureProvider();
+
+ mController = new AutomaticStorageManagementSwitchPreferenceController(
+ mContext, mMetricsFeature, mFragmentManager);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+ }
+
+ @Test
+ public void isAvailable_shouldAlwaysReturnTrue() {
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void onResume_shouldReflectEnabledStatus() {
+ mController.displayPreference(mScreen);
+ ContentResolver resolver = mContext.getContentResolver();
+ Settings.Secure.putInt(resolver, Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED, 1);
+
+ mController.onResume();
+
+ verify(mPreference).setChecked(eq(true));
+ }
+
+ @Test
+ public void onResume_shouldRegisterCallback() {
+ mController.displayPreference(mScreen);
+ mController.onResume();
+
+ verify(mPreference).setOnPreferenceChangeListener(
+ any(Preference.OnPreferenceChangeListener.class));
+ }
+
+ @Test
+ public void togglingShouldCauseMetricsEvent() {
+ // FakeFeatureFactory uses mock contexts, so this test scaffolds itself rather than using
+ // the instance variables.
+ FakeFeatureFactory.setupForTest(mMockContext);
+ FakeFeatureFactory factory =
+ (FakeFeatureFactory) FakeFeatureFactory.getFactory(mMockContext);
+ AutomaticStorageManagementSwitchPreferenceController controller =
+ new AutomaticStorageManagementSwitchPreferenceController(
+ mMockContext, factory.metricsFeatureProvider, mFragmentManager);
+
+ controller.onSwitchToggled(true);
+
+ verify(factory.metricsFeatureProvider, times(1)).action(
+ any(Context.class), eq(MetricsEvent.ACTION_TOGGLE_STORAGE_MANAGER), eq(true));
+ }
+
+ @Test
+ public void togglingShouldUpdateSettingsSecure() {
+ mController.onSwitchToggled(true);
+
+ ContentResolver resolver = mContext.getContentResolver();
+ assertThat(Settings.Secure.getInt(
+ resolver, Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED, 0)).isNotEqualTo(0);
+ }
+
+ @Test
+ public void togglingOnShouldTriggerWarningFragment() {
+ FragmentTransaction transaction = mock(FragmentTransaction.class);
+ when (mFragmentManager.beginTransaction()).thenReturn(transaction);
+
+ mController.onSwitchToggled(true);
+
+ verify(transaction).add(any(), eq(ActivationWarningFragment.TAG));
+ }
+
+ @Test
+ public void togglingOffShouldTriggerWarningFragment() {
+ FragmentTransaction transaction = mock(FragmentTransaction.class);
+ when (mFragmentManager.beginTransaction()).thenReturn(transaction);
+
+ mController.onSwitchToggled(false);
+
+ verify(transaction, never()).add(any(), eq(ActivationWarningFragment.TAG));
+ }
+
+
+ @Config(shadows = {SettingsShadowSystemProperties.class})
+ @Test
+ public void togglingOnShouldNotTriggerWarningFragmentIfEnabledByDefault() {
+ FragmentTransaction transaction = mock(FragmentTransaction.class);
+ when (mFragmentManager.beginTransaction()).thenReturn(transaction);
+ SettingsShadowSystemProperties.set(
+ AutomaticStorageManagementSwitchPreferenceController
+ .STORAGE_MANAGER_ENABLED_BY_DEFAULT_PROPERTY, "true");
+
+ mController.onSwitchToggled(true);
+
+ verify(transaction, never()).add(any(), eq(ActivationWarningFragment.TAG));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java
index c12e515..cbf3414 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java
@@ -114,13 +114,6 @@
}
@Test
- public void testAutomaticStorageManagerLabelOff() throws Exception {
- mPreference.onBindViewHolder(mHolder);
- TextView asmTextView = (TextView) mHolder.findViewById(R.id.storage_manager_indicator);
- assertThat(asmTextView.getText().toString()).isEqualTo("Storage Manager: OFF");
- }
-
- @Test
public void testFreeUpSpaceMetricIsTriggered() throws Exception {
mPreference.onBindViewHolder(mHolder);
Button button = (Button) mHolder.findViewById(R.id.deletion_helper_button);
@@ -130,15 +123,4 @@
verify(mMetricsFeatureProvider, times(1)).action(
any(Context.class), eq(MetricsEvent.STORAGE_FREE_UP_SPACE_NOW));
}
-
- @Test
- public void testAutomaticStorageManagerLabelOn() throws Exception {
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED, 1);
-
- mPreference.onBindViewHolder(mHolder);
-
- TextView asmTextView = (TextView) mHolder.findViewById(R.id.storage_manager_indicator);
- assertThat(asmTextView.getText().toString()).isEqualTo("Storage Manager: ON");
- }
}
diff --git a/tests/robotests/src/com/android/settings/display/ThemePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/ThemePreferenceControllerTest.java
index fe3e7fd..2c0f4a7 100644
--- a/tests/robotests/src/com/android/settings/display/ThemePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/ThemePreferenceControllerTest.java
@@ -17,10 +17,15 @@
package com.android.settings.display;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.support.v7.preference.ListPreference;
import com.android.settings.R;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
+import com.android.settings.display.ThemePreferenceController.OverlayManager;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -28,9 +33,13 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@@ -40,24 +49,19 @@
private ListPreference mPreference;
@Mock
private Context mContext;
+ @Mock
+ private PackageManager mPackageManager;
+ @Mock
+ private ApplicationInfo mApplicationInfo;
private ThemePreferenceController mController;
@Before
- public void setUp() {
+ public void setUp() throws NameNotFoundException {
MockitoAnnotations.initMocks(this);
- mController = spy(new ThemePreferenceController(mContext));
- }
-
- @Test
- public void updateState_nullTheme_shouldSetSummaryToDefault() {
- final String[] themes = {"Theme1", "Theme2"};
- doReturn(null).when(mController).getCurrentTheme();
- doReturn(themes).when(mController).getAvailableThemes();
-
- mController.updateState(mPreference);
-
- verify(mPreference).setSummary(mContext.getString(R.string.default_theme));
+ when(mPackageManager.getApplicationInfo(any(), anyInt())).thenReturn(mApplicationInfo);
+ when(mContext.getPackageManager()).thenReturn(mPackageManager);
+ mController = spy(new ThemePreferenceController(mContext, mock(OverlayManager.class)));
}
@Test
diff --git a/tests/robotests/src/com/android/settings/enterprise/AdminActionPreferenceControllerTestBase.java b/tests/robotests/src/com/android/settings/enterprise/AdminActionPreferenceControllerTestBase.java
index 59043ed..e9b9d86 100644
--- a/tests/robotests/src/com/android/settings/enterprise/AdminActionPreferenceControllerTestBase.java
+++ b/tests/robotests/src/com/android/settings/enterprise/AdminActionPreferenceControllerTestBase.java
@@ -59,12 +59,12 @@
@Test
public void testUpdateState() {
final Preference preference = new Preference(mContext, null, 0, 0);
- when(mContext.getString(R.string.enterprise_privacy_never)).thenReturn("Never");
+ when(mContext.getString(R.string.enterprise_privacy_none)).thenReturn("None");
Settings.System.putString(mContext.getContentResolver(), Settings.System.TIME_12_24, "24");
setDate(null);
mController.updateState(preference);
- assertThat(preference.getSummary()).isEqualTo("Never");
+ assertThat(preference.getSummary()).isEqualTo("None");
final Date date = new GregorianCalendar(2011 /* year */, 10 /* month */, 9 /* dayOfMonth */,
8 /* hourOfDay */, 7 /* minute */, 6 /* second */).getTime();
diff --git a/tests/robotests/src/com/android/settings/enterprise/AdminGrantedCameraPermissionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/AdminGrantedCameraPermissionPreferenceControllerTest.java
index de24885..6efccfc 100644
--- a/tests/robotests/src/com/android/settings/enterprise/AdminGrantedCameraPermissionPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/AdminGrantedCameraPermissionPreferenceControllerTest.java
@@ -18,7 +18,6 @@
import android.Manifest;
-import com.android.settings.R;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import org.junit.runner.RunWith;
@@ -34,8 +33,7 @@
public AdminGrantedCameraPermissionPreferenceControllerTest() {
super("enterprise_privacy_number_camera_access_packages",
- new String[] {Manifest.permission.CAMERA},
- R.plurals.enterprise_privacy_number_camera_access_packages);
+ new String[] {Manifest.permission.CAMERA});
}
@Override
diff --git a/tests/robotests/src/com/android/settings/enterprise/AdminGrantedLocationPermissionsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/AdminGrantedLocationPermissionsPreferenceControllerTest.java
index 1c6f91d..a23ad8b 100644
--- a/tests/robotests/src/com/android/settings/enterprise/AdminGrantedLocationPermissionsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/AdminGrantedLocationPermissionsPreferenceControllerTest.java
@@ -18,7 +18,6 @@
import android.Manifest;
-import com.android.settings.R;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import org.junit.runner.RunWith;
@@ -35,8 +34,7 @@
public AdminGrantedLocationPermissionsPreferenceControllerTest() {
super("enterprise_privacy_number_location_access_packages",
new String[] {Manifest.permission.ACCESS_COARSE_LOCATION,
- Manifest.permission.ACCESS_FINE_LOCATION},
- R.plurals.enterprise_privacy_number_location_access_packages);
+ Manifest.permission.ACCESS_FINE_LOCATION});
}
@Override
diff --git a/tests/robotests/src/com/android/settings/enterprise/AdminGrantedMicrophonePermissionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/AdminGrantedMicrophonePermissionPreferenceControllerTest.java
index bcaf63f..39a715f 100644
--- a/tests/robotests/src/com/android/settings/enterprise/AdminGrantedMicrophonePermissionPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/AdminGrantedMicrophonePermissionPreferenceControllerTest.java
@@ -18,7 +18,6 @@
import android.Manifest;
-import com.android.settings.R;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import org.junit.runner.RunWith;
@@ -34,8 +33,7 @@
public AdminGrantedMicrophonePermissionPreferenceControllerTest() {
super("enterprise_privacy_number_microphone_access_packages",
- new String[] {Manifest.permission.RECORD_AUDIO},
- R.plurals.enterprise_privacy_number_microphone_access_packages);
+ new String[] {Manifest.permission.RECORD_AUDIO});
}
@Override
diff --git a/tests/robotests/src/com/android/settings/enterprise/AdminGrantedPermissionsPreferenceControllerBaseTest.java b/tests/robotests/src/com/android/settings/enterprise/AdminGrantedPermissionsPreferenceControllerBaseTest.java
index 2bebbf0..1f52b0e 100644
--- a/tests/robotests/src/com/android/settings/enterprise/AdminGrantedPermissionsPreferenceControllerBaseTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/AdminGrantedPermissionsPreferenceControllerBaseTest.java
@@ -30,7 +30,7 @@
AdminGrantedPermissionsPreferenceControllerTestBase {
public AdminGrantedPermissionsPreferenceControllerBaseTest() {
- super(null, new String[] {"some.permission"}, 123 /* resourceStringId */);
+ super(null, new String[] {"some.permission"});
}
@Override
@@ -43,8 +43,7 @@
AdminGrantedPermissionsPreferenceControllerBase {
AdminGrantedPermissionsPreferenceControllerBaseTestable() {
- super(AdminGrantedPermissionsPreferenceControllerBaseTest.this.mContext, mPermissions,
- mStringResourceId);
+ super(AdminGrantedPermissionsPreferenceControllerBaseTest.this.mContext, mPermissions);
}
@Override
diff --git a/tests/robotests/src/com/android/settings/enterprise/AdminGrantedPermissionsPreferenceControllerTestBase.java b/tests/robotests/src/com/android/settings/enterprise/AdminGrantedPermissionsPreferenceControllerTestBase.java
index 68ded37..821fb34 100644
--- a/tests/robotests/src/com/android/settings/enterprise/AdminGrantedPermissionsPreferenceControllerTestBase.java
+++ b/tests/robotests/src/com/android/settings/enterprise/AdminGrantedPermissionsPreferenceControllerTestBase.java
@@ -20,6 +20,7 @@
import android.content.res.Resources;
import android.support.v7.preference.Preference;
+import com.android.settings.R;
import com.android.settings.applications.ApplicationFeatureProvider;
import com.android.settings.testutils.FakeFeatureFactory;
@@ -44,7 +45,6 @@
protected final String mKey;
protected final String[] mPermissions;
- protected final int mStringResourceId;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
protected Context mContext;
@@ -52,11 +52,9 @@
protected AdminGrantedPermissionsPreferenceControllerBase mController;
- public AdminGrantedPermissionsPreferenceControllerTestBase(String key, String[] permissions,
- int stringResourceId) {
+ public AdminGrantedPermissionsPreferenceControllerTestBase(String key, String[] permissions) {
mKey = key;
mPermissions = permissions;
- mStringResourceId = stringResourceId;
}
@Before
@@ -83,10 +81,10 @@
preference.setVisible(false);
setNumberOfPackagesWithAdminGrantedPermissions(20);
- when(mContext.getResources().getQuantityString(mStringResourceId, 20, 20))
- .thenReturn("20 packages");
+ when(mContext.getResources().getQuantityString(R.plurals.enterprise_privacy_number_packages,
+ 20, 20)).thenReturn("20 packages");
mController.updateState(preference);
- assertThat(preference.getTitle()).isEqualTo("20 packages");
+ assertThat(preference.getSummary()).isEqualTo("20 packages");
assertThat(preference.isVisible()).isTrue();
setNumberOfPackagesWithAdminGrantedPermissions(0);
diff --git a/tests/robotests/src/com/android/settings/enterprise/CaCertsCurrentUserPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/CaCertsCurrentUserPreferenceControllerTest.java
new file mode 100644
index 0000000..3cd63bb
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/enterprise/CaCertsCurrentUserPreferenceControllerTest.java
@@ -0,0 +1,147 @@
+/*
+ * 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.settings.enterprise;
+
+import android.content.Context;
+import android.content.res.Resources;
+import com.android.settings.R;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.FakeFeatureFactory;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
+/**
+ * Tests for {@link CaCertsCurrentUserPreferenceController}.
+ */
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public final class CaCertsCurrentUserPreferenceControllerTest {
+
+ private final String INSTALLED_CERTS_USER_1 = "cert installed";
+ private final String INSTALLED_CERTS_USER_10 = "certs installed";
+ private final String INSTALLED_CERTS_PERSONAL_1 = "cert installed in personal profile";
+ private final String INSTALLED_CERTS_PERSONAL_10 = "certs installed in personal profile";
+ private final String NUMBER_INSTALLED_CERTS_1 = "1 cert";
+ private final String NUMBER_INSTALLED_CERTS_10 = "10 certs";
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private Context mContext;
+ private FakeFeatureFactory mFeatureFactory;
+
+ private CaCertsCurrentUserPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ FakeFeatureFactory.setupForTest(mContext);
+ mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
+ mController = new CaCertsCurrentUserPreferenceController(mContext);
+
+ when(mContext.getResources().getQuantityString(R.plurals.enterprise_privacy_ca_certs_user,
+ 1)).thenReturn(INSTALLED_CERTS_USER_1);
+ when(mContext.getResources().getQuantityString(R.plurals.enterprise_privacy_ca_certs_user,
+ 10)).thenReturn(INSTALLED_CERTS_USER_10);
+ when(mContext.getResources().getQuantityString(
+ R.plurals.enterprise_privacy_ca_certs_personal, 1))
+ .thenReturn(INSTALLED_CERTS_PERSONAL_1);
+ when(mContext.getResources().getQuantityString(
+ R.plurals.enterprise_privacy_ca_certs_personal, 10))
+ .thenReturn(INSTALLED_CERTS_PERSONAL_10);
+ when(mContext.getResources().getQuantityString(R.plurals.enterprise_privacy_number_ca_certs,
+ 1, 1)).thenReturn(NUMBER_INSTALLED_CERTS_1);
+ when(mContext.getResources().getQuantityString(R.plurals.enterprise_privacy_number_ca_certs,
+ 10, 10)).thenReturn(NUMBER_INSTALLED_CERTS_10);
+ }
+
+ @Test
+ public void testUpdateState() {
+ final Preference preference = new Preference(mContext, null, 0, 0);
+ preference.setVisible(true);
+
+ when(mFeatureFactory.enterprisePrivacyFeatureProvider.isInCompMode()).thenReturn(false);
+
+ when(mFeatureFactory.enterprisePrivacyFeatureProvider
+ .getNumberOfOwnerInstalledCaCertsInCurrentUser()).thenReturn(0);
+ mController.updateState(preference);
+ assertThat(preference.isVisible()).isFalse();
+
+ when(mFeatureFactory.enterprisePrivacyFeatureProvider
+ .getNumberOfOwnerInstalledCaCertsInCurrentUser()).thenReturn(1);
+ mController.updateState(preference);
+ assertThat(preference.isVisible()).isTrue();
+ assertThat(preference.getTitle()).isEqualTo(INSTALLED_CERTS_USER_1);
+ assertThat(preference.getSummary()).isEqualTo(NUMBER_INSTALLED_CERTS_1);
+
+ preference.setVisible(false);
+ when(mFeatureFactory.enterprisePrivacyFeatureProvider
+ .getNumberOfOwnerInstalledCaCertsInCurrentUser()).thenReturn(10);
+ mController.updateState(preference);
+ assertThat(preference.isVisible()).isTrue();
+ assertThat(preference.getTitle()).isEqualTo(INSTALLED_CERTS_USER_10);
+ assertThat(preference.getSummary()).isEqualTo(NUMBER_INSTALLED_CERTS_10);
+
+ when(mFeatureFactory.enterprisePrivacyFeatureProvider.isInCompMode()).thenReturn(true);
+
+ when(mFeatureFactory.enterprisePrivacyFeatureProvider
+ .getNumberOfOwnerInstalledCaCertsInCurrentUser()).thenReturn(0);
+ mController.updateState(preference);
+ assertThat(preference.isVisible()).isFalse();
+
+ when(mFeatureFactory.enterprisePrivacyFeatureProvider
+ .getNumberOfOwnerInstalledCaCertsInCurrentUser()).thenReturn(1);
+ mController.updateState(preference);
+ assertThat(preference.isVisible()).isTrue();
+ assertThat(preference.getTitle()).isEqualTo(INSTALLED_CERTS_PERSONAL_1);
+ assertThat(preference.getSummary()).isEqualTo(NUMBER_INSTALLED_CERTS_1);
+
+ preference.setVisible(false);
+ when(mFeatureFactory.enterprisePrivacyFeatureProvider
+ .getNumberOfOwnerInstalledCaCertsInCurrentUser()).thenReturn(10);
+ mController.updateState(preference);
+ assertThat(preference.isVisible()).isTrue();
+ assertThat(preference.getTitle()).isEqualTo(INSTALLED_CERTS_PERSONAL_10);
+ assertThat(preference.getSummary()).isEqualTo(NUMBER_INSTALLED_CERTS_10);
+ }
+
+ @Test
+ public void testIsAvailable() {
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void testHandlePreferenceTreeClick() {
+ assertThat(mController.handlePreferenceTreeClick(new Preference(mContext, null, 0, 0)))
+ .isFalse();
+ }
+
+ @Test
+ public void testGetPreferenceKey() {
+ assertThat(mController.getPreferenceKey()).isEqualTo("ca_certs_current_user");
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/enterprise/CaCertsManagedProfilePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/CaCertsManagedProfilePreferenceControllerTest.java
new file mode 100644
index 0000000..c66128b
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/enterprise/CaCertsManagedProfilePreferenceControllerTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.settings.enterprise;
+
+import android.content.Context;
+import android.content.res.Resources;
+import com.android.settings.R;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.FakeFeatureFactory;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
+/**
+ * Tests for {@link CaCertsManagedProfilePreferenceController}.
+ */
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public final class CaCertsManagedProfilePreferenceControllerTest {
+
+ private final String INSTALLED_CERTS_1 = "cert installed";
+ private final String INSTALLED_CERTS_10 = "certs installed";
+ private final String NUMBER_INSTALLED_CERTS_1 = "1 cert";
+ private final String NUMBER_INSTALLED_CERTS_10 = "10 certs";
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private Context mContext;
+ private FakeFeatureFactory mFeatureFactory;
+
+ private CaCertsManagedProfilePreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ FakeFeatureFactory.setupForTest(mContext);
+ mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
+ mController = new CaCertsManagedProfilePreferenceController(mContext);
+
+ when(mContext.getResources().getQuantityString(R.plurals.enterprise_privacy_ca_certs_work,
+ 1)).thenReturn(INSTALLED_CERTS_1);
+ when(mContext.getResources().getQuantityString(R.plurals.enterprise_privacy_ca_certs_work,
+ 10)).thenReturn(INSTALLED_CERTS_10);
+ when(mContext.getResources().getQuantityString(R.plurals.enterprise_privacy_number_ca_certs,
+ 1, 1)).thenReturn(NUMBER_INSTALLED_CERTS_1);
+ when(mContext.getResources().getQuantityString(R.plurals.enterprise_privacy_number_ca_certs,
+ 10, 10)).thenReturn(NUMBER_INSTALLED_CERTS_10);
+ }
+
+ @Test
+ public void testUpdateState() {
+ final Preference preference = new Preference(mContext, null, 0, 0);
+ preference.setVisible(true);
+
+ when(mFeatureFactory.enterprisePrivacyFeatureProvider
+ .getNumberOfOwnerInstalledCaCertsInManagedProfile()).thenReturn(0);
+ mController.updateState(preference);
+ assertThat(preference.isVisible()).isFalse();
+
+ when(mFeatureFactory.enterprisePrivacyFeatureProvider
+ .getNumberOfOwnerInstalledCaCertsInManagedProfile()).thenReturn(1);
+ mController.updateState(preference);
+ assertThat(preference.isVisible()).isTrue();
+ assertThat(preference.getTitle()).isEqualTo(INSTALLED_CERTS_1);
+ assertThat(preference.getSummary()).isEqualTo(NUMBER_INSTALLED_CERTS_1);
+
+ preference.setVisible(false);
+ when(mFeatureFactory.enterprisePrivacyFeatureProvider
+ .getNumberOfOwnerInstalledCaCertsInManagedProfile()).thenReturn(10);
+ mController.updateState(preference);
+ assertThat(preference.isVisible()).isTrue();
+ assertThat(preference.getTitle()).isEqualTo(INSTALLED_CERTS_10);
+ assertThat(preference.getSummary()).isEqualTo(NUMBER_INSTALLED_CERTS_10);
+ }
+
+ @Test
+ public void testIsAvailable() {
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void testHandlePreferenceTreeClick() {
+ assertThat(mController.handlePreferenceTreeClick(new Preference(mContext, null, 0, 0)))
+ .isFalse();
+ }
+
+ @Test
+ public void testGetPreferenceKey() {
+ assertThat(mController.getPreferenceKey()).isEqualTo("ca_certs_managed_profile");
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/enterprise/EnterpriseInstalledPackagesPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/EnterpriseInstalledPackagesPreferenceControllerTest.java
index b55b512..46c29b2 100644
--- a/tests/robotests/src/com/android/settings/enterprise/EnterpriseInstalledPackagesPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/EnterpriseInstalledPackagesPreferenceControllerTest.java
@@ -86,11 +86,10 @@
assertThat(preference.isVisible()).isFalse();
setNumberOfEnterpriseInstalledPackages(20);
- when(mContext.getResources().getQuantityString(
- R.plurals.enterprise_privacy_number_enterprise_installed_packages, 20, 20))
- .thenReturn("20 packages");
+ when(mContext.getResources().getQuantityString(R.plurals.enterprise_privacy_number_packages,
+ 20, 20)).thenReturn("20 packages");
mController.updateState(preference);
- assertThat(preference.getTitle()).isEqualTo("20 packages");
+ assertThat(preference.getSummary()).isEqualTo("20 packages");
assertThat(preference.isVisible()).isTrue();
}
diff --git a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java
index da9569e..38d9221 100644
--- a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java
@@ -43,6 +43,7 @@
import org.robolectric.shadows.ShadowApplication;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Date;
import java.util.List;
@@ -255,11 +256,46 @@
assertThat(mProvider.getImeLabelIfOwnerSet()).isEqualTo(IME_PACKAGE_LABEL);
}
+ @Test
+ public void testGetNumberOfOwnerInstalledCaCertsInCurrentUser() {
+ final UserHandle userHandle = new UserHandle(UserHandle.USER_SYSTEM);
+
+ when(mDevicePolicyManager.getOwnerInstalledCaCerts(userHandle))
+ .thenReturn(null);
+ assertThat(mProvider.getNumberOfOwnerInstalledCaCertsInCurrentUser()).isEqualTo(0);
+ when(mDevicePolicyManager.getOwnerInstalledCaCerts(userHandle))
+ .thenReturn(new ArrayList<String>());
+ assertThat(mProvider.getNumberOfOwnerInstalledCaCertsInCurrentUser()).isEqualTo(0);
+ when(mDevicePolicyManager.getOwnerInstalledCaCerts(userHandle))
+ .thenReturn(Arrays.asList(new String[] {"ca1", "ca2"}));
+ assertThat(mProvider.getNumberOfOwnerInstalledCaCertsInCurrentUser()).isEqualTo(2);
+ }
+
+ @Test
+ public void testGetNumberOfOwnerInstalledCaCertsInManagedProfile() {
+ final UserHandle userHandle = new UserHandle(MANAGED_PROFILE_USER_ID);
+ final UserInfo managedProfile =
+ new UserInfo(MANAGED_PROFILE_USER_ID, "", "", UserInfo.FLAG_MANAGED_PROFILE);
+
+ mProfiles.add(managedProfile);
+ when(mDevicePolicyManager.getOwnerInstalledCaCerts(userHandle))
+ .thenReturn(null);
+ assertThat(mProvider.getNumberOfOwnerInstalledCaCertsInManagedProfile()).isEqualTo(0);
+ when(mDevicePolicyManager.getOwnerInstalledCaCerts(userHandle))
+ .thenReturn(new ArrayList<String>());
+ assertThat(mProvider.getNumberOfOwnerInstalledCaCertsInManagedProfile()).isEqualTo(0);
+ when(mDevicePolicyManager.getOwnerInstalledCaCerts(userHandle))
+ .thenReturn(Arrays.asList(new String[] {"ca1", "ca2"}));
+ assertThat(mProvider.getNumberOfOwnerInstalledCaCertsInManagedProfile()).isEqualTo(2);
+
+ mProfiles.remove(managedProfile);
+ assertThat(mProvider.getNumberOfOwnerInstalledCaCertsInManagedProfile()).isEqualTo(0);
+ }
+
private void resetAndInitializePackageManagerWrapper() {
reset(mPackageManagerWrapper);
when(mPackageManagerWrapper.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN))
.thenReturn(true);
when(mPackageManagerWrapper.getPackageManager()).thenReturn(mPackageManager);
-
}
}
diff --git a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacySettingsTest.java b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacySettingsTest.java
index f74c63a..2690198 100644
--- a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacySettingsTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacySettingsTest.java
@@ -73,7 +73,7 @@
final List<PreferenceController> controllers = mSettings.getPreferenceControllers(
ShadowApplication.getInstance().getApplicationContext());
assertThat(controllers).isNotNull();
- assertThat(controllers.size()).isEqualTo(15);
+ assertThat(controllers.size()).isEqualTo(17);
assertThat(controllers.get(0)).isInstanceOf(InstalledPackagesPreferenceController.class);
assertThat(controllers.get(1)).isInstanceOf(NetworkLogsPreferenceController.class);
assertThat(controllers.get(2)).isInstanceOf(BugReportsPreferenceController.class);
@@ -93,8 +93,13 @@
assertThat(controllers.get(10)).isInstanceOf(
AlwaysOnVpnManagedProfilePreferenceController.class);
assertThat(controllers.get(11)).isInstanceOf(GlobalHttpProxyPreferenceController.class);
- assertThat(controllers.get(12)).isInstanceOf(FailedPasswordWipePrimaryUserPreferenceController.class);
- assertThat(controllers.get(13)).isInstanceOf(FailedPasswordWipeManagedProfilePreferenceController.class);
- assertThat(controllers.get(14)).isInstanceOf(ImePreferenceController.class);
+ assertThat(controllers.get(12)).isInstanceOf(CaCertsCurrentUserPreferenceController.class);
+ assertThat(controllers.get(13)).isInstanceOf(
+ CaCertsManagedProfilePreferenceController.class);
+ assertThat(controllers.get(14)).isInstanceOf(
+ FailedPasswordWipePrimaryUserPreferenceController.class);
+ assertThat(controllers.get(15)).isInstanceOf(
+ FailedPasswordWipeManagedProfilePreferenceController.class);
+ assertThat(controllers.get(16)).isInstanceOf(ImePreferenceController.class);
}
}
diff --git a/tests/robotests/src/com/android/settings/enterprise/EnterpriseSetDefaultAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/EnterpriseSetDefaultAppsPreferenceControllerTest.java
index 84520a5..093ce20 100644
--- a/tests/robotests/src/com/android/settings/enterprise/EnterpriseSetDefaultAppsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/EnterpriseSetDefaultAppsPreferenceControllerTest.java
@@ -118,11 +118,10 @@
ContactsContract.Contacts.CONTENT_TYPE)}, 32);
setEnterpriseSetDefaultApps(new Intent[] {new Intent(Intent.ACTION_DIAL),
new Intent(Intent.ACTION_CALL)}, 64);
- when(mContext.getResources().getQuantityString(
- R.plurals.enterprise_privacy_number_enterprise_set_default_apps, 127, 127))
- .thenReturn("127 apps");
+ when(mContext.getResources().getQuantityString(R.plurals.enterprise_privacy_number_packages,
+ 127, 127)).thenReturn("127 apps");
mController.updateState(preference);
- assertThat(preference.getTitle()).isEqualTo("127 apps");
+ assertThat(preference.getSummary()).isEqualTo("127 apps");
assertThat(preference.isVisible()).isTrue();
}
diff --git a/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipeManagedProfilePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipeManagedProfilePreferenceControllerTest.java
index 29952a7..c9981f9 100644
--- a/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipeManagedProfilePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipeManagedProfilePreferenceControllerTest.java
@@ -18,7 +18,6 @@
import android.content.Context;
-import com.android.settings.R;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
@@ -38,8 +37,7 @@
private int mMaximumFailedPasswordsBeforeWipe = 0;
public FailedPasswordWipeManagedProfilePreferenceControllerTest() {
- super("failed_password_wipe_managed_profile",
- R.plurals.enterprise_privacy_failed_password_wipe_work);
+ super("failed_password_wipe_managed_profile");
}
@Override
diff --git a/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipePreferenceControllerBaseTest.java b/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipePreferenceControllerBaseTest.java
index 97d0d6d..1c7b448 100644
--- a/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipePreferenceControllerBaseTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipePreferenceControllerBaseTest.java
@@ -33,7 +33,7 @@
private int mMaximumFailedPasswordsBeforeWipe = 0;
public FailedPasswordWipePreferenceControllerBaseTest() {
- super(null, 123 /* stringResourceId */);
+ super(null);
}
@Override
@@ -50,7 +50,7 @@
private class FailedPasswordWipePreferenceControllerBaseTestable extends
FailedPasswordWipePreferenceControllerBase {
FailedPasswordWipePreferenceControllerBaseTestable() {
- super(FailedPasswordWipePreferenceControllerBaseTest.this.mContext, mStringResourceId);
+ super(FailedPasswordWipePreferenceControllerBaseTest.this.mContext);
}
@Override
diff --git a/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipePreferenceControllerTestBase.java b/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipePreferenceControllerTestBase.java
index 5a74fa5..aa189e2 100644
--- a/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipePreferenceControllerTestBase.java
+++ b/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipePreferenceControllerTestBase.java
@@ -20,6 +20,7 @@
import android.content.res.Resources;
import android.support.v7.preference.Preference;
+import com.android.settings.R;
import com.android.settings.testutils.FakeFeatureFactory;
import org.junit.Before;
@@ -37,7 +38,6 @@
public abstract class FailedPasswordWipePreferenceControllerTestBase {
protected final String mKey;
- protected final int mStringResourceId;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
protected Context mContext;
@@ -45,9 +45,8 @@
protected FailedPasswordWipePreferenceControllerBase mController;
- public FailedPasswordWipePreferenceControllerTestBase(String key, int stringResourceId) {
+ public FailedPasswordWipePreferenceControllerTestBase(String key) {
mKey = key;
- mStringResourceId = stringResourceId;
}
@Before
@@ -65,11 +64,11 @@
preference.setVisible(false);
setMaximumFailedPasswordsBeforeWipe(10);
- when(mContext.getResources().getQuantityString(mStringResourceId, 10, 10))
+ when(mContext.getResources().getQuantityString(
+ R.plurals.enterprise_privacy_number_failed_password_wipe, 10, 10))
.thenReturn("10 attempts");
mController.updateState(preference);
- assertThat(preference.getTitle()).isEqualTo("10 attempts");
- assertThat(preference.isVisible()).isTrue();
+ assertThat(preference.getSummary()).isEqualTo("10 attempts");
setMaximumFailedPasswordsBeforeWipe(0);
mController.updateState(preference);
diff --git a/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipePrimaryUserPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipePrimaryUserPreferenceControllerTest.java
index ea6d977..65c9828 100644
--- a/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipePrimaryUserPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/FailedPasswordWipePrimaryUserPreferenceControllerTest.java
@@ -18,7 +18,6 @@
import android.content.Context;
-import com.android.settings.R;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
@@ -38,8 +37,7 @@
private int mMaximumFailedPasswordsBeforeWipe = 0;
public FailedPasswordWipePrimaryUserPreferenceControllerTest() {
- super("failed_password_wipe_primary_user",
- R.plurals.enterprise_privacy_failed_password_wipe_device);
+ super("failed_password_wipe_primary_user");
}
@Override
diff --git a/tests/robotests/src/com/android/settings/enterprise/ImePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/ImePreferenceControllerTest.java
index 232a872..547746c 100644
--- a/tests/robotests/src/com/android/settings/enterprise/ImePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/ImePreferenceControllerTest.java
@@ -44,7 +44,7 @@
public final class ImePreferenceControllerTest {
private final String DEFAULT_IME_LABEL = "Test IME";
- private final String DEFAULT_IME_TEXT = "IME set to Test IME";
+ private final String DEFAULT_IME_TEXT = "Set to Test IME";
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
@@ -58,7 +58,7 @@
FakeFeatureFactory.setupForTest(mContext);
mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
mController = new ImePreferenceController(mContext);
- when(mContext.getResources().getString(R.string.enterprise_privacy_input_method,
+ when(mContext.getResources().getString(R.string.enterprise_privacy_input_method_name,
DEFAULT_IME_LABEL)).thenReturn(DEFAULT_IME_TEXT);
}
@@ -76,7 +76,7 @@
.thenReturn(DEFAULT_IME_LABEL);
mController.updateState(preference);
assertThat(preference.isVisible()).isTrue();
- assertThat(preference.getTitle()).isEqualTo(DEFAULT_IME_TEXT);
+ assertThat(preference.getSummary()).isEqualTo(DEFAULT_IME_TEXT);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/enterprise/InstalledPackagesPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/InstalledPackagesPreferenceControllerTest.java
index bf2c4ca..60ceed6 100644
--- a/tests/robotests/src/com/android/settings/enterprise/InstalledPackagesPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/InstalledPackagesPreferenceControllerTest.java
@@ -64,22 +64,30 @@
mController = new InstalledPackagesPreferenceController(mContext);
}
- @Test
- public void testUpdateState() {
- final Preference preference = new Preference(mContext, null, 0, 0);
+ private void setNumberOfInstalledPackages(int number) {
doAnswer(new Answer() {
public Object answer(InvocationOnMock invocation) {
((ApplicationFeatureProvider.NumberOfAppsCallback)
- invocation.getArguments()[1]).onNumberOfAppsResult(20);
+ invocation.getArguments()[1]).onNumberOfAppsResult(number);
return null;
}}).when(mFeatureFactory.applicationFeatureProvider)
.calculateNumberOfInstalledApps(
eq(ApplicationFeatureProvider.IGNORE_INSTALL_REASON), anyObject());
- when(mContext.getResources().getQuantityString(
- R.plurals.enterprise_privacy_number_installed_packages, 20, 20))
- .thenReturn("20 packages");
+ }
+
+ @Test
+ public void testUpdateState() {
+ final Preference preference = new Preference(mContext, null, 0, 0);
+
+ setNumberOfInstalledPackages(0);
mController.updateState(preference);
- assertThat(preference.getTitle()).isEqualTo("20 packages");
+ assertThat(preference.getSummary()).isEqualTo("");
+
+ setNumberOfInstalledPackages(20);
+ when(mContext.getResources().getQuantityString(R.plurals.enterprise_privacy_number_packages,
+ 20, 20)).thenReturn("20 packages");
+ mController.updateState(preference);
+ assertThat(preference.getSummary()).isEqualTo("20 packages");
}
@Test
@@ -95,6 +103,6 @@
@Test
public void testGetPreferenceKey() {
- assertThat(mController.getPreferenceKey()).isEqualTo("number_installed_packages");
+ assertThat(mController.getPreferenceKey()).isEqualTo("installed_packages");
}
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java
new file mode 100644
index 0000000..6d3607f
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java
@@ -0,0 +1,149 @@
+/*
+ * 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.settings.fuelgauge;
+
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.support.v14.preference.SwitchPreference;
+
+import com.android.settings.TestConfig;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class BackgroundActivityPreferenceControllerTest {
+ private static final int UID_NORMAL = 1234;
+ private static final int UID_SPECIAL = 2345;
+ private static final String HIGH_SDK_PACKAGE = "com.android.package.high";
+ private static final String LOW_SDK_PACKAGE = "com.android.package.low";
+ private static final String[] PACKAGES_NORMAL = {LOW_SDK_PACKAGE};
+ private static final String[] PACKAGES_SPECIAL = {HIGH_SDK_PACKAGE, LOW_SDK_PACKAGE};
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private Context mContext;
+ @Mock
+ private PackageManager mPackageManager;
+ @Mock
+ private AppOpsManager mAppOpsManager;
+ @Mock
+ private SwitchPreference mPreference;
+ @Mock
+ private ApplicationInfo mHighApplicationInfo;
+ @Mock
+ private ApplicationInfo mLowApplicationInfo;
+ private BackgroundActivityPreferenceController mController;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ when(mContext.getPackageManager()).thenReturn(mPackageManager);
+ when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager);
+ when(mPackageManager.getPackagesForUid(UID_NORMAL)).thenReturn(PACKAGES_NORMAL);
+ when(mPackageManager.getPackagesForUid(UID_SPECIAL)).thenReturn(PACKAGES_SPECIAL);
+
+ when(mPackageManager.getApplicationInfo(HIGH_SDK_PACKAGE, PackageManager.GET_META_DATA))
+ .thenReturn(mHighApplicationInfo);
+ when(mPackageManager.getApplicationInfo(LOW_SDK_PACKAGE, PackageManager.GET_META_DATA))
+ .thenReturn(mLowApplicationInfo);
+ mHighApplicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
+ mLowApplicationInfo.targetSdkVersion = Build.VERSION_CODES.L;
+
+ mController = new BackgroundActivityPreferenceController(mContext, UID_NORMAL);
+ mController.isAvailable();
+ }
+
+ @Test
+ public void testOnPreferenceChange_TurnOnCheck_MethodInvoked() {
+ mController.onPreferenceChange(mPreference, true);
+
+ verify(mAppOpsManager).setUidMode(AppOpsManager.OP_RUN_IN_BACKGROUND,
+ UID_NORMAL, AppOpsManager.MODE_DEFAULT);
+ }
+
+ @Test
+ public void testOnPreferenceChange_TurnOffCheck_MethodInvoked() {
+ mController.onPreferenceChange(null, false);
+
+ verify(mAppOpsManager).setUidMode(AppOpsManager.OP_RUN_IN_BACKGROUND,
+ UID_NORMAL, AppOpsManager.MODE_IGNORED);
+ }
+
+ @Test
+ public void testUpdateState_CheckOn_SetCheckedTrue() {
+ when(mAppOpsManager
+ .checkOpNoThrow(AppOpsManager.OP_RUN_IN_BACKGROUND, UID_NORMAL, LOW_SDK_PACKAGE))
+ .thenReturn(AppOpsManager.MODE_DEFAULT);
+
+ mController.updateState(mPreference);
+
+ verify(mPreference).setChecked(true);
+ }
+
+ @Test
+ public void testUpdateState_CheckOff_SetCheckedFalse() {
+ when(mAppOpsManager
+ .checkOpNoThrow(AppOpsManager.OP_RUN_IN_BACKGROUND, UID_NORMAL, LOW_SDK_PACKAGE))
+ .thenReturn(AppOpsManager.MODE_IGNORED);
+
+ mController.updateState(mPreference);
+
+ verify(mPreference).setChecked(false);
+ }
+
+ @Test
+ public void testIsPackageAvailable_SdkLowerThanO_ReturnTrue() {
+ assertThat(mController.isLegacyApp(LOW_SDK_PACKAGE)).isTrue();
+ }
+
+ @Test
+ public void testIsPackageAvailable_SdkLargerOrEqualThanO_ReturnFalse() {
+ assertThat(mController.isLegacyApp(HIGH_SDK_PACKAGE)).isFalse();
+ }
+
+ @Test
+ public void testMultiplePackages_ReturnStatusForTargetPackage() {
+ mController = new BackgroundActivityPreferenceController(mContext, UID_SPECIAL);
+ when(mAppOpsManager
+ .checkOpNoThrow(AppOpsManager.OP_RUN_IN_BACKGROUND, UID_SPECIAL, LOW_SDK_PACKAGE))
+ .thenReturn(AppOpsManager.MODE_DEFAULT);
+ when(mAppOpsManager
+ .checkOpNoThrow(AppOpsManager.OP_RUN_IN_BACKGROUND, UID_SPECIAL, HIGH_SDK_PACKAGE))
+ .thenReturn(AppOpsManager.MODE_IGNORED);
+
+ final boolean available = mController.isAvailable();
+ mController.updateState(mPreference);
+
+ assertThat(available).isTrue();
+ // Should get status from LOW_SDK_PACKAGE
+ verify(mPreference).setChecked(true);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/gestures/AssistGestureSensitivityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/AssistGestureSensitivityPreferenceControllerTest.java
new file mode 100644
index 0000000..229ef49
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/gestures/AssistGestureSensitivityPreferenceControllerTest.java
@@ -0,0 +1,101 @@
+/*
+ * 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.settings.gestures;
+
+import android.content.Context;
+import android.provider.Settings;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.FakeFeatureFactory;
+
+import com.android.settings.search2.InlineSwitchPayload;
+import com.android.settings.search2.ResultPayload;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static android.provider.Settings.Secure.ASSIST_GESTURE_ENABLED;
+import static android.provider.Settings.Secure.ASSIST_GESTURE_SENSITIVITY;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class AssistGestureSensitivityPreferenceControllerTest {
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private Context mContext;
+ private FakeFeatureFactory mFactory;
+ private AssistGestureSensitivityPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ FakeFeatureFactory.setupForTest(mContext);
+ mFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
+ mController = new AssistGestureSensitivityPreferenceController(mContext, null);
+ }
+
+ @Test
+ public void isAvailable_whenSupportedAndEnabled_shouldReturnTrue() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.ASSIST_GESTURE_ENABLED, 1);
+ when(mFactory.assistGestureFeatureProvider.isSupported(mContext)).thenReturn(true);
+
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void isAvailable_whenSupportedAndDisabled_shouldReturnFalse() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.ASSIST_GESTURE_ENABLED, 0);
+ when(mFactory.assistGestureFeatureProvider.isSupported(mContext)).thenReturn(true);
+
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void isAvailable_whenUnsupportedAndEnabled_shouldReturnFalse() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.ASSIST_GESTURE_ENABLED, 1);
+ when(mFactory.assistGestureFeatureProvider.isSupported(mContext)).thenReturn(false);
+
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void isAvailable_whenUnsupportedAndDisabled_shouldReturnFalse() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.ASSIST_GESTURE_ENABLED, 0);
+ when(mFactory.assistGestureFeatureProvider.isSupported(mContext)).thenReturn(false);
+
+ assertThat(mController.isAvailable()).isFalse();
+ }
+}
+
diff --git a/tests/robotests/src/com/android/settings/notification/WorkSoundPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/WorkSoundPreferenceControllerTest.java
index acfd400..13abd97 100644
--- a/tests/robotests/src/com/android/settings/notification/WorkSoundPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/WorkSoundPreferenceControllerTest.java
@@ -17,11 +17,10 @@
package com.android.settings.notification;
import android.content.Context;
-import android.os.Build.VERSION_CODES;
import android.os.UserHandle;
import android.os.UserManager;
import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceGroup;
+import android.support.v7.preference.PreferenceCategory;
import android.support.v7.preference.PreferenceScreen;
import android.support.v7.preference.TwoStatePreference;
import android.telephony.TelephonyManager;
@@ -36,17 +35,15 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import static com.google.common.truth.Truth.assertThat;
-
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -65,6 +62,8 @@
@Mock
private PreferenceScreen mScreen;
@Mock
+ private PreferenceCategory mWorkCategory;
+ @Mock
private TelephonyManager mTelephonyManager;
@Mock
private AudioHelper mAudioHelper;
@@ -78,6 +77,17 @@
MockitoAnnotations.initMocks(this);
when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
+ when(mScreen.findPreference(KEY_WORK_CATEGORY))
+ .thenReturn(mWorkCategory);
+ when(mWorkCategory.findPreference(KEY_WORK_USE_PERSONAL_SOUNDS))
+ .thenReturn(mock(TwoStatePreference.class));
+ when(mWorkCategory.findPreference(KEY_WORK_PHONE_RINGTONE))
+ .thenReturn(mock(DefaultRingtonePreference.class));
+ when(mWorkCategory.findPreference(KEY_WORK_NOTIFICATION_RINGTONE))
+ .thenReturn(mock(DefaultRingtonePreference.class));
+ when(mWorkCategory.findPreference(KEY_WORK_ALARM_RINGTONE))
+ .thenReturn(mock(DefaultRingtonePreference.class));
+
mController = new WorkSoundPreferenceController(mContext, mFragment, null, mAudioHelper);
}
@@ -112,45 +122,30 @@
}
@Test
- public void onResume_available_shouldAddPreferenceCategory() {
- when(mAudioHelper.getManagedProfileId(any(UserManager.class)))
- .thenReturn(UserHandle.myUserId());
- when(mAudioHelper.isUserUnlocked(any(UserManager.class), anyInt())).thenReturn(true);
- when(mAudioHelper.isSingleVolume()).thenReturn(false);
- when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
- when(mAudioHelper.createPackageContextAsUser(anyInt())).thenReturn(mContext);
- mockWorkCategory();
-
- mController.onResume();
-
- verify(mFragment).addPreferencesFromResource(R.xml.sound_work_settings);
- }
-
- @Test
- public void onManagedProfileAdded_shouldAddPreferenceCategory() {
+ public void onManagedProfileAdded_shouldDisplayPreferenceCategory() {
// Given a device without any managed profiles:
when(mAudioHelper.isSingleVolume()).thenReturn(false);
when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
when(mAudioHelper.createPackageContextAsUser(anyInt())).thenReturn(mContext);
when(mAudioHelper.getManagedProfileId(any(UserManager.class)))
.thenReturn(UserHandle.USER_NULL);
- mockWorkCategory();
- // When the fragment first resumes, the category should not appear.
+ // When the fragment first displays, the category should not appear.
+ mController.displayPreference(mScreen);
+ verify(mWorkCategory).setVisible(false);
+
+
+ // However, when a managed profile is added later, the category should appear.
mController.onResume();
-
- verify(mFragment, never()).addPreferencesFromResource(R.xml.sound_work_settings);
-
- // However, when a managed profile is added after resuming, the category should appear.
when(mAudioHelper.getManagedProfileId(any(UserManager.class)))
.thenReturn(UserHandle.myUserId());
mController.onManagedProfileAdded(UserHandle.myUserId());
- verify(mFragment).addPreferencesFromResource(R.xml.sound_work_settings);
+ verify(mWorkCategory).setVisible(true);
}
@Test
- public void onManagedProfileRemoved_shouldRemovePreferenceCategory() {
+ public void onManagedProfileRemoved_shouldHidePreferenceCategory() {
// Given a device with a managed profile:
when(mAudioHelper.isSingleVolume()).thenReturn(false);
when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
@@ -158,29 +153,44 @@
when(mAudioHelper.getManagedProfileId(any(UserManager.class)))
.thenReturn(UserHandle.myUserId());
when(mAudioHelper.isUserUnlocked(any(UserManager.class), anyInt())).thenReturn(true);
- mockWorkCategory();
// Which is in resumed state:
+ mController.displayPreference(mScreen);
mController.onResume();
- // When a managed profile is removed, the category should be removed.
+ verify(mWorkCategory, times(2)).setVisible(true);
+
+ // When a managed profile is removed, the category should be hidden.
when(mAudioHelper.getManagedProfileId(any(UserManager.class)))
.thenReturn(UserHandle.USER_NULL);
mController.onManagedProfileRemoved(UserHandle.myUserId());
- verify(mScreen).removePreference(mScreen.findPreference(KEY_WORK_CATEGORY));
+ verify(mWorkCategory).setVisible(false);
+ }
+
+
+ @Test
+ public void displayPreference_isAvailable_shouldShowPreferenceCategory() {
+ when(mAudioHelper.getManagedProfileId(any(UserManager.class)))
+ .thenReturn(UserHandle.myUserId());
+ when(mAudioHelper.isUserUnlocked(any(UserManager.class), anyInt())).thenReturn(true);
+ when(mAudioHelper.isSingleVolume()).thenReturn(false);
+ when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
+ when(mAudioHelper.createPackageContextAsUser(anyInt())).thenReturn(mContext);
+
+ mController.displayPreference(mScreen);
+ verify(mWorkCategory).setVisible(true);
}
@Test
- public void onResume_notAvailable_shouldNotAddPreferenceCategory() {
+ public void displayPreference_notAvailable_shouldHidePreferenceCategory() {
when(mAudioHelper.getManagedProfileId(any(UserManager.class)))
- .thenReturn(UserHandle.USER_NULL);
+ .thenReturn(UserHandle.USER_NULL);
when(mAudioHelper.isSingleVolume()).thenReturn(true);
when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
- mController.onResume();
-
- verify(mFragment, never()).addPreferencesFromResource(anyInt());
+ mController.displayPreference(mScreen);
+ verify(mWorkCategory).setVisible(false);
}
@Test
@@ -206,27 +216,19 @@
when(mAudioHelper.getManagedProfileId(any(UserManager.class)))
.thenReturn(UserHandle.myUserId());
when(mAudioHelper.isUserUnlocked(any(UserManager.class), anyInt())).thenReturn(false);
- mockWorkCategory();
// When resumed:
+ mController.displayPreference(mScreen);
mController.onResume();
- // Sound preferences should explain that the profile isn't available yet.
- verify(mScreen.findPreference(KEY_WORK_PHONE_RINGTONE)).setSummary(eq(notAvailable));
- verify(mScreen.findPreference(KEY_WORK_NOTIFICATION_RINGTONE)).setSummary(eq(notAvailable));
- verify(mScreen.findPreference(KEY_WORK_ALARM_RINGTONE)).setSummary(eq(notAvailable));
- }
+ verify(mWorkCategory, times(2)).setVisible(true);
- private void mockWorkCategory() {
- when(mScreen.findPreference(KEY_WORK_CATEGORY))
- .thenReturn(mock(PreferenceGroup.class));
- when(mScreen.findPreference(KEY_WORK_USE_PERSONAL_SOUNDS))
- .thenReturn(mock(TwoStatePreference.class));
- when(mScreen.findPreference(KEY_WORK_PHONE_RINGTONE))
- .thenReturn(mock(DefaultRingtonePreference.class));
- when(mScreen.findPreference(KEY_WORK_NOTIFICATION_RINGTONE))
- .thenReturn(mock(DefaultRingtonePreference.class));
- when(mScreen.findPreference(KEY_WORK_ALARM_RINGTONE))
- .thenReturn(mock(DefaultRingtonePreference.class));
+ // Sound preferences should explain that the profile isn't available yet.
+ verify(mWorkCategory.findPreference(KEY_WORK_PHONE_RINGTONE))
+ .setSummary(eq(notAvailable));
+ verify(mWorkCategory.findPreference(KEY_WORK_NOTIFICATION_RINGTONE))
+ .setSummary(eq(notAvailable));
+ verify(mWorkCategory.findPreference(KEY_WORK_ALARM_RINGTONE))
+ .setSummary(eq(notAvailable));
}
}
diff --git a/tests/robotests/src/com/android/settings/security/SecurityFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/security/SecurityFeatureProviderImplTest.java
index 49eb48b..50debb4 100644
--- a/tests/robotests/src/com/android/settings/security/SecurityFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/security/SecurityFeatureProviderImplTest.java
@@ -171,6 +171,18 @@
verify(screen.findPreference(MOCK_KEY), never()).setSummary(anyString());
}
+ @Test
+ public void initPreferences_shouldLoadDefaults() {
+ PreferenceScreen screen = getPreferenceScreen();
+ DashboardCategory dashboardCategory = getDashboardCategory();
+ dashboardCategory.getTile(0).metaData = new Bundle();
+
+ mImpl.initPreferences(mContext, screen, dashboardCategory);
+ verify(screen.findPreference(MOCK_KEY)).setIcon(SecurityFeatureProviderImpl.DEFAULT_ICON);
+ verify(screen.findPreference(MOCK_KEY))
+ .setSummary(SecurityFeatureProviderImpl.DEFAULT_SUMMARY);
+ }
+
private PreferenceScreen getPreferenceScreen() {
final PreferenceScreen screen = mock(PreferenceScreen.class);
final Preference pref = mock(Preference.class);
diff --git a/tests/robotests/src/com/android/settings/system/FactoryResetPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/system/FactoryResetPreferenceControllerTest.java
new file mode 100644
index 0000000..f41870e
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/system/FactoryResetPreferenceControllerTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.settings.system;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Answers.RETURNS_DEEP_STUBS;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.UserManager;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class FactoryResetPreferenceControllerTest {
+
+ private static final String FACTORY_RESET_KEY = "factory_reset";
+
+ @Mock(answer = RETURNS_DEEP_STUBS)
+ private Context mContext;
+ @Mock
+ private UserManager mUserManager;
+
+ private FactoryResetPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mController = new FactoryResetPreferenceController(mContext, mUserManager);
+ }
+
+ @Test
+ public void isAvailable_systemUser() {
+ when(mUserManager.isAdminUser()).thenReturn(true);
+
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void isAvailable_nonSystemUser() {
+ when(mUserManager.isAdminUser()).thenReturn(false);
+
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test public void getPreferenceKey() {
+ assertThat(mController.getPreferenceKey()).isEqualTo(FACTORY_RESET_KEY);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowZoneGetter.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowZoneGetter.java
new file mode 100644
index 0000000..655acf1
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowZoneGetter.java
@@ -0,0 +1,53 @@
+/*
+ * 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.settings.testutils.shadow;
+
+import android.content.Context;
+
+import com.android.settingslib.datetime.ZoneGetter;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+
+@Implements(ZoneGetter.class)
+public class ShadowZoneGetter {
+
+ @Implementation
+ public static List<Map<String, Object>> getZonesList(Context context) {
+ List<Map<String, Object>> zones = new ArrayList<>();
+ zones.add(createDisplayEntry(TimeZone.getDefault(), "gmt-1:00", "FakePlace", 10000));
+ return zones;
+ }
+
+ private static Map<String, Object> createDisplayEntry(
+ TimeZone tz, CharSequence gmtOffsetText, CharSequence displayName, int offsetMillis) {
+ Map<String, Object> map = new HashMap<>();
+ map.put(ZoneGetter.KEY_ID, tz.getID());
+ map.put(ZoneGetter.KEY_DISPLAYNAME, displayName.toString());
+ map.put(ZoneGetter.KEY_DISPLAY_LABEL, displayName);
+ map.put(ZoneGetter.KEY_GMT, gmtOffsetText.toString());
+ map.put(ZoneGetter.KEY_OFFSET_LABEL, gmtOffsetText);
+ map.put(ZoneGetter.KEY_OFFSET, offsetMillis);
+ return map;
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java b/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java
index c58ce37..728e357 100644
--- a/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java
+++ b/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java
@@ -19,6 +19,7 @@
import static android.provider.Settings.ACTION_WEBVIEW_SETTINGS;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
@@ -33,9 +34,11 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageItemInfo;
+import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.os.UserManager;
-import android.support.v7.preference.PreferenceManager;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
@@ -325,4 +328,30 @@
assertThat(mPicker.getDisabledReason(wvusWrapper, mContext,
DEFAULT_PACKAGE_NAME)).isEqualTo(EXPECTED_DISABLED_REASON);
}
+
+ /**
+ * Ensure that the version name of a WebView package is displayed after its name in the
+ * preference title.
+ */
+ @Test
+ public void testWebViewVersionAddedAfterLabel() throws PackageManager.NameNotFoundException {
+ PackageItemInfo mockPackageItemInfo = mock(PackageItemInfo.class);
+ mockPackageItemInfo.packageName = DEFAULT_PACKAGE_NAME;
+ when(mockPackageItemInfo.loadLabel(any())).thenReturn("myPackage");
+ DefaultAppInfo webviewAppInfo = mPicker.createDefaultAppInfo(
+ mockPackageItemInfo, "" /* disabledReason */);
+
+ PackageInfo packageInfo = new PackageInfo();
+ packageInfo.versionName = "myVersionName";
+ PackageManager pm = mock(PackageManager.class);
+ when(pm.getPackageInfo(eq(DEFAULT_PACKAGE_NAME), anyInt())).thenReturn(packageInfo);
+ when(mPackageManager.getPackageManager()).thenReturn(pm);
+
+ RadioButtonPreference mockPreference = mock(RadioButtonPreference.class);
+ mPicker.configurePreferenceFromAppInfo(mockPreference,
+ DEFAULT_PACKAGE_NAME, webviewAppInfo, null, null);
+
+ verify(mockPreference, times(1)).setTitle(eq("myPackage myVersionName"));
+ verify(mockPreference, times(1)).setTitle(any());
+ }
}
diff --git a/tests/robotests/src/com/android/settings/wfd/WifiDisplaySettingsTest.java b/tests/robotests/src/com/android/settings/wfd/WifiDisplaySettingsTest.java
index c412d55..de097fc 100644
--- a/tests/robotests/src/com/android/settings/wfd/WifiDisplaySettingsTest.java
+++ b/tests/robotests/src/com/android/settings/wfd/WifiDisplaySettingsTest.java
@@ -18,7 +18,9 @@
import android.app.Activity;
import android.content.Context;
+import android.hardware.display.DisplayManager;
import android.media.MediaRouter;
+import android.net.wifi.p2p.WifiP2pManager;
import com.android.settings.R;
import com.android.settings.SettingsRobolectricTestRunner;
@@ -32,6 +34,7 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
+import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -82,4 +85,22 @@
verify(mActivity).getString(R.string.wifi_display_status_connected);
}
+ @Test
+ public void isAvailable_noService_shouldReturnFalse() {
+ assertThat(WifiDisplaySettings.isAvailable(mActivity))
+ .isFalse();
+
+ }
+
+ @Test
+ public void isAvailable_hasService_shouldReturnTrue() {
+ when(mActivity.getSystemService(Context.DISPLAY_SERVICE))
+ .thenReturn(mock(DisplayManager.class));
+ when(mActivity.getSystemService(Context.WIFI_P2P_SERVICE))
+ .thenReturn(mock(WifiP2pManager.class));
+
+ assertThat(WifiDisplaySettings.isAvailable(mActivity))
+ .isTrue();
+ }
+
}
diff --git a/tests/unit/src/com/android/settings/display/ThemePreferenceControllerTest.java b/tests/unit/src/com/android/settings/display/ThemePreferenceControllerTest.java
index 231787e..3137d59 100644
--- a/tests/unit/src/com/android/settings/display/ThemePreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/display/ThemePreferenceControllerTest.java
@@ -14,95 +14,115 @@
* limitations under the License.
*/
-package com.android.settings.core;
-
-import static junit.framework.TestCase.assertNotNull;
+package com.android.settings.display;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.app.UiModeManager;
-import android.content.Context;
import android.content.ContextWrapper;
+import android.content.om.OverlayInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.support.v7.preference.ListPreference;
-import com.android.settings.R;
import com.android.settings.display.ThemePreferenceController;
+import com.android.settings.display.ThemePreferenceController.OverlayManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
+import java.util.ArrayList;
+
@SmallTest
@RunWith(AndroidJUnit4.class)
public class ThemePreferenceControllerTest {
- private UiModeManager mMockUiModeManager;
+ private OverlayManager mMockOverlayManager;
private ContextWrapper mContext;
private ThemePreferenceController mPreferenceController;
+ private PackageManager mMockPackageManager;
@Before
public void setup() {
- mMockUiModeManager = mock(UiModeManager.class);
- mContext = new ContextWrapper(InstrumentationRegistry.getTargetContext()) {
+ mMockOverlayManager = mock(OverlayManager.class);
+ mMockPackageManager = mock(PackageManager.class);
+ mContext = new ContextWrapper(InstrumentationRegistry.getContext()) {
@Override
- public Object getSystemService(String name) {
- if (Context.UI_MODE_SERVICE.equals(name)) {
- return mMockUiModeManager;
- }
- return super.getSystemService(name);
+ public PackageManager getPackageManager() {
+ return mMockPackageManager;
}
};
- mPreferenceController = new ThemePreferenceController(mContext);
+ mPreferenceController = new ThemePreferenceController(mContext, mMockOverlayManager);
}
@Test
- public void testUpdateState() {
- when(mMockUiModeManager.getAvailableThemes()).thenReturn(new String[] {
- null,
- "Theme1",
- "Theme2",
+ public void testUpdateState() throws Exception {
+ OverlayInfo info1 = new OverlayInfo("com.android.Theme1", "android",
+ "", OverlayInfo.STATE_ENABLED, 0);
+ OverlayInfo info2 = new OverlayInfo("com.android.Theme2", "android",
+ "", 0, 0);
+ when(mMockPackageManager.getApplicationInfo(any(), anyInt())).thenAnswer(inv -> {
+ ApplicationInfo info = mock(ApplicationInfo.class);
+ if ("com.android.Theme1".equals(inv.getArguments()[0])) {
+ when(info.loadLabel(any())).thenReturn("Theme1");
+ } else {
+ when(info.loadLabel(any())).thenReturn("Theme2");
+ }
+ return info;
});
- when(mMockUiModeManager.getTheme()).thenReturn("Theme1");
+ when(mMockOverlayManager.getOverlayInfosForTarget(any(), anyInt())).thenReturn(
+ list(info1, info2));
ListPreference pref = mock(ListPreference.class);
mPreferenceController.updateState(pref);
ArgumentCaptor<String[]> arg = ArgumentCaptor.forClass(String[].class);
verify(pref).setEntries(arg.capture());
- String[] entries = arg.getValue();
- assertEquals(3, entries.length);
- assertNotNull(entries[0]);
- assertEquals("Theme1", entries[1]);
- assertEquals("Theme2", entries[2]);
+
+ CharSequence[] entries = arg.getValue();
+ assertEquals(2, entries.length);
+ assertEquals("Theme1", entries[0]);
+ assertEquals("Theme2", entries[1]);
verify(pref).setEntryValues(arg.capture());
- String[] entryValues = arg.getValue();
- assertEquals(3, entryValues.length);
- assertNotNull(entryValues[0]);
- assertEquals("Theme1", entryValues[1]);
- assertEquals("Theme2", entryValues[2]);
+ CharSequence[] entryValues = arg.getValue();
+ assertEquals("com.android.Theme1", entryValues[0]);
+ assertEquals("com.android.Theme2", entryValues[1]);
- verify(pref).setValue(eq("Theme1"));
+ verify(pref).setValue(eq("com.android.Theme1"));
}
@Test
- public void testAvailable_false() {
- when(mMockUiModeManager.getAvailableThemes()).thenReturn(new String[1]);
+ public void testAvailable_false() throws Exception {
+ when(mMockOverlayManager.getOverlayInfosForTarget(any(), anyInt()))
+ .thenReturn(list(new OverlayInfo("", "", "", 0, 0)));
assertFalse(mPreferenceController.isAvailable());
}
@Test
- public void testAvailable_true() {
- when(mMockUiModeManager.getAvailableThemes()).thenReturn(new String[2]);
+ public void testAvailable_true() throws Exception {
+ when(mMockOverlayManager.getOverlayInfosForTarget(any(), anyInt()))
+ .thenReturn(list(new OverlayInfo("", "", "", 0, 0),
+ new OverlayInfo("", "", "", 0, 0)));
assertTrue(mPreferenceController.isAvailable());
}
+
+ private ArrayList<OverlayInfo> list(OverlayInfo... infos) {
+ ArrayList<OverlayInfo> list = new ArrayList<>();
+ for (int i = 0; i < infos.length; i++) {
+ list.add(infos[i]);
+ }
+ return list;
+ }
}
diff --git a/tests/unit/src/com/android/settings/vpn2/PreferenceListTest.java b/tests/unit/src/com/android/settings/vpn2/PreferenceListTest.java
index 40958ba..4a62011 100644
--- a/tests/unit/src/com/android/settings/vpn2/PreferenceListTest.java
+++ b/tests/unit/src/com/android/settings/vpn2/PreferenceListTest.java
@@ -37,9 +37,9 @@
import java.util.Map;
import org.mockito.ArgumentCaptor;
-import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.mockito.compat.ArgumentMatcher;
public class PreferenceListTest extends AndroidTestCase {
private static final String TAG = "PreferenceListTest";
@@ -138,7 +138,7 @@
final ArgumentMatcher<VpnProfile> equalsFake = new ArgumentMatcher<VpnProfile>() {
@Override
- public boolean matches(final Object arg) {
+ public boolean matchesObject(final Object arg) {
if (arg == vpnProfile) return true;
if (arg == null) return false;
return TextUtils.equals(((VpnProfile) arg).key, vpnProfile.key);