Merge "Change automatic brightness summary to absolute brightness."
diff --git a/Android.mk b/Android.mk
index b9121ec..df85bbc 100644
--- a/Android.mk
+++ b/Android.mk
@@ -37,8 +37,8 @@
ims-common
LOCAL_STATIC_JAVA_LIBRARIES := \
- apptoolkit-arch-core-runtime \
- apptoolkit-lifecycle-extensions \
+ android-arch-lifecycle-runtime \
+ android-arch-lifecycle-extensions \
jsr305 \
settings-logtags \
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 2e51108..f9e123a 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -146,7 +146,7 @@
android:parentActivityName="Settings">
</activity>
- <activity android:name="CreateShortcut"
+ <activity android:name=".shortcut.CreateShortcut"
android:label="@string/settings_shortcut">
<intent-filter>
<action android:name="android.intent.action.CREATE_SHORTCUT"/>
@@ -1279,7 +1279,7 @@
android:value="true" />
</activity>
- <activity android:name="Settings$SecuritySettingsActivity"
+ <activity android:name=".Settings$SecurityDashboardActivity"
android:label="@string/security_settings_title"
android:icon="@drawable/ic_homepage_security"
android:configChanges="orientation|keyboardHidden|screenSize"
@@ -1306,28 +1306,6 @@
android:value="true" />
</activity>
- <!-- TODO(32953042) Merge with Settings$SecuritySettingsActivity -->
- <activity android:name="Settings$SecuritySettingsActivityV2"
- android:label="@string/security_settings_title"
- android:icon="@drawable/ic_homepage_security"
- android:enabled="false"
- android:configChanges="orientation|keyboardHidden|screenSize"
- android:taskAffinity=""
- android:parentActivityName="Settings">
- <intent-filter android:priority="-1">
- <action android:name="android.settings.SECURITY_SETTINGS" />
- <action android:name="android.credentials.UNLOCK" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- <intent-filter android:priority="4">
- <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.homepage" />
- <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
- android:value="com.android.settings.security.SecuritySettingsV2" />
- </activity>
-
<activity android:name="MonitoringCertInfoActivity"
android:label=""
android:theme="@style/Transparent"
@@ -1358,16 +1336,6 @@
android:value="true" />
</activity>
- <!-- Keep compatibility with old shortcuts. -->
- <activity-alias android:name="SecuritySettings"
- android:label="@string/security_settings_title"
- android:configChanges="orientation|keyboardHidden|screenSize"
- android:exported="true"
- android:targetActivity="Settings$SecuritySettingsActivity">
- <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
- android:value="com.android.settings.security.SecuritySettings" />
- </activity-alias>
-
<activity android:name="Settings$PrivacySettingsActivity"
android:label="@string/privacy_settings_title"
android:icon="@drawable/ic_settings_backup"
@@ -1405,7 +1373,7 @@
<activity android:name="Settings$DeviceAdminSettingsActivity"
android:label="@string/device_admin_settings_title"
android:taskAffinity="com.android.settings"
- android:parentActivityName="Settings$SecuritySettingsActivity">
+ android:parentActivityName=".Settings$SecurityDashboardActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
@@ -1436,7 +1404,7 @@
<activity android:name="Settings$UsageAccessSettingsActivity"
android:label="@string/usage_access_title"
android:taskAffinity="com.android.settings"
- android:parentActivityName="Settings$SecuritySettingsActivity">
+ android:parentActivityName=".Settings$SecurityDashboardActivity">
<intent-filter android:priority="1">
<action android:name="android.settings.USAGE_ACCESS_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
@@ -1574,7 +1542,7 @@
<activity android:name="Settings$EnterprisePrivacySettingsActivity"
android:label="@string/enterprise_privacy_settings"
android:taskAffinity="com.android.settings"
- android:parentActivityName="Settings$SecuritySettingsActivity">
+ android:parentActivityName=".Settings$SecurityDashboardActivity">
<intent-filter>
<action android:name="android.settings.ENTERPRISE_PRIVACY_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
diff --git a/res/layout/suggestion_container.xml b/res/layout/suggestion_container.xml
index 9110c58..640a91f 100644
--- a/res/layout/suggestion_container.xml
+++ b/res/layout/suggestion_container.xml
@@ -55,7 +55,7 @@
android:id="@+id/suggestion_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingTop="18dp"
+ android:paddingTop="14dp"
android:paddingBottom="16dp"
android:scrollbars="none"/>
diff --git a/res/layout/suggestion_tile_v2.xml b/res/layout/suggestion_tile_v2.xml
index e04febb..a7717b7 100644
--- a/res/layout/suggestion_tile_v2.xml
+++ b/res/layout/suggestion_tile_v2.xml
@@ -18,7 +18,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/suggestion_card"
- android:layout_width="328dp"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardPreventCornerOverlap="false"
app:cardUseCompatPadding="true"
@@ -65,7 +65,7 @@
android:layout_marginEnd="12dp"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.SuggestionTitleV2"
- android:ellipsize="marquee"
+ android:ellipsize="end"
android:fadingEdge="horizontal" />
<TextView
diff --git a/res/layout/suggestion_tile_with_button_v2.xml b/res/layout/suggestion_tile_with_button_v2.xml
index 5f4ed18..bedc6da 100644
--- a/res/layout/suggestion_tile_with_button_v2.xml
+++ b/res/layout/suggestion_tile_with_button_v2.xml
@@ -18,8 +18,9 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/suggestion_card"
- android:layout_width="328dp"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ app:cardPreventCornerOverlap="false"
app:cardUseCompatPadding="true"
app:cardElevation="2dp"
app:cardCornerRadius="@dimen/suggestion_card_corner_radius">
@@ -37,16 +38,17 @@
<ImageView
android:id="@android:id/icon"
- android:layout_width="@dimen/dashboard_tile_image_size"
- android:layout_height="@dimen/dashboard_tile_image_size"
+ android:layout_width="@dimen/suggestion_card_icon_size"
+ android:layout_height="@dimen/suggestion_card_icon_size"
style="@style/SuggestionCardIcon"
android:layout_marginTop="16dp"
android:layout_marginBottom="8dp" />
<ImageView
android:id="@+id/close_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="18dp"
+ android:layout_height="18dp"
+ android:alpha="0.54"
android:layout_alignParentEnd="true"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
@@ -62,8 +64,8 @@
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:singleLine="true"
- android:textAppearance="@style/TextAppearance.TileTitle"
- android:ellipsize="marquee"
+ android:textAppearance="@style/TextAppearance.SuggestionTitleV2"
+ android:ellipsize="end"
android:fadingEdge="horizontal" />
<TextView
diff --git a/res/values-sw400dp/dimens.xml b/res/values-sw400dp/dimens.xml
index 4f13e09..8d45dd4 100755
--- a/res/values-sw400dp/dimens.xml
+++ b/res/values-sw400dp/dimens.xml
@@ -23,9 +23,9 @@
<dimen name="support_escalation_card_padding_end">56dp</dimen>
<!-- Suggestion cards-->
- <dimen name="suggestion_card_width_one_card">380dp</dimen>
- <dimen name="suggestion_card_width_two_cards">184dp</dimen>
- <dimen name="suggestion_card_width_multiple_cards">176dp</dimen>
+ <dimen name="suggestion_card_width_one_card">384dp</dimen>
+ <dimen name="suggestion_card_width_two_cards">188dp</dimen>
+ <dimen name="suggestion_card_width_multiple_cards">180dp</dimen>
<dimen name="suggestion_card_padding_bottom_one_card">22dp</dimen>
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 332deea..f9ab821 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -304,9 +304,9 @@
<!-- Suggestion cards size and padding -->
<dimen name="suggestion_card_icon_size">24dp</dimen>
- <dimen name="suggestion_card_width_one_card">328dp</dimen>
- <dimen name="suggestion_card_width_two_cards">158dp</dimen>
- <dimen name="suggestion_card_width_multiple_cards">152dp</dimen>
+ <dimen name="suggestion_card_width_one_card">332dp</dimen>
+ <dimen name="suggestion_card_width_two_cards">162dp</dimen>
+ <dimen name="suggestion_card_width_multiple_cards">156dp</dimen>
<dimen name="suggestion_card_outer_margin">16dp</dimen>
<dimen name="suggestion_card_inner_margin">12dp</dimen>
<dimen name="suggestion_card_padding_bottom_one_card">16dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index c1f40af..fe32e9d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1133,8 +1133,12 @@
<!-- Title for suggested actions for settings up a fingerprint lock [CHAR LIMIT=34] -->
<string name="suggested_fingerprint_lock_settings_title">Unlock with fingerprint</string>
- <!-- Summary for suggested actions for settings up a fingerprint lock -->
- <string name="suggested_fingerprint_lock_settings_summary">Unlock with your fingerprint</string>
+ <!-- Summary for suggested actions for settings up a fingerprint lock (tablet) -->
+ <string name="suggested_fingerprint_lock_settings_summary" product="tablet">Unlock with your fingerprint</string>
+ <!-- Summary for suggested actions for settings up a fingerprint lock (device) -->
+ <string name="suggested_fingerprint_lock_settings_summary" product="device">Unlock with your fingerprint</string>
+ <!-- Summary for suggested actions for settings up a fingerprint lock (phone) -->
+ <string name="suggested_fingerprint_lock_settings_summary" product="default">Unlock with your fingerprint</string>
<!-- Title for security picker to choose the unlock method: None/Pattern/PIN/Password [CHAR LIMIT=22] -->
<string name="lock_settings_picker_title">Choose screen lock</string>
@@ -2579,6 +2583,7 @@
<!-- [CHAR LIMIT=30] Title of the preference that opens the Ambient display settings screen. -->
<string name="ambient_display_screen_title">Ambient display</string>
+
<!-- [CHAR LIMIT=50] Summary of the preference that opens the Ambient display settings screen, when Ambient display is set to be always on -->
<string name="ambient_display_screen_summary_always_on">Always on / Increased battery usage</string>
<!-- [CHAR LIMIT=30] Summary of the preference that opens the Ambient display settings screen, when Ambient display is set to show when new notifications come in. -->
@@ -6714,6 +6719,8 @@
<string name="keywords_sim_status">network, mobile network state, service state, signal strength, mobile network type, roaming, iccid</string>
<string name="keywords_model_and_hardware">serial number, hardware version</string>
<string name="keywords_android_version">android security patch level, baseband version, kernel version</string>
+ <!-- Search keyword for Ambient display settings screen. -->
+ <string name="keywords_ambient_display_screen">Ambient display, Lock screen display</string>
<!-- NFC Wi-Fi pairing/setup strings-->
@@ -8777,6 +8784,9 @@
<!-- [CHAR LIMIT=25] Title of developer tile to toggle layer trace -->
<string name="layer_trace_quick_settings_title">Surface Trace</string>
+ <!-- Template for formatting country and language. eg Canada - French [CHAR LIMIT=NONE]-->
+ <string name="support_country_format"><xliff:g id="country" example="Canada">%1$s</xliff:g> - <xliff:g id="language" example="French">%2$s</xliff:g></string>
+
<!-- [CHAR LIMIT=60] Title of work profile setting page -->
<string name="managed_profile_settings_title">Work profile settings</string>
<!-- [CHAR LIMIT=60] The preference title for enabling cross-profile remote contact search -->
diff --git a/res/xml/ambient_display_settings.xml b/res/xml/ambient_display_settings.xml
index a8ded0d..8bd9bd6 100644
--- a/res/xml/ambient_display_settings.xml
+++ b/res/xml/ambient_display_settings.xml
@@ -17,7 +17,9 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="ambient_display_preference_screen"
+ settings:keywords="@string/keywords_ambient_display_screen"
android:title="@string/ambient_display_screen_title">
<PreferenceCategory
diff --git a/res/xml/app_data_usage.xml b/res/xml/app_data_usage.xml
index 3e94135..a4b2159 100644
--- a/res/xml/app_data_usage.xml
+++ b/res/xml/app_data_usage.xml
@@ -16,6 +16,8 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:key="app_data_usage_screen"
android:title="@string/data_usage_app_summary_title">
<com.android.settings.datausage.SpinnerPreference
@@ -50,15 +52,19 @@
android:key="app_settings"
android:title="@string/data_usage_app_settings" />
- <SwitchPreference
+ <com.android.settingslib.RestrictedSwitchPreference
android:key="restrict_background"
android:title="@string/data_usage_app_restrict_background"
- android:summary="@string/data_usage_app_restrict_background_summary" />
+ android:summary="@string/data_usage_app_restrict_background_summary"
+ settings:useAdditionalSummary="true"
+ settings:restrictedSwitchSummary="@string/disabled_by_admin" />
- <SwitchPreference
+ <com.android.settingslib.RestrictedSwitchPreference
android:key="unrestricted_data_saver"
android:title="@string/unrestricted_app_title"
- android:summary="@string/unrestricted_app_summary" />
+ android:summary="@string/unrestricted_app_summary"
+ settings:useAdditionalSummary="true"
+ settings:restrictedSwitchSummary="@string/disabled_by_admin" />
</PreferenceCategory>
diff --git a/res/xml/security_settings_v2.xml b/res/xml/security_dashboard_settings.xml
similarity index 100%
rename from res/xml/security_settings_v2.xml
rename to res/xml/security_dashboard_settings.xml
diff --git a/res/xml/security_settings.xml b/res/xml/security_settings.xml
deleted file mode 100644
index 31f2334..0000000
--- a/res/xml/security_settings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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-auto"
- android:key="security_dashboard_page"
- android:title="@string/security_settings_title"
- settings:initialExpandedChildrenCount="9">
-
-</PreferenceScreen>
diff --git a/res/xml/security_settings_chooser.xml b/res/xml/security_settings_chooser.xml
deleted file mode 100644
index 360e620..0000000
--- a/res/xml/security_settings_chooser.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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-auto"
- android:key="security_settings_chooser_screen"
- android:title="@string/security_settings_title">
-
- <PreferenceCategory
- android:key="security_category"
- android:title="@string/lock_settings_title">
-
- <com.android.settings.widget.GearPreference
- android:key="unlock_set_or_change"
- android:title="@string/unlock_set_unlock_launch_picker_title"
- android:summary="@string/unlock_set_unlock_mode_none"
- settings:keywords="@string/keywords_lockscreen"
- android:persistent="false"/>
-
- <Preference android:key="lockscreen_preferences"
- android:title="@string/lockscreen_settings_title"
- android:fragment="com.android.settings.security.LockscreenDashboardFragment"/>
-
- </PreferenceCategory>
-
-</PreferenceScreen>
diff --git a/res/xml/security_settings_lockscreen.xml b/res/xml/security_settings_lockscreen.xml
deleted file mode 100644
index 56410fb..0000000
--- a/res/xml/security_settings_lockscreen.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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-auto"
- android:key="security_settings_lockscreen_screen"
- android:title="@string/security_settings_title">
-
- <PreferenceCategory
- android:key="security_category"
- android:title="@string/lock_settings_title">
-
- <com.android.settingslib.RestrictedPreference
- android:key="unlock_set_or_change"
- android:title="@string/unlock_set_unlock_launch_picker_title"
- android:summary="@string/unlock_set_unlock_mode_off"
- settings:keywords="@string/keywords_lockscreen"
- android:persistent="false"/>
-
- </PreferenceCategory>
-
-</PreferenceScreen>
diff --git a/res/xml/security_settings_lockscreen_profile.xml b/res/xml/security_settings_lockscreen_profile.xml
deleted file mode 100644
index a0c3f02..0000000
--- a/res/xml/security_settings_lockscreen_profile.xml
+++ /dev/null
@@ -1,29 +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-auto"
- android:key="security_settings_lockscreen_profile_screen"
- android:title="@string/security_settings_title">
-
- <com.android.settingslib.RestrictedPreference
- android:key="unlock_set_or_change_profile"
- android:title="@string/unlock_set_unlock_launch_picker_title_profile"
- android:summary="@string/unlock_set_unlock_mode_off"
- settings:keywords="@string/keywords_lockscreen"
- android:persistent="false"/>
-
-</PreferenceScreen>
diff --git a/res/xml/security_settings_misc.xml b/res/xml/security_settings_misc.xml
deleted file mode 100644
index 730686c..0000000
--- a/res/xml/security_settings_misc.xml
+++ /dev/null
@@ -1,88 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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"
- android:key="security_settings_misc_screen"
- android:title="@string/security_settings_title">
-
- <PreferenceCategory
- android:key="security_settings_misc_category"
- android:title="@string/security_passwords_title">
-
- <Preference
- android:key="location"
- android:title="@string/location_settings_title"
- android:fragment="com.android.settings.location.LocationSettings">
- </Preference>
-
- <SwitchPreference
- android:key="show_password"
- android:title="@string/show_password"
- android:summary="@string/show_password_summary"/>
-
- </PreferenceCategory>
-
- <PreferenceCategory
- android:key="security_settings_device_admin_category">
-
- <Preference android:key="manage_device_admin"
- android:title="@string/manage_device_admin"
- android:persistent="false"
- android:fragment="com.android.settings.DeviceAdminSettings"/>
-
- <Preference android:key="enterprise_privacy"
- android:title="@string/enterprise_privacy_settings"
- android:persistent="false"
- android:fragment="com.android.settings.enterprise.EnterprisePrivacySettings"/>
-
- </PreferenceCategory>
-
- <Preference android:key="sim_lock_settings"
- android:title="@string/sim_lock_settings_category"
- android:persistent="false">
-
- <intent android:action="android.intent.action.MAIN"
- android:targetPackage="com.android.settings"
- android:targetClass="com.android.settings.Settings$IccLockSettingsActivity"/>
-
- </Preference>
-
- <Preference
- android:key="encryption_and_credential"
- android:title="@string/encryption_and_credential_settings_title"
- android:summary="@string/encryption_and_credential_settings_summary"
- android:fragment="com.android.settings.security.EncryptionAndCredential"/>
-
- <Preference android:key="manage_trust_agents"
- android:title="@string/manage_trust_agents"
- android:persistent="false"
- android:fragment="com.android.settings.security.trustagent.TrustAgentSettings"/>
-
- <Preference
- android:key="screen_pinning_settings"
- android:title="@string/screen_pinning_title"
- android:summary="@string/switch_off_text"
- android:fragment="com.android.settings.security.ScreenPinningSettings"/>
-
- <Preference android:key="security_misc_usage_access"
- android:title="@string/usage_access_title"
- android:fragment="com.android.settings.applications.manageapplications.ManageApplications">
- <extra
- android:name="classname"
- android:value="com.android.settings.Settings$UsageAccessSettingsActivity" />
- </Preference>
-
-</PreferenceScreen>
diff --git a/res/xml/security_settings_password.xml b/res/xml/security_settings_password.xml
deleted file mode 100644
index 26077c7..0000000
--- a/res/xml/security_settings_password.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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-auto"
- android:key="security_settings_password_screen"
- android:title="@string/lock_settings_picker_title">
-
- <PreferenceCategory
- android:key="security_category"
- android:title="@string/lock_settings_title">
-
- <com.android.settings.widget.GearPreference
- android:key="unlock_set_or_change"
- android:title="@string/unlock_set_unlock_launch_picker_title"
- android:summary="@string/unlock_set_unlock_mode_password"
- settings:keywords="@string/keywords_lockscreen" />
-
- <Preference android:key="lockscreen_preferences"
- android:title="@string/lockscreen_settings_title"
- android:fragment="com.android.settings.security.LockscreenDashboardFragment"/>
-
- </PreferenceCategory>
-
-</PreferenceScreen>
diff --git a/res/xml/security_settings_password_profile.xml b/res/xml/security_settings_password_profile.xml
deleted file mode 100644
index 257b234..0000000
--- a/res/xml/security_settings_password_profile.xml
+++ /dev/null
@@ -1,29 +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-auto"
- android:key="security_settings_password_profile_screen"
- android:title="@string/security_settings_title">
-
- <com.android.settingslib.RestrictedPreference
- android:key="unlock_set_or_change_profile"
- android:title="@string/unlock_set_unlock_launch_picker_title_profile"
- android:summary="@string/unlock_set_unlock_mode_password"
- settings:keywords="@string/keywords_lockscreen"
- android:persistent="false"/>
-
-</PreferenceScreen>
diff --git a/res/xml/security_settings_pattern.xml b/res/xml/security_settings_pattern.xml
deleted file mode 100644
index 9b7482f..0000000
--- a/res/xml/security_settings_pattern.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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-auto"
- android:key="security_settings_pattern_screen"
- android:title="@string/lock_settings_picker_title">
-
- <PreferenceCategory
- android:key="security_category"
- android:title="@string/lock_settings_title">
-
- <com.android.settings.widget.GearPreference
- android:key="unlock_set_or_change"
- android:title="@string/unlock_set_unlock_launch_picker_title"
- android:summary="@string/unlock_set_unlock_mode_pattern"
- settings:keywords="@string/keywords_lockscreen" />
-
- <Preference android:key="lockscreen_preferences"
- android:title="@string/lockscreen_settings_title"
- android:fragment="com.android.settings.security.LockscreenDashboardFragment"/>
-
- </PreferenceCategory>
-
-</PreferenceScreen>
diff --git a/res/xml/security_settings_pattern_profile.xml b/res/xml/security_settings_pattern_profile.xml
deleted file mode 100644
index e095486..0000000
--- a/res/xml/security_settings_pattern_profile.xml
+++ /dev/null
@@ -1,33 +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-auto"
- android:key="security_settings_pattern_profile_screen"
- android:title="@string/security_settings_title">
-
- <com.android.settingslib.RestrictedPreference
- android:key="unlock_set_or_change_profile"
- android:title="@string/unlock_set_unlock_launch_picker_title_profile"
- android:summary="@string/unlock_set_unlock_mode_pattern"
- settings:keywords="@string/keywords_lockscreen"
- android:persistent="false"/>
-
- <SwitchPreference
- android:key="visiblepattern_profile"
- android:title="@string/lockpattern_settings_enable_visible_pattern_title_profile"/>
-
-</PreferenceScreen>
diff --git a/res/xml/security_settings_pin.xml b/res/xml/security_settings_pin.xml
deleted file mode 100644
index 780ca19..0000000
--- a/res/xml/security_settings_pin.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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-auto"
- android:title="@string/lock_settings_picker_title">
-
- <PreferenceCategory
- android:key="security_category"
- android:title="@string/lock_settings_title">
-
- <com.android.settings.widget.GearPreference
- android:key="unlock_set_or_change"
- android:title="@string/unlock_set_unlock_launch_picker_title"
- android:summary="@string/unlock_set_unlock_mode_pin"
- settings:keywords="@string/keywords_lockscreen" />
-
- <Preference android:key="lockscreen_preferences"
- android:title="@string/lockscreen_settings_title"
- android:fragment="com.android.settings.security.LockscreenDashboardFragment"/>
-
- </PreferenceCategory>
-
-</PreferenceScreen>
diff --git a/res/xml/security_settings_pin_profile.xml b/res/xml/security_settings_pin_profile.xml
deleted file mode 100644
index 071b2f5..0000000
--- a/res/xml/security_settings_pin_profile.xml
+++ /dev/null
@@ -1,29 +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-auto"
- android:key="security_settings_pin_profile_screen"
- android:title="@string/security_settings_title">
-
- <com.android.settingslib.RestrictedPreference
- android:key="unlock_set_or_change_profile"
- android:title="@string/unlock_set_unlock_launch_picker_title_profile"
- android:summary="@string/unlock_set_unlock_mode_pin"
- settings:keywords="@string/keywords_lockscreen"
- android:persistent="false"/>
-
-</PreferenceScreen>
diff --git a/res/xml/security_settings_profile.xml b/res/xml/security_settings_profile.xml
deleted file mode 100644
index 9870e30..0000000
--- a/res/xml/security_settings_profile.xml
+++ /dev/null
@@ -1,27 +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-auto"
- android:title="@string/lock_settings_picker_title">
-
- <PreferenceCategory
- android:key="security_category_profile"
- android:title="@string/lock_settings_profile_title">
-
- </PreferenceCategory>
-
-</PreferenceScreen>
diff --git a/res/xml/security_settings_status.xml b/res/xml/security_settings_status.xml
deleted file mode 100644
index 06930f9..0000000
--- a/res/xml/security_settings_status.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
- android:title="@string/security_settings_title">
-
- <PreferenceCategory
- android:key="security_status"
- android:title="@string/security_status_title"/>
-
-</PreferenceScreen>
diff --git a/res/xml/security_settings_unification.xml b/res/xml/security_settings_unification.xml
deleted file mode 100644
index b9c59e5..0000000
--- a/res/xml/security_settings_unification.xml
+++ /dev/null
@@ -1,27 +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-auto"
- android:title="@string/security_settings_title">
-
- <com.android.settingslib.RestrictedSwitchPreference
- android:key="unification"
- android:title="@string/lock_settings_profile_unification_title"
- android:summary="@string/lock_settings_profile_unification_summary"
- settings:keywords="@string/keywords_unification"/>
-
-</PreferenceScreen>
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 0b6fe89..b4908dd 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -67,8 +67,7 @@
public static class AccessibilityInversionSettingsActivity extends SettingsActivity { /* empty */ }
public static class AccessibilityContrastSettingsActivity extends SettingsActivity { /* empty */ }
public static class AccessibilityDaltonizerSettingsActivity extends SettingsActivity { /* empty */ }
- public static class SecuritySettingsActivity extends SettingsActivity { /* empty */ }
- public static class SecuritySettingsActivityV2 extends SettingsActivity { /* empty */ }
+ public static class SecurityDashboardActivity extends SettingsActivity { /* empty */ }
public static class UsageAccessSettingsActivity extends SettingsActivity { /* empty */ }
public static class LocationSettingsActivity extends SettingsActivity { /* empty */ }
public static class PrivacySettingsActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index d4584b7..3c18efb 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -802,20 +802,6 @@
!isConnectedDeviceV2Enabled && !UserManager.isDeviceInDemoMode(this) /* enabled */,
isAdmin) || somethingChanged;
- final boolean isSecurityV2Enabled = featureFactory.getSecurityFeatureProvider()
- .isSecuritySettingsV2Enabled(this);
-
- // Enable new security page if v2 enabled
- somethingChanged = setTileEnabled(
- new ComponentName(packageName,Settings.SecuritySettingsActivityV2.class.getName()),
- isSecurityV2Enabled,
- isAdmin) || somethingChanged;
- // Enable old security page if v2 disabled
- somethingChanged = setTileEnabled(
- new ComponentName(packageName,Settings.SecuritySettingsActivity.class.getName()),
- !isSecurityV2Enabled,
- isAdmin) || somethingChanged;
-
somethingChanged = setTileEnabled(new ComponentName(packageName,
Settings.SimSettingsActivity.class.getName()),
Utils.showSimCardTile(this), isAdmin)
diff --git a/src/com/android/settings/SettingsInitialize.java b/src/com/android/settings/SettingsInitialize.java
index 6b15770..9f2bdcc 100644
--- a/src/com/android/settings/SettingsInitialize.java
+++ b/src/com/android/settings/SettingsInitialize.java
@@ -34,6 +34,8 @@
import static android.content.pm.PackageManager.GET_RESOLVED_FILTER;
import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
+import com.android.settings.shortcut.CreateShortcut;
+
/**
* Listens to {@link Intent.ACTION_PRE_BOOT_COMPLETED} and {@link Intent.ACTION_USER_INITIALIZED}
* performs setup steps for a managed profile (disables the launcher icon of the Settings app,
diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java
deleted file mode 100755
index f78459f..0000000
--- a/src/com/android/settings/applications/InstalledAppDetails.java
+++ /dev/null
@@ -1,1478 +0,0 @@
-/*
- * Copyright (C) 2007 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 com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
-
-import android.Manifest.permission;
-import android.app.Activity;
-import android.app.ActivityManager;
-import android.app.AlertDialog;
-import android.app.LoaderManager;
-import android.app.LoaderManager.LoaderCallbacks;
-import android.content.ActivityNotFoundException;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.Loader;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ResolveInfo;
-import android.content.pm.UserInfo;
-import android.content.res.Resources;
-import android.icu.text.ListFormatter;
-import android.net.INetworkStatsService;
-import android.net.INetworkStatsSession;
-import android.net.NetworkTemplate;
-import android.net.TrafficStats;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.BatteryStats;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.support.annotation.VisibleForTesting;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.Preference.OnPreferenceClickListener;
-import android.support.v7.preference.PreferenceCategory;
-import android.support.v7.preference.PreferenceScreen;
-import android.text.BidiFormatter;
-import android.text.TextUtils;
-import android.text.format.DateUtils;
-import android.text.format.Formatter;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.webkit.IWebViewUpdateService;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.os.BatterySipper;
-import com.android.internal.os.BatteryStatsHelper;
-import com.android.settings.DeviceAdminAdd;
-import com.android.settings.R;
-import com.android.settings.SettingsActivity;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.Utils;
-import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
-import com.android.settings.applications.appinfo.DrawOverlayDetails;
-import com.android.settings.applications.appinfo.ExternalSourcesDetails;
-import com.android.settings.applications.appinfo.PictureInPictureDetails;
-import com.android.settings.applications.appinfo.PictureInPictureSettings;
-import com.android.settings.applications.appinfo.WriteSettingsDetails;
-import com.android.settings.applications.defaultapps.DefaultBrowserPreferenceController;
-import com.android.settings.applications.defaultapps.DefaultEmergencyPreferenceController;
-import com.android.settings.applications.defaultapps.DefaultHomePreferenceController;
-import com.android.settings.applications.defaultapps.DefaultPhonePreferenceController;
-import com.android.settings.applications.defaultapps.DefaultSmsPreferenceController;
-import com.android.settings.applications.instantapps.InstantAppButtonsController;
-import com.android.settings.datausage.AppDataUsage;
-import com.android.settings.datausage.DataUsageList;
-import com.android.settings.datausage.DataUsageUtils;
-import com.android.settings.fuelgauge.AdvancedPowerUsageDetail;
-import com.android.settings.fuelgauge.BatteryEntry;
-import com.android.settings.fuelgauge.BatteryStatsHelperLoader;
-import com.android.settings.fuelgauge.BatteryUtils;
-import com.android.settings.notification.AppNotificationSettings;
-import com.android.settings.notification.NotificationBackend;
-import com.android.settings.notification.NotificationBackend.AppRow;
-import com.android.settings.widget.ActionButtonPreference;
-import com.android.settings.widget.EntityHeaderController;
-import com.android.settingslib.AppItem;
-import com.android.settingslib.RestrictedLockUtils;
-import com.android.settingslib.applications.AppUtils;
-import com.android.settingslib.applications.ApplicationsState;
-import com.android.settingslib.applications.ApplicationsState.AppEntry;
-import com.android.settingslib.applications.PermissionsSummaryHelper;
-import com.android.settingslib.applications.PermissionsSummaryHelper.PermissionsResultCallback;
-import com.android.settingslib.applications.StorageStatsSource;
-import com.android.settingslib.applications.StorageStatsSource.AppStorageStats;
-import com.android.settingslib.development.DevelopmentSettingsEnabler;
-import com.android.settingslib.net.ChartData;
-import com.android.settingslib.net.ChartDataLoader;
-import com.android.settingslib.wrapper.PackageManagerWrapper;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Activity to display application information from Settings. This activity presents
- * extended information associated with a package like code, data, total size, permissions
- * used by the application and also the set of default launchable activities.
- * For system applications, an option to clear user data is displayed only if data size is > 0.
- * System applications that do not want clear user data do not have this option.
- * For non-system applications, there is no option to clear data. Instead there is an option to
- * uninstall the application.
- *
- * deprecated in favor of {@link AppInfoDashboardFragment}
- */
-@Deprecated
-public class InstalledAppDetails extends AppInfoBase
- implements OnPreferenceClickListener, LoaderManager.LoaderCallbacks<AppStorageStats> {
-
- private static final String LOG_TAG = "InstalledAppDetails";
-
- // Menu identifiers
- public static final int UNINSTALL_ALL_USERS_MENU = 1;
- public static final int UNINSTALL_UPDATES = 2;
-
- // Result code identifiers
- public static final int REQUEST_UNINSTALL = 0;
- private static final int REQUEST_REMOVE_DEVICE_ADMIN = 1;
-
- private static final int SUB_INFO_FRAGMENT = 1;
-
- private static final int LOADER_CHART_DATA = 2;
- private static final int LOADER_STORAGE = 3;
- @VisibleForTesting
- static final int LOADER_BATTERY = 4;
-
- private static final int DLG_FORCE_STOP = DLG_BASE + 1;
- private static final int DLG_DISABLE = DLG_BASE + 2;
- private static final int DLG_SPECIAL_DISABLE = DLG_BASE + 3;
- private static final String EXTRA_HIDE_INFO_BUTTON = "hideInfoButton";
- private static final String KEY_HEADER = "header_view";
- private static final String KEY_INSTANT_APP_BUTTONS = "instant_app_buttons";
- private static final String KEY_ACTION_BUTTONS = "action_buttons";
- private static final String KEY_NOTIFICATION = "notification_settings";
- private static final String KEY_STORAGE = "storage_settings";
- private static final String KEY_PERMISSION = "permission_settings";
- private static final String KEY_DATA = "data_settings";
- private static final String KEY_LAUNCH = "preferred_settings";
- private static final String KEY_BATTERY = "battery";
- private static final String KEY_MEMORY = "memory";
- private static final String KEY_VERSION = "app_version";
- private static final String KEY_INSTANT_APP_SUPPORTED_LINKS =
- "instant_app_launch_supported_domain_urls";
-
- private final HashSet<String> mHomePackages = new HashSet<>();
-
- private boolean mInitialized;
- private boolean mShowUninstalled;
- private LayoutPreference mHeader;
- private boolean mUpdatedSysApp = false;
- private Preference mNotificationPreference;
- private Preference mStoragePreference;
- private Preference mPermissionsPreference;
- private Preference mLaunchPreference;
- private Preference mDataPreference;
- private Preference mMemoryPreference;
- private Preference mVersionPreference;
- private AppDomainsPreference mInstantAppDomainsPreference;
- private boolean mDisableAfterUninstall;
-
- // Used for updating notification preference.
- private final NotificationBackend mBackend = new NotificationBackend();
-
- private ChartData mChartData;
- private INetworkStatsSession mStatsSession;
-
- @VisibleForTesting
- ActionButtonPreference mActionButtons;
- @VisibleForTesting
- Preference mBatteryPreference;
- @VisibleForTesting
- BatterySipper mSipper;
- @VisibleForTesting
- BatteryStatsHelper mBatteryHelper;
- @VisibleForTesting
- BatteryUtils mBatteryUtils;
-
- protected ProcStatsData mStatsManager;
- protected ProcStatsPackageEntry mStats;
-
- private InstantAppButtonsController mInstantAppButtonsController;
-
- private AppStorageStats mLastResult;
- private String mBatteryPercent;
-
- @VisibleForTesting
- final LoaderCallbacks<BatteryStatsHelper> mBatteryCallbacks =
- new LoaderCallbacks<BatteryStatsHelper>() {
-
- @Override
- public Loader<BatteryStatsHelper> onCreateLoader(int id, Bundle args) {
- return new BatteryStatsHelperLoader(getContext());
- }
-
- @Override
- public void onLoadFinished(Loader<BatteryStatsHelper> loader,
- BatteryStatsHelper batteryHelper) {
- mBatteryHelper = batteryHelper;
- if (mPackageInfo != null) {
- mSipper = findTargetSipper(batteryHelper, mPackageInfo.applicationInfo.uid);
- if (getActivity() != null) {
- updateBattery();
- }
- }
- }
-
- @Override
- public void onLoaderReset(Loader<BatteryStatsHelper> loader) {
- }
- };
-
- @VisibleForTesting
- boolean handleDisableable() {
- boolean disableable = false;
- // Try to prevent the user from bricking their phone
- // by not allowing disabling of apps signed with the
- // system cert and any launcher app in the system.
- if (mHomePackages.contains(mAppEntry.info.packageName)
- || Utils.isSystemPackage(getContext().getResources(), mPm, mPackageInfo)) {
- // Disable button for core system applications.
- mActionButtons
- .setButton1Text(R.string.disable_text)
- .setButton1Positive(false);
- } else if (mAppEntry.info.enabled && !isDisabledUntilUsed()) {
- mActionButtons
- .setButton1Text(R.string.disable_text)
- .setButton1Positive(false);
- disableable = !mApplicationFeatureProvider.getKeepEnabledPackages()
- .contains(mAppEntry.info.packageName);
- } else {
- mActionButtons
- .setButton1Text(R.string.enable_text)
- .setButton1Positive(true);
- disableable = true;
- }
-
- return disableable;
- }
-
- private boolean isDisabledUntilUsed() {
- return mAppEntry.info.enabledSetting
- == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
- }
-
- private void initUninstallButtons() {
- final boolean isBundled = (mAppEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
- boolean enabled;
- if (isBundled) {
- enabled = handleDisableable();
- } else {
- enabled = initUninstallButtonForUserApp();
- }
- // If this is a device admin, it can't be uninstalled or disabled.
- // We do this here so the text of the button is still set correctly.
- if (isBundled && mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) {
- enabled = false;
- }
-
- // We don't allow uninstalling DO/PO on *any* users, because if it's a system app,
- // "uninstall" is actually "downgrade to the system version + disable", and "downgrade"
- // will clear data on all users.
- if (Utils.isProfileOrDeviceOwner(mUserManager, mDpm, mPackageInfo.packageName)) {
- enabled = false;
- }
-
- // Don't allow uninstalling the device provisioning package.
- if (Utils.isDeviceProvisioningPackage(getResources(), mAppEntry.info.packageName)) {
- enabled = false;
- }
-
- // If the uninstall intent is already queued, disable the uninstall button
- if (mDpm.isUninstallInQueue(mPackageName)) {
- enabled = false;
- }
-
- // Home apps need special handling. Bundled ones we don't risk downgrading
- // because that can interfere with home-key resolution. Furthermore, we
- // can't allow uninstallation of the only home app, and we don't want to
- // allow uninstallation of an explicitly preferred one -- the user can go
- // to Home settings and pick a different one, after which we'll permit
- // uninstallation of the now-not-default one.
- if (enabled && mHomePackages.contains(mPackageInfo.packageName)) {
- if (isBundled) {
- enabled = false;
- } else {
- ArrayList<ResolveInfo> homeActivities = new ArrayList<ResolveInfo>();
- ComponentName currentDefaultHome = mPm.getHomeActivities(homeActivities);
- if (currentDefaultHome == null) {
- // No preferred default, so permit uninstall only when
- // there is more than one candidate
- enabled = (mHomePackages.size() > 1);
- } else {
- // There is an explicit default home app -- forbid uninstall of
- // that one, but permit it for installed-but-inactive ones.
- enabled = !mPackageInfo.packageName.equals(currentDefaultHome.getPackageName());
- }
- }
- }
-
- if (mAppsControlDisallowedBySystem) {
- enabled = false;
- }
-
- try {
- IWebViewUpdateService webviewUpdateService =
- IWebViewUpdateService.Stub.asInterface(ServiceManager.getService("webviewupdate"));
- if (webviewUpdateService.isFallbackPackage(mAppEntry.info.packageName)) {
- enabled = false;
- }
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
-
- mActionButtons.setButton1Enabled(enabled);
- if (enabled) {
- // Register listener
- mActionButtons.setButton1OnClickListener(v -> handleUninstallButtonClick());
- }
- }
-
- @VisibleForTesting
- boolean initUninstallButtonForUserApp() {
- boolean enabled = true;
- if ((mPackageInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED) == 0
- && mUserManager.getUsers().size() >= 2) {
- // When we have multiple users, there is a separate menu
- // to uninstall for all users.
- enabled = false;
- } else if (AppUtils.isInstant(mPackageInfo.applicationInfo)) {
- enabled = false;
- mActionButtons.setButton1Visible(false);
- }
- mActionButtons.setButton1Text(R.string.uninstall_text).setButton1Positive(false);
- return enabled;
- }
-
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- final Activity activity = getActivity();
-
- if (!ensurePackageInfoAvailable(activity)) {
- return;
- }
-
- setHasOptionsMenu(true);
- addPreferencesFromResource(R.xml.installed_app_details);
-
- addDynamicPrefs();
- if (Utils.isBandwidthControlEnabled()) {
- INetworkStatsService statsService = INetworkStatsService.Stub.asInterface(
- ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
- try {
- mStatsSession = statsService.openSession();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- } else {
- removePreference(KEY_DATA);
- }
- mBatteryUtils = BatteryUtils.getInstance(getContext());
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsEvent.APPLICATIONS_INSTALLED_APP_DETAILS;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- if (mFinishing) {
- return;
- }
- AppItem app = new AppItem(mAppEntry.info.uid);
- app.addUid(mAppEntry.info.uid);
- if (mStatsSession != null) {
- LoaderManager loaderManager = getLoaderManager();
- loaderManager.restartLoader(LOADER_CHART_DATA,
- ChartDataLoader.buildArgs(getTemplate(getContext()), app),
- mDataCallbacks);
- loaderManager.restartLoader(LOADER_STORAGE, Bundle.EMPTY, this);
- }
- restartBatteryStatsLoader();
- if (DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(getContext())) {
- new MemoryUpdater().execute();
- }
- updateDynamicPrefs();
- }
-
- @VisibleForTesting
- public void restartBatteryStatsLoader() {
- getLoaderManager().restartLoader(LOADER_BATTERY, Bundle.EMPTY, mBatteryCallbacks);
- }
-
- @Override
- public void onPause() {
- getLoaderManager().destroyLoader(LOADER_CHART_DATA);
- super.onPause();
- }
-
- @Override
- public void onDestroy() {
- TrafficStats.closeQuietly(mStatsSession);
- super.onDestroy();
- }
-
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- if (mFinishing) {
- return;
- }
- final Activity activity = getActivity();
- mHeader = (LayoutPreference) findPreference(KEY_HEADER);
- mActionButtons = ((ActionButtonPreference) findPreference(KEY_ACTION_BUTTONS))
- .setButton2Text(R.string.force_stop)
- .setButton2Positive(false)
- .setButton2Enabled(false);
- EntityHeaderController.newInstance(activity, this, mHeader.findViewById(R.id.entity_header))
- .setRecyclerView(getListView(), getLifecycle())
- .setPackageName(mPackageName)
- .setHasAppInfoLink(false)
- .setButtonActions(EntityHeaderController.ActionType.ACTION_APP_PREFERENCE,
- EntityHeaderController.ActionType.ACTION_NONE)
- .styleActionBar(activity)
- .bindHeaderButtons();
-
- mNotificationPreference = findPreference(KEY_NOTIFICATION);
- mNotificationPreference.setOnPreferenceClickListener(this);
- mStoragePreference = findPreference(KEY_STORAGE);
- mStoragePreference.setOnPreferenceClickListener(this);
- mPermissionsPreference = findPreference(KEY_PERMISSION);
- mPermissionsPreference.setOnPreferenceClickListener(this);
- mDataPreference = findPreference(KEY_DATA);
- if (mDataPreference != null) {
- mDataPreference.setOnPreferenceClickListener(this);
- }
- mBatteryPreference = findPreference(KEY_BATTERY);
- mBatteryPreference.setEnabled(false);
- mBatteryPreference.setOnPreferenceClickListener(this);
- mMemoryPreference = findPreference(KEY_MEMORY);
- mMemoryPreference.setOnPreferenceClickListener(this);
- mMemoryPreference.setVisible(
- DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(getContext()));
- mVersionPreference = findPreference(KEY_VERSION);
- mInstantAppDomainsPreference =
- (AppDomainsPreference) findPreference(KEY_INSTANT_APP_SUPPORTED_LINKS);
- mLaunchPreference = findPreference(KEY_LAUNCH);
- if (mAppEntry != null && mAppEntry.info != null) {
- if ((mAppEntry.info.flags&ApplicationInfo.FLAG_INSTALLED) == 0 ||
- !mAppEntry.info.enabled) {
- mLaunchPreference.setEnabled(false);
- } else {
- mLaunchPreference.setOnPreferenceClickListener(this);
- }
- } else {
- mLaunchPreference.setEnabled(false);
- }
- }
-
- @Override
- public void onPackageSizeChanged(String packageName) {
- if (!TextUtils.equals(packageName, mPackageName)) {
- Log.d(LOG_TAG, "Package change irrelevant, skipping");
- return;
- }
- refreshUi();
- }
-
- /**
- * Ensures the {@link PackageInfo} is available to proceed. If it's not available, the fragment
- * will finish.
- *
- * @return true if packageInfo is available.
- */
- @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
- boolean ensurePackageInfoAvailable(Activity activity) {
- if (mPackageInfo == null) {
- mFinishing = true;
- Log.w(LOG_TAG, "Package info not available. Is this package already uninstalled?");
- activity.finishAndRemoveTask();
- return false;
- }
- return true;
- }
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- super.onCreateOptionsMenu(menu, inflater);
- menu.add(0, UNINSTALL_UPDATES, 0, R.string.app_factory_reset)
- .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
- menu.add(0, UNINSTALL_ALL_USERS_MENU, 1, R.string.uninstall_all_users_text)
- .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
- }
-
- @Override
- public void onPrepareOptionsMenu(Menu menu) {
- if (mFinishing) {
- return;
- }
- menu.findItem(UNINSTALL_ALL_USERS_MENU).setVisible(shouldShowUninstallForAll(mAppEntry));
- mUpdatedSysApp = (mAppEntry.info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
- MenuItem uninstallUpdatesItem = menu.findItem(UNINSTALL_UPDATES);
- uninstallUpdatesItem.setVisible(mUpdatedSysApp && !mAppsControlDisallowedBySystem);
- if (uninstallUpdatesItem.isVisible()) {
- RestrictedLockUtils.setMenuItemAsDisabledByAdmin(getActivity(),
- uninstallUpdatesItem, mAppsControlDisallowedAdmin);
- }
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case UNINSTALL_ALL_USERS_MENU:
- uninstallPkg(mAppEntry.info.packageName, true, false);
- return true;
- case UNINSTALL_UPDATES:
- uninstallPkg(mAppEntry.info.packageName, false, false);
- return true;
- }
- return false;
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- switch (requestCode) {
- case REQUEST_UNINSTALL:
- // Refresh option menu
- getActivity().invalidateOptionsMenu();
-
- if (mDisableAfterUninstall) {
- mDisableAfterUninstall = false;
- new DisableChanger(this, mAppEntry.info,
- PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER)
- .execute((Object)null);
- }
- // continue with following operations
- case REQUEST_REMOVE_DEVICE_ADMIN:
- if (!refreshUi()) {
- setIntentAndFinish(true, true);
- } else {
- startListeningToPackageRemove();
- }
- break;
- }
- }
-
- @Override
- public Loader<AppStorageStats> onCreateLoader(int id, Bundle args) {
- Context context = getContext();
- return new FetchPackageStorageAsyncLoader(
- context, new StorageStatsSource(context), mAppEntry.info, UserHandle.of(mUserId));
- }
-
- @Override
- public void onLoadFinished(Loader<AppStorageStats> loader, AppStorageStats result) {
- mLastResult = result;
- refreshUi();
- }
-
- @Override
- public void onLoaderReset(Loader<AppStorageStats> loader) {
- }
-
- /**
- * Utility method to hide and show specific preferences based on whether the app being displayed
- * is an Instant App or an installed app.
- */
- @VisibleForTesting
- void prepareInstantAppPrefs() {
- final boolean isInstant = AppUtils.isInstant(mPackageInfo.applicationInfo);
- if (isInstant) {
- Set<String> handledDomainSet = Utils.getHandledDomains(mPm, mPackageInfo.packageName);
- String[] handledDomains = handledDomainSet.toArray(new String[handledDomainSet.size()]);
- mInstantAppDomainsPreference.setTitles(handledDomains);
- // Dummy values, unused in the implementation
- mInstantAppDomainsPreference.setValues(new int[handledDomains.length]);
- getPreferenceScreen().removePreference(mLaunchPreference);
- } else {
- getPreferenceScreen().removePreference(mInstantAppDomainsPreference);
- }
- }
-
- // Utility method to set application label and icon.
- private void setAppLabelAndIcon(PackageInfo pkgInfo) {
- final View appSnippet = mHeader.findViewById(R.id.entity_header);
- mState.ensureIcon(mAppEntry);
- final Activity activity = getActivity();
- final boolean isInstantApp = AppUtils.isInstant(mPackageInfo.applicationInfo);
- final CharSequence summary =
- isInstantApp ? null : getString(Utils.getInstallationStatus(mAppEntry.info));
- EntityHeaderController.newInstance(activity, this, appSnippet)
- .setLabel(mAppEntry)
- .setIcon(mAppEntry)
- .setSummary(summary)
- .setIsInstantApp(isInstantApp)
- .done(activity, false /* rebindActions */);
- mVersionPreference.setSummary(getString(R.string.version_text,
- BidiFormatter.getInstance().unicodeWrap(pkgInfo.versionName)));
- }
-
- @VisibleForTesting
- boolean shouldShowUninstallForAll(ApplicationsState.AppEntry appEntry) {
- boolean showIt = true;
- if (mUpdatedSysApp) {
- showIt = false;
- } else if (appEntry == null) {
- showIt = false;
- } else if ((appEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
- showIt = false;
- } else if (mPackageInfo == null || mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) {
- showIt = false;
- } else if (UserHandle.myUserId() != 0) {
- showIt = false;
- } else if (mUserManager.getUsers().size() < 2) {
- showIt = false;
- } else if (PackageUtil.countPackageInUsers(mPm, mUserManager, mPackageName) < 2
- && (appEntry.info.flags & ApplicationInfo.FLAG_INSTALLED) != 0) {
- showIt = false;
- } else if (AppUtils.isInstant(appEntry.info)) {
- showIt = false;
- }
- return showIt;
- }
-
- @VisibleForTesting
- BatterySipper findTargetSipper(BatteryStatsHelper batteryHelper, int uid) {
- List<BatterySipper> usageList = batteryHelper.getUsageList();
- for (int i = 0, size = usageList.size(); i < size; i++) {
- BatterySipper sipper = usageList.get(i);
- if (sipper.getUid() == uid) {
- return sipper;
- }
- }
-
- return null;
- }
-
- private boolean signaturesMatch(String pkg1, String pkg2) {
- if (pkg1 != null && pkg2 != null) {
- try {
- final int match = mPm.checkSignatures(pkg1, pkg2);
- if (match >= PackageManager.SIGNATURE_MATCH) {
- return true;
- }
- } catch (Exception e) {
- // e.g. named alternate package not found during lookup;
- // this is an expected case sometimes
- }
- }
- return false;
- }
-
- @Override
- protected boolean refreshUi() {
- retrieveAppEntry();
- if (mAppEntry == null) {
- return false; // onCreate must have failed, make sure to exit
- }
-
- if (mPackageInfo == null) {
- return false; // onCreate must have failed, make sure to exit
- }
-
- // Get list of "home" apps and trace through any meta-data references
- List<ResolveInfo> homeActivities = new ArrayList<ResolveInfo>();
- mPm.getHomeActivities(homeActivities);
- mHomePackages.clear();
- for (int i = 0; i< homeActivities.size(); i++) {
- ResolveInfo ri = homeActivities.get(i);
- final String activityPkg = ri.activityInfo.packageName;
- mHomePackages.add(activityPkg);
-
- // Also make sure to include anything proxying for the home app
- final Bundle metadata = ri.activityInfo.metaData;
- if (metadata != null) {
- final String metaPkg = metadata.getString(ActivityManager.META_HOME_ALTERNATE);
- if (signaturesMatch(metaPkg, activityPkg)) {
- mHomePackages.add(metaPkg);
- }
- }
- }
-
- checkForceStop();
- setAppLabelAndIcon(mPackageInfo);
- initUninstallButtons();
- prepareInstantAppPrefs();
-
- // Update the preference summaries.
- Activity context = getActivity();
- boolean isExternal = ((mAppEntry.info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
- mStoragePreference.setSummary(getStorageSummary(context, mLastResult, isExternal));
-
- PermissionsSummaryHelper.getPermissionSummary(getContext(),
- mPackageName, mPermissionCallback);
- mLaunchPreference.setSummary(AppUtils.getLaunchByDefaultSummary(mAppEntry, mUsbManager,
- mPm, context));
- mNotificationPreference.setSummary(getNotificationSummary(mAppEntry, context,
- mBackend));
- if (mDataPreference != null) {
- mDataPreference.setSummary(getDataSummary());
- }
-
- if (!mInitialized) {
- // First time init: are we displaying an uninstalled app?
- mInitialized = true;
- mShowUninstalled = (mAppEntry.info.flags&ApplicationInfo.FLAG_INSTALLED) == 0;
- } else {
- // All other times: if the app no longer exists then we want
- // to go away.
- try {
- ApplicationInfo ainfo = context.getPackageManager().getApplicationInfo(
- mAppEntry.info.packageName,
- PackageManager.MATCH_DISABLED_COMPONENTS
- | PackageManager.MATCH_ANY_USER);
- if (!mShowUninstalled) {
- // If we did not start out with the app uninstalled, then
- // it transitioning to the uninstalled state for the current
- // user means we should go away as well.
- return (ainfo.flags&ApplicationInfo.FLAG_INSTALLED) != 0;
- }
- } catch (NameNotFoundException e) {
- return false;
- }
- }
-
- return true;
- }
-
- @VisibleForTesting
- void updateBattery() {
- mBatteryPreference.setEnabled(true);
- if (isBatteryStatsAvailable()) {
- final int dischargeAmount = mBatteryHelper.getStats().getDischargeAmount(
- BatteryStats.STATS_SINCE_CHARGED);
-
- final List<BatterySipper> usageList = new ArrayList<>(mBatteryHelper.getUsageList());
- final double hiddenAmount = mBatteryUtils.removeHiddenBatterySippers(usageList);
- final int percentOfMax = (int) mBatteryUtils.calculateBatteryPercent(
- mSipper.totalPowerMah, mBatteryHelper.getTotalPower(), hiddenAmount,
- dischargeAmount);
- mBatteryPercent = Utils.formatPercentage(percentOfMax);
- mBatteryPreference.setSummary(getString(R.string.battery_summary, mBatteryPercent));
- } else {
- mBatteryPreference.setSummary(getString(R.string.no_battery_summary));
- }
- }
-
- private CharSequence getDataSummary() {
- if (mChartData != null) {
- long totalBytes = mChartData.detail.getTotalBytes();
- if (totalBytes == 0) {
- return getString(R.string.no_data_usage);
- }
- Context context = getActivity();
- return getString(R.string.data_summary_format,
- Formatter.formatFileSize(context, totalBytes),
- DateUtils.formatDateTime(context, mChartData.detail.getStart(),
- DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_MONTH));
- }
- return getString(R.string.computing_size);
- }
-
- @VisibleForTesting
- static CharSequence getStorageSummary(
- Context context, AppStorageStats stats, boolean isExternal) {
- if (stats == null) {
- return context.getText(R.string.computing_size);
- } else {
- CharSequence storageType = context.getString(isExternal
- ? R.string.storage_type_external
- : R.string.storage_type_internal);
- return context.getString(R.string.storage_summary_format,
- getSize(context, stats), storageType.toString().toLowerCase());
- }
- }
-
- @VisibleForTesting
- boolean isBatteryStatsAvailable() {
- return mBatteryHelper != null && mSipper != null;
- }
-
- private static CharSequence getSize(Context context, AppStorageStats stats) {
- return Formatter.formatFileSize(context, stats.getTotalBytes());
- }
-
-
- @Override
- protected AlertDialog createDialog(int id, int errorCode) {
- switch (id) {
- case DLG_DISABLE:
- return new AlertDialog.Builder(getActivity())
- .setMessage(getActivity().getText(R.string.app_disable_dlg_text))
- .setPositiveButton(R.string.app_disable_dlg_positive,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- // Disable the app
- mMetricsFeatureProvider.action(getContext(),
- MetricsEvent.ACTION_SETTINGS_DISABLE_APP);
- new DisableChanger(InstalledAppDetails.this, mAppEntry.info,
- PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER)
- .execute((Object)null);
- }
- })
- .setNegativeButton(R.string.dlg_cancel, null)
- .create();
- case DLG_SPECIAL_DISABLE:
- return new AlertDialog.Builder(getActivity())
- .setMessage(getActivity().getText(R.string.app_disable_dlg_text))
- .setPositiveButton(R.string.app_disable_dlg_positive,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- // Disable the app and ask for uninstall
- mMetricsFeatureProvider.action(getContext(),
- MetricsEvent.ACTION_SETTINGS_DISABLE_APP);
- uninstallPkg(mAppEntry.info.packageName,
- false, true);
- }
- })
- .setNegativeButton(R.string.dlg_cancel, null)
- .create();
- case DLG_FORCE_STOP:
- return new AlertDialog.Builder(getActivity())
- .setTitle(getActivity().getText(R.string.force_stop_dlg_title))
- .setMessage(getActivity().getText(R.string.force_stop_dlg_text))
- .setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- // Force stop
- forceStopPackage(mAppEntry.info.packageName);
- }
- })
- .setNegativeButton(R.string.dlg_cancel, null)
- .create();
- }
- if (mInstantAppButtonsController != null) {
- return mInstantAppButtonsController.createDialog(id);
- }
- return null;
- }
-
- private void uninstallPkg(String packageName, boolean allUsers, boolean andDisable) {
- stopListeningToPackageRemove();
- // Create new intent to launch Uninstaller activity
- Uri packageURI = Uri.parse("package:"+packageName);
- Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageURI);
- uninstallIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, allUsers);
- mMetricsFeatureProvider.action(
- getContext(), MetricsEvent.ACTION_SETTINGS_UNINSTALL_APP);
- startActivityForResult(uninstallIntent, REQUEST_UNINSTALL);
- mDisableAfterUninstall = andDisable;
- }
-
- private void forceStopPackage(String pkgName) {
- mMetricsFeatureProvider.action(getContext(), MetricsEvent.ACTION_APP_FORCE_STOP, pkgName);
- ActivityManager am = (ActivityManager) getActivity().getSystemService(
- Context.ACTIVITY_SERVICE);
- Log.d(LOG_TAG, "Stopping package " + pkgName);
- am.forceStopPackage(pkgName);
- int userId = UserHandle.getUserId(mAppEntry.info.uid);
- mState.invalidatePackage(pkgName, userId);
- ApplicationsState.AppEntry newEnt = mState.getEntry(pkgName, userId);
- if (newEnt != null) {
- mAppEntry = newEnt;
- }
- checkForceStop();
- }
-
- private void updateForceStopButton(boolean enabled) {
- mActionButtons
- .setButton2Enabled(mAppsControlDisallowedBySystem ? false : enabled)
- .setButton2OnClickListener(mAppsControlDisallowedBySystem
- ? null : v -> handleForceStopButtonClick());
- }
-
- @VisibleForTesting
- void checkForceStop() {
- if (mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) {
- // User can't force stop device admin.
- Log.w(LOG_TAG, "User can't force stop device admin");
- updateForceStopButton(false);
- } else if (AppUtils.isInstant(mPackageInfo.applicationInfo)) {
- updateForceStopButton(false);
- mActionButtons.setButton2Visible(false);
- } else if ((mAppEntry.info.flags & ApplicationInfo.FLAG_STOPPED) == 0) {
- // If the app isn't explicitly stopped, then always show the
- // force stop button.
- Log.w(LOG_TAG, "App is not explicitly stopped");
- updateForceStopButton(true);
- } else {
- Intent intent = new Intent(Intent.ACTION_QUERY_PACKAGE_RESTART,
- Uri.fromParts("package", mAppEntry.info.packageName, null));
- intent.putExtra(Intent.EXTRA_PACKAGES, new String[] { mAppEntry.info.packageName });
- intent.putExtra(Intent.EXTRA_UID, mAppEntry.info.uid);
- intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(mAppEntry.info.uid));
- Log.d(LOG_TAG, "Sending broadcast to query restart status for "
- + mAppEntry.info.packageName);
- getActivity().sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null,
- mCheckKillProcessesReceiver, null, Activity.RESULT_CANCELED, null, null);
- }
- }
-
- private void startManagePermissionsActivity() {
- // start new activity to manage app permissions
- Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSIONS);
- intent.putExtra(Intent.EXTRA_PACKAGE_NAME, mAppEntry.info.packageName);
- intent.putExtra(EXTRA_HIDE_INFO_BUTTON, true);
- try {
- getActivity().startActivityForResult(intent, SUB_INFO_FRAGMENT);
- } catch (ActivityNotFoundException e) {
- Log.w(LOG_TAG, "No app can handle android.intent.action.MANAGE_APP_PERMISSIONS");
- }
- }
-
- private void startAppInfoFragment(Class<?> fragment, int title) {
- startAppInfoFragment(fragment, title, this, mAppEntry);
- }
-
- public static void startAppInfoFragment(Class<?> fragment, int title,
- SettingsPreferenceFragment caller, AppEntry appEntry) {
- // start new fragment to display extended information
- Bundle args = new Bundle();
- args.putString(ARG_PACKAGE_NAME, appEntry.info.packageName);
- args.putInt(ARG_PACKAGE_UID, appEntry.info.uid);
-
- SettingsActivity sa = (SettingsActivity) caller.getActivity();
- sa.startPreferencePanel(caller, fragment.getName(), args, title, null, caller,
- SUB_INFO_FRAGMENT);
- }
-
- private void handleUninstallButtonClick() {
- if (mAppEntry == null) {
- setIntentAndFinish(true, true);
- return;
- }
- final String packageName = mAppEntry.info.packageName;
- if (mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) {
- stopListeningToPackageRemove();
- Activity activity = getActivity();
- Intent uninstallDAIntent = new Intent(activity, DeviceAdminAdd.class);
- uninstallDAIntent.putExtra(DeviceAdminAdd.EXTRA_DEVICE_ADMIN_PACKAGE_NAME,
- mPackageName);
- mMetricsFeatureProvider.action(
- activity, MetricsEvent.ACTION_SETTINGS_UNINSTALL_DEVICE_ADMIN);
- activity.startActivityForResult(uninstallDAIntent, REQUEST_REMOVE_DEVICE_ADMIN);
- return;
- }
- EnforcedAdmin admin = RestrictedLockUtils.checkIfUninstallBlocked(getActivity(),
- packageName, mUserId);
- boolean uninstallBlockedBySystem = mAppsControlDisallowedBySystem ||
- RestrictedLockUtils.hasBaseUserRestriction(getActivity(), packageName, mUserId);
- if (admin != null && !uninstallBlockedBySystem) {
- RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getActivity(), admin);
- } else if ((mAppEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
- if (mAppEntry.info.enabled && !isDisabledUntilUsed()) {
- // If the system app has an update and this is the only user on the device,
- // then offer to downgrade the app, otherwise only offer to disable the
- // app for this user.
- if (mUpdatedSysApp && isSingleUser()) {
- showDialogInner(DLG_SPECIAL_DISABLE, 0);
- } else {
- showDialogInner(DLG_DISABLE, 0);
- }
- } else {
- mMetricsFeatureProvider.action(
- getActivity(),
- MetricsEvent.ACTION_SETTINGS_ENABLE_APP);
- new DisableChanger(this, mAppEntry.info,
- PackageManager.COMPONENT_ENABLED_STATE_ENABLED)
- .execute((Object) null);
- }
- } else if ((mAppEntry.info.flags & ApplicationInfo.FLAG_INSTALLED) == 0) {
- uninstallPkg(packageName, true, false);
- } else {
- uninstallPkg(packageName, false, false);
- }
- }
-
- private void handleForceStopButtonClick() {
- if (mAppEntry == null) {
- setIntentAndFinish(true, true);
- return;
- }
- if (mAppsControlDisallowedAdmin != null && !mAppsControlDisallowedBySystem) {
- RestrictedLockUtils.sendShowAdminSupportDetailsIntent(
- getActivity(), mAppsControlDisallowedAdmin);
- } else {
- showDialogInner(DLG_FORCE_STOP, 0);
- //forceStopPackage(mAppInfo.packageName);
- }
- }
-
- /** Returns whether there is only one user on this device, not including the system-only user */
- private boolean isSingleUser() {
- final int userCount = mUserManager.getUserCount();
- return userCount == 1
- || (mUserManager.isSplitSystemUser() && userCount == 2);
- }
-
- @Override
- public boolean onPreferenceClick(Preference preference) {
- if (preference == mStoragePreference) {
- startAppInfoFragment(AppStorageSettings.class, R.string.storage_settings);
- } else if (preference == mNotificationPreference) {
- startAppInfoFragment(AppNotificationSettings.class, R.string.app_notifications_title);
- } else if (preference == mPermissionsPreference) {
- startManagePermissionsActivity();
- } else if (preference == mLaunchPreference) {
- startAppInfoFragment(AppLaunchSettings.class, R.string.launch_by_default);
- } else if (preference == mMemoryPreference) {
- ProcessStatsBase.launchMemoryDetail((SettingsActivity) getActivity(),
- mStatsManager.getMemInfo(), mStats, false);
- } else if (preference == mDataPreference) {
- startAppInfoFragment(AppDataUsage.class, R.string.app_data_usage);
- } else if (preference == mBatteryPreference) {
- if (isBatteryStatsAvailable()) {
- BatteryEntry entry = new BatteryEntry(getContext(), null, mUserManager, mSipper);
- entry.defaultPackageName = mPackageName;
- AdvancedPowerUsageDetail.startBatteryDetailPage((SettingsActivity) getActivity(),
- this, mBatteryHelper, BatteryStats.STATS_SINCE_CHARGED, entry,
- mBatteryPercent, null /* mAnomalies */);
- } else {
- AdvancedPowerUsageDetail.startBatteryDetailPage((SettingsActivity) getActivity(),
- this, mPackageName);
- }
- } else {
- return false;
- }
- return true;
- }
-
- private void addDynamicPrefs() {
- if (UserManager.get(getContext()).isManagedProfile()) {
- return;
- }
- final PreferenceScreen screen = getPreferenceScreen();
- final Context context = getContext();
- if (DefaultHomePreferenceController.hasHomePreference(mPackageName, context)) {
- screen.addPreference(new ShortcutPreference(getPrefContext(),
- DefaultAppSettings.class, "default_home", R.string.home_app,
- R.string.configure_apps));
- }
- if (DefaultBrowserPreferenceController.hasBrowserPreference(mPackageName, context)) {
- screen.addPreference(new ShortcutPreference(getPrefContext(),
- DefaultAppSettings.class, "default_browser", R.string.default_browser_title,
- R.string.configure_apps));
- }
- if (DefaultPhonePreferenceController.hasPhonePreference(mPackageName, context)) {
- screen.addPreference(new ShortcutPreference(getPrefContext(),
- DefaultAppSettings.class, "default_phone_app", R.string.default_phone_title,
- R.string.configure_apps));
- }
- if (DefaultEmergencyPreferenceController.hasEmergencyPreference(mPackageName, context)) {
- screen.addPreference(new ShortcutPreference(getPrefContext(),
- DefaultAppSettings.class, "default_emergency_app",
- R.string.default_emergency_app, R.string.configure_apps));
- }
- if (DefaultSmsPreferenceController.hasSmsPreference(mPackageName, context)) {
- screen.addPreference(new ShortcutPreference(getPrefContext(),
- DefaultAppSettings.class, "default_sms_app", R.string.sms_application_title,
- R.string.configure_apps));
- }
-
- // Get the package info with the activities
- PackageInfo packageInfoWithActivities = null;
- try {
- packageInfoWithActivities = mPm.getPackageInfoAsUser(mPackageName,
- PackageManager.GET_ACTIVITIES, UserHandle.myUserId());
- } catch (NameNotFoundException e) {
- Log.e(TAG, "Exception while retrieving the package info of " + mPackageName, e);
- }
-
- boolean hasDrawOverOtherApps = hasPermission(permission.SYSTEM_ALERT_WINDOW);
- boolean hasWriteSettings = hasPermission(permission.WRITE_SETTINGS);
- boolean hasPictureInPictureActivities = (packageInfoWithActivities != null) &&
- PictureInPictureSettings.checkPackageHasPictureInPictureActivities(
- packageInfoWithActivities.packageName,
- packageInfoWithActivities.activities);
- boolean isPotentialAppSource = isPotentialAppSource();
- if (hasDrawOverOtherApps || hasWriteSettings || hasPictureInPictureActivities ||
- isPotentialAppSource) {
- PreferenceCategory category = new PreferenceCategory(getPrefContext());
- category.setTitle(R.string.advanced_apps);
- screen.addPreference(category);
-
- if (hasDrawOverOtherApps) {
- Preference pref = new Preference(getPrefContext());
- pref.setTitle(R.string.draw_overlay);
- pref.setKey("system_alert_window");
- pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- startAppInfoFragment(DrawOverlayDetails.class, R.string.draw_overlay);
- return true;
- }
- });
- category.addPreference(pref);
- }
- if (hasWriteSettings) {
- Preference pref = new Preference(getPrefContext());
- pref.setTitle(R.string.write_settings);
- pref.setKey("write_settings_apps");
- pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- startAppInfoFragment(WriteSettingsDetails.class, R.string.write_settings);
- return true;
- }
- });
- category.addPreference(pref);
- }
- if (hasPictureInPictureActivities) {
- Preference pref = new Preference(getPrefContext());
- pref.setTitle(R.string.picture_in_picture_app_detail_title);
- pref.setKey("picture_in_picture");
- pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- AppInfoBase.startAppInfoFragment(PictureInPictureDetails.class,
- R.string.picture_in_picture_app_detail_title, mPackageName,
- mPackageInfo.applicationInfo.uid, InstalledAppDetails.this,
- -1, getMetricsCategory());
- return true;
- }
- });
- category.addPreference(pref);
- }
- if (isPotentialAppSource) {
- Preference pref = new Preference(getPrefContext());
- pref.setTitle(R.string.install_other_apps);
- pref.setKey("install_other_apps");
- pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- startAppInfoFragment(ExternalSourcesDetails.class,
- R.string.install_other_apps);
- return true;
- }
- });
- category.addPreference(pref);
- }
- }
-
- addAppInstallerInfoPref(screen);
- maybeAddInstantAppButtons();
- }
-
- private boolean isPotentialAppSource() {
- AppStateInstallAppsBridge.InstallAppsState appState =
- new AppStateInstallAppsBridge(getContext(), null, null)
- .createInstallAppsStateFor(mPackageName, mPackageInfo.applicationInfo.uid);
- return appState.isPotentialAppSource();
- }
-
- private void addAppInstallerInfoPref(PreferenceScreen screen) {
- String installerPackageName =
- AppStoreUtil.getInstallerPackageName(getContext(), mPackageName);
-
- final CharSequence installerLabel = Utils.getApplicationLabel(getContext(),
- installerPackageName);
- if (installerLabel == null) {
- return;
- }
- final int detailsStringId = AppUtils.isInstant(mPackageInfo.applicationInfo)
- ? R.string.instant_app_details_summary
- : R.string.app_install_details_summary;
- PreferenceCategory category = new PreferenceCategory(getPrefContext());
- category.setTitle(R.string.app_install_details_group_title);
- screen.addPreference(category);
- Preference pref = new Preference(getPrefContext());
- pref.setTitle(R.string.app_install_details_title);
- pref.setKey("app_info_store");
- pref.setSummary(getString(detailsStringId, installerLabel));
-
- Intent intent =
- AppStoreUtil.getAppStoreLink(getContext(), installerPackageName, mPackageName);
- if (intent != null) {
- pref.setIntent(intent);
- } else {
- pref.setEnabled(false);
- }
- category.addPreference(pref);
- }
-
- @VisibleForTesting
- void maybeAddInstantAppButtons() {
- if (AppUtils.isInstant(mPackageInfo.applicationInfo)) {
- LayoutPreference buttons = (LayoutPreference) findPreference(KEY_INSTANT_APP_BUTTONS);
- mInstantAppButtonsController = mApplicationFeatureProvider
- .newInstantAppButtonsController(this,
- buttons.findViewById(R.id.instant_app_button_container),
- id -> showDialogInner(id, 0))
- .setPackageName(mPackageName)
- .show();
- }
- }
-
- private boolean hasPermission(String permission) {
- if (mPackageInfo == null || mPackageInfo.requestedPermissions == null) {
- return false;
- }
- for (int i = 0; i < mPackageInfo.requestedPermissions.length; i++) {
- if (mPackageInfo.requestedPermissions[i].equals(permission)) {
- return true;
- }
- }
- return false;
- }
-
- private void updateDynamicPrefs() {
- final Context context = getContext();
- Preference pref = findPreference("default_home");
-
- if (pref != null) {
- pref.setSummary(DefaultHomePreferenceController.isHomeDefault(mPackageName,
- new PackageManagerWrapper(context.getPackageManager()))
- ? R.string.yes : R.string.no);
- }
- pref = findPreference("default_browser");
- if (pref != null) {
- pref.setSummary(new DefaultBrowserPreferenceController(context)
- .isBrowserDefault(mPackageName, mUserId)
- ? R.string.yes : R.string.no);
- }
- pref = findPreference("default_phone_app");
- if (pref != null) {
- pref.setSummary(
- DefaultPhonePreferenceController.isPhoneDefault(mPackageName, context)
- ? R.string.yes : R.string.no);
- }
- pref = findPreference("default_emergency_app");
- if (pref != null) {
- pref.setSummary(DefaultEmergencyPreferenceController.isEmergencyDefault(mPackageName,
- getContext()) ? R.string.yes : R.string.no);
- }
- pref = findPreference("default_sms_app");
- if (pref != null) {
- pref.setSummary(DefaultSmsPreferenceController.isSmsDefault(mPackageName, context)
- ? R.string.yes : R.string.no);
- }
- pref = findPreference("system_alert_window");
- if (pref != null) {
- pref.setSummary(DrawOverlayDetails.getSummary(getContext(), mAppEntry));
- }
- pref = findPreference("picture_in_picture");
- if (pref != null) {
- pref.setSummary(PictureInPictureDetails.getPreferenceSummary(getContext(),
- mPackageInfo.applicationInfo.uid, mPackageName));
- }
- pref = findPreference("write_settings_apps");
- if (pref != null) {
- pref.setSummary(WriteSettingsDetails.getSummary(getContext(), mAppEntry));
- }
- pref = findPreference("install_other_apps");
- if (pref != null) {
- pref.setSummary(ExternalSourcesDetails.getPreferenceSummary(getContext(), mAppEntry));
- }
- }
-
- public static NetworkTemplate getTemplate(Context context) {
- if (DataUsageList.hasReadyMobileRadio(context)) {
- return NetworkTemplate.buildTemplateMobileWildcard();
- }
- if (DataUsageUtils.hasWifiRadio(context)) {
- return NetworkTemplate.buildTemplateWifiWildcard();
- }
- return NetworkTemplate.buildTemplateEthernet();
- }
-
- public static CharSequence getNotificationSummary(AppEntry appEntry, Context context,
- NotificationBackend backend) {
- AppRow appRow = backend.loadAppRow(context, context.getPackageManager(), appEntry.info);
- return getNotificationSummary(appRow, context);
- }
-
- public static CharSequence getNotificationSummary(AppRow appRow, Context context) {
- // TODO: implement summary when it is known what it should say
- return "";
- }
-
- @Override
- protected void onPackageRemoved() {
- getActivity().finishActivity(SUB_INFO_FRAGMENT);
- super.onPackageRemoved();
- }
-
- private class MemoryUpdater extends AsyncTask<Void, Void, ProcStatsPackageEntry> {
-
- @Override
- protected ProcStatsPackageEntry doInBackground(Void... params) {
- if (getActivity() == null) {
- return null;
- }
- if (mPackageInfo == null) {
- return null;
- }
- if (mStatsManager == null) {
- mStatsManager = new ProcStatsData(getActivity(), false);
- mStatsManager.setDuration(ProcessStatsBase.sDurations[0]);
- }
- mStatsManager.refreshStats(true);
- for (ProcStatsPackageEntry pkgEntry : mStatsManager.getEntries()) {
- for (ProcStatsEntry entry : pkgEntry.mEntries) {
- if (entry.mUid == mPackageInfo.applicationInfo.uid) {
- pkgEntry.updateMetrics();
- return pkgEntry;
- }
- }
- }
- return null;
- }
-
- @Override
- protected void onPostExecute(ProcStatsPackageEntry entry) {
- if (getActivity() == null) {
- return;
- }
- if (entry != null) {
- mStats = entry;
- mMemoryPreference.setEnabled(true);
- double amount = Math.max(entry.mRunWeight, entry.mBgWeight)
- * mStatsManager.getMemInfo().weightToRam;
- mMemoryPreference.setSummary(getString(R.string.memory_use_summary,
- Formatter.formatShortFileSize(getContext(), (long) amount)));
- } else {
- mMemoryPreference.setEnabled(false);
- mMemoryPreference.setSummary(getString(R.string.no_memory_use_summary));
- }
- }
-
- }
-
- /**
- * Elicit this class for testing. Test cannot be done in robolectric because it
- * invokes the new API.
- */
- @VisibleForTesting
- public static class PackageUtil {
- /**
- * Count how many users in device have installed package {@paramref packageName}
- */
- public static int countPackageInUsers(PackageManager packageManager, UserManager
- userManager, String packageName) {
- final List<UserInfo> userInfos = userManager.getUsers(true);
- int count = 0;
-
- for (final UserInfo userInfo : userInfos) {
- try {
- // Use this API to check whether user has this package
- final ApplicationInfo info = packageManager.getApplicationInfoAsUser(
- packageName, PackageManager.GET_META_DATA, userInfo.id);
- if ((info.flags & ApplicationInfo.FLAG_INSTALLED) != 0) {
- count++;
- }
- } catch(NameNotFoundException e) {
- Log.e(TAG, "Package: " + packageName + " not found for user: " + userInfo.id);
- }
- }
-
- return count;
- }
- }
-
- private static class DisableChanger extends AsyncTask<Object, Object, Object> {
- final PackageManager mPm;
- final WeakReference<InstalledAppDetails> mActivity;
- final ApplicationInfo mInfo;
- final int mState;
-
- DisableChanger(InstalledAppDetails activity, ApplicationInfo info, int state) {
- mPm = activity.mPm;
- mActivity = new WeakReference<InstalledAppDetails>(activity);
- mInfo = info;
- mState = state;
- }
-
- @Override
- protected Object doInBackground(Object... params) {
- mPm.setApplicationEnabledSetting(mInfo.packageName, mState, 0);
- return null;
- }
- }
-
- private final LoaderCallbacks<ChartData> mDataCallbacks = new LoaderCallbacks<ChartData>() {
-
- @Override
- public Loader<ChartData> onCreateLoader(int id, Bundle args) {
- return new ChartDataLoader(getActivity(), mStatsSession, args);
- }
-
- @Override
- public void onLoadFinished(Loader<ChartData> loader, ChartData data) {
- mChartData = data;
- mDataPreference.setSummary(getDataSummary());
- }
-
- @Override
- public void onLoaderReset(Loader<ChartData> loader) {
- // Leave last result.
- }
- };
-
- private final BroadcastReceiver mCheckKillProcessesReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- final boolean enabled = getResultCode() != Activity.RESULT_CANCELED;
- Log.d(LOG_TAG, "Got broadcast response: Restart status for "
- + mAppEntry.info.packageName + " " + enabled);
- updateForceStopButton(enabled);
- }
- };
-
- private final PermissionsResultCallback mPermissionCallback
- = new PermissionsResultCallback() {
- @Override
- public void onPermissionSummaryResult(int standardGrantedPermissionCount,
- int requestedPermissionCount, int additionalGrantedPermissionCount,
- List<CharSequence> grantedGroupLabels) {
- if (getActivity() == null) {
- return;
- }
- final Resources res = getResources();
- CharSequence summary = null;
-
- if (requestedPermissionCount == 0) {
- summary = res.getString(
- R.string.runtime_permissions_summary_no_permissions_requested);
- mPermissionsPreference.setOnPreferenceClickListener(null);
- mPermissionsPreference.setEnabled(false);
- } else {
- final ArrayList<CharSequence> list = new ArrayList<>(grantedGroupLabels);
- if (additionalGrantedPermissionCount > 0) {
- // N additional permissions.
- list.add(res.getQuantityString(
- R.plurals.runtime_permissions_additional_count,
- additionalGrantedPermissionCount, additionalGrantedPermissionCount));
- }
- if (list.size() == 0) {
- summary = res.getString(
- R.string.runtime_permissions_summary_no_permissions_granted);
- } else {
- summary = ListFormatter.getInstance().format(list);
- }
- mPermissionsPreference.setOnPreferenceClickListener(InstalledAppDetails.this);
- mPermissionsPreference.setEnabled(true);
- }
- mPermissionsPreference.setSummary(summary);
- }
- };
-}
diff --git a/src/com/android/settings/applications/InstalledAppDetailsTop.java b/src/com/android/settings/applications/InstalledAppDetailsTop.java
index 8090de0..2d9756a 100644
--- a/src/com/android/settings/applications/InstalledAppDetailsTop.java
+++ b/src/com/android/settings/applications/InstalledAppDetailsTop.java
@@ -17,30 +17,21 @@
package com.android.settings.applications;
import android.content.Intent;
-import android.util.FeatureFlagUtils;
import com.android.settings.SettingsActivity;
import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
-import com.android.settings.core.FeatureFlags;
public class InstalledAppDetailsTop extends SettingsActivity {
@Override
public Intent getIntent() {
Intent modIntent = new Intent(super.getIntent());
- if (FeatureFlagUtils.isEnabled(this, FeatureFlags.APP_INFO_V2)) {
- modIntent.putExtra(EXTRA_SHOW_FRAGMENT, AppInfoDashboardFragment.class.getName());
- } else {
- modIntent.putExtra(EXTRA_SHOW_FRAGMENT, InstalledAppDetails.class.getName());
- }
+ modIntent.putExtra(EXTRA_SHOW_FRAGMENT, AppInfoDashboardFragment.class.getName());
return modIntent;
}
@Override
protected boolean isValidFragment(String fragmentName) {
- if (FeatureFlagUtils.isEnabled(this, FeatureFlags.APP_INFO_V2)) {
- return AppInfoDashboardFragment.class.getName().equals(fragmentName);
- }
- return InstalledAppDetails.class.getName().equals(fragmentName);
+ return AppInfoDashboardFragment.class.getName().equals(fragmentName);
}
}
diff --git a/src/com/android/settings/applications/RecentAppsPreferenceController.java b/src/com/android/settings/applications/RecentAppsPreferenceController.java
index 3859081..e15671b 100644
--- a/src/com/android/settings/applications/RecentAppsPreferenceController.java
+++ b/src/com/android/settings/applications/RecentAppsPreferenceController.java
@@ -34,14 +34,12 @@
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
-import android.util.FeatureFlagUtils;
import android.util.IconDrawableFactory;
import android.util.Log;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
-import com.android.settings.core.FeatureFlags;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.widget.AppPreference;
import com.android.settingslib.applications.AppUtils;
@@ -245,17 +243,10 @@
System.currentTimeMillis() - stat.getLastTimeUsed(), false));
pref.setOrder(i);
pref.setOnPreferenceClickListener(preference -> {
- if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.APP_INFO_V2)) {
- AppInfoBase.startAppInfoFragment(AppInfoDashboardFragment.class,
- R.string.application_info_label, pkgName, appEntry.info.uid, mHost,
- 1001 /*RequestCode*/, SETTINGS_APP_NOTIF_CATEGORY);
- return true;
- } else {
- AppInfoBase.startAppInfoFragment(InstalledAppDetails.class,
- R.string.application_info_label, pkgName, appEntry.info.uid, mHost,
- 1001 /*RequestCode*/, SETTINGS_APP_NOTIF_CATEGORY);
- return true;
- }
+ AppInfoBase.startAppInfoFragment(AppInfoDashboardFragment.class,
+ R.string.application_info_label, pkgName, appEntry.info.uid, mHost,
+ 1001 /*RequestCode*/, SETTINGS_APP_NOTIF_CATEGORY);
+ return true;
});
if (!rebindPref) {
mCategory.addPreference(pref);
diff --git a/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceController.java b/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceController.java
index 130138c..1a5a285 100644
--- a/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceController.java
@@ -16,18 +16,14 @@
package com.android.settings.applications.appinfo;
-import android.app.Activity;
import android.app.ActivityManager;
import android.app.admin.DevicePolicyManager;
-import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
-import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -35,7 +31,6 @@
import android.os.UserManager;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.PreferenceScreen;
-import android.util.Log;
import android.webkit.IWebViewUpdateService;
import com.android.settings.R;
@@ -71,16 +66,6 @@
private UserManager mUserManager;
private PackageManager mPm;
- private final BroadcastReceiver mCheckKillProcessesReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- final boolean enabled = getResultCode() != Activity.RESULT_CANCELED;
- Log.d(TAG, "Got broadcast response: Restart status for "
- + mParent.getAppEntry().info.packageName + " " + enabled);
- updateForceStopButton(enabled);
- }
- };
-
public AppActionButtonPreferenceController(Context context, AppInfoDashboardFragment parent,
String packageName) {
super(context, KEY_ACTION_BUTTONS);
@@ -101,9 +86,7 @@
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mActionButtons = ((ActionButtonPreference) screen.findPreference(KEY_ACTION_BUTTONS))
- .setButton2Text(R.string.force_stop)
- .setButton2Positive(false)
- .setButton2Enabled(false);
+ .setButton2Visible(false);
}
@Override
@@ -140,7 +123,6 @@
}
}
- checkForceStop(appEntry, packageInfo);
initUninstallButtons(appEntry, packageInfo);
}
@@ -269,41 +251,6 @@
return disableable;
}
- private void updateForceStopButton(boolean enabled) {
- final boolean disallowedBySystem = RestrictedLockUtils.hasBaseUserRestriction(
- mContext, UserManager.DISALLOW_APPS_CONTROL, mUserId);
- mActionButtons
- .setButton2Enabled(disallowedBySystem ? false : enabled)
- .setButton2OnClickListener(
- disallowedBySystem ? null : v -> mParent.handleForceStopButtonClick());
- }
-
- void checkForceStop(AppEntry appEntry, PackageInfo packageInfo) {
- if (mDpm.packageHasActiveAdmins(packageInfo.packageName)) {
- // User can't force stop device admin.
- Log.w(TAG, "User can't force stop device admin");
- updateForceStopButton(false);
- } else if (AppUtils.isInstant(packageInfo.applicationInfo)) {
- updateForceStopButton(false);
- mActionButtons.setButton2Visible(false);
- } else if ((appEntry.info.flags & ApplicationInfo.FLAG_STOPPED) == 0) {
- // If the app isn't explicitly stopped, then always show the
- // force stop button.
- Log.w(TAG, "App is not explicitly stopped");
- updateForceStopButton(true);
- } else {
- final Intent intent = new Intent(Intent.ACTION_QUERY_PACKAGE_RESTART,
- Uri.fromParts("package", appEntry.info.packageName, null));
- intent.putExtra(Intent.EXTRA_PACKAGES, new String[] { appEntry.info.packageName });
- intent.putExtra(Intent.EXTRA_UID, appEntry.info.uid);
- intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(appEntry.info.uid));
- Log.d(TAG, "Sending broadcast to query restart status for "
- + appEntry.info.packageName);
- mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null,
- mCheckKillProcessesReceiver, null, Activity.RESULT_CANCELED, null, null);
- }
- }
-
private boolean signaturesMatch(String pkg1, String pkg2) {
if (pkg1 != null && pkg2 != null) {
try {
diff --git a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
index 41c1f7c..a99ba65 100755
--- a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
+++ b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
@@ -19,7 +19,6 @@
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import android.app.Activity;
-import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
@@ -45,19 +44,15 @@
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
-import android.view.View;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.DeviceAdminAdd;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.Utils;
-import com.android.settings.applications.LayoutPreference;
import com.android.settings.applications.manageapplications.ManageApplications;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.dashboard.DashboardFragment;
-import com.android.settings.widget.EntityHeaderController;
import com.android.settings.widget.PreferenceCategoryController;
import com.android.settings.wrapper.DevicePolicyManagerWrapper;
import com.android.settingslib.RestrictedLockUtils;
@@ -89,6 +84,7 @@
// Menu identifiers
private static final int UNINSTALL_ALL_USERS_MENU = 1;
private static final int UNINSTALL_UPDATES = 2;
+ static final int FORCE_STOP_MENU = 3;
// Result code identifiers
@VisibleForTesting
@@ -103,7 +99,7 @@
// Dialog identifiers used in showDialog
private static final int DLG_BASE = 0;
- private static final int DLG_FORCE_STOP = DLG_BASE + 1;
+ static final int DLG_FORCE_STOP = DLG_BASE + 1;
private static final int DLG_DISABLE = DLG_BASE + 2;
private static final int DLG_SPECIAL_DISABLE = DLG_BASE + 3;
@@ -141,6 +137,7 @@
private InstantAppButtonsPreferenceController mInstantAppButtonPreferenceController;
private AppActionButtonPreferenceController mAppActionButtonPreferenceController;
+ private ForceStopOptionsMenuController mForceStopOptionsMenuController;
/**
* Callback to invoke when app info has been changed.
@@ -172,6 +169,9 @@
return;
}
+ mForceStopOptionsMenuController =
+ new ForceStopOptionsMenuController(activity, this /* parent */, mDpm,
+ mMetricsFeatureProvider, getLifecycle());
setHasOptionsMenu(true);
}
@@ -268,6 +268,10 @@
return mAppEntry;
}
+ void setAppEntry(ApplicationsState.AppEntry appEntry) {
+ mAppEntry = appEntry;
+ }
+
PackageInfo getPackageInfo() {
if (mAppEntry == null) {
retrieveAppEntry();
@@ -275,6 +279,10 @@
return mPackageInfo;
}
+ ApplicationsState getAppState() {
+ return mState;
+ }
+
@Override
public void onPackageSizeChanged(String packageName) {
if (!TextUtils.equals(packageName, mPackageName)) {
@@ -315,6 +323,7 @@
if (mFinishing) {
return;
}
+ super.onPrepareOptionsMenu(menu);
menu.findItem(UNINSTALL_ALL_USERS_MENU).setVisible(shouldShowUninstallForAll(mAppEntry));
mUpdatedSysApp = (mAppEntry.info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
final MenuItem uninstallUpdatesItem = menu.findItem(UNINSTALL_UPDATES);
@@ -335,7 +344,7 @@
uninstallPkg(mAppEntry.info.packageName, false, false);
return true;
}
- return false;
+ return super.onOptionsItemSelected(item);
}
@Override
@@ -465,18 +474,10 @@
})
.setNegativeButton(R.string.dlg_cancel, null)
.create();
- case DLG_FORCE_STOP:
- return new AlertDialog.Builder(getActivity())
- .setTitle(getActivity().getText(R.string.force_stop_dlg_title))
- .setMessage(getActivity().getText(R.string.force_stop_dlg_text))
- .setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- // Force stop
- forceStopPackage(mAppEntry.info.packageName);
- }
- })
- .setNegativeButton(R.string.dlg_cancel, null)
- .create();
+ }
+ final AlertDialog dialog = mForceStopOptionsMenuController.createDialog(id);
+ if (dialog != null) {
+ return dialog;
}
return mInstantAppButtonPreferenceController.createDialog(id);
}
@@ -493,21 +494,6 @@
mDisableAfterUninstall = andDisable;
}
- private void forceStopPackage(String pkgName) {
- mMetricsFeatureProvider.action(getContext(), MetricsEvent.ACTION_APP_FORCE_STOP, pkgName);
- final ActivityManager am = (ActivityManager) getActivity().getSystemService(
- Context.ACTIVITY_SERVICE);
- Log.d(TAG, "Stopping package " + pkgName);
- am.forceStopPackage(pkgName);
- final int userId = UserHandle.getUserId(mAppEntry.info.uid);
- mState.invalidatePackage(pkgName, userId);
- final AppEntry newEnt = mState.getEntry(pkgName, userId);
- if (newEnt != null) {
- mAppEntry = newEnt;
- }
- mAppActionButtonPreferenceController.checkForceStop(mAppEntry, mPackageInfo);
- }
-
public static void startAppInfoFragment(Class<?> fragment, int title,
SettingsPreferenceFragment caller, AppEntry appEntry) {
// start new fragment to display extended information
@@ -568,20 +554,6 @@
}
}
- void handleForceStopButtonClick() {
- if (mAppEntry == null) {
- setIntentAndFinish(true, true);
- return;
- }
- if (mAppsControlDisallowedAdmin != null && !mAppsControlDisallowedBySystem) {
- RestrictedLockUtils.sendShowAdminSupportDetailsIntent(
- getActivity(), mAppsControlDisallowedAdmin);
- } else {
- showDialogInner(DLG_FORCE_STOP, 0);
- //forceStopPackage(mAppInfo.packageName);
- }
- }
-
/** Returns whether there is only one user on this device, not including the system-only user */
private boolean isSingleUser() {
final int userCount = mUserManager.getUserCount();
@@ -679,7 +651,7 @@
}
}
- private void setIntentAndFinish(boolean finish, boolean appChanged) {
+ void setIntentAndFinish(boolean finish, boolean appChanged) {
if (localLOGV) Log.i(TAG, "appChanged="+appChanged);
final Intent intent = new Intent();
intent.putExtra(ManageApplications.APP_CHG, appChanged);
diff --git a/src/com/android/settings/applications/appinfo/ForceStopOptionsMenuController.java b/src/com/android/settings/applications/appinfo/ForceStopOptionsMenuController.java
new file mode 100644
index 0000000..cf87147
--- /dev/null
+++ b/src/com/android/settings/applications/appinfo/ForceStopOptionsMenuController.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2018 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.appinfo;
+
+import static com.android.settings.applications.appinfo.AppInfoDashboardFragment.FORCE_STOP_MENU;
+import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.AlertDialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.net.Uri;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.support.annotation.VisibleForTesting;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.R;
+import com.android.settings.wrapper.DevicePolicyManagerWrapper;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.applications.AppUtils;
+import com.android.settingslib.applications.ApplicationsState;
+import com.android.settingslib.applications.ApplicationsState.AppEntry;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnCreateOptionsMenu;
+import com.android.settingslib.core.lifecycle.events.OnOptionsItemSelected;
+import com.android.settingslib.core.lifecycle.events.OnPrepareOptionsMenu;
+
+public class ForceStopOptionsMenuController implements LifecycleObserver, OnCreateOptionsMenu,
+ OnPrepareOptionsMenu, OnOptionsItemSelected {
+
+ private static final String TAG = "ForceStopMenuController";
+
+ private final Context mContext;
+ private final AppInfoDashboardFragment mParent;
+ private final DevicePolicyManagerWrapper mDpm;
+ private final MetricsFeatureProvider mMetricsFeatureProvider;
+
+ private int mUserId;
+ private MenuItem mForceStopMenu;
+
+ private final BroadcastReceiver mCheckKillProcessesReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final boolean enabled = getResultCode() != Activity.RESULT_CANCELED;
+ Log.d(TAG, "Got broadcast response: Restart status for "
+ + mParent.getAppEntry().info.packageName + " " + enabled);
+ enableForceStopMenu(enabled);
+ }
+ };
+
+ public ForceStopOptionsMenuController(Context context, AppInfoDashboardFragment parent,
+ DevicePolicyManagerWrapper devicePolicyManager,
+ MetricsFeatureProvider metricsFeatureProvider, Lifecycle lifecycle) {
+ mContext = context;
+ mParent = parent;
+ mDpm = devicePolicyManager;
+ mMetricsFeatureProvider = metricsFeatureProvider;
+ mUserId = UserHandle.myUserId();
+ if (lifecycle != null) {
+ lifecycle.addObserver(this);
+ }
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ menu.add(0, FORCE_STOP_MENU, 2, R.string.force_stop)
+ .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem menuItem) {
+ if (menuItem.getItemId() == FORCE_STOP_MENU) {
+ handleForceStopMenuClick();
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void onPrepareOptionsMenu(Menu menu) {
+ mForceStopMenu = menu.findItem(FORCE_STOP_MENU);
+ updateForceStopMenu(mParent.getAppEntry(), mParent.getPackageInfo());
+ }
+
+ @VisibleForTesting
+ void updateForceStopMenu(AppEntry appEntry, PackageInfo packageInfo) {
+ boolean enabled = false;
+ if (mDpm.packageHasActiveAdmins(packageInfo.packageName)) {
+ // User can't force stop device admin.
+ Log.w(TAG, "User can't force stop device admin");
+ } else if (AppUtils.isInstant(packageInfo.applicationInfo)) {
+ // No force stop for instant app
+ if (mForceStopMenu != null) {
+ mForceStopMenu.setVisible(false);
+ }
+ } else if ((appEntry.info.flags & ApplicationInfo.FLAG_STOPPED) == 0) {
+ // If the app isn't explicitly stopped, then always show the
+ // force stop button.
+ Log.w(TAG, "App is not explicitly stopped");
+ enabled = true;
+ } else {
+ final Intent intent = new Intent(Intent.ACTION_QUERY_PACKAGE_RESTART,
+ Uri.fromParts("package", appEntry.info.packageName, null));
+ intent.putExtra(Intent.EXTRA_PACKAGES, new String[] { appEntry.info.packageName });
+ intent.putExtra(Intent.EXTRA_UID, appEntry.info.uid);
+ intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(appEntry.info.uid));
+ Log.d(TAG, "Sending broadcast to query restart status for "
+ + appEntry.info.packageName);
+ mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null,
+ mCheckKillProcessesReceiver, null, Activity.RESULT_CANCELED, null, null);
+ }
+ enableForceStopMenu(enabled);
+ }
+
+ private void enableForceStopMenu(boolean enabled) {
+ if (mForceStopMenu != null) {
+ final boolean disallowedBySystem = RestrictedLockUtils.hasBaseUserRestriction(
+ mContext, UserManager.DISALLOW_APPS_CONTROL, mUserId);
+ mForceStopMenu.setEnabled(disallowedBySystem ? false : enabled);
+ }
+ }
+
+ @VisibleForTesting
+ void handleForceStopMenuClick() {
+ if (mParent.getAppEntry() == null) {
+ mParent.setIntentAndFinish(true, true);
+ return;
+ }
+ final EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(
+ mContext, UserManager.DISALLOW_APPS_CONTROL, mUserId);
+ final boolean disallowedBySystem = RestrictedLockUtils.hasBaseUserRestriction(
+ mContext, UserManager.DISALLOW_APPS_CONTROL, mUserId);
+ if (admin != null && !disallowedBySystem) {
+ RestrictedLockUtils.sendShowAdminSupportDetailsIntent(mContext, admin);
+ } else {
+ mParent.showDialogInner(mParent.DLG_FORCE_STOP, 0);
+ }
+ }
+
+ private void forceStopPackage(String pkgName) {
+ mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_APP_FORCE_STOP, pkgName);
+ final ActivityManager am = (ActivityManager) mContext.getSystemService(
+ Context.ACTIVITY_SERVICE);
+ Log.d(TAG, "Stopping package " + pkgName);
+ am.forceStopPackage(pkgName);
+ final int userId = UserHandle.getUserId(mParent.getAppEntry().info.uid);
+ final ApplicationsState appState = mParent.getAppState();
+ appState.invalidatePackage(pkgName, userId);
+ final AppEntry newEnt = appState.getEntry(pkgName, userId);
+ if (newEnt != null) {
+ mParent.setAppEntry(newEnt);
+ }
+ }
+
+ public AlertDialog createDialog(int id) {
+ if (id != mParent.DLG_FORCE_STOP) {
+ return null;
+ }
+ return new AlertDialog.Builder(mContext)
+ .setTitle(mContext.getText(R.string.force_stop_dlg_title))
+ .setMessage(mContext.getText(R.string.force_stop_dlg_text))
+ .setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ // Force stop
+ forceStopPackage(mParent.getAppEntry().info.packageName);
+ }
+ })
+ .setNegativeButton(R.string.dlg_cancel, null)
+ .create();
+ }
+
+}
diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java
index 09896dc..06ba86e 100644
--- a/src/com/android/settings/applications/manageapplications/ManageApplications.java
+++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java
@@ -50,7 +50,6 @@
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.ArraySet;
-import android.util.FeatureFlagUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -91,15 +90,14 @@
import com.android.settings.applications.AppStorageSettings;
import com.android.settings.applications.DefaultAppSettings;
import com.android.settings.applications.InstalledAppCounter;
-import com.android.settings.applications.InstalledAppDetails;
import com.android.settings.applications.NotificationApps;
import com.android.settings.applications.DirectoryAccessDetails;
import com.android.settings.applications.UsageAccessDetails;
import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
+import com.android.settings.applications.appinfo.AppNotificationPreferenceController;
import com.android.settings.applications.appinfo.DrawOverlayDetails;
import com.android.settings.applications.appinfo.ExternalSourcesDetails;
import com.android.settings.applications.appinfo.WriteSettingsDetails;
-import com.android.settings.core.FeatureFlags;
import com.android.settings.core.InstrumentedPreferenceFragment;
import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.fuelgauge.HighPowerDetail;
@@ -151,7 +149,7 @@
private static final String EXTRA_HAS_ENTRIES = "hasEntries";
private static final String EXTRA_HAS_BRIDGE = "hasBridge";
- // attributes used as keys when passing values to InstalledAppDetails activity
+ // attributes used as keys when passing values to AppInfoDashboardFragment activity
public static final String APP_CHG = "chg";
// constant value that can be used to check return code from sub activity.
@@ -553,13 +551,8 @@
// process ahead of time, to avoid a long load of data when user clicks on a managed
// app. Maybe when they load the list of apps that contains managed profile apps.
default:
- if (FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.APP_INFO_V2)) {
- startAppInfoFragment(
- AppInfoDashboardFragment.class, R.string.application_info_label);
- } else {
- startAppInfoFragment(
- InstalledAppDetails.class, R.string.application_info_label);
- }
+ startAppInfoFragment(
+ AppInfoDashboardFragment.class, R.string.application_info_label);
break;
}
}
@@ -1227,7 +1220,8 @@
switch (mManageApplications.mListType) {
case LIST_TYPE_NOTIFICATION:
if (entry.extraInfo != null) {
- holder.setSummary(InstalledAppDetails.getNotificationSummary(
+ holder.setSummary(
+ AppNotificationPreferenceController.getNotificationSummary(
(AppRow) entry.extraInfo, mContext));
} else {
holder.setSummary(null);
diff --git a/src/com/android/settings/core/FeatureFlags.java b/src/com/android/settings/core/FeatureFlags.java
index e1636b4..687442e 100644
--- a/src/com/android/settings/core/FeatureFlags.java
+++ b/src/com/android/settings/core/FeatureFlags.java
@@ -20,11 +20,9 @@
* This class keeps track of all feature flags in Settings.
*/
public class FeatureFlags {
- public static final String APP_INFO_V2 = "settings_app_info_v2";
public static final String CONNECTED_DEVICE_V2 = "settings_connected_device_v2";
public static final String BATTERY_SETTINGS_V2 = "settings_battery_v2";
public static final String BATTERY_DISPLAY_APP_LIST = "settings_battery_display_app_list";
- public static final String SECURITY_SETTINGS_V2 = "settings_security_settings_v2";
public static final String ZONE_PICKER_V2 = "settings_zone_picker_v2";
public static final String SUGGESTION_UI_V2 = "settings_suggestion_ui_v2";
public static final String ABOUT_PHONE_V2 = "settings_about_phone_v2";
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index ecf0584..91fc108 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -39,7 +39,6 @@
import com.android.settings.accounts.AccountDashboardFragment;
import com.android.settings.applications.AppAndNotificationDashboardFragment;
import com.android.settings.applications.DefaultAppSettings;
-import com.android.settings.applications.InstalledAppDetails;
import com.android.settings.applications.ManageDomainUrls;
import com.android.settings.applications.NotificationApps;
import com.android.settings.applications.ProcessStatsSummary;
@@ -116,7 +115,6 @@
import com.android.settings.security.CryptKeeperSettings;
import com.android.settings.security.LockscreenDashboardFragment;
import com.android.settings.security.SecuritySettings;
-import com.android.settings.security.SecuritySettingsV2;
import com.android.settings.sim.SimSettings;
import com.android.settings.support.SupportDashboardActivity;
import com.android.settings.system.ResetDashboardFragment;
@@ -165,7 +163,6 @@
NotificationStation.class.getName(),
LocationSettings.class.getName(),
SecuritySettings.class.getName(),
- SecuritySettingsV2.class.getName(),
UsageAccessDetails.class.getName(),
PrivacySettings.class.getName(),
DeviceAdminSettings.class.getName(),
@@ -209,7 +206,6 @@
ConfigureNotificationSettings.class.getName(),
ChooseLockPassword.ChooseLockPasswordFragment.class.getName(),
ChooseLockPattern.ChooseLockPatternFragment.class.getName(),
- InstalledAppDetails.class.getName(),
AppInfoDashboardFragment.class.getName(),
BatterySaverSettings.class.getName(),
AppNotificationSettings.class.getName(),
@@ -271,8 +267,7 @@
Settings.PowerUsageSummaryActivity.class.getName(),
Settings.PowerUsageSummaryLegacyActivity.class.getName(),
Settings.AccountDashboardActivity.class.getName(),
- Settings.SecuritySettingsActivity.class.getName(),
- Settings.SecuritySettingsActivityV2.class.getName(),
+ Settings.SecurityDashboardActivity.class.getName(),
Settings.AccessibilitySettingsActivity.class.getName(),
Settings.SystemDashboardActivity.class.getName(),
SupportDashboardActivity.class.getName(),
diff --git a/src/com/android/settings/dashboard/DashboardAdapterV2.java b/src/com/android/settings/dashboard/DashboardAdapterV2.java
index 7cd4f38..f98b440 100644
--- a/src/com/android/settings/dashboard/DashboardAdapterV2.java
+++ b/src/com/android/settings/dashboard/DashboardAdapterV2.java
@@ -151,13 +151,10 @@
if (list.size() == 1) {
// The only suggestion is dismissed, and the the empty suggestion container will
// remain as the dashboard item. Need to refresh the dashboard list.
- final DashboardDataV2 prevData = mDashboardData;
- mDashboardData = new DashboardDataV2.Builder(prevData)
- .setSuggestions(null)
- .build();
- notifyDashboardDataChanged(prevData);
+ setSuggestions(null);
} else {
mSuggestionAdapter.removeSuggestion(suggestion);
+ notifyItemChanged(0, null);
}
}
diff --git a/src/com/android/settings/dashboard/DashboardFragmentRegistry.java b/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
index bb575ea..275af3d 100644
--- a/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
+++ b/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
@@ -33,7 +33,7 @@
import com.android.settings.notification.ConfigureNotificationSettings;
import com.android.settings.notification.SoundSettings;
import com.android.settings.security.LockscreenDashboardFragment;
-import com.android.settings.security.SecuritySettingsV2;
+import com.android.settings.security.SecuritySettings;
import com.android.settings.system.SystemDashboardFragment;
import com.android.settingslib.drawer.CategoryKey;
@@ -77,7 +77,7 @@
CategoryKey.CATEGORY_SOUND);
PARENT_TO_CATEGORY_KEY_MAP.put(StorageDashboardFragment.class.getName(),
CategoryKey.CATEGORY_STORAGE);
- PARENT_TO_CATEGORY_KEY_MAP.put(SecuritySettingsV2.class.getName(),
+ PARENT_TO_CATEGORY_KEY_MAP.put(SecuritySettings.class.getName(),
CategoryKey.CATEGORY_SECURITY);
PARENT_TO_CATEGORY_KEY_MAP.put(AccountDetailDashboardFragment.class.getName(),
CategoryKey.CATEGORY_ACCOUNT_DETAIL);
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2.java b/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2.java
index 483af92..e29ca5f 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2.java
@@ -18,6 +18,8 @@
import android.app.PendingIntent;
import android.content.Context;
import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.service.settings.suggestions.Suggestion;
import android.support.v7.widget.RecyclerView;
@@ -34,6 +36,7 @@
import com.android.settings.dashboard.DashboardAdapterV2.DashboardItemHolder;
import com.android.settings.dashboard.DashboardAdapterV2.IconCache;
import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.Utils;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
@@ -55,6 +58,7 @@
private final MetricsFeatureProvider mMetricsFeatureProvider;
private final IconCache mCache;
private final ArrayList<String> mSuggestionsShownLogged;
+ private final SuggestionFeatureProvider mSuggestionFeatureProvider;
private final SuggestionControllerMixin mSuggestionControllerMixin;
private final Callback mCallback;
private final CardConfig mConfig;
@@ -75,6 +79,7 @@
mCache = new IconCache(context);
final FeatureFactory factory = FeatureFactory.getFactory(context);
mMetricsFeatureProvider = factory.getMetricsFeatureProvider();
+ mSuggestionFeatureProvider = factory.getSuggestionFeatureProvider(context);
mCallback = callback;
if (savedInstanceState != null) {
mSuggestions = savedInstanceState.getParcelableArrayList(STATE_SUGGESTION_LIST);
@@ -109,7 +114,12 @@
mSuggestionsShownLogged.add(id);
}
mConfig.setCardLayout(holder, suggestionCount, position);
- holder.icon.setImageDrawable(mCache.getIcon(suggestion.getIcon()));
+ final Icon icon = suggestion.getIcon();
+ final Drawable drawable = mCache.getIcon(icon);
+ if (drawable != null && TextUtils.equals(icon.getResPackage(), mContext.getPackageName())) {
+ drawable.setTint(Utils.getColorAccent(mContext));
+ }
+ holder.icon.setImageDrawable(drawable);
holder.title.setText(suggestion.getTitle());
holder.title.setSingleLine(suggestionCount == 1);
@@ -129,13 +139,13 @@
final ImageView closeButton = holder.itemView.findViewById(R.id.close_button);
if (closeButton != null) {
- if (mCallback != null) {
- closeButton.setOnClickListener(v -> {
+ closeButton.setOnClickListener(v -> {
+ mSuggestionFeatureProvider.dismissSuggestion(
+ mContext, mSuggestionControllerMixin, suggestion);
+ if (mCallback != null) {
mCallback.onSuggestionClosed(suggestion);
- });
- } else {
- closeButton.setOnClickListener(null);
- }
+ }
+ });
}
View clickHandler = holder.itemView;
diff --git a/src/com/android/settings/datausage/AppDataUsage.java b/src/com/android/settings/datausage/AppDataUsage.java
index 5470e63..a0d0ec0 100644
--- a/src/com/android/settings/datausage/AppDataUsage.java
+++ b/src/com/android/settings/datausage/AppDataUsage.java
@@ -33,7 +33,6 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.support.annotation.VisibleForTesting;
-import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceCategory;
import android.text.format.Formatter;
@@ -48,6 +47,9 @@
import com.android.settings.applications.AppInfoBase;
import com.android.settings.widget.EntityHeaderController;
import com.android.settingslib.AppItem;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedSwitchPreference;
import com.android.settingslib.net.ChartData;
import com.android.settingslib.net.ChartDataLoader;
import com.android.settingslib.net.UidDetail;
@@ -80,7 +82,7 @@
private Preference mForegroundUsage;
private Preference mBackgroundUsage;
private Preference mAppSettings;
- private SwitchPreference mRestrictBackground;
+ private RestrictedSwitchPreference mRestrictBackground;
private PreferenceCategory mAppList;
private Drawable mIcon;
@@ -97,7 +99,7 @@
private AppItem mAppItem;
private Intent mAppSettingsIntent;
private SpinnerPreference mCycle;
- private SwitchPreference mUnrestrictedData;
+ private RestrictedSwitchPreference mUnrestrictedData;
private DataSaverBackend mDataSaverBackend;
@Override
@@ -160,9 +162,11 @@
removePreference(KEY_UNRESTRICTED_DATA);
removePreference(KEY_RESTRICT_BACKGROUND);
} else {
- mRestrictBackground = (SwitchPreference) findPreference(KEY_RESTRICT_BACKGROUND);
+ mRestrictBackground = (RestrictedSwitchPreference) findPreference(
+ KEY_RESTRICT_BACKGROUND);
mRestrictBackground.setOnPreferenceChangeListener(this);
- mUnrestrictedData = (SwitchPreference) findPreference(KEY_UNRESTRICTED_DATA);
+ mUnrestrictedData = (RestrictedSwitchPreference) findPreference(
+ KEY_UNRESTRICTED_DATA);
mUnrestrictedData.setOnPreferenceChangeListener(this);
}
mDataSaverBackend = new DataSaverBackend(getContext());
@@ -261,8 +265,11 @@
}
private void updatePrefs(boolean restrictBackground, boolean unrestrictData) {
+ final EnforcedAdmin admin = RestrictedLockUtils.checkIfMeteredDataRestricted(
+ getContext(), mPackageName, UserHandle.getUserId(mAppItem.key));
if (mRestrictBackground != null) {
mRestrictBackground.setChecked(!restrictBackground);
+ mRestrictBackground.setDisabledByAdmin(admin);
}
if (mUnrestrictedData != null) {
if (restrictBackground) {
@@ -270,6 +277,7 @@
} else {
mUnrestrictedData.setVisible(true);
mUnrestrictedData.setChecked(unrestrictData);
+ mUnrestrictedData.setDisabledByAdmin(admin);
}
}
}
diff --git a/src/com/android/settings/datausage/DataSaverPreference.java b/src/com/android/settings/datausage/DataSaverPreference.java
index 13ef9d7..f1f648a 100644
--- a/src/com/android/settings/datausage/DataSaverPreference.java
+++ b/src/com/android/settings/datausage/DataSaverPreference.java
@@ -37,7 +37,7 @@
@Override
public void onDetached() {
super.onDetached();
- mDataSaverBackend.addListener(this);
+ mDataSaverBackend.remListener(this);
}
@Override
diff --git a/src/com/android/settings/datausage/UnrestrictedDataAccess.java b/src/com/android/settings/datausage/UnrestrictedDataAccess.java
index e8a7bbf..2e20406 100644
--- a/src/com/android/settings/datausage/UnrestrictedDataAccess.java
+++ b/src/com/android/settings/datausage/UnrestrictedDataAccess.java
@@ -14,13 +14,14 @@
package com.android.settings.datausage;
+import static com.android.settingslib.RestrictedLockUtils.checkIfMeteredDataRestricted;
+
import android.app.Application;
import android.content.Context;
import android.os.Bundle;
import android.os.UserHandle;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceViewHolder;
-import android.util.FeatureFlagUtils;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
@@ -31,12 +32,12 @@
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.applications.AppStateBaseBridge;
-import com.android.settings.applications.InstalledAppDetails;
import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
-import com.android.settings.core.FeatureFlags;
import com.android.settings.datausage.AppStateDataUsageBridge.DataUsageState;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.widget.AppSwitchPreference;
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedPreferenceHelper;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.ApplicationsState.AppEntry;
import com.android.settingslib.applications.ApplicationsState.AppFilter;
@@ -172,6 +173,8 @@
preference.setOnPreferenceChangeListener(this);
getPreferenceScreen().addPreference(preference);
} else {
+ preference.setDisabledByAdmin(checkIfMeteredDataRestricted(getContext(),
+ entry.info.packageName, UserHandle.getUserId(entry.info.uid)));
preference.reuse();
}
preference.setOrder(i);
@@ -242,16 +245,22 @@
return app != null && UserHandle.isApp(app.info.uid);
}
- private class AccessPreference extends AppSwitchPreference
+ @VisibleForTesting
+ class AccessPreference extends AppSwitchPreference
implements DataSaverBackend.Listener {
private final AppEntry mEntry;
private final DataUsageState mState;
+ private final RestrictedPreferenceHelper mHelper;
public AccessPreference(final Context context, AppEntry entry) {
super(context);
+ setWidgetLayoutResource(R.layout.restricted_switch_widget);
+ mHelper = new RestrictedPreferenceHelper(context, this, null);
mEntry = entry;
mState = (DataUsageState) mEntry.extraInfo;
mEntry.ensureLabel(getContext());
+ setDisabledByAdmin(checkIfMeteredDataRestricted(context, entry.info.packageName,
+ UserHandle.getUserId(entry.info.uid)));
setState();
if (mEntry.icon != null) {
setIcon(mEntry.icon);
@@ -274,29 +283,31 @@
protected void onClick() {
if (mState.isDataSaverBlacklisted) {
// app is blacklisted, launch App Data Usage screen
- if (FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.APP_INFO_V2)) {
- AppInfoDashboardFragment.startAppInfoFragment(AppDataUsage.class,
- R.string.app_data_usage,
- UnrestrictedDataAccess.this,
- mEntry);
- } else {
- InstalledAppDetails.startAppInfoFragment(AppDataUsage.class,
- R.string.app_data_usage,
- UnrestrictedDataAccess.this,
- mEntry);
- }
+ AppInfoDashboardFragment.startAppInfoFragment(AppDataUsage.class,
+ R.string.app_data_usage,
+ UnrestrictedDataAccess.this,
+ mEntry);
} else {
// app is not blacklisted, let superclass handle toggle switch
super.onClick();
}
}
+ @Override
+ public void performClick() {
+ if (!mHelper.performClick()) {
+ super.performClick();
+ }
+ }
+
// Sets UI state based on whitelist/blacklist status.
private void setState() {
setTitle(mEntry.label);
if (mState != null) {
setChecked(mState.isDataSaverWhitelisted);
- if (mState.isDataSaverBlacklisted) {
+ if (isDisabledByAdmin()) {
+ setSummary(R.string.disabled_by_admin);
+ } else if (mState.isDataSaverBlacklisted) {
setSummary(R.string.restrict_background_blacklisted);
} else {
setSummary("");
@@ -323,10 +334,21 @@
}
});
}
- holder.findViewById(android.R.id.widget_frame)
- .setVisibility(mState != null && mState.isDataSaverBlacklisted
- ? View.INVISIBLE : View.VISIBLE);
+ final boolean disabledByAdmin = isDisabledByAdmin();
+ final View widgetFrame = holder.findViewById(android.R.id.widget_frame);
+ if (disabledByAdmin) {
+ widgetFrame.setVisibility(View.VISIBLE);
+ } else {
+ widgetFrame.setVisibility(mState != null && mState.isDataSaverBlacklisted
+ ? View.INVISIBLE : View.VISIBLE);
+ }
super.onBindViewHolder(holder);
+
+ mHelper.onBindViewHolder(holder);
+ holder.findViewById(R.id.restricted_icon).setVisibility(
+ disabledByAdmin ? View.VISIBLE : View.GONE);
+ holder.findViewById(android.R.id.switch_widget).setVisibility(
+ disabledByAdmin ? View.GONE : View.VISIBLE);
}
@Override
@@ -348,6 +370,19 @@
reuse();
}
}
+
+ public void setDisabledByAdmin(EnforcedAdmin admin) {
+ mHelper.setDisabledByAdmin(admin);
+ }
+
+ public boolean isDisabledByAdmin() {
+ return mHelper.isDisabledByAdmin();
+ }
+
+ @VisibleForTesting
+ public AppEntry getEntryForTest() {
+ return mEntry;
+ }
}
}
diff --git a/src/com/android/settings/fingerprint/FingerprintSettings.java b/src/com/android/settings/fingerprint/FingerprintSettings.java
index de7187c..caad988 100644
--- a/src/com/android/settings/fingerprint/FingerprintSettings.java
+++ b/src/com/android/settings/fingerprint/FingerprintSettings.java
@@ -35,7 +35,6 @@
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import android.support.v7.preference.Preference.OnPreferenceChangeListener;
-import android.support.v7.preference.Preference.OnPreferenceClickListener;
import android.support.v7.preference.PreferenceGroup;
import android.support.v7.preference.PreferenceScreen;
import android.support.v7.preference.PreferenceViewHolder;
@@ -921,49 +920,4 @@
});
}
}
-
- /**
- * @deprecated in favor of new SecuritySettings.
- */
- @Deprecated
- public static Preference getFingerprintPreferenceForUser(Context context, final int userId) {
- final FingerprintManager fpm = Utils.getFingerprintManagerOrNull(context);
- if (fpm == null || !fpm.isHardwareDetected()) {
- Log.v(TAG, "No fingerprint hardware detected!!");
- return null;
- }
- Preference fingerprintPreference = new Preference(context);
- fingerprintPreference.setKey(KEY_FINGERPRINT_SETTINGS);
- fingerprintPreference.setTitle(R.string.security_settings_fingerprint_preference_title);
- final List<Fingerprint> items = fpm.getEnrolledFingerprints(userId);
- final int fingerprintCount = items != null ? items.size() : 0;
- final String clazz;
- if (fingerprintCount > 0) {
- fingerprintPreference.setSummary(context.getResources().getQuantityString(
- R.plurals.security_settings_fingerprint_preference_summary,
- fingerprintCount, fingerprintCount));
- clazz = FingerprintSettings.class.getName();
- } else {
- fingerprintPreference.setSummary(
- R.string.security_settings_fingerprint_preference_summary_none);
- clazz = FingerprintEnrollIntroduction.class.getName();
- }
- fingerprintPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- final Context context = preference.getContext();
- final UserManager userManager = UserManager.get(context);
- if (Utils.startQuietModeDialogIfNecessary(context, userManager,
- userId)) {
- return false;
- }
- Intent intent = new Intent();
- intent.setClassName("com.android.settings", clazz);
- intent.putExtra(Intent.EXTRA_USER_ID, userId);
- context.startActivity(intent);
- return true;
- }
- });
- return fingerprintPreference;
- }
}
diff --git a/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java b/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java
index a52433b..7bd1b3d 100644
--- a/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java
@@ -74,7 +74,7 @@
* An easy way to handle them is to delegate them to {@link #handleDialogClick(int)} and
* {@link #handleActivityResult(int, int, Intent)} in this controller.
*/
-//TODO(b/35810915): Make InstalledAppDetails use this controller
+//TODO(b/35810915): Make AppInfoDashboardFragment use this controller
public class AppButtonsPreferenceController extends AbstractPreferenceController implements
PreferenceControllerMixin, LifecycleObserver, OnResume, OnDestroy,
ApplicationsState.Callbacks {
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index e0954e5..2a841f9 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -93,14 +93,10 @@
private static final int MENU_STATS_TYPE = Menu.FIRST;
@VisibleForTesting
static final int MENU_HIGH_POWER_APPS = Menu.FIRST + 3;
- @VisibleForTesting
- static final int MENU_TOGGLE_APPS = Menu.FIRST + 4;
private static final int MENU_HELP = Menu.FIRST + 5;
public static final int DEBUG_INFO_LOADER = 3;
@VisibleForTesting
- boolean mShowAllApps = false;
- @VisibleForTesting
PowerGaugePreference mScreenUsagePref;
@VisibleForTesting
PowerGaugePreference mLastFullChargePref;
@@ -221,7 +217,6 @@
mAnomalySparseArray = new SparseArray<>();
restartBatteryInfoLoader();
- restoreSavedInstance(icicle);
}
@Override
@@ -230,12 +225,6 @@
}
@Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- outState.putBoolean(KEY_SHOW_ALL_APPS, mShowAllApps);
- }
-
- @Override
public boolean onPreferenceTreeClick(Preference preference) {
if (KEY_BATTERY_HEADER.equals(preference.getKey())) {
performBatteryHeaderClick();
@@ -284,11 +273,6 @@
menu.add(Menu.NONE, MENU_HIGH_POWER_APPS, Menu.NONE, R.string.high_power_apps);
- if (mPowerFeatureProvider.isPowerAccountingToggleEnabled()) {
- menu.add(Menu.NONE, MENU_TOGGLE_APPS, Menu.NONE,
- mShowAllApps ? R.string.hide_extra_apps : R.string.show_all_apps);
- }
-
super.onCreateOptionsMenu(menu, inflater);
}
@@ -322,25 +306,11 @@
metricsFeatureProvider.action(context,
MetricsEvent.ACTION_SETTINGS_MENU_BATTERY_OPTIMIZATION);
return true;
- case MENU_TOGGLE_APPS:
- mShowAllApps = !mShowAllApps;
- item.setTitle(mShowAllApps ? R.string.hide_extra_apps : R.string.show_all_apps);
- metricsFeatureProvider.action(context,
- MetricsEvent.ACTION_SETTINGS_MENU_BATTERY_APPS_TOGGLE, mShowAllApps);
- restartBatteryStatsLoader(false /* clearHeader */);
- return true;
default:
return super.onOptionsItemSelected(item);
}
}
- @VisibleForTesting
- void restoreSavedInstance(Bundle savedInstance) {
- if (savedInstance != null) {
- mShowAllApps = savedInstance.getBoolean(KEY_SHOW_ALL_APPS, false);
- }
- }
-
private void performBatteryHeaderClick() {
if (mPowerFeatureProvider.isAdvancedUiEnabled()) {
Utils.startWithFragment(getContext(), PowerUsageAdvanced.class.getName(), null,
@@ -375,8 +345,8 @@
final CharSequence timeSequence = Utils.formatRelativeTime(context, lastFullChargeTime,
false);
- mBatteryAppListPreferenceController.refreshAppListGroup(mStatsHelper, mShowAllApps,
- timeSequence);
+ mBatteryAppListPreferenceController.refreshAppListGroup(mStatsHelper,
+ false /* showAllApps */, timeSequence);
}
@VisibleForTesting
diff --git a/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java b/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java
index 1d21c12..0d8cbaf 100644
--- a/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java
+++ b/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java
@@ -34,7 +34,7 @@
import com.android.internal.app.LocalePicker;
import com.android.internal.app.LocaleStore;
-import com.android.settings.CreateShortcut;
+import com.android.settings.shortcut.CreateShortcut;
import com.android.settings.R;
import java.text.NumberFormat;
diff --git a/src/com/android/settings/location/RecentLocationRequestPreferenceController.java b/src/com/android/settings/location/RecentLocationRequestPreferenceController.java
index 8cbe95c..b17d19e 100644
--- a/src/com/android/settings/location/RecentLocationRequestPreferenceController.java
+++ b/src/com/android/settings/location/RecentLocationRequestPreferenceController.java
@@ -20,19 +20,15 @@
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceCategory;
import android.support.v7.preference.PreferenceScreen;
-import android.util.FeatureFlagUtils;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
-import com.android.settings.applications.InstalledAppDetails;
import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
-import com.android.settings.core.FeatureFlags;
import com.android.settings.widget.AppPreference;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.location.RecentLocationApps;
import java.util.ArrayList;
-import java.util.Comparator;
import java.util.List;
public class RecentLocationRequestPreferenceController extends LocationBasePreferenceController {
@@ -60,19 +56,11 @@
public boolean onPreferenceClick(Preference preference) {
// start new fragment to display extended information
final Bundle args = new Bundle();
- if (FeatureFlagUtils.isEnabled(mFragment.getActivity(), FeatureFlags.APP_INFO_V2)) {
- args.putString(AppInfoDashboardFragment.ARG_PACKAGE_NAME, mPackage);
- ((SettingsActivity) mFragment.getActivity()).startPreferencePanelAsUser(
- mFragment,
- AppInfoDashboardFragment.class.getName(), args,
- R.string.application_info_label, null, mUserHandle);
- } else {
- args.putString(InstalledAppDetails.ARG_PACKAGE_NAME, mPackage);
- ((SettingsActivity) mFragment.getActivity()).startPreferencePanelAsUser(
- mFragment,
- InstalledAppDetails.class.getName(), args,
- R.string.application_info_label, null, mUserHandle);
- }
+ args.putString(AppInfoDashboardFragment.ARG_PACKAGE_NAME, mPackage);
+ ((SettingsActivity) mFragment.getActivity()).startPreferencePanelAsUser(
+ mFragment,
+ AppInfoDashboardFragment.class.getName(), args,
+ R.string.application_info_label, null, mUserHandle);
return true;
}
}
diff --git a/src/com/android/settings/password/ManagedLockPasswordProvider.java b/src/com/android/settings/password/ManagedLockPasswordProvider.java
index 82135cf..5786a5a 100644
--- a/src/com/android/settings/password/ManagedLockPasswordProvider.java
+++ b/src/com/android/settings/password/ManagedLockPasswordProvider.java
@@ -55,17 +55,6 @@
CharSequence getPickerOptionTitle(boolean forFingerprint) { return ""; }
/**
- * Gets resource id of the lock screen preference that should be displayed in security settings
- * if the current password quality is set to
- * {@link android.app.admin.DevicePolicyManager#PASSWORD_QUALITY_MANAGED}.
- * @param forProfile Whether the settings are shown for a user profile rather than a user.
- */
- public int getResIdForLockUnlockScreen(boolean forProfile) {
- return forProfile ? R.xml.security_settings_password_profile
- : R.xml.security_settings_password;
- }
-
- /**
* Creates intent that should be launched when user chooses managed password in the lock
* settings picker.
* @param requirePasswordToDecrypt Whether a password is needed to decrypt the user.
diff --git a/src/com/android/settings/search/SearchIndexableResourcesImpl.java b/src/com/android/settings/search/SearchIndexableResourcesImpl.java
index faa4b8c..38dc15d 100644
--- a/src/com/android/settings/search/SearchIndexableResourcesImpl.java
+++ b/src/com/android/settings/search/SearchIndexableResourcesImpl.java
@@ -21,7 +21,6 @@
import com.android.settings.DateTimeSettings;
import com.android.settings.DisplaySettings;
import com.android.settings.LegalSettings;
-import com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment;
import com.android.settings.accessibility.AccessibilitySettings;
import com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment;
import com.android.settings.accessibility.MagnificationPreferenceFragment;
@@ -42,6 +41,7 @@
import com.android.settings.deviceinfo.DeviceInfoSettings;
import com.android.settings.deviceinfo.StorageDashboardFragment;
import com.android.settings.deviceinfo.StorageSettings;
+import com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment;
import com.android.settings.display.AmbientDisplaySettings;
import com.android.settings.display.NightDisplaySettings;
import com.android.settings.display.ScreenZoomSettings;
@@ -75,7 +75,7 @@
import com.android.settings.security.EncryptionAndCredential;
import com.android.settings.security.LockscreenDashboardFragment;
import com.android.settings.security.ScreenPinningSettings;
-import com.android.settings.security.SecuritySettingsV2;
+import com.android.settings.security.SecuritySettings;
import com.android.settings.security.screenlock.ScreenLockSettings;
import com.android.settings.sim.SimSettings;
import com.android.settings.support.SupportDashboardActivity;
@@ -132,7 +132,7 @@
addIndex(LanguageAndInputSettings.class);
addIndex(LocationSettings.class);
addIndex(ScanningSettings.class);
- addIndex(SecuritySettingsV2.class);
+ addIndex(SecuritySettings.class);
addIndex(ScreenLockSettings.class);
addIndex(EncryptionAndCredential.class);
addIndex(ScreenPinningSettings.class);
diff --git a/src/com/android/settings/security/ChangeProfileScreenLockPreferenceController.java b/src/com/android/settings/security/ChangeProfileScreenLockPreferenceController.java
index 9a33ec3..91c4410 100644
--- a/src/com/android/settings/security/ChangeProfileScreenLockPreferenceController.java
+++ b/src/com/android/settings/security/ChangeProfileScreenLockPreferenceController.java
@@ -16,8 +16,7 @@
package com.android.settings.security;
-import static com.android.settings.security
- .SecuritySettingsV2.SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE;
+import static com.android.settings.security.SecuritySettings.SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
@@ -37,7 +36,7 @@
private static final String KEY_UNLOCK_SET_OR_CHANGE_PROFILE = "unlock_set_or_change_profile";
public ChangeProfileScreenLockPreferenceController(Context context,
- SecuritySettingsV2 host) {
+ SecuritySettings host) {
super(context, host);
}
diff --git a/src/com/android/settings/security/ChangeScreenLockPreferenceController.java b/src/com/android/settings/security/ChangeScreenLockPreferenceController.java
index fdb9349..10143d2 100644
--- a/src/com/android/settings/security/ChangeScreenLockPreferenceController.java
+++ b/src/com/android/settings/security/ChangeScreenLockPreferenceController.java
@@ -16,7 +16,7 @@
package com.android.settings.security;
-import static com.android.settings.security.SecuritySettingsV2.SET_OR_CHANGE_LOCK_METHOD_REQUEST;
+import static com.android.settings.security.SecuritySettings.SET_OR_CHANGE_LOCK_METHOD_REQUEST;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
@@ -45,7 +45,7 @@
private static final String KEY_UNLOCK_SET_OR_CHANGE = "unlock_set_or_change";
protected final DevicePolicyManager mDPM;
- protected final SecuritySettingsV2 mHost;
+ protected final SecuritySettings mHost;
protected final UserManager mUm;
protected final LockPatternUtils mLockPatternUtils;
@@ -54,7 +54,7 @@
protected RestrictedPreference mPreference;
- public ChangeScreenLockPreferenceController(Context context, SecuritySettingsV2 host) {
+ public ChangeScreenLockPreferenceController(Context context, SecuritySettings host) {
super(context);
mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
mDPM = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
diff --git a/src/com/android/settings/security/LockUnificationPreferenceController.java b/src/com/android/settings/security/LockUnificationPreferenceController.java
index 5486e29..abbf2f4 100644
--- a/src/com/android/settings/security/LockUnificationPreferenceController.java
+++ b/src/com/android/settings/security/LockUnificationPreferenceController.java
@@ -16,11 +16,10 @@
package com.android.settings.security;
-import static com.android.settings.security
- .SecuritySettingsV2.SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE;
-import static com.android.settings.security.SecuritySettingsV2.UNIFY_LOCK_CONFIRM_DEVICE_REQUEST;
-import static com.android.settings.security.SecuritySettingsV2.UNIFY_LOCK_CONFIRM_PROFILE_REQUEST;
-import static com.android.settings.security.SecuritySettingsV2.UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST;
+import static com.android.settings.security.SecuritySettings.SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE;
+import static com.android.settings.security.SecuritySettings.UNIFY_LOCK_CONFIRM_DEVICE_REQUEST;
+import static com.android.settings.security.SecuritySettings.UNIFY_LOCK_CONFIRM_PROFILE_REQUEST;
+import static com.android.settings.security.SecuritySettings.UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST;
import android.app.Activity;
import android.app.admin.DevicePolicyManager;
@@ -53,7 +52,7 @@
private final UserManager mUm;
private final LockPatternUtils mLockPatternUtils;
private final int mProfileChallengeUserId;
- private final SecuritySettingsV2 mHost;
+ private final SecuritySettings mHost;
private RestrictedSwitchPreference mUnifyProfile;
@@ -67,7 +66,7 @@
mUnifyProfile = (RestrictedSwitchPreference) screen.findPreference(KEY_UNIFICATION);
}
- public LockUnificationPreferenceController(Context context, SecuritySettingsV2 host) {
+ public LockUnificationPreferenceController(Context context, SecuritySettings host) {
super(context);
mHost = host;
mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
@@ -212,7 +211,7 @@
mCurrentProfilePassword);
mHost.startFragment(mHost, ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
R.string.lock_settings_picker_title,
- SecuritySettingsV2.SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
+ SecuritySettings.SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
}
}
diff --git a/src/com/android/settings/security/SecurityFeatureProvider.java b/src/com/android/settings/security/SecurityFeatureProvider.java
index 35ff586..d533d1e 100644
--- a/src/com/android/settings/security/SecurityFeatureProvider.java
+++ b/src/com/android/settings/security/SecurityFeatureProvider.java
@@ -17,26 +17,14 @@
package com.android.settings.security;
import android.content.Context;
-import android.support.v7.preference.PreferenceScreen;
-import android.util.FeatureFlagUtils;
import com.android.internal.widget.LockPatternUtils;
-import com.android.settings.core.FeatureFlags;
import com.android.settings.security.trustagent.TrustAgentManager;
-import com.android.settingslib.drawer.DashboardCategory;
/** FeatureProvider for security. */
public interface SecurityFeatureProvider {
- default boolean isSecuritySettingsV2Enabled(Context context) {
- return FeatureFlagUtils.isEnabled(context, FeatureFlags.SECURITY_SETTINGS_V2);
- }
-
- /** Update preferences with data from associated tiles. */
- void updatePreferences(Context context, PreferenceScreen preferenceScreen,
- DashboardCategory dashboardCategory);
-
/** Returns the {@link TrustAgentManager} bound to this {@link SecurityFeatureProvider}. */
TrustAgentManager getTrustAgentManager();
diff --git a/src/com/android/settings/security/SecurityFeatureProviderImpl.java b/src/com/android/settings/security/SecurityFeatureProviderImpl.java
index 70b1ec1..56a0884 100644
--- a/src/com/android/settings/security/SecurityFeatureProviderImpl.java
+++ b/src/com/android/settings/security/SecurityFeatureProviderImpl.java
@@ -17,28 +17,9 @@
package com.android.settings.security;
import android.content.Context;
-import android.content.IContentProvider;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-import android.support.annotation.VisibleForTesting;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.Pair;
import com.android.internal.widget.LockPatternUtils;
-import com.android.settings.R;
import com.android.settings.security.trustagent.TrustAgentManager;
-import com.android.settingslib.drawer.DashboardCategory;
-import com.android.settingslib.drawer.Tile;
-import com.android.settingslib.drawer.TileUtils;
-import com.android.settingslib.utils.ThreadUtils;
-
-import java.util.Map;
-import java.util.TreeMap;
/** Implementation for {@code SecurityFeatureProvider}. */
public class SecurityFeatureProviderImpl implements SecurityFeatureProvider {
@@ -46,150 +27,6 @@
private TrustAgentManager mTrustAgentManager;
private LockPatternUtils mLockPatternUtils;
- @VisibleForTesting
- static final Drawable DEFAULT_ICON = null;
-
- @VisibleForTesting
- static Map<String, Pair<String, Integer>> sIconCache = new TreeMap<>();
-
- @VisibleForTesting
- static Map<String, String> sSummaryCache = new TreeMap<>();
-
- /** 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.
- ThreadUtils.postOnBackgroundThread(() ->
- updatePreferencesToRunOnWorkerThread(context, preferenceScreen, dashboardCategory));
- }
-
- @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;
- }
- // Either remove an icon by replacing them with nothing, or use the cached one since
- // there is a delay in fetching the injected icon, and we don't want an inappropriate
- // icon to be displayed while waiting for the injected icon.
- final String iconUri =
- tile.metaData.getString(TileUtils.META_DATA_PREFERENCE_ICON_URI, null);
- Drawable drawable = DEFAULT_ICON;
- if ((iconUri != null) && sIconCache.containsKey(iconUri)) {
- Pair<String, Integer> icon = sIconCache.get(iconUri);
- try {
- drawable = context.getPackageManager()
- .getResourcesForApplication(icon.first /* package name */)
- .getDrawable(icon.second /* res id */,
- context.getTheme());
- } catch (PackageManager.NameNotFoundException e) {
- // Ignore and just load the default icon.
- }
- }
- matchingPref.setIcon(drawable);
- // Either reserve room for the summary or load the cached one. This prevents the title
- // from shifting when the final summary is injected.
- final String summaryUri =
- tile.metaData.getString(TileUtils.META_DATA_PREFERENCE_SUMMARY_URI, null);
- String summary = context.getString(R.string.summary_placeholder);
- if ((summaryUri != null) && sSummaryCache.containsKey(summaryUri)) {
- summary = sSummaryCache.get(summaryUri);
- }
- matchingPref.setSummary(summary);
- }
- }
-
- @VisibleForTesting
- void updatePreferencesToRunOnWorkerThread(Context context, PreferenceScreen preferenceScreen,
- DashboardCategory dashboardCategory) {
-
- int tilesCount = (dashboardCategory != null) ? dashboardCategory.getTilesCount() : 0;
- Map<String, IContentProvider> providerMap = new ArrayMap<>();
- 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;
- }
- // Check if the tile has content providers for dynamically updatable content.
- final String iconUri =
- tile.metaData.getString(TileUtils.META_DATA_PREFERENCE_ICON_URI, null);
- final String summaryUri =
- tile.metaData.getString(TileUtils.META_DATA_PREFERENCE_SUMMARY_URI, null);
- if (!TextUtils.isEmpty(iconUri)) {
- String packageName = null;
- if (tile.intent != null) {
- Intent intent = tile.intent;
- if (!TextUtils.isEmpty(intent.getPackage())) {
- packageName = intent.getPackage();
- } else if (intent.getComponent() != null) {
- packageName = intent.getComponent().getPackageName();
- }
- }
- Pair<String, Integer> icon =
- TileUtils.getIconFromUri(context, packageName, iconUri, providerMap);
- if (icon != null) {
- sIconCache.put(iconUri, icon);
- // Icon is only returned if the icon belongs to Settings or the target app.
- // setIcon must be called on the UI thread.
- ThreadUtils.postOnMainThread(() -> {
- try {
- matchingPref.setIcon(context.getPackageManager()
- .getResourcesForApplication(icon.first /* package name */)
- .getDrawable(icon.second /* res id */,
- context.getTheme()));
- } catch (PackageManager.NameNotFoundException
- | Resources.NotFoundException e) {
- // Intentionally ignored. If icon resources cannot be found, do not
- // update.
- }
- });
- }
- }
- if (!TextUtils.isEmpty(summaryUri)) {
- String summary = TileUtils.getTextFromUri(context, summaryUri, providerMap,
- TileUtils.META_DATA_PREFERENCE_SUMMARY);
- sSummaryCache.put(summaryUri, summary);
- // setSummary must be called on UI thread.
- ThreadUtils.postOnMainThread(() -> {
- // Only update the summary if it has actually changed.
- if (summary == null) {
- if (matchingPref.getSummary() != null) {
- matchingPref.setSummary(summary);
- }
- } else if (!summary.equals(matchingPref.getSummary())) {
- matchingPref.setSummary(summary);
- }
- });
- }
- }
- }
-
@Override
public TrustAgentManager getTrustAgentManager() {
if (mTrustAgentManager == null) {
diff --git a/src/com/android/settings/security/SecuritySettings.java b/src/com/android/settings/security/SecuritySettings.java
index f099b44..df3b455 100644
--- a/src/com/android/settings/security/SecuritySettings.java
+++ b/src/com/android/settings/security/SecuritySettings.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 The Android Open Source Project
+ * Copyright (C) 2018 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.
@@ -13,744 +13,62 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package com.android.settings.security;
-import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import static com.android.settings.security.EncryptionStatusPreferenceController
+ .PREF_KEY_ENCRYPTION_SECURITY_PAGE;
import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.FragmentManager;
-import android.app.admin.DevicePolicyManager;
import android.content.Context;
-import android.content.DialogInterface;
import android.content.Intent;
-import android.content.res.Resources;
import android.hardware.fingerprint.FingerprintManager;
-import android.os.Bundle;
-import android.os.PersistableBundle;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.os.storage.StorageManager;
import android.provider.SearchIndexableResource;
-import android.provider.Settings;
-import android.support.annotation.VisibleForTesting;
-import android.support.v14.preference.SwitchPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.Preference.OnPreferenceChangeListener;
-import android.support.v7.preference.PreferenceGroup;
-import android.support.v7.preference.PreferenceScreen;
-import android.telephony.CarrierConfigManager;
-import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.Utils;
-import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
-import com.android.settings.dashboard.DashboardFeatureProvider;
+import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.enterprise.EnterprisePrivacyPreferenceController;
import com.android.settings.enterprise.ManageDeviceAdminPreferenceController;
-import com.android.settings.fingerprint.FingerprintSettings;
+import com.android.settings.fingerprint.FingerprintProfileStatusPreferenceController;
+import com.android.settings.fingerprint.FingerprintStatusPreferenceController;
import com.android.settings.location.LocationPreferenceController;
-import com.android.settings.notification.LockScreenNotificationPreferenceController;
-import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment;
-import com.android.settings.password.ChooseLockSettingsHelper;
-import com.android.settings.password.ManagedLockPasswordProvider;
import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
-import com.android.settings.search.SearchIndexableRaw;
-import com.android.settings.security.screenlock.ScreenLockSettings;
-import com.android.settings.security.trustagent.TrustAgentManager;
-import com.android.settings.security.trustagent.TrustAgentManager.TrustAgentComponentInfo;
-import com.android.settings.widget.GearPreference;
-import com.android.settingslib.RestrictedLockUtils;
-import com.android.settingslib.RestrictedPreference;
-import com.android.settingslib.RestrictedSwitchPreference;
-import com.android.settingslib.drawer.CategoryKey;
+import com.android.settings.security.screenlock.LockScreenPreferenceController;
+import com.android.settings.security.trustagent.ManageTrustAgentsPreferenceController;
+import com.android.settings.security.trustagent.TrustAgentListPreferenceController;
+import com.android.settings.widget.PreferenceCategoryController;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
import java.util.ArrayList;
import java.util.List;
-/**
- * Gesture lock pattern settings.
- */
-public class SecuritySettings extends SettingsPreferenceFragment
- implements OnPreferenceChangeListener, Indexable,
- GearPreference.OnGearClickListener {
+public class SecuritySettings extends DashboardFragment {
private static final String TAG = "SecuritySettings";
- private static final String TRUST_AGENT_CLICK_INTENT = "trust_agent_click_intent";
-
- // Lock Settings
- private static final String KEY_UNLOCK_SET_OR_CHANGE = "unlock_set_or_change";
- private static final String KEY_UNLOCK_SET_OR_CHANGE_PROFILE = "unlock_set_or_change_profile";
- private static final String KEY_VISIBLE_PATTERN_PROFILE = "visiblepattern_profile";
- private static final String KEY_SECURITY_CATEGORY = "security_category";
- @VisibleForTesting
- static final String KEY_MANAGE_TRUST_AGENTS = "manage_trust_agents";
- private static final String KEY_UNIFICATION = "unification";
- @VisibleForTesting
- static final String KEY_LOCKSCREEN_PREFERENCES = "lockscreen_preferences";
- private static final String KEY_ENCRYPTION_AND_CREDENTIALS = "encryption_and_credential";
- private static final String KEY_LOCATION_SCANNING = "location_scanning";
- private static final String KEY_LOCATION = "location";
-
- private static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST = 123;
- private static final int CHANGE_TRUST_AGENT_SETTINGS = 126;
- private static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE = 127;
- private static final int UNIFY_LOCK_CONFIRM_DEVICE_REQUEST = 128;
- private static final int UNIFY_LOCK_CONFIRM_PROFILE_REQUEST = 129;
- private static final int UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST = 130;
- private static final String TAG_UNIFICATION_DIALOG = "unification_dialog";
-
- // Misc Settings
- private static final String KEY_SIM_LOCK = "sim_lock_settings";
- private static final String KEY_SHOW_PASSWORD = "show_password";
- private static final String KEY_TRUST_AGENT = "trust_agent";
- private static final String KEY_SCREEN_PINNING = "screen_pinning_settings";
-
- // Security status
- private static final String KEY_SECURITY_STATUS = "security_status";
- private static final String SECURITY_STATUS_KEY_PREFIX = "security_status_";
-
- // Device management settings
- private static final String KEY_ENTERPRISE_PRIVACY = "enterprise_privacy";
- private static final String KEY_MANAGE_DEVICE_ADMIN = "manage_device_admin";
-
- // These switch preferences need special handling since they're not all stored in Settings.
- private static final String SWITCH_PREFERENCE_KEYS[] = {
- KEY_SHOW_PASSWORD, KEY_UNIFICATION, KEY_VISIBLE_PATTERN_PROFILE
- };
-
- private static final int MY_USER_ID = UserHandle.myUserId();
-
- private DashboardFeatureProvider mDashboardFeatureProvider;
- private DevicePolicyManager mDPM;
- private SecurityFeatureProvider mSecurityFeatureProvider;
- private TrustAgentManager mTrustAgentManager;
- private SubscriptionManager mSubscriptionManager;
- private UserManager mUm;
-
- private ChooseLockSettingsHelper mChooseLockSettingsHelper;
- private LockPatternUtils mLockPatternUtils;
- private ManagedLockPasswordProvider mManagedPasswordProvider;
-
- private SwitchPreference mVisiblePatternProfile;
- private RestrictedSwitchPreference mUnifyProfile;
-
- private SwitchPreference mShowPassword;
-
- private boolean mIsAdmin;
-
- private Intent mTrustAgentClickIntent;
-
- private int mProfileChallengeUserId;
-
- private String mCurrentDevicePassword;
- private String mCurrentProfilePassword;
-
- private LocationPreferenceController mLocationcontroller;
- private ManageDeviceAdminPreferenceController mManageDeviceAdminPreferenceController;
- private EnterprisePrivacyPreferenceController mEnterprisePrivacyPreferenceController;
+ public static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST = 123;
+ public static final int CHANGE_TRUST_AGENT_SETTINGS = 126;
+ public static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE = 127;
+ public static final int UNIFY_LOCK_CONFIRM_DEVICE_REQUEST = 128;
+ public static final int UNIFY_LOCK_CONFIRM_PROFILE_REQUEST = 129;
+ public static final int UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST = 130;
@Override
public int getMetricsCategory() {
- return MetricsEvent.SECURITY;
+ return MetricsProto.MetricsEvent.SECURITY;
}
@Override
- public void onAttach(Context context) {
- super.onAttach(context);
- mLocationcontroller = new LocationPreferenceController(context, getLifecycle());
+ protected int getPreferenceScreenResId() {
+ return R.xml.security_dashboard_settings;
}
@Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- final Activity activity = getActivity();
-
- mSubscriptionManager = SubscriptionManager.from(activity);
-
- mLockPatternUtils = new LockPatternUtils(activity);
-
- mManagedPasswordProvider = ManagedLockPasswordProvider.get(activity, MY_USER_ID);
-
- mDPM = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE);
-
- mUm = UserManager.get(activity);
-
- mChooseLockSettingsHelper = new ChooseLockSettingsHelper(activity);
-
- mDashboardFeatureProvider = FeatureFactory.getFactory(activity)
- .getDashboardFeatureProvider(activity);
-
- mSecurityFeatureProvider = FeatureFactory.getFactory(activity).getSecurityFeatureProvider();
-
- mTrustAgentManager = mSecurityFeatureProvider.getTrustAgentManager();
-
- if (savedInstanceState != null
- && savedInstanceState.containsKey(TRUST_AGENT_CLICK_INTENT)) {
- mTrustAgentClickIntent = savedInstanceState.getParcelable(TRUST_AGENT_CLICK_INTENT);
- }
-
- mManageDeviceAdminPreferenceController
- = new ManageDeviceAdminPreferenceController(activity);
- mEnterprisePrivacyPreferenceController
- = new EnterprisePrivacyPreferenceController(activity);
- }
-
- private static int getResIdForLockUnlockScreen(LockPatternUtils lockPatternUtils,
- ManagedLockPasswordProvider managedPasswordProvider, int userId) {
- final boolean isMyUser = userId == MY_USER_ID;
- int resid = 0;
- if (!lockPatternUtils.isSecure(userId)) {
- if (!isMyUser) {
- resid = R.xml.security_settings_lockscreen_profile;
- } else if (lockPatternUtils.isLockScreenDisabled(userId)) {
- resid = R.xml.security_settings_lockscreen;
- } else {
- resid = R.xml.security_settings_chooser;
- }
- } else {
- switch (lockPatternUtils.getKeyguardStoredPasswordQuality(userId)) {
- case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
- resid = isMyUser ? R.xml.security_settings_pattern
- : R.xml.security_settings_pattern_profile;
- break;
- case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
- case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
- resid = isMyUser ? R.xml.security_settings_pin
- : R.xml.security_settings_pin_profile;
- break;
- case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
- case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
- case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
- resid = isMyUser ? R.xml.security_settings_password
- : R.xml.security_settings_password_profile;
- break;
- case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
- resid = managedPasswordProvider.getResIdForLockUnlockScreen(!isMyUser);
- break;
- }
- }
- return resid;
- }
-
- /**
- * Important!
- *
- * Don't forget to update the SecuritySearchIndexProvider if you are doing any change in the
- * logic or adding/removing preferences here.
- */
- private PreferenceScreen createPreferenceHierarchy() {
- PreferenceScreen root = getPreferenceScreen();
- if (root != null) {
- root.removeAll();
- }
- addPreferencesFromResource(R.xml.security_settings);
- root = getPreferenceScreen();
-
- // Add category for security status
- addPreferencesFromResource(R.xml.security_settings_status);
-
- // Add options for lock/unlock screen
- final int resid = getResIdForLockUnlockScreen(mLockPatternUtils,
- mManagedPasswordProvider, MY_USER_ID);
- addPreferencesFromResource(resid);
-
- // DO or PO installed in the user may disallow to change password.
- disableIfPasswordQualityManaged(KEY_UNLOCK_SET_OR_CHANGE, MY_USER_ID);
-
- mProfileChallengeUserId = Utils.getManagedProfileId(mUm, MY_USER_ID);
- if (mProfileChallengeUserId != UserHandle.USER_NULL
- && mLockPatternUtils.isSeparateProfileChallengeAllowed(mProfileChallengeUserId)) {
- addPreferencesFromResource(R.xml.security_settings_profile);
- addPreferencesFromResource(R.xml.security_settings_unification);
- final int profileResid = getResIdForLockUnlockScreen(mLockPatternUtils,
- mManagedPasswordProvider, mProfileChallengeUserId);
- addPreferencesFromResource(profileResid);
- maybeAddFingerprintPreference(root, mProfileChallengeUserId);
- if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId)) {
- final Preference lockPreference =
- root.findPreference(KEY_UNLOCK_SET_OR_CHANGE_PROFILE);
- final String summary = getContext().getString(
- R.string.lock_settings_profile_unified_summary);
- lockPreference.setSummary(summary);
- lockPreference.setEnabled(false);
- // PO may disallow to change password for the profile, but screen lock and managed
- // profile's lock is the same. Disable main "Screen lock" menu.
- disableIfPasswordQualityManaged(KEY_UNLOCK_SET_OR_CHANGE, mProfileChallengeUserId);
- } else {
- // PO may disallow to change profile password, and the profile's password is
- // separated from screen lock password. Disable profile specific "Screen lock" menu.
- disableIfPasswordQualityManaged(KEY_UNLOCK_SET_OR_CHANGE_PROFILE,
- mProfileChallengeUserId);
- }
- }
-
- Preference unlockSetOrChange = findPreference(KEY_UNLOCK_SET_OR_CHANGE);
- if (unlockSetOrChange instanceof GearPreference) {
- ((GearPreference) unlockSetOrChange).setOnGearClickListener(this);
- }
-
- mIsAdmin = mUm.isAdminUser();
-
- // Fingerprint and trust agents
- int numberOfTrustAgent = 0;
- PreferenceGroup securityCategory = (PreferenceGroup)
- root.findPreference(KEY_SECURITY_CATEGORY);
- if (securityCategory != null) {
- maybeAddFingerprintPreference(securityCategory, UserHandle.myUserId());
- numberOfTrustAgent = addTrustAgentSettings(securityCategory);
- setLockscreenPreferencesSummary(securityCategory);
- }
-
- mVisiblePatternProfile =
- (SwitchPreference) root.findPreference(KEY_VISIBLE_PATTERN_PROFILE);
- mUnifyProfile = (RestrictedSwitchPreference) root.findPreference(KEY_UNIFICATION);
-
- // Append the rest of the settings
- addPreferencesFromResource(R.xml.security_settings_misc);
-
- // Do not display SIM lock for devices without an Icc card
- TelephonyManager tm = TelephonyManager.getDefault();
- CarrierConfigManager cfgMgr = (CarrierConfigManager)
- getActivity().getSystemService(Context.CARRIER_CONFIG_SERVICE);
- PersistableBundle b = cfgMgr.getConfig();
- if (!mIsAdmin || !isSimIccReady() ||
- b.getBoolean(CarrierConfigManager.KEY_HIDE_SIM_LOCK_SETTINGS_BOOL)) {
- root.removePreference(root.findPreference(KEY_SIM_LOCK));
- } else {
- // Disable SIM lock if there is no ready SIM card.
- root.findPreference(KEY_SIM_LOCK).setEnabled(isSimReady());
- }
- if (Settings.System.getInt(getContentResolver(),
- Settings.System.LOCK_TO_APP_ENABLED, 0) != 0) {
- root.findPreference(KEY_SCREEN_PINNING).setSummary(
- getResources().getString(R.string.switch_on_text));
- }
-
- // Encryption status of device
- if (LockPatternUtils.isDeviceEncryptionEnabled()) {
- root.findPreference(KEY_ENCRYPTION_AND_CREDENTIALS).setSummary(
- R.string.encryption_and_credential_settings_summary);
- } else {
- root.findPreference(KEY_ENCRYPTION_AND_CREDENTIALS).setSummary(
- R.string.summary_placeholder);
- }
-
- // Show password
- mShowPassword = (SwitchPreference) root.findPreference(KEY_SHOW_PASSWORD);
-
- // Credential storage
- final UserManager um = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
-
- // Advanced Security features
- initTrustAgentPreference(root, numberOfTrustAgent);
-
- PreferenceGroup securityStatusPreferenceGroup =
- (PreferenceGroup) root.findPreference(KEY_SECURITY_STATUS);
- final List<Preference> tilePrefs = mDashboardFeatureProvider.getPreferencesForCategory(
- getActivity(), getPrefContext(), getMetricsCategory(),
- CategoryKey.CATEGORY_SECURITY);
- int numSecurityStatusPrefs = 0;
- if (tilePrefs != null && !tilePrefs.isEmpty()) {
- for (Preference preference : tilePrefs) {
- if (!TextUtils.isEmpty(preference.getKey())
- && preference.getKey().startsWith(SECURITY_STATUS_KEY_PREFIX)) {
- // Injected security status settings are placed under the Security status
- // category.
- securityStatusPreferenceGroup.addPreference(preference);
- numSecurityStatusPrefs++;
- } else {
- // Other injected settings are placed under the Security preference screen.
- root.addPreference(preference);
- }
- }
- }
-
- if (numSecurityStatusPrefs == 0) {
- root.removePreference(securityStatusPreferenceGroup);
- } else if (numSecurityStatusPrefs > 0) {
- // Update preference data with tile data. Security feature provider only updates the
- // data if it actually needs to be changed.
- mSecurityFeatureProvider.updatePreferences(getActivity(), root,
- mDashboardFeatureProvider.getTilesForCategory(
- CategoryKey.CATEGORY_SECURITY));
- }
-
- for (int i = 0; i < SWITCH_PREFERENCE_KEYS.length; i++) {
- final Preference pref = findPreference(SWITCH_PREFERENCE_KEYS[i]);
- if (pref != null) pref.setOnPreferenceChangeListener(this);
- }
-
- mLocationcontroller.displayPreference(root);
- mManageDeviceAdminPreferenceController.updateState(
- root.findPreference(KEY_MANAGE_DEVICE_ADMIN));
- mEnterprisePrivacyPreferenceController.displayPreference(root);
- final Preference enterprisePrivacyPreference = root.findPreference(
- mEnterprisePrivacyPreferenceController.getPreferenceKey());
- mEnterprisePrivacyPreferenceController.updateState(enterprisePrivacyPreference);
-
- return root;
- }
-
- @VisibleForTesting
- void initTrustAgentPreference(PreferenceScreen root, int numberOfTrustAgent) {
- Preference manageAgents = root.findPreference(KEY_MANAGE_TRUST_AGENTS);
- if (manageAgents != null) {
- if (!mLockPatternUtils.isSecure(MY_USER_ID)) {
- manageAgents.setEnabled(false);
- manageAgents.setSummary(R.string.disabled_because_no_backup_security);
- } else if (numberOfTrustAgent > 0) {
- manageAgents.setSummary(getActivity().getResources().getQuantityString(
- R.plurals.manage_trust_agents_summary_on,
- numberOfTrustAgent, numberOfTrustAgent));
- } else {
- manageAgents.setSummary(R.string.manage_trust_agents_summary);
- }
- }
- }
-
- @VisibleForTesting
- void setLockscreenPreferencesSummary(PreferenceGroup group) {
- final Preference lockscreenPreferences = group.findPreference(KEY_LOCKSCREEN_PREFERENCES);
- if (lockscreenPreferences != null) {
- lockscreenPreferences.setSummary(
- LockScreenNotificationPreferenceController.getSummaryResource(getContext()));
- }
- }
-
- /*
- * Sets the preference as disabled by admin if PASSWORD_QUALITY_MANAGED is set.
- * The preference must be a RestrictedPreference.
- */
- private void disableIfPasswordQualityManaged(String preferenceKey, int userId) {
- final EnforcedAdmin admin = RestrictedLockUtils.checkIfPasswordQualityIsSet(
- getActivity(), userId);
- if (admin != null && mDPM.getPasswordQuality(admin.component, userId) ==
- DevicePolicyManager.PASSWORD_QUALITY_MANAGED) {
- final RestrictedPreference pref =
- (RestrictedPreference) getPreferenceScreen().findPreference(preferenceKey);
- pref.setDisabledByAdmin(admin);
- }
- }
-
- private void maybeAddFingerprintPreference(PreferenceGroup securityCategory, int userId) {
- Preference fingerprintPreference =
- FingerprintSettings.getFingerprintPreferenceForUser(
- securityCategory.getContext(), userId);
- if (fingerprintPreference != null) {
- securityCategory.addPreference(fingerprintPreference);
- }
- }
-
- // Return the number of trust agents being added
- private int addTrustAgentSettings(PreferenceGroup securityCategory) {
- final boolean hasSecurity = mLockPatternUtils.isSecure(MY_USER_ID);
- final List<TrustAgentComponentInfo> agents = mTrustAgentManager.getActiveTrustAgents(
- getActivity(), mLockPatternUtils);
- for (TrustAgentComponentInfo agent : agents) {
- final RestrictedPreference trustAgentPreference =
- new RestrictedPreference(securityCategory.getContext());
- trustAgentPreference.setKey(KEY_TRUST_AGENT);
- trustAgentPreference.setTitle(agent.title);
- trustAgentPreference.setSummary(agent.summary);
- // Create intent for this preference.
- Intent intent = new Intent();
- intent.setComponent(agent.componentName);
- intent.setAction(Intent.ACTION_MAIN);
- trustAgentPreference.setIntent(intent);
- // Add preference to the settings menu.
- securityCategory.addPreference(trustAgentPreference);
-
- trustAgentPreference.setDisabledByAdmin(agent.admin);
- if (!trustAgentPreference.isDisabledByAdmin() && !hasSecurity) {
- trustAgentPreference.setEnabled(false);
- trustAgentPreference.setSummary(R.string.disabled_because_no_backup_security);
- }
- }
- return agents.size();
- }
-
- /* Return true if a there is a Slot that has Icc.
- */
- private boolean isSimIccReady() {
- TelephonyManager tm = TelephonyManager.getDefault();
- final List<SubscriptionInfo> subInfoList =
- mSubscriptionManager.getActiveSubscriptionInfoList();
-
- if (subInfoList != null) {
- for (SubscriptionInfo subInfo : subInfoList) {
- if (tm.hasIccCard(subInfo.getSimSlotIndex())) {
- return true;
- }
- }
- }
-
- return false;
- }
-
- /* Return true if a SIM is ready for locking.
- * TODO: consider adding to TelephonyManager or SubscritpionManasger.
- */
- private boolean isSimReady() {
- int simState = TelephonyManager.SIM_STATE_UNKNOWN;
- final List<SubscriptionInfo> subInfoList =
- mSubscriptionManager.getActiveSubscriptionInfoList();
- if (subInfoList != null) {
- for (SubscriptionInfo subInfo : subInfoList) {
- simState = TelephonyManager.getDefault().getSimState(subInfo.getSimSlotIndex());
- if((simState != TelephonyManager.SIM_STATE_ABSENT) &&
- (simState != TelephonyManager.SIM_STATE_UNKNOWN)){
- return true;
- }
- }
- }
- return false;
- }
-
- @Override
- public void onGearClick(GearPreference p) {
- if (KEY_UNLOCK_SET_OR_CHANGE.equals(p.getKey())) {
- startFragment(this, ScreenLockSettings.class.getName(), 0, 0, null);
- }
- }
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- if (mTrustAgentClickIntent != null) {
- outState.putParcelable(TRUST_AGENT_CLICK_INTENT, mTrustAgentClickIntent);
- }
- }
-
- @Override
- public void onResume() {
- super.onResume();
-
- // Make sure we reload the preference hierarchy since some of these settings
- // depend on others...
- createPreferenceHierarchy();
-
- if (mVisiblePatternProfile != null) {
- mVisiblePatternProfile.setChecked(mLockPatternUtils.isVisiblePatternEnabled(
- mProfileChallengeUserId));
- }
-
- updateUnificationPreference();
-
- if (mShowPassword != null) {
- mShowPassword.setChecked(Settings.System.getInt(getContentResolver(),
- Settings.System.TEXT_SHOW_PASSWORD, 1) != 0);
- }
-
- mLocationcontroller.updateSummary();
- }
-
- @VisibleForTesting
- void updateUnificationPreference() {
- if (mUnifyProfile != null) {
- final boolean separate =
- mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId);
- mUnifyProfile.setChecked(!separate);
- if (separate) {
- mUnifyProfile.setDisabledByAdmin(RestrictedLockUtils.checkIfRestrictionEnforced(
- getContext(), UserManager.DISALLOW_UNIFIED_PASSWORD,
- mProfileChallengeUserId));
- }
- }
- }
-
- @Override
- public boolean onPreferenceTreeClick(Preference preference) {
- final String key = preference.getKey();
- if (KEY_UNLOCK_SET_OR_CHANGE.equals(key)) {
- // TODO(b/35930129): Remove once existing password can be passed into vold directly.
- // Currently we need this logic to ensure that the QUIET_MODE is off for any work
- // profile with unified challenge on FBE-enabled devices. Otherwise, vold would not be
- // able to complete the operation due to the lack of (old) encryption key.
- if (mProfileChallengeUserId != UserHandle.USER_NULL
- && !mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId)
- && StorageManager.isFileEncryptedNativeOnly()) {
- if (Utils.startQuietModeDialogIfNecessary(this.getActivity(), mUm,
- mProfileChallengeUserId)) {
- return false;
- }
- }
- startFragment(this, ChooseLockGenericFragment.class.getName(),
- R.string.lock_settings_picker_title, SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
- } else if (KEY_UNLOCK_SET_OR_CHANGE_PROFILE.equals(key)) {
- if (Utils.startQuietModeDialogIfNecessary(this.getActivity(), mUm,
- mProfileChallengeUserId)) {
- return false;
- }
- Bundle extras = new Bundle();
- extras.putInt(Intent.EXTRA_USER_ID, mProfileChallengeUserId);
- startFragment(this, ChooseLockGenericFragment.class.getName(),
- R.string.lock_settings_picker_title_profile,
- SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE, extras);
- } else if (KEY_TRUST_AGENT.equals(key)) {
- ChooseLockSettingsHelper helper =
- new ChooseLockSettingsHelper(this.getActivity(), this);
- mTrustAgentClickIntent = preference.getIntent();
- boolean confirmationLaunched = helper.launchConfirmationActivity(
- CHANGE_TRUST_AGENT_SETTINGS, preference.getTitle());
- if (!confirmationLaunched&& mTrustAgentClickIntent != null) {
- // If this returns false, it means no password confirmation is required.
- startActivity(mTrustAgentClickIntent);
- mTrustAgentClickIntent = null;
- }
- } else {
- // If we didn't handle it, let preferences handle it.
- return super.onPreferenceTreeClick(preference);
- }
- return true;
- }
-
- /**
- * see confirmPatternThenDisableAndClear
- */
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if (requestCode == CHANGE_TRUST_AGENT_SETTINGS && resultCode == Activity.RESULT_OK) {
- if (mTrustAgentClickIntent != null) {
- startActivity(mTrustAgentClickIntent);
- mTrustAgentClickIntent = null;
- }
- return;
- } else if (requestCode == UNIFY_LOCK_CONFIRM_DEVICE_REQUEST
- && resultCode == Activity.RESULT_OK) {
- mCurrentDevicePassword =
- data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
- launchConfirmProfileLockForUnification();
- return;
- } else if (requestCode == UNIFY_LOCK_CONFIRM_PROFILE_REQUEST
- && resultCode == Activity.RESULT_OK) {
- mCurrentProfilePassword =
- data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
- unifyLocks();
- return;
- } else if (requestCode == UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST
- && resultCode == Activity.RESULT_OK) {
- ununifyLocks();
- return;
- }
- createPreferenceHierarchy();
- }
-
- private void launchConfirmDeviceLockForUnification() {
- final String title = getActivity().getString(
- R.string.unlock_set_unlock_launch_picker_title);
- final ChooseLockSettingsHelper helper =
- new ChooseLockSettingsHelper(getActivity(), this);
- if (!helper.launchConfirmationActivity(
- UNIFY_LOCK_CONFIRM_DEVICE_REQUEST, title, true, MY_USER_ID)) {
- launchConfirmProfileLockForUnification();
- }
- }
-
- private void launchConfirmProfileLockForUnification() {
- final String title = getActivity().getString(
- R.string.unlock_set_unlock_launch_picker_title_profile);
- final ChooseLockSettingsHelper helper =
- new ChooseLockSettingsHelper(getActivity(), this);
- if (!helper.launchConfirmationActivity(
- UNIFY_LOCK_CONFIRM_PROFILE_REQUEST, title, true, mProfileChallengeUserId)) {
- unifyLocks();
- createPreferenceHierarchy();
- }
- }
-
- private void unifyLocks() {
- int profileQuality =
- mLockPatternUtils.getKeyguardStoredPasswordQuality(mProfileChallengeUserId);
- if (profileQuality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) {
- mLockPatternUtils.saveLockPattern(
- LockPatternUtils.stringToPattern(mCurrentProfilePassword),
- mCurrentDevicePassword, MY_USER_ID);
- } else {
- mLockPatternUtils.saveLockPassword(
- mCurrentProfilePassword, mCurrentDevicePassword,
- profileQuality, MY_USER_ID);
- }
- mLockPatternUtils.setSeparateProfileChallengeEnabled(mProfileChallengeUserId, false,
- mCurrentProfilePassword);
- final boolean profilePatternVisibility =
- mLockPatternUtils.isVisiblePatternEnabled(mProfileChallengeUserId);
- mLockPatternUtils.setVisiblePatternEnabled(profilePatternVisibility, MY_USER_ID);
- mCurrentDevicePassword = null;
- mCurrentProfilePassword = null;
- }
-
- private void unifyUncompliantLocks() {
- mLockPatternUtils.setSeparateProfileChallengeEnabled(mProfileChallengeUserId, false,
- mCurrentProfilePassword);
- startFragment(this, ChooseLockGenericFragment.class.getName(),
- R.string.lock_settings_picker_title, SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
- }
-
- private void ununifyLocks() {
- Bundle extras = new Bundle();
- extras.putInt(Intent.EXTRA_USER_ID, mProfileChallengeUserId);
- startFragment(this,
- ChooseLockGenericFragment.class.getName(),
- R.string.lock_settings_picker_title_profile,
- SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE, extras);
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object value) {
- boolean result = true;
- final String key = preference.getKey();
- final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils();
- if (KEY_VISIBLE_PATTERN_PROFILE.equals(key)) {
- if (Utils.startQuietModeDialogIfNecessary(this.getActivity(), mUm,
- mProfileChallengeUserId)) {
- return false;
- }
- lockPatternUtils.setVisiblePatternEnabled((Boolean) value, mProfileChallengeUserId);
- } else if (KEY_UNIFICATION.equals(key)) {
- if (Utils.startQuietModeDialogIfNecessary(this.getActivity(), mUm,
- mProfileChallengeUserId)) {
- return false;
- }
- if ((Boolean) value) {
- final boolean compliantForDevice =
- (mLockPatternUtils.getKeyguardStoredPasswordQuality(mProfileChallengeUserId)
- >= DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
- && mLockPatternUtils.isSeparateProfileChallengeAllowedToUnify(
- mProfileChallengeUserId));
- UnificationConfirmationDialog dialog =
- UnificationConfirmationDialog.newIntance(compliantForDevice);
- dialog.show(getChildFragmentManager(), TAG_UNIFICATION_DIALOG);
- } else {
- final String title = getActivity().getString(
- R.string.unlock_set_unlock_launch_picker_title);
- final ChooseLockSettingsHelper helper =
- new ChooseLockSettingsHelper(getActivity(), this);
- if(!helper.launchConfirmationActivity(
- UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST, title, true, MY_USER_ID)) {
- ununifyLocks();
- }
- }
- } else if (KEY_SHOW_PASSWORD.equals(key)) {
- Settings.System.putInt(getContentResolver(), Settings.System.TEXT_SHOW_PASSWORD,
- ((Boolean) value) ? 1 : 0);
- lockPatternUtils.setVisiblePasswordEnabled((Boolean) value, MY_USER_ID);
- }
- return result;
+ protected String getLogTag() {
+ return TAG;
}
@Override
@@ -758,206 +76,95 @@
return R.string.help_url_security;
}
+ @Override
+ protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ return buildPreferenceControllers(context, getLifecycle(), this /* host*/);
+ }
+
+ /**
+ * see confirmPatternThenDisableAndClear
+ */
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (getPreferenceController(TrustAgentListPreferenceController.class)
+ .handleActivityResult(requestCode, resultCode)) {
+ return;
+ }
+ if (getPreferenceController(LockUnificationPreferenceController.class)
+ .handleActivityResult(requestCode, resultCode, data)) {
+ return;
+ }
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+
+ void launchConfirmDeviceLockForUnification() {
+ getPreferenceController(LockUnificationPreferenceController.class)
+ .launchConfirmDeviceLockForUnification();
+ }
+
+ void unifyUncompliantLocks() {
+ getPreferenceController(LockUnificationPreferenceController.class).unifyUncompliantLocks();
+ }
+
+ void updateUnificationPreference() {
+ getPreferenceController(LockUnificationPreferenceController.class).updateState(null);
+ }
+
+ private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
+ Lifecycle lifecycle, SecuritySettings host) {
+ final List<AbstractPreferenceController> controllers = new ArrayList<>();
+ controllers.add(new LocationPreferenceController(context, lifecycle));
+ controllers.add(new ManageDeviceAdminPreferenceController(context));
+ controllers.add(new EnterprisePrivacyPreferenceController(context));
+ controllers.add(new ManageTrustAgentsPreferenceController(context));
+ controllers.add(new ScreenPinningPreferenceController(context));
+ controllers.add(new SimLockPreferenceController(context));
+ controllers.add(new ShowPasswordPreferenceController(context));
+ controllers.add(new FingerprintStatusPreferenceController(context));
+ controllers.add(new EncryptionStatusPreferenceController(context,
+ PREF_KEY_ENCRYPTION_SECURITY_PAGE));
+ controllers.add(new TrustAgentListPreferenceController(context, host, lifecycle));
+ controllers.add(new LockScreenPreferenceController(context, lifecycle));
+ controllers.add(new ChangeScreenLockPreferenceController(context, host));
+
+ final List<AbstractPreferenceController> profileSecurityControllers = new ArrayList<>();
+ profileSecurityControllers.add(new ChangeProfileScreenLockPreferenceController(
+ context, host));
+ profileSecurityControllers.add(new LockUnificationPreferenceController(context, host));
+ profileSecurityControllers.add(new VisiblePatternProfilePreferenceController(
+ context, lifecycle));
+ profileSecurityControllers.add(new FingerprintProfileStatusPreferenceController(context));
+ controllers.add(new PreferenceCategoryController(context, "security_category_profile",
+ profileSecurityControllers));
+ controllers.addAll(profileSecurityControllers);
+
+ return controllers;
+ }
+
/**
* For Search. Please keep it in sync when updating "createPreferenceHierarchy()"
*/
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new SecuritySearchIndexProvider();
+ new BaseSearchIndexProvider() {
- private static class SecuritySearchIndexProvider extends BaseSearchIndexProvider {
-
- // TODO (b/68001777) Refactor indexing to include all XML and block other settings.
-
- @Override
- public List<SearchIndexableResource> getXmlResourcesToIndex(
- Context context, boolean enabled) {
- final List<SearchIndexableResource> index = new ArrayList<>();
-
- final LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
- final ManagedLockPasswordProvider managedPasswordProvider =
- ManagedLockPasswordProvider.get(context, MY_USER_ID);
- final DevicePolicyManager dpm = (DevicePolicyManager)
- context.getSystemService(Context.DEVICE_POLICY_SERVICE);
- final UserManager um = UserManager.get(context);
- final int profileUserId = Utils.getManagedProfileId(um, MY_USER_ID);
-
- // To add option for unlock screen, user's password must not be managed and
- // must not be unified with managed profile, whose password is managed.
- if (!isPasswordManaged(MY_USER_ID, context, dpm)
- && (profileUserId == UserHandle.USER_NULL
- || lockPatternUtils.isSeparateProfileChallengeAllowed(profileUserId)
- || !isPasswordManaged(profileUserId, context, dpm))) {
- // Add options for lock/unlock screen
- final int resId = getResIdForLockUnlockScreen(lockPatternUtils,
- managedPasswordProvider, MY_USER_ID);
- index.add(getSearchResource(context, resId));
- }
-
- if (profileUserId != UserHandle.USER_NULL
- && lockPatternUtils.isSeparateProfileChallengeAllowed(profileUserId)
- && !isPasswordManaged(profileUserId, context, dpm)) {
- index.add(getSearchResource(context, getResIdForLockUnlockScreen(
- lockPatternUtils, managedPasswordProvider, profileUserId)));
- }
-
- // Append the rest of the settings
- index.add(getSearchResource(context, R.xml.security_settings_misc));
-
- return index;
- }
-
- private SearchIndexableResource getSearchResource(Context context, int xmlResId) {
- final SearchIndexableResource sir = new SearchIndexableResource(context);
- sir.xmlResId = xmlResId;
- return sir;
- }
-
- private boolean isPasswordManaged(int userId, Context context, DevicePolicyManager dpm) {
- final EnforcedAdmin admin = RestrictedLockUtils.checkIfPasswordQualityIsSet(
- context, userId);
- return admin != null && dpm.getPasswordQuality(admin.component, userId) ==
- DevicePolicyManager.PASSWORD_QUALITY_MANAGED;
- }
-
- @Override
- public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
- final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
- final Resources res = context.getResources();
-
- final String screenTitle = res.getString(R.string.security_settings_title);
-
- SearchIndexableRaw data = new SearchIndexableRaw(context);
- data.title = screenTitle;
- data.key = "security_settings_screen";
- data.screenTitle = screenTitle;
- result.add(data);
-
- final UserManager um = UserManager.get(context);
-
- // Fingerprint
- final FingerprintManager fpm = Utils.getFingerprintManagerOrNull(context);
- if (fpm != null && fpm.isHardwareDetected()) {
- // This catches the title which can be overloaded in an overlay
- data = new SearchIndexableRaw(context);
- data.title = res.getString(R.string.security_settings_fingerprint_preference_title);
- data.key = "security_fingerprint";
- data.screenTitle = screenTitle;
- result.add(data);
- // Fallback for when the above doesn't contain "fingerprint"
- data = new SearchIndexableRaw(context);
- data.title = res.getString(R.string.fingerprint_manage_category_title);
- data.key = "security_managed_fingerprint";
- data.screenTitle = screenTitle;
- result.add(data);
- }
-
- final LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
- final int profileUserId = Utils.getManagedProfileId(um, MY_USER_ID);
- if (profileUserId != UserHandle.USER_NULL
- && lockPatternUtils.isSeparateProfileChallengeAllowed(profileUserId)) {
- if (lockPatternUtils.getKeyguardStoredPasswordQuality(profileUserId)
- >= DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
- && lockPatternUtils.isSeparateProfileChallengeAllowedToUnify(
- profileUserId)) {
- data = new SearchIndexableRaw(context);
- data.title = res.getString(R.string.lock_settings_profile_unification_title);
- data.key = "security_use_one_lock";
- data.screenTitle = screenTitle;
- result.add(data);
+ @Override
+ public List<SearchIndexableResource> getXmlResourcesToIndex(
+ Context context, boolean enabled) {
+ final List<SearchIndexableResource> index = new ArrayList<>();
+ // Append the rest of the settings
+ final SearchIndexableResource sir = new SearchIndexableResource(context);
+ sir.xmlResId = R.xml.security_dashboard_settings;
+ index.add(sir);
+ return index;
}
- }
- return result;
- }
- @Override
- public List<String> getNonIndexableKeys(Context context) {
- final List<String> keys = super.getNonIndexableKeys(context);
-
- LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
-
- // Do not display SIM lock for devices without an Icc card
- final UserManager um = UserManager.get(context);
- final TelephonyManager tm = TelephonyManager.from(context);
- if (!um.isAdminUser() || !tm.hasIccCard()) {
- keys.add(KEY_SIM_LOCK);
- }
-
- // TrustAgent settings disappear when the user has no primary security.
- if (!lockPatternUtils.isSecure(MY_USER_ID)) {
- keys.add(KEY_TRUST_AGENT);
- keys.add(KEY_MANAGE_TRUST_AGENTS);
- }
-
- if (!(new EnterprisePrivacyPreferenceController(context))
- .isAvailable()) {
- keys.add(KEY_ENTERPRISE_PRIVACY);
- }
-
- // Duplicate in special app access
- keys.add(KEY_MANAGE_DEVICE_ADMIN);
- // Duplicates between parent-child
- keys.add(KEY_LOCATION);
- keys.add(KEY_ENCRYPTION_AND_CREDENTIALS);
- keys.add(KEY_SCREEN_PINNING);
- keys.add(KEY_LOCATION_SCANNING);
-
- return keys;
- }
- }
-
- public static class UnificationConfirmationDialog extends InstrumentedDialogFragment {
- private static final String EXTRA_COMPLIANT = "compliant";
-
- public static UnificationConfirmationDialog newIntance(boolean compliant) {
- UnificationConfirmationDialog dialog = new UnificationConfirmationDialog();
- Bundle args = new Bundle();
- args.putBoolean(EXTRA_COMPLIANT, compliant);
- dialog.setArguments(args);
- return dialog;
- }
-
- @Override
- public void show(FragmentManager manager, String tag) {
- if (manager.findFragmentByTag(tag) == null) {
- // Prevent opening multiple dialogs if tapped on button quickly
- super.show(manager, tag);
- }
- }
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- final SecuritySettings parentFragment = ((SecuritySettings) getParentFragment());
- final boolean compliant = getArguments().getBoolean(EXTRA_COMPLIANT);
- return new AlertDialog.Builder(getActivity())
- .setTitle(R.string.lock_settings_profile_unification_dialog_title)
- .setMessage(compliant ? R.string.lock_settings_profile_unification_dialog_body
- : R.string.lock_settings_profile_unification_dialog_uncompliant_body)
- .setPositiveButton(
- compliant ? R.string.lock_settings_profile_unification_dialog_confirm
- : R.string.lock_settings_profile_unification_dialog_uncompliant_confirm,
- (dialog, whichButton) -> {
- if (compliant) {
- parentFragment.launchConfirmDeviceLockForUnification();
- } else {
- parentFragment.unifyUncompliantLocks();
- }
- }
- )
- .setNegativeButton(R.string.cancel, null)
- .create();
- }
-
- @Override
- public void onDismiss(DialogInterface dialog) {
- super.onDismiss(dialog);
- ((SecuritySettings) getParentFragment()).updateUnificationPreference();
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsEvent.DIALOG_UNIFICATION_CONFIRMATION;
- }
- }
+ @Override
+ public List<AbstractPreferenceController> getPreferenceControllers(Context
+ context) {
+ return buildPreferenceControllers(context, null /* lifecycle */,
+ null /* host*/);
+ }
+ };
static class SummaryProvider implements SummaryLoader.SummaryProvider {
@@ -973,13 +180,13 @@
public void setListening(boolean listening) {
if (listening) {
final FingerprintManager fpm =
- Utils.getFingerprintManagerOrNull(mContext);
+ Utils.getFingerprintManagerOrNull(mContext);
if (fpm != null && fpm.isHardwareDetected()) {
mSummaryLoader.setSummary(this,
- mContext.getString(R.string.security_dashboard_summary));
+ mContext.getString(R.string.security_dashboard_summary));
} else {
mSummaryLoader.setSummary(this, mContext.getString(
- R.string.security_dashboard_summary_no_fingerprint));
+ R.string.security_dashboard_summary_no_fingerprint));
}
}
}
@@ -987,11 +194,10 @@
public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY =
new SummaryLoader.SummaryProviderFactory() {
- @Override
- public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
- SummaryLoader summaryLoader) {
- return new SummaryProvider(activity, summaryLoader);
- }
- };
-
+ @Override
+ public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
+ SummaryLoader summaryLoader) {
+ return new SummaryProvider(activity, summaryLoader);
+ }
+ };
}
diff --git a/src/com/android/settings/security/SecuritySettingsV2.java b/src/com/android/settings/security/SecuritySettingsV2.java
deleted file mode 100644
index 323c0f4..0000000
--- a/src/com/android/settings/security/SecuritySettingsV2.java
+++ /dev/null
@@ -1,188 +0,0 @@
-package com.android.settings.security;
-
-import static com.android.settings.security.EncryptionStatusPreferenceController
- .PREF_KEY_ENCRYPTION_SECURITY_PAGE;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.hardware.fingerprint.FingerprintManager;
-import android.provider.SearchIndexableResource;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.Utils;
-import com.android.settings.dashboard.DashboardFragment;
-import com.android.settings.dashboard.SummaryLoader;
-import com.android.settings.enterprise.EnterprisePrivacyPreferenceController;
-import com.android.settings.enterprise.ManageDeviceAdminPreferenceController;
-import com.android.settings.fingerprint.FingerprintProfileStatusPreferenceController;
-import com.android.settings.fingerprint.FingerprintStatusPreferenceController;
-import com.android.settings.location.LocationPreferenceController;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.security.screenlock.LockScreenPreferenceController;
-import com.android.settings.security.trustagent.ManageTrustAgentsPreferenceController;
-import com.android.settings.security.trustagent.TrustAgentListPreferenceController;
-import com.android.settings.widget.PreferenceCategoryController;
-import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class SecuritySettingsV2 extends DashboardFragment {
-
- private static final String TAG = "SecuritySettingsV2";
-
- public static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST = 123;
- public static final int CHANGE_TRUST_AGENT_SETTINGS = 126;
- public static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE = 127;
- public static final int UNIFY_LOCK_CONFIRM_DEVICE_REQUEST = 128;
- public static final int UNIFY_LOCK_CONFIRM_PROFILE_REQUEST = 129;
- public static final int UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST = 130;
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.SECURITY;
- }
-
- @Override
- protected int getPreferenceScreenResId() {
- return R.xml.security_settings_v2;
- }
-
- @Override
- protected String getLogTag() {
- return TAG;
- }
-
- @Override
- public int getHelpResource() {
- return R.string.help_url_security;
- }
-
- @Override
- protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
- return buildPreferenceControllers(context, getLifecycle(), this /* host*/);
- }
-
- /**
- * see confirmPatternThenDisableAndClear
- */
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (getPreferenceController(TrustAgentListPreferenceController.class)
- .handleActivityResult(requestCode, resultCode)) {
- return;
- }
- if (getPreferenceController(LockUnificationPreferenceController.class)
- .handleActivityResult(requestCode, resultCode, data)) {
- return;
- }
- super.onActivityResult(requestCode, resultCode, data);
- }
-
- void launchConfirmDeviceLockForUnification() {
- getPreferenceController(LockUnificationPreferenceController.class)
- .launchConfirmDeviceLockForUnification();
- }
-
- void unifyUncompliantLocks() {
- getPreferenceController(LockUnificationPreferenceController.class).unifyUncompliantLocks();
- }
-
- void updateUnificationPreference() {
- getPreferenceController(LockUnificationPreferenceController.class).updateState(null);
- }
-
- private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
- Lifecycle lifecycle, SecuritySettingsV2 host) {
- final List<AbstractPreferenceController> controllers = new ArrayList<>();
- controllers.add(new LocationPreferenceController(context, lifecycle));
- controllers.add(new ManageDeviceAdminPreferenceController(context));
- controllers.add(new EnterprisePrivacyPreferenceController(context));
- controllers.add(new ManageTrustAgentsPreferenceController(context));
- controllers.add(new ScreenPinningPreferenceController(context));
- controllers.add(new SimLockPreferenceController(context));
- controllers.add(new ShowPasswordPreferenceController(context));
- controllers.add(new FingerprintStatusPreferenceController(context));
- controllers.add(new EncryptionStatusPreferenceController(context,
- PREF_KEY_ENCRYPTION_SECURITY_PAGE));
- controllers.add(new TrustAgentListPreferenceController(context, host, lifecycle));
- controllers.add(new LockScreenPreferenceController(context, lifecycle));
- controllers.add(new ChangeScreenLockPreferenceController(context, host));
-
- final List<AbstractPreferenceController> profileSecurityControllers = new ArrayList<>();
- profileSecurityControllers.add(new ChangeProfileScreenLockPreferenceController(
- context, host));
- profileSecurityControllers.add(new LockUnificationPreferenceController(context, host));
- profileSecurityControllers.add(new VisiblePatternProfilePreferenceController(
- context, lifecycle));
- profileSecurityControllers.add(new FingerprintProfileStatusPreferenceController(context));
- controllers.add(new PreferenceCategoryController(context, "security_category_profile",
- profileSecurityControllers));
- controllers.addAll(profileSecurityControllers);
-
- return controllers;
- }
-
- /**
- * For Search. Please keep it in sync when updating "createPreferenceHierarchy()"
- */
- public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider() {
-
- @Override
- public List<SearchIndexableResource> getXmlResourcesToIndex(
- Context context, boolean enabled) {
- final List<SearchIndexableResource> index = new ArrayList<>();
- // Append the rest of the settings
- final SearchIndexableResource sir = new SearchIndexableResource(context);
- sir.xmlResId = R.xml.security_settings_v2;
- index.add(sir);
- return index;
- }
-
- @Override
- public List<AbstractPreferenceController> getPreferenceControllers(Context
- context) {
- return buildPreferenceControllers(context, null /* lifecycle */,
- null /* host*/);
- }
- };
-
- static class SummaryProvider implements SummaryLoader.SummaryProvider {
-
- private final Context mContext;
- private final SummaryLoader mSummaryLoader;
-
- public SummaryProvider(Context context, SummaryLoader summaryLoader) {
- mContext = context;
- mSummaryLoader = summaryLoader;
- }
-
- @Override
- public void setListening(boolean listening) {
- if (listening) {
- final FingerprintManager fpm =
- Utils.getFingerprintManagerOrNull(mContext);
- if (fpm != null && fpm.isHardwareDetected()) {
- mSummaryLoader.setSummary(this,
- mContext.getString(R.string.security_dashboard_summary));
- } else {
- mSummaryLoader.setSummary(this, mContext.getString(
- R.string.security_dashboard_summary_no_fingerprint));
- }
- }
- }
- }
-
- public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY =
- new SummaryLoader.SummaryProviderFactory() {
- @Override
- public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
- SummaryLoader summaryLoader) {
- return new SummaryProvider(activity, summaryLoader);
- }
- };
-}
diff --git a/src/com/android/settings/security/UnificationConfirmationDialog.java b/src/com/android/settings/security/UnificationConfirmationDialog.java
index 482e268..029e64f 100644
--- a/src/com/android/settings/security/UnificationConfirmationDialog.java
+++ b/src/com/android/settings/security/UnificationConfirmationDialog.java
@@ -40,7 +40,7 @@
return dialog;
}
- public void show(SecuritySettingsV2 host) {
+ public void show(SecuritySettings host) {
final FragmentManager manager = host.getChildFragmentManager();
if (manager.findFragmentByTag(TAG_UNIFICATION_DIALOG) == null) {
// Prevent opening multiple dialogs if tapped on button quickly
@@ -50,7 +50,7 @@
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
- final SecuritySettingsV2 parentFragment = ((SecuritySettingsV2) getParentFragment());
+ final SecuritySettings parentFragment = ((SecuritySettings) getParentFragment());
final boolean compliant = getArguments().getBoolean(EXTRA_COMPLIANT);
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.lock_settings_profile_unification_dialog_title)
@@ -75,7 +75,7 @@
@Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
- ((SecuritySettingsV2) getParentFragment()).updateUnificationPreference();
+ ((SecuritySettings) getParentFragment()).updateUnificationPreference();
}
@Override
diff --git a/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java b/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java
index 0c591ed..ec81aad 100644
--- a/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java
+++ b/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java
@@ -16,7 +16,7 @@
package com.android.settings.security.trustagent;
-import static com.android.settings.security.SecuritySettingsV2.CHANGE_TRUST_AGENT_SETTINGS;
+import static com.android.settings.security.SecuritySettings.CHANGE_TRUST_AGENT_SETTINGS;
import android.app.Activity;
import android.content.Context;
@@ -35,7 +35,7 @@
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.security.SecurityFeatureProvider;
-import com.android.settings.security.SecuritySettingsV2;
+import com.android.settings.security.SecuritySettings;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -59,12 +59,12 @@
private final LockPatternUtils mLockPatternUtils;
private final TrustAgentManager mTrustAgentManager;
- private final SecuritySettingsV2 mHost;
+ private final SecuritySettings mHost;
private Intent mTrustAgentClickIntent;
private PreferenceCategory mSecurityCategory;
- public TrustAgentListPreferenceController(Context context, SecuritySettingsV2 host,
+ public TrustAgentListPreferenceController(Context context, SecuritySettings host,
Lifecycle lifecycle) {
super(context);
final SecurityFeatureProvider provider = FeatureFactory.getFactory(context)
diff --git a/src/com/android/settings/CreateShortcut.java b/src/com/android/settings/shortcut/CreateShortcut.java
similarity index 92%
rename from src/com/android/settings/CreateShortcut.java
rename to src/com/android/settings/shortcut/CreateShortcut.java
index 8bc801b..2bd9b761 100644
--- a/src/com/android/settings/CreateShortcut.java
+++ b/src/com/android/settings/shortcut/CreateShortcut.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settings;
+package com.android.settings.shortcut;
import android.app.LauncherActivity;
import android.content.ComponentName;
@@ -28,7 +28,9 @@
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
+import android.graphics.drawable.LayerDrawable;
import android.net.ConnectivityManager;
import android.os.AsyncTask;
import android.support.annotation.VisibleForTesting;
@@ -40,6 +42,7 @@
import android.widget.ListView;
import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
import com.android.settings.Settings.TetherSettingsActivity;
import com.android.settings.overlay.FeatureFactory;
@@ -65,7 +68,8 @@
finish();
}
- protected Intent createResultIntent(Intent shortcutIntent, ResolveInfo resolveInfo,
+ @VisibleForTesting
+ Intent createResultIntent(Intent shortcutIntent, ResolveInfo resolveInfo,
CharSequence label) {
shortcutIntent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
ShortcutManager sm = getSystemService(ShortcutManager.class);
@@ -94,8 +98,8 @@
if (activityInfo.icon != 0) {
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, createIcon(activityInfo.icon,
- R.layout.shortcut_badge,
- getResources().getDimensionPixelSize(R.dimen.shortcut_size)));
+ R.layout.shortcut_badge,
+ getResources().getDimensionPixelSize(R.dimen.shortcut_size)));
}
return intent;
}
@@ -112,7 +116,11 @@
private Bitmap createIcon(int resource, int layoutRes, int size) {
Context context = new ContextThemeWrapper(this, android.R.style.Theme_Material);
View view = LayoutInflater.from(context).inflate(layoutRes, null);
- ((ImageView) view.findViewById(android.R.id.icon)).setImageResource(resource);
+ Drawable iconDrawable = getDrawable(resource);
+ if (iconDrawable instanceof LayerDrawable) {
+ iconDrawable = ((LayerDrawable) iconDrawable).getDrawable(1);
+ }
+ ((ImageView) view.findViewById(android.R.id.icon)).setImageDrawable(iconDrawable);
int spec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
view.measure(spec, spec);
diff --git a/src/com/android/settings/widget/EntityHeaderController.java b/src/com/android/settings/widget/EntityHeaderController.java
index 8607211..4ebc369 100644
--- a/src/com/android/settings/widget/EntityHeaderController.java
+++ b/src/com/android/settings/widget/EntityHeaderController.java
@@ -37,7 +37,6 @@
import android.support.annotation.VisibleForTesting;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
-import android.util.FeatureFlagUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -48,10 +47,8 @@
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.applications.AppInfoBase;
-import com.android.settings.applications.InstalledAppDetails;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
-import com.android.settings.core.FeatureFlags;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -285,17 +282,10 @@
entityHeaderContent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- if (FeatureFlagUtils.isEnabled(mAppContext, FeatureFlags.APP_INFO_V2)) {
- AppInfoBase.startAppInfoFragment(
- AppInfoDashboardFragment.class, R.string.application_info_label,
- mPackageName, mUid, mFragment, 0 /* request */,
- mMetricsCategory);
- } else {
- AppInfoBase.startAppInfoFragment(
- InstalledAppDetails.class, R.string.application_info_label,
- mPackageName, mUid, mFragment, 0 /* request */,
- mMetricsCategory);
- }
+ AppInfoBase.startAppInfoFragment(
+ AppInfoDashboardFragment.class, R.string.application_info_label,
+ mPackageName, mUid, mFragment, 0 /* request */,
+ mMetricsCategory);
}
});
return;
diff --git a/src/com/android/settings/wifi/SavedAccessPointsWifiSettings.java b/src/com/android/settings/wifi/SavedAccessPointsWifiSettings.java
index 9f52159..3079f8d 100644
--- a/src/com/android/settings/wifi/SavedAccessPointsWifiSettings.java
+++ b/src/com/android/settings/wifi/SavedAccessPointsWifiSettings.java
@@ -161,7 +161,7 @@
final int accessPointsSize = accessPoints.size();
for (int i = 0; i < accessPointsSize; ++i) {
AccessPoint ap = accessPoints.get(i);
- String key = AccessPointPreference.generatePreferenceKey(ap);
+ String key = ap.getKey();
LongPressAccessPointPreference preference =
(LongPressAccessPointPreference) getCachedPreference(key);
if (preference == null) {
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 83d9c18..e32bef4 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -777,7 +777,7 @@
AccessPoint accessPoint = accessPoints.get(index);
// Ignore access points that are out of range.
if (accessPoint.isReachable()) {
- String key = AccessPointPreference.generatePreferenceKey(accessPoint);
+ String key = accessPoint.getKey();
hasAvailableAccessPoints = true;
LongPressAccessPointPreference pref =
(LongPressAccessPointPreference) getCachedPreference(key);
diff --git a/tests/robotests/assets/grandfather_not_implementing_indexable b/tests/robotests/assets/grandfather_not_implementing_indexable
index 9d593a0..ece35fb 100644
--- a/tests/robotests/assets/grandfather_not_implementing_indexable
+++ b/tests/robotests/assets/grandfather_not_implementing_indexable
@@ -43,7 +43,6 @@
com.android.settings.applications.RunningServices
com.android.settings.applications.ConfirmConvertToFbe
com.android.settings.deviceinfo.PublicVolumeSettings
-com.android.settings.applications.InstalledAppDetails
com.android.settings.accessibility.ToggleAccessibilityServicePreferenceFragment
com.android.settings.print.PrintServiceSettingsFragment
com.android.settings.deviceinfo.PrivateVolumeSettings
diff --git a/tests/robotests/assets/grandfather_not_in_search_index_provider_registry b/tests/robotests/assets/grandfather_not_in_search_index_provider_registry
index 6a831b0..666b224 100644
--- a/tests/robotests/assets/grandfather_not_in_search_index_provider_registry
+++ b/tests/robotests/assets/grandfather_not_in_search_index_provider_registry
@@ -1,3 +1,2 @@
com.android.settings.display.ScreenZoomPreferenceFragmentForSetupWizard
-com.android.settings.search.indexing.FakeSettingsFragment
-com.android.settings.security.SecuritySettings
\ No newline at end of file
+com.android.settings.search.indexing.FakeSettingsFragment
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java b/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java
deleted file mode 100644
index 21e7848..0000000
--- a/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java
+++ /dev/null
@@ -1,591 +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;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.nullable;
-import static org.mockito.Matchers.anyDouble;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.AlertDialog;
-import android.app.AppOpsManager;
-import android.app.Fragment;
-import android.app.LoaderManager;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.os.BatteryStats;
-import android.os.Bundle;
-import android.os.UserManager;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceManager;
-import android.support.v7.preference.PreferenceScreen;
-import android.view.View;
-
-import com.android.internal.os.BatterySipper;
-import com.android.internal.os.BatteryStatsHelper;
-import com.android.settings.R;
-import com.android.settings.SettingsActivity;
-import com.android.settings.TestConfig;
-import com.android.settings.applications.instantapps.InstantAppButtonsController;
-import com.android.settings.applications.instantapps.InstantAppButtonsController.ShowDialogDelegate;
-import com.android.settings.fuelgauge.BatteryUtils;
-import com.android.settings.testutils.FakeFeatureFactory;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.widget.ActionButtonPreferenceTest;
-import com.android.settings.wrapper.DevicePolicyManagerWrapper;
-import com.android.settingslib.Utils;
-import com.android.settingslib.applications.AppUtils;
-import com.android.settingslib.applications.ApplicationsState.AppEntry;
-import com.android.settingslib.applications.StorageStatsSource.AppStorageStats;
-import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
-
-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.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-import org.robolectric.util.ReflectionHelpers;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(
- manifest = TestConfig.MANIFEST_PATH,
- sdk = TestConfig.SDK_VERSION,
- shadows = InstalledAppDetailsTest.ShadowUtils.class
-)
-public final class InstalledAppDetailsTest {
-
- private static final String PACKAGE_NAME = "test_package_name";
- private static final int TARGET_UID = 111;
- private static final int OTHER_UID = 222;
- private static final double BATTERY_LEVEL = 60;
- private static final String BATTERY_LEVEL_STRING = "60%";
-
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private Context mContext;
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private UserManager mUserManager;
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private SettingsActivity mActivity;
- @Mock
- private DevicePolicyManagerWrapper mDevicePolicyManager;
- @Mock
- private BatterySipper mBatterySipper;
- @Mock
- private BatterySipper mOtherBatterySipper;
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private BatteryStatsHelper mBatteryStatsHelper;
- @Mock
- private BatteryStats.Uid mUid;
- @Mock
- private PackageManager mPackageManager;
- @Mock
- private BatteryUtils mBatteryUtils;
- @Mock
- private LoaderManager mLoaderManager;
- @Mock
- private AppOpsManager mAppOpsManager;
-
- private FakeFeatureFactory mFeatureFactory;
- private InstalledAppDetails mAppDetail;
- private Context mShadowContext;
- private Preference mBatteryPreference;
-
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mFeatureFactory = FakeFeatureFactory.setupForTest();
- mShadowContext = RuntimeEnvironment.application;
- mAppDetail = spy(new InstalledAppDetails());
- mAppDetail.mBatteryUtils = mBatteryUtils;
-
- mBatteryPreference = new Preference(mShadowContext);
- mAppDetail.mBatteryPreference = mBatteryPreference;
- mAppDetail.mActionButtons = ActionButtonPreferenceTest.createMock();
-
- mBatterySipper.drainType = BatterySipper.DrainType.IDLE;
- mBatterySipper.uidObj = mUid;
- doReturn(TARGET_UID).when(mBatterySipper).getUid();
- doReturn(OTHER_UID).when(mOtherBatterySipper).getUid();
- doReturn(mActivity).when(mAppDetail).getActivity();
- doReturn(mShadowContext).when(mAppDetail).getContext();
- doReturn(mPackageManager).when(mActivity).getPackageManager();
- doReturn(mAppOpsManager).when(mActivity).getSystemService(Context.APP_OPS_SERVICE);
-
- // Default to not considering any apps to be instant (individual tests can override this).
- ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
- (InstantAppDataProvider) (i -> false));
- }
-
- @Test
- public void shouldShowUninstallForAll_installForOneOtherUserOnly_shouldReturnTrue() {
- when(mDevicePolicyManager.packageHasActiveAdmins(nullable(String.class))).thenReturn(false);
- when(mUserManager.getUsers().size()).thenReturn(2);
- ReflectionHelpers.setField(mAppDetail, "mDpm", mDevicePolicyManager);
- ReflectionHelpers.setField(mAppDetail, "mUserManager", mUserManager);
- final ApplicationInfo info = new ApplicationInfo();
- info.enabled = true;
- final AppEntry appEntry = mock(AppEntry.class);
- appEntry.info = info;
- final PackageInfo packageInfo = mock(PackageInfo.class);
- ReflectionHelpers.setField(mAppDetail, "mPackageInfo", packageInfo);
-
- assertThat(mAppDetail.shouldShowUninstallForAll(appEntry)).isTrue();
- }
-
- @Test
- public void shouldShowUninstallForAll_installForSelfOnly_shouldReturnFalse() {
- when(mDevicePolicyManager.packageHasActiveAdmins(nullable(String.class))).thenReturn(false);
- when(mUserManager.getUsers().size()).thenReturn(2);
- ReflectionHelpers.setField(mAppDetail, "mDpm", mDevicePolicyManager);
- ReflectionHelpers.setField(mAppDetail, "mUserManager", mUserManager);
- final ApplicationInfo info = new ApplicationInfo();
- info.flags = ApplicationInfo.FLAG_INSTALLED;
- info.enabled = true;
- final AppEntry appEntry = mock(AppEntry.class);
- appEntry.info = info;
- final PackageInfo packageInfo = mock(PackageInfo.class);
- ReflectionHelpers.setField(mAppDetail, "mPackageInfo", packageInfo);
-
- assertThat(mAppDetail.shouldShowUninstallForAll(appEntry)).isFalse();
- }
-
- @Test
- public void getStorageSummary_shouldWorkForExternal() {
- Context context = RuntimeEnvironment.application.getApplicationContext();
- AppStorageStats stats = mock(AppStorageStats.class);
- when(stats.getTotalBytes()).thenReturn(1L);
-
- assertThat(InstalledAppDetails.getStorageSummary(context, stats, true))
- .isEqualTo("1 B used in external storage");
- }
-
- @Test
- public void getStorageSummary_shouldWorkForInternal() {
- Context context = RuntimeEnvironment.application.getApplicationContext();
- AppStorageStats stats = mock(AppStorageStats.class);
- when(stats.getTotalBytes()).thenReturn(1L);
-
- assertThat(InstalledAppDetails.getStorageSummary(context, stats, false))
- .isEqualTo("1 B used in internal storage");
- }
-
- @Test
- public void launchFragment_hasNoPackageInfo_shouldFinish() {
- ReflectionHelpers.setField(mAppDetail, "mPackageInfo", null);
-
- assertThat(mAppDetail.ensurePackageInfoAvailable(mActivity)).isFalse();
- verify(mActivity).finishAndRemoveTask();
- }
-
- @Test
- public void launchFragment_hasPackageInfo_shouldReturnTrue() {
- final PackageInfo packageInfo = mock(PackageInfo.class);
- ReflectionHelpers.setField(mAppDetail, "mPackageInfo", packageInfo);
-
- assertThat(mAppDetail.ensurePackageInfoAvailable(mActivity)).isTrue();
- verify(mActivity, never()).finishAndRemoveTask();
- }
-
- @Test
- public void packageSizeChange_isOtherPackage_shouldNotRefreshUi() {
- ReflectionHelpers.setField(mAppDetail, "mPackageName", PACKAGE_NAME);
- mAppDetail.onPackageSizeChanged("Not_" + PACKAGE_NAME);
-
- verify(mAppDetail, never()).refreshUi();
- }
-
- @Test
- public void packageSizeChange_isOwnPackage_shouldRefreshUi() {
- doReturn(Boolean.TRUE).when(mAppDetail).refreshUi();
- ReflectionHelpers.setField(mAppDetail, "mPackageName", PACKAGE_NAME);
-
- mAppDetail.onPackageSizeChanged(PACKAGE_NAME);
-
- verify(mAppDetail).refreshUi();
- }
-
- @Test
- public void launchPowerUsageDetailFragment_shouldNotCrash() {
- mAppDetail.mBatteryPreference = mBatteryPreference;
- mAppDetail.mSipper = mBatterySipper;
- mAppDetail.mBatteryHelper = mBatteryStatsHelper;
-
- // Should not crash
- mAppDetail.onPreferenceClick(mBatteryPreference);
- }
-
- // Tests that we don't show the "uninstall for all users" button for instant apps.
- @Test
- public void instantApps_noUninstallForAllButton() {
- // Make this app appear to be instant.
- ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
- (InstantAppDataProvider) (i -> true));
- when(mDevicePolicyManager.packageHasActiveAdmins(nullable(String.class))).thenReturn(false);
- when(mUserManager.getUsers().size()).thenReturn(2);
-
- final ApplicationInfo info = new ApplicationInfo();
- info.enabled = true;
- final AppEntry appEntry = mock(AppEntry.class);
- appEntry.info = info;
- final PackageInfo packageInfo = mock(PackageInfo.class);
-
- ReflectionHelpers.setField(mAppDetail, "mDpm", mDevicePolicyManager);
- ReflectionHelpers.setField(mAppDetail, "mUserManager", mUserManager);
- ReflectionHelpers.setField(mAppDetail, "mPackageInfo", packageInfo);
-
- assertThat(mAppDetail.shouldShowUninstallForAll(appEntry)).isFalse();
- }
-
- // Tests that we don't show the uninstall button for instant apps"
- @Test
- public void instantApps_noUninstallButton() {
- // Make this app appear to be instant.
- ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
- (InstantAppDataProvider) (i -> true));
- final ApplicationInfo info = new ApplicationInfo();
- info.flags = ApplicationInfo.FLAG_INSTALLED;
- info.enabled = true;
- final AppEntry appEntry = mock(AppEntry.class);
- appEntry.info = info;
- final PackageInfo packageInfo = mock(PackageInfo.class);
- packageInfo.applicationInfo = info;
-
- ReflectionHelpers.setField(mAppDetail, "mUserManager", mUserManager);
- ReflectionHelpers.setField(mAppDetail, "mAppEntry", appEntry);
- ReflectionHelpers.setField(mAppDetail, "mPackageInfo", packageInfo);
-
- mAppDetail.initUninstallButtonForUserApp();
- verify(mAppDetail.mActionButtons).setButton1Visible(false);
- }
-
- // Tests that we don't show the force stop button for instant apps (they aren't allowed to run
- // when they aren't in the foreground).
- @Test
- public void instantApps_noForceStop() {
- // Make this app appear to be instant.
- ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
- (InstantAppDataProvider) (i -> true));
- final PackageInfo packageInfo = mock(PackageInfo.class);
- final AppEntry appEntry = mock(AppEntry.class);
- final ApplicationInfo info = new ApplicationInfo();
- appEntry.info = info;
-
- ReflectionHelpers.setField(mAppDetail, "mDpm", mDevicePolicyManager);
- ReflectionHelpers.setField(mAppDetail, "mPackageInfo", packageInfo);
- ReflectionHelpers.setField(mAppDetail, "mAppEntry", appEntry);
-
- mAppDetail.checkForceStop();
- verify(mAppDetail.mActionButtons).setButton2Visible(false);
- }
-
- @Test
- public void instantApps_buttonControllerHandlesDialog() {
- InstantAppButtonsController mockController = mock(InstantAppButtonsController.class);
- ReflectionHelpers.setField(
- mAppDetail, "mInstantAppButtonsController", mockController);
- // Make sure first that button controller is not called for supported dialog id
- AlertDialog mockDialog = mock(AlertDialog.class);
- when(mockController.createDialog(InstantAppButtonsController.DLG_CLEAR_APP))
- .thenReturn(mockDialog);
- assertThat(mAppDetail.createDialog(InstantAppButtonsController.DLG_CLEAR_APP, 0))
- .isEqualTo(mockDialog);
- verify(mockController).createDialog(InstantAppButtonsController.DLG_CLEAR_APP);
- }
-
- // A helper class for testing the InstantAppButtonsController - it lets us look up the
- // preference associated with a key for instant app buttons and get back a mock
- // LayoutPreference (to avoid a null pointer exception).
- public static class InstalledAppDetailsWithMockInstantButtons extends InstalledAppDetails {
- @Mock
- private LayoutPreference mInstantButtons;
-
- public InstalledAppDetailsWithMockInstantButtons() {
- super();
- MockitoAnnotations.initMocks(this);
- }
-
- @Override
- public Preference findPreference(CharSequence key) {
- if (key == "instant_app_buttons") {
- return mInstantButtons;
- }
- return super.findPreference(key);
- }
- }
-
- @Test
- public void instantApps_instantSpecificButtons() {
- // Make this app appear to be instant.
- ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
- (InstantAppDataProvider) (i -> true));
- final PackageInfo packageInfo = mock(PackageInfo.class);
-
- final InstalledAppDetailsWithMockInstantButtons
- fragment = new InstalledAppDetailsWithMockInstantButtons();
- ReflectionHelpers.setField(fragment, "mPackageInfo", packageInfo);
- ReflectionHelpers.setField(fragment, "mApplicationFeatureProvider",
- mFeatureFactory.applicationFeatureProvider);
-
- final InstantAppButtonsController buttonsController =
- mock(InstantAppButtonsController.class);
- when(buttonsController.setPackageName(nullable(String.class)))
- .thenReturn(buttonsController);
- when(mFeatureFactory.applicationFeatureProvider.newInstantAppButtonsController(
- nullable(Fragment.class), nullable(View.class), nullable(ShowDialogDelegate.class)))
- .thenReturn(buttonsController);
-
- fragment.maybeAddInstantAppButtons();
- verify(buttonsController).setPackageName(nullable(String.class));
- verify(buttonsController).show();
- }
-
- @Test
- public void instantApps_removeCorrectPref() {
- PreferenceScreen mockPreferenceScreen = mock(PreferenceScreen.class);
- PreferenceManager mockPreferenceManager = mock(PreferenceManager.class);
- AppDomainsPreference mockAppDomainsPref = mock(AppDomainsPreference.class);
- Preference mockLaunchPreference = mock(Preference.class);
- PackageInfo mockPackageInfo = mock(PackageInfo.class);
- PackageManager mockPackageManager = mock(PackageManager.class);
- ReflectionHelpers.setField(
- mAppDetail, "mLaunchPreference", mockLaunchPreference);
- ReflectionHelpers.setField(
- mAppDetail, "mInstantAppDomainsPreference", mockAppDomainsPref);
- ReflectionHelpers.setField(
- mAppDetail, "mPreferenceManager", mockPreferenceManager);
- ReflectionHelpers.setField(
- mAppDetail, "mPackageInfo", mockPackageInfo);
- ReflectionHelpers.setField(
- mAppDetail, "mPm", mockPackageManager);
- when(mockPreferenceManager.getPreferenceScreen()).thenReturn(mockPreferenceScreen);
-
- ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
- (InstantAppDataProvider) (i -> false));
- mAppDetail.prepareInstantAppPrefs();
-
- // For the non instant case we remove the app domain pref, and leave the launch pref
- verify(mockPreferenceScreen).removePreference(mockAppDomainsPref);
- verify(mockPreferenceScreen, never()).removePreference(mockLaunchPreference);
-
- // For the instant app case we remove the launch preff, and leave the app domain pref
- ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
- (InstantAppDataProvider) (i -> true));
-
- mAppDetail.prepareInstantAppPrefs();
- verify(mockPreferenceScreen).removePreference(mockLaunchPreference);
- // Will be 1 still due to above call
- verify(mockPreferenceScreen, times(1))
- .removePreference(mockAppDomainsPref);
- }
-
- @Test
- public void onActivityResult_uninstalledUpdates_shouldInvalidateOptionsMenu() {
- doReturn(true).when(mAppDetail).refreshUi();
-
- mAppDetail.onActivityResult(InstalledAppDetails.REQUEST_UNINSTALL, 0, mock(Intent.class));
-
- verify(mActivity).invalidateOptionsMenu();
- }
-
- @Test
- public void findTargetSipper_findCorrectSipper() {
- List<BatterySipper> usageList = new ArrayList<>();
- usageList.add(mBatterySipper);
- usageList.add(mOtherBatterySipper);
- doReturn(usageList).when(mBatteryStatsHelper).getUsageList();
-
- assertThat(mAppDetail.findTargetSipper(mBatteryStatsHelper, TARGET_UID)).isEqualTo(
- mBatterySipper);
- }
-
- @Test
- public void updateBattery_noBatteryStats_summaryNo() {
- doReturn(mShadowContext.getString(R.string.no_battery_summary)).when(mAppDetail).getString(
- R.string.no_battery_summary);
- mAppDetail.updateBattery();
-
- assertThat(mBatteryPreference.getSummary()).isEqualTo(
- "No battery use since last full charge");
- }
-
- @Test
- public void updateBattery_hasBatteryStats_summaryPercent() {
- mAppDetail.mBatteryHelper = mBatteryStatsHelper;
- mAppDetail.mSipper = mBatterySipper;
- doReturn(BATTERY_LEVEL).when(mBatteryUtils).calculateBatteryPercent(anyDouble(),
- anyDouble(), anyDouble(), anyInt());
- doReturn(mShadowContext.getString(R.string.battery_summary, BATTERY_LEVEL_STRING)).when(
- mAppDetail).getString(R.string.battery_summary, BATTERY_LEVEL_STRING);
- doReturn(new ArrayList<>()).when(mBatteryStatsHelper).getUsageList();
-
- mAppDetail.updateBattery();
-
- assertThat(mBatteryPreference.getSummary()).isEqualTo("60% use since last full charge");
- }
-
- @Test
- public void isBatteryStatsAvailable_hasBatteryStatsHelperAndSipper_returnTrue() {
- mAppDetail.mBatteryHelper = mBatteryStatsHelper;
- mAppDetail.mSipper = mBatterySipper;
-
- assertThat(mAppDetail.isBatteryStatsAvailable()).isTrue();
- }
-
- @Test
- public void isBatteryStatsAvailable_parametersNull_returnFalse() {
- assertThat(mAppDetail.isBatteryStatsAvailable()).isFalse();
- }
-
- @Test
- public void handleDisableable_appIsHomeApp_buttonShouldNotWork() {
- final ApplicationInfo info = new ApplicationInfo();
- info.packageName = "pkg";
- info.enabled = true;
- final AppEntry appEntry = mock(AppEntry.class);
- appEntry.info = info;
- final HashSet<String> homePackages = new HashSet<>();
- homePackages.add(info.packageName);
-
- ReflectionHelpers.setField(mAppDetail, "mHomePackages", homePackages);
- ReflectionHelpers.setField(mAppDetail, "mAppEntry", appEntry);
-
- assertThat(mAppDetail.handleDisableable()).isFalse();
- verify(mAppDetail.mActionButtons).setButton1Text(R.string.disable_text);
- }
-
- @Test
- public void handleDisableable_appIsEnabled_buttonShouldWork() {
- final ApplicationInfo info = new ApplicationInfo();
- info.packageName = "pkg";
- info.enabled = true;
- info.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
-
- final AppEntry appEntry = mock(AppEntry.class);
- appEntry.info = info;
- when(mFeatureFactory.applicationFeatureProvider.getKeepEnabledPackages()).thenReturn(
- new HashSet<>());
-
- ReflectionHelpers.setField(mAppDetail, "mApplicationFeatureProvider",
- mFeatureFactory.applicationFeatureProvider);
- ReflectionHelpers.setField(mAppDetail, "mAppEntry", appEntry);
-
- assertThat(mAppDetail.handleDisableable()).isTrue();
- verify(mAppDetail.mActionButtons).setButton1Text(R.string.disable_text);
- }
-
- @Test
- @Config(shadows = ShadowUtils.class)
- public void handleDisableable_appIsDisabled_buttonShouldShowEnable() {
- final ApplicationInfo info = new ApplicationInfo();
- info.packageName = "pkg";
- info.enabled = false;
- info.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
-
- final AppEntry appEntry = mock(AppEntry.class);
- appEntry.info = info;
- when(mFeatureFactory.applicationFeatureProvider.getKeepEnabledPackages()).thenReturn(
- new HashSet<>());
-
- ReflectionHelpers.setField(mAppDetail, "mApplicationFeatureProvider",
- mFeatureFactory.applicationFeatureProvider);
- ReflectionHelpers.setField(mAppDetail, "mAppEntry", appEntry);
-
- assertThat(mAppDetail.handleDisableable()).isTrue();
- verify(mAppDetail.mActionButtons).setButton1Text(R.string.enable_text);
- verify(mAppDetail.mActionButtons).setButton1Positive(true);
- }
-
- @Test
- public void handleDisableable_appIsEnabledAndInKeepEnabledWhitelist_buttonShouldNotWork() {
- final ApplicationInfo info = new ApplicationInfo();
- info.packageName = "pkg";
- info.enabled = true;
- info.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
-
- final AppEntry appEntry = mock(AppEntry.class);
- appEntry.info = info;
-
- final HashSet<String> packages = new HashSet<>();
- packages.add(info.packageName);
- when(mFeatureFactory.applicationFeatureProvider.getKeepEnabledPackages()).thenReturn(
- packages);
-
- ReflectionHelpers.setField(mAppDetail, "mApplicationFeatureProvider",
- mFeatureFactory.applicationFeatureProvider);
- ReflectionHelpers.setField(mAppDetail, "mAppEntry", appEntry);
-
- assertThat(mAppDetail.handleDisableable()).isFalse();
- verify(mAppDetail.mActionButtons).setButton1Text(R.string.disable_text);
- }
-
- @Test
- public void testRestartBatteryStatsLoader() {
- doReturn(mLoaderManager).when(mAppDetail).getLoaderManager();
-
- mAppDetail.restartBatteryStatsLoader();
-
- verify(mLoaderManager).restartLoader(InstalledAppDetails.LOADER_BATTERY, Bundle.EMPTY,
- mAppDetail.mBatteryCallbacks);
- }
-
- @Test
- public void initUninstallButtonForUserApp_shouldSetNegativeButton() {
- final ApplicationInfo info = new ApplicationInfo();
- info.flags = ApplicationInfo.FLAG_INSTALLED;
- info.enabled = true;
- final PackageInfo packageInfo = mock(PackageInfo.class);
- packageInfo.applicationInfo = info;
- ReflectionHelpers.setField(mAppDetail, "mUserManager", mUserManager);
- ReflectionHelpers.setField(mAppDetail, "mPackageInfo", packageInfo);
-
- mAppDetail.initUninstallButtonForUserApp();
-
- verify(mAppDetail.mActionButtons).setButton1Positive(false);
- }
-
- @Implements(Utils.class)
- public static class ShadowUtils {
- @Implementation
- public static boolean isSystemPackage(Resources resources, PackageManager pm,
- PackageInfo pkg) {
- return false;
- }
- }
-}
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceControllerTest.java
index 7d5eb31..70b9cc9 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceControllerTest.java
@@ -18,27 +18,18 @@
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.content.BroadcastReceiver;
import android.content.Context;
-import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.content.res.Resources;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.UserHandle;
import android.os.UserManager;
import android.support.v7.preference.PreferenceScreen;
@@ -120,16 +111,14 @@
}
@Test
- public void displayPreference_shouldInitializeForceStopButton() {
+ public void displayPreference_shouldSetButton2Invisible() {
final PreferenceScreen screen = mock(PreferenceScreen.class);
final ActionButtonPreference preference = spy(new ActionButtonPreference(mContext));
when(screen.findPreference(mController.getPreferenceKey())).thenReturn(preference);
mController.displayPreference(screen);
- verify(preference).setButton2Positive(false);
- verify(preference).setButton2Text(R.string.force_stop);
- verify(preference).setButton2Enabled(false);
+ verify(preference).setButton2Visible(false);
}
@Test
@@ -138,14 +127,12 @@
final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class);
final ApplicationInfo info = new ApplicationInfo();
appEntry.info = info;
- doNothing().when(mController).checkForceStop(appEntry, packageInfo);
doNothing().when(mController).initUninstallButtons(appEntry, packageInfo);
when(mFragment.getAppEntry()).thenReturn(appEntry);
when(mFragment.getPackageInfo()).thenReturn(packageInfo);
mController.refreshUi();
- verify(mController).checkForceStop(appEntry, packageInfo);
verify(mController).initUninstallButtons(appEntry, packageInfo);
}
@@ -198,71 +185,6 @@
assertThat(mController.initUninstallButtonForUserApp()).isFalse();
}
- // Tests that we don't show the force stop button for instant apps (they aren't allowed to run
- // when they aren't in the foreground).
- @Test
- public void checkForceStop_instantApps_shouldNotShowForceStop() {
- // Make this app appear to be instant.
- ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
- (InstantAppDataProvider) (i -> true));
- final PackageInfo packageInfo = mock(PackageInfo.class);
- final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class);
- final ApplicationInfo info = new ApplicationInfo();
- appEntry.info = info;
-
- mController.checkForceStop(appEntry, packageInfo);
-
- verify(mController.mActionButtons).setButton2Visible(false);
- }
-
- @Test
- public void checkForceStop_hasActiveAdmin_shouldDisableForceStop() {
- ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
- (InstantAppDataProvider) (i -> false));
- final String packageName = "Package1";
- final PackageInfo packageInfo = new PackageInfo();
- packageInfo.packageName = packageName;
- final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class);
- when(mDevicePolicyManager.packageHasActiveAdmins(packageName)).thenReturn(true);
-
- mController.checkForceStop(appEntry, packageInfo);
-
- verify(mController.mActionButtons).setButton2Enabled(false);
- }
-
- @Test
- public void checkForceStop_appRunning_shouldEnableForceStop() {
- ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
- (InstantAppDataProvider) (i -> false));
- final PackageInfo packageInfo = mock(PackageInfo.class);
- final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class);
- final ApplicationInfo info = new ApplicationInfo();
- appEntry.info = info;
-
- mController.checkForceStop(appEntry, packageInfo);
-
- verify(mController.mActionButtons).setButton2Enabled(true);
- }
-
- @Test
- public void checkForceStop_appStopped_shouldQueryPackageRestart() {
- ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
- (InstantAppDataProvider) (i -> false));
- final PackageInfo packageInfo = mock(PackageInfo.class);
- final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class);
- final ApplicationInfo info = new ApplicationInfo();
- appEntry.info = info;
- info.flags = ApplicationInfo.FLAG_STOPPED;
- info.packageName = "com.android.setting";
-
- mController.checkForceStop(appEntry, packageInfo);
-
- verify(mContext).sendOrderedBroadcastAsUser(argThat(intent-> intent != null
- && intent.getAction().equals(Intent.ACTION_QUERY_PACKAGE_RESTART)),
- any(UserHandle.class), nullable(String.class), any(BroadcastReceiver.class),
- nullable(Handler.class), anyInt(), nullable(String.class), nullable(Bundle.class));
- }
-
@Test
public void handleDisableable_appIsHomeApp_buttonShouldNotWork() {
final ApplicationInfo info = new ApplicationInfo();
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceControllerTest.java
index ee870b7..7108ef0 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppHeaderViewPreferenceControllerTest.java
@@ -42,7 +42,9 @@
import com.android.settings.TestConfig;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.applications.AppUtils;
import com.android.settingslib.applications.ApplicationsState;
+import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
@@ -53,6 +55,7 @@
import org.robolectric.Robolectric;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@@ -103,7 +106,8 @@
appEntry.info = info;
when(mFragment.getAppEntry()).thenReturn(appEntry);
when(mFragment.getPackageInfo()).thenReturn(packageInfo);
-
+ ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
+ (InstantAppDataProvider) (i -> false));
final TextView title = mHeader.findViewById(R.id.entity_header_title);
final TextView summary = mHeader.findViewById(R.id.entity_header_summary);
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/ForceStopOptionsMenuControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/ForceStopOptionsMenuControllerTest.java
new file mode 100644
index 0000000..4719008
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/ForceStopOptionsMenuControllerTest.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2018 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.appinfo;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.doNothing;
+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;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.view.Menu;
+import android.view.MenuItem;
+
+import com.android.settings.R;
+import com.android.settings.SettingsActivity;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.wrapper.DevicePolicyManagerWrapper;
+import com.android.settingslib.applications.AppUtils;
+import com.android.settingslib.applications.ApplicationsState.AppEntry;
+import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
+
+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.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(
+ manifest = TestConfig.MANIFEST_PATH,
+ sdk = TestConfig.SDK_VERSION
+)
+public final class ForceStopOptionsMenuControllerTest {
+
+ private static final String PACKAGE_NAME = "test_package_name";
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private UserManager mUserManager;
+ @Mock
+ private SettingsActivity mActivity;
+ @Mock
+ private DevicePolicyManagerWrapper mDevicePolicyManager;
+ @Mock
+ private PackageManager mPackageManager;
+
+ private AppInfoDashboardFragment mFragment;
+ private ForceStopOptionsMenuController mController;
+ private Context mShadowContext;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mShadowContext = spy(RuntimeEnvironment.application);
+ mFragment = spy(new AppInfoDashboardFragment());
+ ReflectionHelpers.setField(mFragment, "mDpm", mDevicePolicyManager);
+ ReflectionHelpers.setField(mFragment, "mUserManager", mUserManager);
+ doReturn(mActivity).when(mFragment).getActivity();
+ doReturn(mShadowContext).when(mFragment).getContext();
+ doReturn(mPackageManager).when(mActivity).getPackageManager();
+ when(mShadowContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+ mController = spy(new ForceStopOptionsMenuController(
+ mShadowContext, mFragment, mDevicePolicyManager,
+ null /* metricsFeatureProvider */, null /* lifecycle */));
+
+ // Default to not considering any apps to be instant (individual tests can override this).
+ ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
+ (InstantAppDataProvider) (i -> false));
+ }
+
+ @Test
+ public void onCreateOptionsMenu_shouldAddForceStop() {
+ final Menu menu = mock(Menu.class);
+ when(menu.add(anyInt(), anyInt(), anyInt(), anyInt())).thenReturn(mock(MenuItem.class));
+
+ mController.onCreateOptionsMenu(menu, null /* inflater */);
+
+ verify(menu).add(anyInt(), eq(AppInfoDashboardFragment.FORCE_STOP_MENU), anyInt(),
+ eq(R.string.force_stop));
+ }
+
+ @Test
+ public void onPrepareOptionsMenu_shouldUpdateForceStopMenu() {
+ final Menu menu = mock(Menu.class);
+ doNothing().when(mController).updateForceStopMenu(any(), any());
+ doReturn(mock(AppEntry.class)).when(mFragment).getAppEntry();
+ doReturn(mock(PackageInfo.class)).when(mFragment).getPackageInfo();
+
+ mController.onPrepareOptionsMenu(menu);
+
+ verify(mController).updateForceStopMenu(any(), any());
+ }
+
+ @Test
+ public void onOptionsItemSelected_shouldHandleForceStopMenuClick() {
+ doReturn(mock(AppEntry.class)).when(mFragment).getAppEntry();
+ doNothing().when(mController).handleForceStopMenuClick();
+ final MenuItem menu = mock(MenuItem.class);
+ when(menu.getItemId()).thenReturn(AppInfoDashboardFragment.FORCE_STOP_MENU);
+
+ mController.onOptionsItemSelected(menu);
+
+ verify(mController).handleForceStopMenuClick();
+ }
+
+ // Tests that we don't show the force stop button for instant apps (they aren't allowed to run
+ // when they aren't in the foreground).
+ @Test
+ public void updateForceStopMenu_instantApps_shouldNotShowForceStop() {
+ when(mDevicePolicyManager.packageHasActiveAdmins(nullable(String.class))).thenReturn(false);
+ final MenuItem forceStopMenu = mock(MenuItem.class);
+ ReflectionHelpers.setField(mController, "mForceStopMenu", forceStopMenu);
+ // Make this app appear to be instant.
+ ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
+ (InstantAppDataProvider) (i -> true));
+ final PackageInfo packageInfo = mock(PackageInfo.class);
+ final AppEntry appEntry = mock(AppEntry.class);
+ final ApplicationInfo info = new ApplicationInfo();
+ appEntry.info = info;
+
+ mController.updateForceStopMenu(appEntry, packageInfo);
+
+ verify(forceStopMenu).setVisible(false);
+ }
+
+ @Test
+ public void updateForceStopMenu_hasActiveAdmin_shouldDisableForceStop() {
+ when(mDevicePolicyManager.packageHasActiveAdmins(nullable(String.class))).thenReturn(false);
+ final MenuItem forceStopMenu = mock(MenuItem.class);
+ ReflectionHelpers.setField(mController, "mForceStopMenu", forceStopMenu);
+ ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
+ (InstantAppDataProvider) (i -> false));
+ final String packageName = "Package1";
+ final PackageInfo packageInfo = new PackageInfo();
+ packageInfo.packageName = packageName;
+ final AppEntry appEntry = mock(AppEntry.class);
+ when(mDevicePolicyManager.packageHasActiveAdmins(packageName)).thenReturn(true);
+
+ mController.updateForceStopMenu(appEntry, packageInfo);
+
+ verify(forceStopMenu).setEnabled(false);
+ }
+
+ @Test
+ public void updateForceStopMenu_appRunning_shouldEnableForceStop() {
+ when(mDevicePolicyManager.packageHasActiveAdmins(nullable(String.class))).thenReturn(false);
+ final MenuItem forceStopMenu = mock(MenuItem.class);
+ ReflectionHelpers.setField(mController, "mForceStopMenu", forceStopMenu);
+ ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
+ (InstantAppDataProvider) (i -> false));
+ final PackageInfo packageInfo = mock(PackageInfo.class);
+ final AppEntry appEntry = mock(AppEntry.class);
+ final ApplicationInfo info = new ApplicationInfo();
+ appEntry.info = info;
+
+ mController.updateForceStopMenu(appEntry, packageInfo);
+
+ verify(forceStopMenu).setEnabled(true);
+ }
+
+ @Test
+ public void updateForceStopMenu_appStopped_shouldQueryPackageRestart() {
+ when(mDevicePolicyManager.packageHasActiveAdmins(nullable(String.class))).thenReturn(false);
+ ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
+ (InstantAppDataProvider) (i -> false));
+ final PackageInfo packageInfo = mock(PackageInfo.class);
+ final AppEntry appEntry = mock(AppEntry.class);
+ final ApplicationInfo info = new ApplicationInfo();
+ appEntry.info = info;
+ info.flags = ApplicationInfo.FLAG_STOPPED;
+ info.packageName = "com.android.setting";
+
+ mController.updateForceStopMenu(appEntry, packageInfo);
+
+ verify(mShadowContext).sendOrderedBroadcastAsUser(argThat(intent-> intent != null
+ && intent.getAction().equals(Intent.ACTION_QUERY_PACKAGE_RESTART)),
+ any(UserHandle.class), nullable(String.class), any(BroadcastReceiver.class),
+ nullable(Handler.class), anyInt(), nullable(String.class), nullable(Bundle.class));
+ }
+
+}
diff --git a/tests/robotests/src/com/android/settings/core/XmlControllerAttributeTest.java b/tests/robotests/src/com/android/settings/core/XmlControllerAttributeTest.java
index e6ca59b..e69b97e 100644
--- a/tests/robotests/src/com/android/settings/core/XmlControllerAttributeTest.java
+++ b/tests/robotests/src/com/android/settings/core/XmlControllerAttributeTest.java
@@ -19,7 +19,6 @@
import com.android.settings.search.SearchFeatureProviderImpl;
import com.android.settings.search.XmlParserUtils;
import com.android.settings.security.SecuritySettings;
-import com.android.settings.security.SecuritySettingsV2;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
@@ -32,7 +31,6 @@
import org.xmlpull.v1.XmlPullParser;
import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -47,25 +45,13 @@
// List of classes that are too hard to mock in order to retrieve xml information.
private final List<Class> illegalClasses = new ArrayList<>(
Arrays.asList(
- SecuritySettings.class,
- SecuritySettingsV2.class
+ SecuritySettings.class
));
// List of XML that could be retrieved from the illegalClasses list.
private final List<Integer> whitelistXml = new ArrayList<>(
Arrays.asList(
- R.xml.security_settings_misc,
- R.xml.security_settings_lockscreen_profile,
- R.xml.security_settings_lockscreen,
- R.xml.security_settings_chooser,
- R.xml.security_settings_pattern_profile,
- R.xml.security_settings_pin_profile,
- R.xml.security_settings_password_profile,
- R.xml.security_settings_pattern,
- R.xml.security_settings_pin,
- R.xml.security_settings_password,
- R.xml.security_settings,
- R.xml.security_settings_status
+ R.xml.security_dashboard_settings
));
private static final String NO_VALID_CONSTRUCTOR_ERROR =
diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2Test.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2Test.java
index 1e76e2d..181c878 100644
--- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2Test.java
+++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2Test.java
@@ -17,12 +17,19 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.app.PendingIntent;
import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
import android.service.settings.suggestions.Suggestion;
import android.view.LayoutInflater;
import android.view.View;
@@ -46,6 +53,7 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.List;
@@ -200,7 +208,71 @@
mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
mSuggestionHolder.itemView.findViewById(R.id.close_button).performClick();
- verify(callback).onSuggestionClosed(suggestions.get(0));
+ final Suggestion suggestion = suggestions.get(0);
+ verify(mFeatureFactory.suggestionsFeatureProvider).dismissSuggestion(
+ mActivity, mSuggestionControllerMixin, suggestion);
+ verify(callback).onSuggestionClosed(suggestion);
+ }
+
+ @Test
+ public void onBindViewHolder_differentPackage_shouldNotTintIcon()
+ throws PendingIntent.CanceledException {
+ final Icon icon = mock(Icon.class);
+ when(icon.getResPackage()).thenReturn("pkg1");
+ when(mActivity.getPackageName()).thenReturn("pkg2");
+ final Suggestion suggestion = new Suggestion.Builder("pkg1")
+ .setPendingIntent(mock(PendingIntent.class))
+ .setIcon(icon)
+ .build();
+ final List<Suggestion> suggestions = new ArrayList<>();
+ suggestions.add(suggestion);
+ mSuggestionAdapter = new SuggestionAdapterV2(mActivity, mSuggestionControllerMixin,
+ null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
+ mSuggestionAdapter.setSuggestions(suggestions);
+ mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
+ new FrameLayout(RuntimeEnvironment.application),
+ mSuggestionAdapter.getItemViewType(0));
+ DashboardAdapterV2.IconCache cache = mock(DashboardAdapterV2.IconCache.class);
+ final Drawable drawable = mock(Drawable.class);
+ when(cache.getIcon(icon)).thenReturn(drawable);
+ ReflectionHelpers.setField(mSuggestionAdapter, "mCache", cache);
+
+ mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
+
+ verify(drawable, never()).setTint(anyInt());
+ }
+
+ @Test
+ public void onBindViewHolder_samePackage_shouldTintIcon()
+ throws PendingIntent.CanceledException {
+ final Icon icon = mock(Icon.class);
+ final String packageName = "pkg1";
+ when(icon.getResPackage()).thenReturn(packageName);
+ when(mActivity.getPackageName()).thenReturn(packageName);
+ final Suggestion suggestion = new Suggestion.Builder(packageName)
+ .setPendingIntent(mock(PendingIntent.class))
+ .setIcon(icon)
+ .build();
+ final List<Suggestion> suggestions = new ArrayList<>();
+ suggestions.add(suggestion);
+ mSuggestionAdapter = new SuggestionAdapterV2(mActivity, mSuggestionControllerMixin,
+ null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
+ mSuggestionAdapter.setSuggestions(suggestions);
+ mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
+ new FrameLayout(RuntimeEnvironment.application),
+ mSuggestionAdapter.getItemViewType(0));
+ DashboardAdapterV2.IconCache cache = mock(DashboardAdapterV2.IconCache.class);
+ final Drawable drawable = mock(Drawable.class);
+ when(cache.getIcon(icon)).thenReturn(drawable);
+ ReflectionHelpers.setField(mSuggestionAdapter, "mCache", cache);
+ TypedArray typedArray = mock(TypedArray.class);
+ final int colorAccent = 1234;
+ when(mActivity.obtainStyledAttributes(any())).thenReturn(typedArray);
+ when(typedArray.getColor(anyInt(), anyInt())).thenReturn(colorAccent);
+
+ mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
+
+ verify(drawable).setTint(colorAccent);
}
private void setupSuggestions(Context context, List<Suggestion> suggestions) {
diff --git a/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java b/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java
index 7cd09de..58643b6 100644
--- a/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java
@@ -29,8 +29,8 @@
import static org.mockito.Mockito.when;
import android.content.pm.PackageManager;
+import android.net.NetworkPolicyManager;
import android.os.Bundle;
-import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.PreferenceManager;
import android.support.v7.preference.PreferenceScreen;
import android.util.ArraySet;
@@ -40,8 +40,11 @@
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
+import com.android.settings.testutils.shadow.ShadowRestrictedLockUtils;
import com.android.settings.widget.EntityHeaderController;
import com.android.settingslib.AppItem;
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedSwitchPreference;
import com.android.settingslib.wrapper.PackageManagerWrapper;
import org.junit.After;
@@ -57,7 +60,10 @@
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
- shadows = ShadowEntityHeaderController.class)
+ shadows = {
+ ShadowEntityHeaderController.class,
+ ShadowRestrictedLockUtils.class
+ })
public class AppDataUsageTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
@@ -134,7 +140,7 @@
public void changePreference_backgroundData_shouldUpdateUI() {
mFragment = spy(new AppDataUsage());
final AppItem appItem = new AppItem(123456789);
- final SwitchPreference pref = mock(SwitchPreference.class);
+ final RestrictedSwitchPreference pref = mock(RestrictedSwitchPreference.class);
final DataSaverBackend dataSaverBackend = mock(DataSaverBackend.class);
ReflectionHelpers.setField(mFragment, "mAppItem", appItem);
ReflectionHelpers.setField(mFragment, "mRestrictBackground", pref);
@@ -146,4 +152,31 @@
verify(mFragment).updatePrefs();
}
+
+ @Test
+ public void updatePrefs_restrictedByAdmin_shouldDisablePreference() {
+ mFragment = spy(new AppDataUsage());
+ final int testUid = 123123;
+ final AppItem appItem = new AppItem(testUid);
+ final RestrictedSwitchPreference restrictBackgroundPref
+ = mock(RestrictedSwitchPreference.class);
+ final RestrictedSwitchPreference unrestrictedDataPref
+ = mock(RestrictedSwitchPreference.class);
+ final DataSaverBackend dataSaverBackend = mock(DataSaverBackend.class);
+ final NetworkPolicyManager networkPolicyManager = mock(NetworkPolicyManager.class);
+ ReflectionHelpers.setField(mFragment, "mAppItem", appItem);
+ ReflectionHelpers.setField(mFragment, "mRestrictBackground", restrictBackgroundPref);
+ ReflectionHelpers.setField(mFragment, "mUnrestrictedData", unrestrictedDataPref);
+ ReflectionHelpers.setField(mFragment, "mDataSaverBackend", dataSaverBackend);
+ ReflectionHelpers.setField(mFragment.services, "mPolicyManager", networkPolicyManager);
+
+ ShadowRestrictedLockUtils.setRestricted(true);
+ doReturn(NetworkPolicyManager.POLICY_NONE).when(networkPolicyManager)
+ .getUidPolicy(testUid);
+
+ mFragment.updatePrefs();
+
+ verify(restrictBackgroundPref).setDisabledByAdmin(any(EnforcedAdmin.class));
+ verify(unrestrictedDataPref).setDisabledByAdmin(any(EnforcedAdmin.class));
+ }
}
diff --git a/tests/robotests/src/com/android/settings/datausage/UnrestrictedDataAccessTest.java b/tests/robotests/src/com/android/settings/datausage/UnrestrictedDataAccessTest.java
index 53cb7ed..fff879f 100644
--- a/tests/robotests/src/com/android/settings/datausage/UnrestrictedDataAccessTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/UnrestrictedDataAccessTest.java
@@ -16,41 +16,68 @@
package com.android.settings.datausage;
import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.os.Process;
+import android.support.v7.preference.PreferenceManager;
+import android.support.v7.preference.PreferenceScreen;
import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
import com.android.settings.TestConfig;
+import com.android.settings.datausage.AppStateDataUsageBridge.DataUsageState;
+import com.android.settings.datausage.UnrestrictedDataAccess.AccessPreference;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settingslib.applications.ApplicationsState;
+import com.android.settings.testutils.shadow.ShadowRestrictedLockUtils;
+import com.android.settingslib.applications.ApplicationsState.AppEntry;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
+
+import java.util.ArrayList;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
+ shadows = {
+ ShadowRestrictedLockUtils.class
+ })
public class UnrestrictedDataAccessTest {
@Mock
- private ApplicationsState.AppEntry mAppEntry;
+ private AppEntry mAppEntry;
private UnrestrictedDataAccess mFragment;
private FakeFeatureFactory mFeatureFactory;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+ @Mock
+ private PreferenceManager mPreferenceManager;
+ @Mock
+ private DataSaverBackend mDataSaverBackend;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mFeatureFactory = FakeFeatureFactory.setupForTest();
- mFragment = new UnrestrictedDataAccess();
+ mFragment = spy(new UnrestrictedDataAccess());
}
@Test
@@ -80,4 +107,66 @@
eq(MetricsProto.MetricsEvent.APP_SPECIAL_PERMISSION_UNL_DATA_DENY), eq("app"));
}
+ @Test
+ public void testOnRebuildComplete_restricted_shouldBeDisabled() {
+ final Context context = RuntimeEnvironment.application;
+ doReturn(context).when(mFragment).getContext();
+ doReturn(context).when(mPreferenceManager).getContext();
+ doReturn(true).when(mFragment).shouldAddPreference(any(AppEntry.class));
+ doNothing().when(mFragment).setLoading(anyBoolean(), anyBoolean());
+ doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen();
+ doReturn(mPreferenceManager).when(mFragment).getPreferenceManager();
+ ReflectionHelpers.setField(mFragment, "mDataSaverBackend", mDataSaverBackend);
+
+ final String testPkg1 = "com.example.one";
+ final String testPkg2 = "com.example.two";
+ ShadowRestrictedLockUtils.setRestrictedPkgs(testPkg2);
+
+ doAnswer((invocation) -> {
+ final AccessPreference preference = invocation.getArgument(0);
+ final AppEntry entry = preference.getEntryForTest();
+ // Verify preference is disabled by admin and the summary is changed accordingly.
+ if (testPkg1.equals(entry.info.packageName)) {
+ assertThat(preference.isDisabledByAdmin()).isFalse();
+ assertThat(preference.getSummary()).isEqualTo("");
+ } else if (testPkg2.equals(entry.info.packageName)) {
+ assertThat(preference.isDisabledByAdmin()).isTrue();
+ assertThat(preference.getSummary()).isEqualTo(
+ context.getString(R.string.disabled_by_admin));
+ }
+ assertThat(preference.isChecked()).isFalse();
+ preference.performClick();
+ // Verify that when the preference is clicked, support details intent is launched
+ // if the preference is disabled by admin, otherwise the switch is toggled.
+ if (testPkg1.equals(entry.info.packageName)) {
+ assertThat(preference.isChecked()).isTrue();
+ assertThat(ShadowRestrictedLockUtils.hasAdminSupportDetailsIntentLaunched())
+ .isFalse();
+ } else if (testPkg2.equals(entry.info.packageName)) {
+ assertThat(preference.isChecked()).isFalse();
+ assertThat(ShadowRestrictedLockUtils.hasAdminSupportDetailsIntentLaunched())
+ .isTrue();
+ }
+ ShadowRestrictedLockUtils.clearAdminSupportDetailsIntentLaunch();
+ return null;
+ }).when(mPreferenceScreen).addPreference(any(AccessPreference.class));
+ mFragment.onRebuildComplete(createAppEntries(testPkg1, testPkg2));
+ }
+
+ private ArrayList<AppEntry> createAppEntries(String... packageNames) {
+ final ArrayList<AppEntry> appEntries = new ArrayList<>();
+ for (int i = 0; i < packageNames.length; ++i) {
+ final ApplicationInfo info = new ApplicationInfo();
+ info.packageName = packageNames[i];
+ info.uid = Process.FIRST_APPLICATION_UID + i;
+ info.sourceDir = info.packageName;
+ final AppEntry appEntry = spy(new AppEntry(RuntimeEnvironment.application,
+ info, i));
+ appEntry.extraInfo = new DataUsageState(false, false);
+ doNothing().when(appEntry).ensureLabel(any(Context.class));
+ ReflectionHelpers.setField(appEntry, "info", info);
+ appEntries.add(appEntry);
+ }
+ return appEntries;
+ }
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryLegacyTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryLegacyTest.java
index 45448a9..e707ede 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryLegacyTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryLegacyTest.java
@@ -15,8 +15,8 @@
*/
package com.android.settings.fuelgauge;
-import static com.android.settings.fuelgauge.PowerUsageSummary.MENU_HIGH_POWER_APPS;
-import static com.android.settings.fuelgauge.PowerUsageSummary.MENU_TOGGLE_APPS;
+import static com.android.settings.fuelgauge.PowerUsageSummaryLegacy.MENU_HIGH_POWER_APPS;
+import static com.android.settings.fuelgauge.PowerUsageSummaryLegacy.MENU_TOGGLE_APPS;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
index 6fecf3c..35af8bb 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
@@ -16,7 +16,6 @@
package com.android.settings.fuelgauge;
import static com.android.settings.fuelgauge.PowerUsageSummary.MENU_HIGH_POWER_APPS;
-import static com.android.settings.fuelgauge.PowerUsageSummary.MENU_TOGGLE_APPS;
import static com.google.common.truth.Truth.assertThat;
@@ -170,7 +169,6 @@
doReturn(mock(LoaderManager.class)).when(mFragment).getLoaderManager();
when(mFragment.getActivity()).thenReturn(mSettingsActivity);
- when(mToggleAppsMenu.getItemId()).thenReturn(MENU_TOGGLE_APPS);
when(mHighPowerMenu.getItemId()).thenReturn(MENU_HIGH_POWER_APPS);
when(mFeatureFactory.powerUsageFeatureProvider.getAdditionalBatteryInfoIntent())
.thenReturn(sAdditionalBatteryInfoIntent);
@@ -215,39 +213,6 @@
}
@Test
- public void testOptionsMenu_menuAppToggle_metricEventInvoked() {
- mFragment.onOptionsItemSelected(mToggleAppsMenu);
- mFragment.mShowAllApps = false;
-
- verify(mFeatureFactory.metricsFeatureProvider).action(mContext,
- MetricsProto.MetricsEvent.ACTION_SETTINGS_MENU_BATTERY_APPS_TOGGLE, true);
- }
-
- @Test
- public void testOptionsMenu_toggleAppsEnabled() {
- when(mFeatureFactory.powerUsageFeatureProvider.isPowerAccountingToggleEnabled())
- .thenReturn(true);
- mFragment.mShowAllApps = false;
-
- mFragment.onCreateOptionsMenu(mMenu, mMenuInflater);
-
- verify(mMenu).add(Menu.NONE, MENU_TOGGLE_APPS, Menu.NONE, R.string.show_all_apps);
- }
-
- @Test
- public void testOptionsMenu_clickToggleAppsMenu_dataChanged() {
- testToggleAllApps(true);
- testToggleAllApps(false);
- }
-
- private void testToggleAllApps(final boolean isShowApps) {
- mFragment.mShowAllApps = isShowApps;
-
- mFragment.onOptionsItemSelected(mToggleAppsMenu);
- assertThat(mFragment.mShowAllApps).isEqualTo(!isShowApps);
- }
-
- @Test
public void testUpdateLastFullChargePreference_showCorrectSummary() {
doReturn(mRealContext).when(mFragment).getContext();
@@ -324,18 +289,6 @@
}
@Test
- public void testSaveInstanceState_showAllAppsRestored() {
- Bundle bundle = new Bundle();
- mFragment.mShowAllApps = true;
- doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen();
-
- mFragment.onSaveInstanceState(bundle);
- mFragment.restoreSavedInstance(bundle);
-
- assertThat(mFragment.mShowAllApps).isTrue();
- }
-
- @Test
public void testDebugMode() {
doReturn(true).when(mFeatureFactory.powerUsageFeatureProvider).isEstimateDebugEnabled();
diff --git a/tests/robotests/src/com/android/settings/location/RecentLocationRequestPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/RecentLocationRequestPreferenceControllerTest.java
index f114ff3..7f495ab 100644
--- a/tests/robotests/src/com/android/settings/location/RecentLocationRequestPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/location/RecentLocationRequestPreferenceControllerTest.java
@@ -33,14 +33,11 @@
import android.support.v7.preference.PreferenceCategory;
import android.support.v7.preference.PreferenceScreen;
import android.text.TextUtils;
-import android.util.FeatureFlagUtils;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.TestConfig;
-import com.android.settings.applications.InstalledAppDetails;
import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
-import com.android.settings.core.FeatureFlags;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.widget.AppPreference;
import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -179,15 +176,9 @@
preference.performClick();
- if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.APP_INFO_V2)) {
- verify(activity).startPreferencePanelAsUser(any(),
- eq(AppInfoDashboardFragment.class.getName()),
- any(Bundle.class), anyInt(), any(), any());
- } else {
- verify(activity).startPreferencePanelAsUser(any(),
- eq(InstalledAppDetails.class.getName()),
- any(Bundle.class), anyInt(), any(), any());
- }
+ verify(activity).startPreferencePanelAsUser(any(),
+ eq(AppInfoDashboardFragment.class.getName()),
+ any(Bundle.class), anyInt(), any(), any());
}
private static ArgumentMatcher<Preference> titleMatches(String expected) {
diff --git a/tests/robotests/src/com/android/settings/security/LockUnificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/LockUnificationPreferenceControllerTest.java
index 7a5a9fa..2b612e1 100644
--- a/tests/robotests/src/com/android/settings/security/LockUnificationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/security/LockUnificationPreferenceControllerTest.java
@@ -55,7 +55,7 @@
@Mock
private PreferenceScreen mScreen;
@Mock
- private SecuritySettingsV2 mHost;
+ private SecuritySettings mHost;
private FakeFeatureFactory mFeatureFactory;
private Context mContext;
diff --git a/tests/robotests/src/com/android/settings/security/SecurityFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/security/SecurityFeatureProviderImplTest.java
index 627ecf5..86ba40f 100644
--- a/tests/robotests/src/com/android/settings/security/SecurityFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/security/SecurityFeatureProviderImplTest.java
@@ -16,192 +16,51 @@
package com.android.settings.security;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
+import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
-import android.content.Intent;
import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
-import com.android.settings.R;
+import com.android.internal.widget.LockPatternUtils;
import com.android.settings.TestConfig;
+import com.android.settings.security.trustagent.TrustAgentManager;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.testutils.shadow.ShadowTileUtils;
-import com.android.settingslib.drawer.DashboardCategory;
-import com.android.settingslib.drawer.Tile;
-import com.android.settingslib.drawer.TileUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-import org.robolectric.shadows.ShadowLooper;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SecurityFeatureProviderImplTest {
- private static final String MOCK_KEY = "key";
- private static final String MOCK_SUMMARY = "summary";
- private static final String URI_GET_SUMMARY = "content://package/text/summary";
- private static final String URI_GET_ICON = "content://package/icon/my_icon";
-
- @Mock
- private Drawable mMockDrawable;
- @Mock
private Context mContext;
- @Mock
- private PackageManager mPackageManager;
- @Mock
- private Resources mResources;
-
private SecurityFeatureProviderImpl mImpl;
@Before
public void setUp() throws PackageManager.NameNotFoundException {
MockitoAnnotations.initMocks(this);
- mContext = spy(RuntimeEnvironment.application);
+ mContext = RuntimeEnvironment.application;
mImpl = new SecurityFeatureProviderImpl();
- when(mContext.getPackageManager()).thenReturn(mPackageManager);
- when(mPackageManager.getResourcesForApplication(anyString())).thenReturn(mResources);
- when(mResources.getDrawable(anyInt(), any())).thenReturn(mMockDrawable);
}
@Test
- public void updateTilesData_shouldNotProcessEmptyScreenOrTiles() {
- mImpl.updatePreferencesToRunOnWorkerThread(mContext, null, null);
- ShadowLooper.runUiThreadTasks();
- mImpl.updatePreferencesToRunOnWorkerThread(
- mContext, new PreferenceScreen(mContext, null), null);
- ShadowLooper.runUiThreadTasks();
- verifyNoMoreInteractions(mPackageManager);
+ public void getTrustAgentManager_shouldReturnCache() {
+ final TrustAgentManager m1 = mImpl.getTrustAgentManager();
+ final TrustAgentManager m2 = mImpl.getTrustAgentManager();
+
+ assertThat(m1).isSameAs(m2);
}
@Test
- public void updateTilesData_shouldNotProcessNonMatchingPreference() {
- DashboardCategory dashboardCategory = new DashboardCategory();
- dashboardCategory.addTile(new Tile());
- mImpl.updatePreferencesToRunOnWorkerThread(
- mContext, getPreferenceScreen(), dashboardCategory);
- ShadowLooper.runUiThreadTasks();
- verifyNoMoreInteractions(mPackageManager);
+ public void getLockPatternUtils_shouldReturnCache() {
+ final LockPatternUtils l1 = mImpl.getLockPatternUtils(mContext);
+ final LockPatternUtils l2 = mImpl.getLockPatternUtils(mContext);
+
+ assertThat(l1).isSameAs(l2);
}
- @Test
- public void updateTilesData_shouldNotProcessMatchingPreferenceWithNoData() {
- mImpl.updatePreferencesToRunOnWorkerThread(
- mContext, getPreferenceScreen(), getDashboardCategory());
- ShadowLooper.runUiThreadTasks();
- verifyNoMoreInteractions(mPackageManager);
- }
-
- @Test
- @Config(shadows = {
- ShadowTileUtils.class,
- })
- public void updateTilesData_shouldUpdateMatchingPreference() {
- Bundle bundle = new Bundle();
- bundle.putString(TileUtils.META_DATA_PREFERENCE_ICON_URI, URI_GET_ICON);
- bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY_URI, URI_GET_SUMMARY);
-
- PreferenceScreen screen = getPreferenceScreen();
- DashboardCategory dashboardCategory = getDashboardCategory();
- dashboardCategory.getTile(0).intent = new Intent().setPackage("package");
- dashboardCategory.getTile(0).metaData = bundle;
-
- mImpl.updatePreferencesToRunOnWorkerThread(mContext, screen, dashboardCategory);
- ShadowLooper.runUiThreadTasks();
- verify(screen.findPreference(MOCK_KEY)).setIcon(mMockDrawable);
- verify(screen.findPreference(MOCK_KEY)).setSummary(MOCK_SUMMARY);
- }
-
- @Test
- @Config(shadows = {
- ShadowTileUtils.class,
- })
- public void updateTilesData_shouldNotUpdateAlreadyUpdatedPreference() {
- Bundle bundle = new Bundle();
- bundle.putString(TileUtils.META_DATA_PREFERENCE_ICON_URI, URI_GET_ICON);
- bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY_URI, URI_GET_SUMMARY);
-
- PreferenceScreen screen = getPreferenceScreen();
- when(screen.findPreference(MOCK_KEY).getSummary()).thenReturn(MOCK_SUMMARY);
- when(screen.findPreference(MOCK_KEY).getIcon()).thenReturn(mMockDrawable);
-
- DashboardCategory dashboardCategory = getDashboardCategory();
- dashboardCategory.getTile(0).intent = new Intent().setPackage("package");
- dashboardCategory.getTile(0).metaData = bundle;
-
- mImpl.updatePreferencesToRunOnWorkerThread(mContext, screen, dashboardCategory);
- ShadowLooper.runUiThreadTasks();
- 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(mContext.getString(R.string.summary_placeholder));
- }
-
- @Test
- @Config(shadows = {
- ShadowTileUtils.class,
- })
- public void initPreferences_shouldLoadCached() {
- Bundle bundle = new Bundle();
- bundle.putString(TileUtils.META_DATA_PREFERENCE_ICON_URI, URI_GET_ICON);
- bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY_URI, URI_GET_SUMMARY);
-
- PreferenceScreen screen = getPreferenceScreen();
- DashboardCategory dashboardCategory = getDashboardCategory();
- dashboardCategory.getTile(0).metaData = bundle;
-
- SecurityFeatureProviderImpl.sIconCache.put(
- URI_GET_ICON,
- ShadowTileUtils.getIconFromUri(null, null, null, null));
- SecurityFeatureProviderImpl.sSummaryCache.put(
- URI_GET_SUMMARY,
- MOCK_SUMMARY);
-
- mImpl.initPreferences(mContext, screen, dashboardCategory);
- verify(screen.findPreference(MOCK_KEY)).setIcon(mMockDrawable);
- verify(screen.findPreference(MOCK_KEY)).setSummary(MOCK_SUMMARY);
- }
-
- private PreferenceScreen getPreferenceScreen() {
- final PreferenceScreen screen = mock(PreferenceScreen.class);
- final Preference pref = mock(Preference.class);
- when(screen.findPreference(MOCK_KEY)).thenReturn(pref);
- when(pref.getKey()).thenReturn(MOCK_KEY);
- return screen;
- }
-
- private static DashboardCategory getDashboardCategory() {
- DashboardCategory dashboardCategory = new DashboardCategory();
- Tile tile = new Tile();
- tile.key = MOCK_KEY;
- dashboardCategory.addTile(tile);
- return dashboardCategory;
- }
}
diff --git a/tests/robotests/src/com/android/settings/security/SecuritySettingsTest.java b/tests/robotests/src/com/android/settings/security/SecuritySettingsTest.java
index 3171c3d..421efe8 100644
--- a/tests/robotests/src/com/android/settings/security/SecuritySettingsTest.java
+++ b/tests/robotests/src/com/android/settings/security/SecuritySettingsTest.java
@@ -16,34 +16,18 @@
package com.android.settings.security;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
-import android.app.Activity;
import android.content.Context;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.os.UserManager.EnforcingUser;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
+import android.content.pm.PackageManager;
+import android.hardware.fingerprint.FingerprintManager;
-import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.TestConfig;
import com.android.settings.dashboard.SummaryLoader;
-import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.testutils.XmlTestUtils;
-import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
-import com.android.settings.testutils.shadow.ShadowUserManager;
-import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
-import com.android.settingslib.RestrictedSwitchPreference;
import org.junit.Before;
import org.junit.Test;
@@ -51,123 +35,65 @@
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 org.robolectric.util.ReflectionHelpers;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
- shadows = {
- ShadowLockPatternUtils.class,
- ShadowUserManager.class,
- })
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SecuritySettingsTest {
-
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
@Mock
private SummaryLoader mSummaryLoader;
-
+ @Mock
+ private FingerprintManager mFingerprintManager;
private SecuritySettings.SummaryProvider mSummaryProvider;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- FakeFeatureFactory.setupForTest();
+ when(mContext.getSystemService(Context.FINGERPRINT_SERVICE))
+ .thenReturn(mFingerprintManager);
+
mSummaryProvider = new SecuritySettings.SummaryProvider(mContext, mSummaryLoader);
}
@Test
- public void testInitTrustAgentPreference_secure_shouldSetSummaryToNumberOfTrustAgent() {
- final Preference preference = mock(Preference.class);
- final PreferenceScreen screen = mock(PreferenceScreen.class);
- when(screen.findPreference(SecuritySettings.KEY_MANAGE_TRUST_AGENTS))
- .thenReturn(preference);
- final LockPatternUtils utils = mock(LockPatternUtils.class);
- when(utils.isSecure(anyInt())).thenReturn(true);
- final Context context = ShadowApplication.getInstance().getApplicationContext();
- final Activity activity = mock(Activity.class);
- when(activity.getResources()).thenReturn(context.getResources());
- final SecuritySettings securitySettings = spy(new SecuritySettings());
- when(securitySettings.getActivity()).thenReturn(activity);
+ public void testSummaryProvider_notListening() {
+ mSummaryProvider.setListening(false);
- ReflectionHelpers.setField(securitySettings, "mLockPatternUtils", utils);
-
- securitySettings.initTrustAgentPreference(screen, 0);
- verify(preference).setSummary(R.string.manage_trust_agents_summary);
-
- securitySettings.initTrustAgentPreference(screen, 2);
- verify(preference).setSummary(context.getResources().getQuantityString(
- R.plurals.manage_trust_agents_summary_on, 2, 2));
+ verifyNoMoreInteractions(mSummaryLoader);
}
@Test
- public void testNonIndexableKeys_existInXmlLayout() {
- final Context context = spy(RuntimeEnvironment.application);
- UserManager manager = mock(UserManager.class);
- when(manager.isAdminUser()).thenReturn(false);
- doReturn(manager).when(context).getSystemService(Context.USER_SERVICE);
- final List<String> niks = SecuritySettings.SEARCH_INDEX_DATA_PROVIDER
- .getNonIndexableKeys(context);
+ public void testSummaryProvider_hasFingerPrint_hasStaticSummary() {
+ when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
+ .thenReturn(true);
+ when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
- final List<String> keys = XmlTestUtils.getKeysFromPreferenceXml(context,
- R.xml.security_settings_misc);
- keys.addAll(XmlTestUtils.getKeysFromPreferenceXml(context,
- R.xml.location_settings));
- keys.addAll(XmlTestUtils.getKeysFromPreferenceXml(context,
- R.xml.encryption_and_credential));
+ mSummaryProvider.setListening(true);
- assertThat(keys).containsAllIn(niks);
+ verify(mContext).getString(R.string.security_dashboard_summary);
}
@Test
- public void testUnifyLockRestriction() {
- // Set up instance under test.
- final Context context = spy(RuntimeEnvironment.application);
- final SecuritySettings securitySettings = spy(new SecuritySettings());
- when(securitySettings.getContext()).thenReturn(context);
+ public void testSummaryProvider_noFpFeature_shouldSetSummaryWithNoFingerprint() {
+ when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
+ .thenReturn(false);
- final int userId = 123;
- ReflectionHelpers.setField(securitySettings, "mProfileChallengeUserId", userId);
+ mSummaryProvider.setListening(true);
- final LockPatternUtils utils = mock(LockPatternUtils.class);
- when(utils.isSeparateProfileChallengeEnabled(userId)).thenReturn(true);
- ReflectionHelpers.setField(securitySettings, "mLockPatternUtils", utils);
+ verify(mContext).getString(R.string.security_dashboard_summary_no_fingerprint);
+ }
- final RestrictedSwitchPreference unifyProfile = mock(RestrictedSwitchPreference.class);
- ReflectionHelpers.setField(securitySettings, "mUnifyProfile", unifyProfile);
+ @Test
+ public void testSummaryProvider_noFpHardware_shouldSetSummaryWithNoFingerprint() {
+ when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
+ .thenReturn(true);
+ when(mFingerprintManager.isHardwareDetected()).thenReturn(false);
- // Pretend that no admins enforce the restriction.
- ShadowUserManager.getShadow().setUserRestrictionSources(
- UserManager.DISALLOW_UNIFIED_PASSWORD,
- UserHandle.of(userId),
- Collections.emptyList());
+ mSummaryProvider.setListening(true);
- securitySettings.updateUnificationPreference();
-
- verify(unifyProfile).setDisabledByAdmin(null);
-
- reset(unifyProfile);
-
- // Pretend that the restriction is enforced by several admins. Having just one would
- // require more mocking of implementation details.
- final EnforcingUser enforcer1 = new EnforcingUser(
- userId, UserManager.RESTRICTION_SOURCE_PROFILE_OWNER);
- final EnforcingUser enforcer2 = new EnforcingUser(
- UserHandle.USER_SYSTEM, UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
- ShadowUserManager.getShadow().setUserRestrictionSources(
- UserManager.DISALLOW_UNIFIED_PASSWORD,
- UserHandle.of(userId),
- Arrays.asList(enforcer1, enforcer2));
-
- securitySettings.updateUnificationPreference();
-
- verify(unifyProfile).setDisabledByAdmin(EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN);
+ verify(mContext).getString(R.string.security_dashboard_summary_no_fingerprint);
}
}
diff --git a/tests/robotests/src/com/android/settings/security/SecuritySettingsV2Test.java b/tests/robotests/src/com/android/settings/security/SecuritySettingsV2Test.java
deleted file mode 100644
index f77903b..0000000
--- a/tests/robotests/src/com/android/settings/security/SecuritySettingsV2Test.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2018 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.security;
-
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.hardware.fingerprint.FingerprintManager;
-
-import com.android.settings.R;
-import com.android.settings.TestConfig;
-import com.android.settings.dashboard.SummaryLoader;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-
-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;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class SecuritySettingsV2Test {
-
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private Context mContext;
- @Mock
- private SummaryLoader mSummaryLoader;
- @Mock
- private FingerprintManager mFingerprintManager;
- private SecuritySettings.SummaryProvider mSummaryProvider;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- when(mContext.getSystemService(Context.FINGERPRINT_SERVICE))
- .thenReturn(mFingerprintManager);
-
- mSummaryProvider = new SecuritySettings.SummaryProvider(mContext, mSummaryLoader);
- }
-
- @Test
- public void testSummaryProvider_notListening() {
- mSummaryProvider.setListening(false);
-
- verifyNoMoreInteractions(mSummaryLoader);
- }
-
- @Test
- public void testSummaryProvider_hasFingerPrint_hasStaticSummary() {
- when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
- .thenReturn(true);
- when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
-
- mSummaryProvider.setListening(true);
-
- verify(mContext).getString(R.string.security_dashboard_summary);
- }
-
- @Test
- public void testSummaryProvider_noFpFeature_shouldSetSummaryWithNoFingerprint() {
- when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
- .thenReturn(false);
-
- mSummaryProvider.setListening(true);
-
- verify(mContext).getString(R.string.security_dashboard_summary_no_fingerprint);
- }
-
- @Test
- public void testSummaryProvider_noFpHardware_shouldSetSummaryWithNoFingerprint() {
- when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
- .thenReturn(true);
- when(mFingerprintManager.isHardwareDetected()).thenReturn(false);
-
- mSummaryProvider.setListening(true);
-
- verify(mContext).getString(R.string.security_dashboard_summary_no_fingerprint);
- }
-}
diff --git a/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java
index 7dd04c6..258833e 100644
--- a/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java
@@ -40,7 +40,7 @@
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.TestConfig;
import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.security.SecuritySettingsV2;
+import com.android.settings.security.SecuritySettings;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -69,7 +69,7 @@
@Mock
private PreferenceCategory mCategory;
@Mock
- private SecuritySettingsV2 mFragment;
+ private SecuritySettings mFragment;
private Lifecycle mLifecycle;
private LifecycleOwner mLifecycleOwner;
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRestrictedLockUtils.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRestrictedLockUtils.java
new file mode 100644
index 0000000..afede1a
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRestrictedLockUtils.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2018 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.internal.util.ArrayUtils;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+@Implements(RestrictedLockUtils.class)
+public class ShadowRestrictedLockUtils {
+ private static boolean isRestricted;
+ private static String[] restrictedPkgs;
+ private static boolean adminSupportDetailsIntentLaunched;
+
+ @Implementation
+ public static RestrictedLockUtils.EnforcedAdmin checkIfMeteredDataRestricted(Context context,
+ String packageName, int userId) {
+ if (isRestricted) {
+ return new EnforcedAdmin();
+ }
+ if (ArrayUtils.contains(restrictedPkgs, packageName)) {
+ return new EnforcedAdmin();
+ }
+ return null;
+ }
+
+ @Implementation
+ public static void sendShowAdminSupportDetailsIntent(Context context, EnforcedAdmin admin) {
+ adminSupportDetailsIntentLaunched = true;
+ }
+
+ public static boolean hasAdminSupportDetailsIntentLaunched() {
+ return adminSupportDetailsIntentLaunched;
+ }
+
+ public static void clearAdminSupportDetailsIntentLaunch() {
+ adminSupportDetailsIntentLaunched = false;
+ }
+
+ public static void setRestricted(boolean restricted) {
+ isRestricted = restricted;
+ }
+
+ public static void setRestrictedPkgs(String... pkgs) {
+ restrictedPkgs = pkgs;
+ }
+}
diff --git a/tests/uitests/Android.mk b/tests/uitests/Android.mk
index 870f59c..d52911d 100644
--- a/tests/uitests/Android.mk
+++ b/tests/uitests/Android.mk
@@ -19,16 +19,22 @@
LOCAL_COMPATIBILITY_SUITE := device-tests
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_MODULE_TAGS := tests
-LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
+
+LOCAL_JAVA_LIBRARIES := \
+ android.test.runner \
+ android.test.base
+
LOCAL_STATIC_JAVA_LIBRARIES := \
+ android-support-test \
app-helpers-core \
launcher-helper-lib \
- settings-helper \
- timeresult-helper-lib \
- ub-uiautomator \
- sysui-helper \
metrics-helper-lib \
platform-test-annotations \
+ settings-helper \
+ sysui-helper \
+ timeresult-helper-lib \
+ truth-prebuilt \
+ ub-uiautomator \
#LOCAL_SDK_VERSION := current
diff --git a/tests/uitests/src/com/android/settings/ui/AboutPhoneSettingsTests.java b/tests/uitests/src/com/android/settings/ui/AboutPhoneSettingsTests.java
index 57f9bc2..b92a707 100644
--- a/tests/uitests/src/com/android/settings/ui/AboutPhoneSettingsTests.java
+++ b/tests/uitests/src/com/android/settings/ui/AboutPhoneSettingsTests.java
@@ -16,57 +16,55 @@
package com.android.settings.ui;
+import static com.android.settings.ui.testutils.SettingsTestUtils.SETTINGS_PACKAGE;
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.app.Instrumentation;
import android.content.Intent;
import android.os.RemoteException;
import android.provider.Settings;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
import android.support.test.uiautomator.By;
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.test.InstrumentationTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
import android.text.TextUtils;
-import android.util.Log;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
/** Verifies basic functionality of the About Phone screen */
-public class AboutPhoneSettingsTests extends InstrumentationTestCase {
- private static final boolean LOCAL_LOGV = false;
- private static final String TAG = "AboutPhoneSettingsTest";
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class AboutPhoneSettingsTests {
private static final int TIMEOUT = 2000;
- private static final String SETTINGS_PACKAGE = "com.android.settings";
-
- private UiDevice mDevice;
// TODO: retrieve using name/ids from com.android.settings package
private static final String[] sResourceTexts = {
- "Status",
- "Legal information",
- "Regulatory labels",
- "Model",
- "Android version",
- "Android security patch level",
- "Baseband version",
- "Kernel version",
- "Build number"
+ "Phone number",
+ "SIM status",
+ "Model & hardware",
+ "MEID",
+ "Android version"
};
- private static final String[] sClickableResourceTexts = {
- "Status", "Legal information", "Regulatory labels",
- };
+ private UiDevice mDevice;
+ private Instrumentation mInstrumentation;
- @Override
+ @Before
public void setUp() throws Exception {
- if (LOCAL_LOGV) {
- Log.d(TAG, "-------");
- }
- super.setUp();
- mDevice = UiDevice.getInstance(getInstrumentation());
+ mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ mDevice = UiDevice.getInstance(mInstrumentation);
try {
mDevice.setOrientationNatural();
} catch (RemoteException e) {
@@ -82,84 +80,40 @@
UiObject2 view =
mDevice.wait(
Until.findObject(By.res(SETTINGS_PACKAGE + ":id/main_content")), TIMEOUT);
- assertNotNull("Could not find main About Phone screen", view);
+ assertThat(view).isNotNull();
view.scroll(Direction.UP, 1.0f);
}
- @Override
- protected void tearDown() throws Exception {
+ @After
+ public void tearDown() throws Exception {
// Adding an extra pressBack so we exit About Phone Settings
// and finish the test cleanly
mDevice.pressBack();
mDevice.pressHome(); // finish settings activity
mDevice.waitForIdle(TIMEOUT * 2); // give UI time to finish animating
- super.tearDown();
+ }
+
+ @Test
+ public void testAllMenuEntriesExist() throws Exception {
+ searchForItemsAndTakeAction(mDevice, sResourceTexts);
}
private void launchAboutPhoneSettings(String aboutSetting) throws Exception {
Intent aboutIntent = new Intent(aboutSetting);
aboutIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- getInstrumentation().getContext().startActivity(aboutIntent);
- }
-
- /**
- * Callable actions that can be taken when a UIObject2 is found
- *
- * @param device The current UiDevice
- * @param item The UiObject2 that was found and can be acted on
- *
- * @return {@code true} if the call was successful, and {@code false} otherwise
- */
- public interface UIObject2Callback {
- boolean call(UiDevice device, UiObject2 item) throws Exception;
- }
-
- /**
- * Clicks the given item and then presses the Back button
- *
- * <p>Used to test whether a given UiObject2 can be successfully clicked.
- * Presses Back to restore state to the previous screen.
- *
- * @param device The device that can be used to press Back
- * @param item The item to click
- *
- * @return {@code true} if clicking the item succeeded, and {@code false} otherwise
- */
- public class UiObject2Clicker implements UIObject2Callback {
- public boolean call(UiDevice device, UiObject2 item) throws Exception {
- item.click();
- Thread.sleep(TIMEOUT * 2); // give UI time to finish animating
- boolean pressWorked = device.pressBack();
- Thread.sleep(TIMEOUT * 2);
- return pressWorked;
- }
+ InstrumentationRegistry.getTargetContext().startActivity(aboutIntent);
}
/**
* Removes items found in the view and optionally takes some action.
- *
- * @param device The current UiDevice
- * @param itemsLeftToFind The items to search for in the current view
- * @param action Action to call on each item that is found; pass {@code null} to take no action
*/
- private void removeItemsAndTakeAction(
- UiDevice device, ArrayList<String> itemsLeftToFind, UIObject2Callback action) throws Exception {
+ private void removeItemsAndTakeAction(UiDevice device, ArrayList<String> itemsLeftToFind)
+ throws Exception {
for (Iterator<String> iterator = itemsLeftToFind.iterator(); iterator.hasNext(); ) {
String itemText = iterator.next();
UiObject2 item = device.wait(Until.findObject(By.text(itemText)), TIMEOUT);
if (item != null) {
- if (LOCAL_LOGV) {
- Log.d(TAG, itemText + " is present");
- }
iterator.remove();
- if (action != null) {
- boolean success = action.call(device, item);
- assertTrue("Calling action after " + itemText + " did not work", success);
- }
- } else {
- if (LOCAL_LOGV) {
- Log.d(TAG, "Could not find " + itemText);
- }
}
}
}
@@ -169,25 +123,18 @@
*
* <p>Will scroll down the screen until it has found all elements or reached the bottom.
* This allows elements to be found and acted on even if they change order.
- *
- * @param device The current UiDevice
- * @param itemsToFind The items to search for in the current view
- * @param action Action to call on each item that is found; pass {@code null} to take no action
*/
- public void searchForItemsAndTakeAction(UiDevice device, String[] itemsToFind, UIObject2Callback action)
+ private void searchForItemsAndTakeAction(UiDevice device, String[] itemsToFind)
throws Exception {
- ArrayList<String> itemsLeftToFind = new ArrayList<String>(Arrays.asList(itemsToFind));
- assertFalse(
- "There must be at least one item to search for on the screen!",
- itemsLeftToFind.isEmpty());
+ ArrayList<String> itemsLeftToFind = new ArrayList<>(Arrays.asList(itemsToFind));
+ assertWithMessage("There must be at least one item to search for on the screen!")
+ .that(itemsLeftToFind)
+ .isNotEmpty();
- if (LOCAL_LOGV) {
- Log.d(TAG, "items: " + TextUtils.join(", ", itemsLeftToFind));
- }
boolean canScrollDown = true;
while (canScrollDown && !itemsLeftToFind.isEmpty()) {
- removeItemsAndTakeAction(device, itemsLeftToFind, action);
+ removeItemsAndTakeAction(device, itemsLeftToFind);
// when we've finished searching the current view, scroll down
UiObject2 view =
@@ -201,24 +148,11 @@
}
}
// check the last items once we have reached the bottom of the view
- removeItemsAndTakeAction(device, itemsLeftToFind, action);
+ removeItemsAndTakeAction(device, itemsLeftToFind);
- assertTrue(
- "The following items were not found on the screen: "
- + TextUtils.join(", ", itemsLeftToFind),
- itemsLeftToFind.isEmpty());
- }
-
- @MediumTest // UI interaction
- public void testAllMenuEntriesExist() throws Exception {
- searchForItemsAndTakeAction(mDevice, sResourceTexts, null);
- }
-
- // Suppressing this test as it might be causing other test failures
- // Will verify that this test is the cause before proceeding with solution
- @Suppress
- @MediumTest // UI interaction
- public void testClickableEntriesCanBeClicked() throws Exception {
- searchForItemsAndTakeAction(mDevice, sClickableResourceTexts, new UiObject2Clicker());
+ assertWithMessage("The following items were not found on the screen: "
+ + TextUtils.join(", ", itemsLeftToFind))
+ .that(itemsLeftToFind)
+ .isEmpty();
}
}
diff --git a/tests/uitests/src/com/android/settings/ui/HomepageDisplayTests.java b/tests/uitests/src/com/android/settings/ui/HomepageDisplayTests.java
index 7931d30..3b7b006 100644
--- a/tests/uitests/src/com/android/settings/ui/HomepageDisplayTests.java
+++ b/tests/uitests/src/com/android/settings/ui/HomepageDisplayTests.java
@@ -16,6 +16,9 @@
package com.android.settings.ui;
+import static com.android.settings.ui.testutils.SettingsTestUtils.SETTINGS_PACKAGE;
+import static com.android.settings.ui.testutils.SettingsTestUtils.TIMEOUT;
+
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
@@ -36,9 +39,6 @@
import org.junit.Test;
import org.junit.runner.RunWith;
-import static com.android.settings.ui.testutils.SettingsTestUtils.SETTINGS_PACKAGE;
-import static com.android.settings.ui.testutils.SettingsTestUtils.TIMEOUT;
-
@MediumTest
@RunWith(AndroidJUnit4.class)
public class HomepageDisplayTests {
@@ -52,19 +52,17 @@
"Sound",
"Storage",
"Security & location",
- "Users & accounts",
+ "Accounts",
"Accessibility",
"System",
"Support & tips"
};
private UiDevice mDevice;
- private SettingsHelper mSettingsHelper;
@Before
public void setUp() throws Exception {
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
- mSettingsHelper = new SettingsHelper();
try {
mDevice.setOrientationNatural();
} catch (RemoteException e) {
diff --git a/tests/uitests/src/com/android/settings/ui/SecuritySettingsLaunchTest.java b/tests/uitests/src/com/android/settings/ui/SecuritySettingsLaunchTest.java
index b730690..6803c7e 100644
--- a/tests/uitests/src/com/android/settings/ui/SecuritySettingsLaunchTest.java
+++ b/tests/uitests/src/com/android/settings/ui/SecuritySettingsLaunchTest.java
@@ -66,7 +66,7 @@
public void launchSecuritySettings() throws Exception {
// Launch Settings
SettingsHelper.launchSettingsPage(
- InstrumentationRegistry.getContext(), Settings.ACTION_SECURITY_SETTINGS);
+ InstrumentationRegistry.getTargetContext(), Settings.ACTION_SECURITY_SETTINGS);
mHelper.scrollVert(false);
for (String category : CATEGORIES) {
SettingsTestUtils.assertTitleMatch(mDevice, category);
diff --git a/tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsAdditionalTests.java b/tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsAdditionalTests.java
new file mode 100644
index 0000000..4ed2a1d
--- /dev/null
+++ b/tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsAdditionalTests.java
@@ -0,0 +1,766 @@
+/*
+ * Copyright (C) 2018 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.ui;
+
+import android.content.Context;
+import android.net.wifi.WifiManager;
+import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+import android.provider.Settings;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.Direction;
+import android.support.test.uiautomator.StaleObjectException;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.Until;
+import android.system.helpers.CommandsHelper;
+import android.system.helpers.SettingsHelper;
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.Suppress;
+import android.util.Log;
+
+/**
+ * Additional tests for Wifi Settings.
+ */
+public class WirelessNetworkSettingsAdditionalTests extends InstrumentationTestCase {
+ // These back button presses are performed in tearDown() to exit Wifi
+ // Settings sub-menus that a test might finish in. This number should be
+ // high enough to account for the deepest sub-menu a test might enter.
+ private static final int NUM_BACK_BUTTON_PRESSES = 5;
+ private static final int TIMEOUT = 2000;
+ private static final int SLEEP_TIME = 500;
+ private static final String AIRPLANE_MODE_BROADCAST =
+ "am broadcast -a android.intent.action.AIRPLANE_MODE";
+ private static final String TAG="WirelessNetworkSettingsTests";
+
+ // Note: The values of these variables might affect flakiness in tests that involve
+ // scrolling. Adjust where necessary.
+ private static final float SCROLL_UP_PERCENT = 10.0f;
+ private static final float SCROLL_DOWN_PERCENT = 0.5f;
+ private static final int MAX_SCROLL_ATTEMPTS = 10;
+ private static final int MAX_ADD_NETWORK_BUTTON_ATTEMPTS = 3;
+ private static final int SCROLL_SPEED = 2000;
+
+ private static final String TEST_SSID = "testSsid";
+ private static final String TEST_PW_GE_8_CHAR = "testPasswordGreaterThan8Char";
+ private static final String TEST_PW_LT_8_CHAR = "lt8Char";
+ private static final String TEST_DOMAIN = "testDomain.com";
+
+ private static final String SETTINGS_PACKAGE = "com.android.settings";
+
+ private static final String CHECKBOX_CLASS = "android.widget.CheckBox";
+ private static final String SPINNER_CLASS = "android.widget.Spinner";
+ private static final String EDIT_TEXT_CLASS = "android.widget.EditText";
+ private static final String SCROLLVIEW_CLASS = "android.widget.ScrollView";
+ private static final String LISTVIEW_CLASS = "android.widget.ListView";
+
+ private static final String ADD_NETWORK_MENU_CANCEL_BUTTON_TEXT = "CANCEL";
+ private static final String ADD_NETWORK_MENU_SAVE_BUTTON_TEXT = "SAVE";
+ private static final String ADD_NETWORK_PREFERENCE_TEXT = "Add network";
+ private static final String CONFIGURE_WIFI_PREFERENCE_TEXT = "Wi‑Fi preferences";
+ private static final String CONFIGURE_WIFI_ADVANCED_PREFERENCE_TEXT = "Advanced";
+ private static final String CACERT_MENU_PLEASE_SELECT_TEXT = "Please select";
+ private static final String CACERT_MENU_USE_SYSTEM_CERTS_TEXT = "Use system certificates";
+ private static final String CACERT_MENU_DO_NOT_VALIDATE_TEXT = "Do not validate";
+ private static final String USERCERT_MENU_PLEASE_SELECT_TEXT = "Please select";
+ private static final String USERCERT_MENU_DO_NOT_PROVIDE_TEXT = "Do not provide";
+ private static final String SECURITY_OPTION_NONE_TEXT = "None";
+ private static final String SECURITY_OPTION_WEP_TEXT = "WEP";
+ private static final String SECURITY_OPTION_PSK_TEXT = "WPA/WPA2 PSK";
+ private static final String SECURITY_OPTION_EAP_TEXT = "802.1x EAP";
+ private static final String EAP_METHOD_PEAP_TEXT = "PEAP";
+ private static final String EAP_METHOD_TLS_TEXT = "TLS";
+ private static final String EAP_METHOD_TTLS_TEXT = "TTLS";
+ private static final String EAP_METHOD_PWD_TEXT = "PWD";
+ private static final String EAP_METHOD_SIM_TEXT = "SIM";
+ private static final String EAP_METHOD_AKA_TEXT = "AKA";
+ private static final String EAP_METHOD_AKA_PRIME_TEXT = "AKA'";
+ private static final String PHASE2_MENU_NONE_TEXT = "None";
+ private static final String PHASE2_MENU_MSCHAPV2_TEXT = "MSCHAPV2";
+ private static final String PHASE2_MENU_GTC_TEXT = "GTC";
+
+ private static final String ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID = "wifi_advanced_togglebox";
+ private static final String ADD_NETWORK_MENU_IP_SETTINGS_RES_ID = "ip_settings";
+ private static final String ADD_NETWORK_MENU_PROXY_SETTINGS_RES_ID = "proxy_settings";
+ private static final String ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID = "security";
+ private static final String ADD_NETWORK_MENU_EAP_METHOD_RES_ID = "method";
+ private static final String ADD_NETWORK_MENU_SSID_RES_ID = "ssid";
+ private static final String ADD_NETWORK_MENU_PHASE2_RES_ID = "phase2";
+ private static final String ADD_NETWORK_MENU_CACERT_RES_ID = "ca_cert";
+ private static final String ADD_NETWORK_MENU_USERCERT_RES_ID = "user_cert";
+ private static final String ADD_NETWORK_MENU_NO_DOMAIN_WARNING_RES_ID = "no_domain_warning";
+ private static final String ADD_NETWORK_MENU_NO_CACERT_WARNING_RES_ID = "no_ca_cert_warning";
+ private static final String ADD_NETWORK_MENU_DOMAIN_LAYOUT_RES_ID = "l_domain";
+ private static final String ADD_NETWORK_MENU_DOMAIN_RES_ID = "domain";
+ private static final String ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID = "l_identity";
+ private static final String ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID = "l_anonymous";
+ private static final String ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID = "password_layout";
+ private static final String ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID =
+ "show_password_layout";
+ private static final String ADD_NETWORK_MENU_PASSWORD_RES_ID = "password";
+
+ private static final BySelector ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR =
+ By.scrollable(true).clazz(SCROLLVIEW_CLASS);
+ private static final BySelector SPINNER_OPTIONS_SCROLLABLE_BY_SELECTOR =
+ By.scrollable(true).clazz(LISTVIEW_CLASS);
+
+ private UiDevice mDevice;
+ private CommandsHelper mCommandsHelper;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ mDevice = UiDevice.getInstance(getInstrumentation());
+ try {
+ mDevice.setOrientationNatural();
+ } catch (RemoteException e) {
+ throw new RuntimeException("failed to freeze device orientation", e);
+ }
+ // Ensure airplane mode is OFF so that wifi can be enabled using WiFiManager.
+ Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
+ Settings.Global.AIRPLANE_MODE_ON, "0");
+ Log.d(TAG, "sending airplane mode broadcast to device");
+ mCommandsHelper = CommandsHelper.getInstance();
+ mCommandsHelper.executeShellCommand(AIRPLANE_MODE_BROADCAST);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ // Exit all settings sub-menus.
+ for (int i = 0; i < NUM_BACK_BUTTON_PRESSES; ++i) {
+ mDevice.pressBack();
+ }
+ mDevice.pressHome();
+ super.tearDown();
+ }
+
+ @MediumTest
+ public void testWifiMenuLoadConfigure() throws Exception {
+ loadWiFiConfigureMenu();
+ Thread.sleep(SLEEP_TIME);
+ UiObject2 configureWiFiHeading = mDevice.wait(Until.findObject
+ (By.text(CONFIGURE_WIFI_PREFERENCE_TEXT)), TIMEOUT);
+ assertNotNull("Configure WiFi menu has not loaded correctly", configureWiFiHeading);
+ }
+
+ @MediumTest
+ public void testNetworkNotificationsOn() throws Exception {
+ verifyNetworkNotificationsOnOrOff(true);
+ }
+
+ @MediumTest
+ public void testNetworkNotificationsOff() throws Exception {
+ verifyNetworkNotificationsOnOrOff(false);
+ }
+
+ @MediumTest
+ public void testAddNetworkMenu_Default() throws Exception {
+ loadAddNetworkMenu();
+
+ // Submit button should be disabled by default, while cancel button should be enabled.
+ assertFalse(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+ assertTrue(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_CANCEL_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+ // Check that the SSID field is defaults to the hint.
+ assertEquals("Enter the SSID", mDevice.wait(Until.findObject(By
+ .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SSID_RES_ID)
+ .clazz(EDIT_TEXT_CLASS)), TIMEOUT*2)
+ .getText());
+
+ // Check Security defaults to None.
+ assertEquals("None", mDevice.wait(Until.findObject(By
+ .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID)
+ .clazz(SPINNER_CLASS)), TIMEOUT)
+ .getChildren().get(0).getText());
+
+ // Check advanced options are collapsed by default.
+ assertFalse(mDevice.wait(Until.findObject(By
+ .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID)
+ .clazz(CHECKBOX_CLASS)), TIMEOUT).isChecked());
+
+ }
+
+ @Suppress
+ @MediumTest
+ public void testAddNetworkMenu_Proxy() throws Exception {
+ loadAddNetworkMenu();
+
+ // Toggle advanced options.
+ mDevice.wait(Until.findObject(By
+ .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID)
+ .clazz(CHECKBOX_CLASS)), TIMEOUT).click();
+
+ // Verify Proxy defaults to None.
+ BySelector proxySettingsBySelector =
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PROXY_SETTINGS_RES_ID)
+ .clazz(SPINNER_CLASS);
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector);
+ assertEquals("None", mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT)
+ .getChildren().get(0).getText());
+
+ // Verify that Proxy Manual fields appear.
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector);
+ mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT).click();
+ mDevice.wait(Until.findObject(By.text("Manual")), TIMEOUT).click();
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, "proxy_warning_limited_support"));
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, "proxy_hostname"));
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, "proxy_exclusionlist"));
+
+ // Verify that Proxy Auto-Config options appear.
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector);
+ mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT).click();
+ mDevice.wait(Until.findObject(By.text("Proxy Auto-Config")), TIMEOUT).click();
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, "proxy_pac"));
+ }
+
+ @Suppress
+ @MediumTest
+ public void testAddNetworkMenu_IpSettings() throws Exception {
+ loadAddNetworkMenu();
+
+ // Toggle advanced options.
+ mDevice.wait(Until.findObject(By
+ .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID)
+ .clazz(CHECKBOX_CLASS)), TIMEOUT).click();
+
+ // Verify IP settings defaults to DHCP.
+ BySelector ipSettingsBySelector =
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IP_SETTINGS_RES_ID).clazz(SPINNER_CLASS);
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, ipSettingsBySelector);
+ assertEquals("DHCP", mDevice.wait(Until.findObject(ipSettingsBySelector), TIMEOUT)
+ .getChildren().get(0).getText());
+
+ // Verify that Static IP settings options appear.
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, ipSettingsBySelector).click();
+ mDevice.wait(Until.findObject(By.text("Static")), TIMEOUT).click();
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, "ipaddress"));
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, "gateway"));
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, "network_prefix_length"));
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, "dns1"));
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, "dns2"));
+ }
+
+ @Suppress
+ @MediumTest
+ public void testPhase2Settings() throws Exception {
+ loadAddNetworkMenu();
+ selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
+
+ BySelector phase2SettingsBySelector =
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID).clazz(SPINNER_CLASS);
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, phase2SettingsBySelector);
+ assertEquals(PHASE2_MENU_NONE_TEXT, mDevice.wait(Until
+ .findObject(phase2SettingsBySelector), TIMEOUT).getChildren().get(0).getText());
+ mDevice.wait(Until.findObject(phase2SettingsBySelector), TIMEOUT).click();
+ Thread.sleep(SLEEP_TIME);
+
+ // Verify Phase 2 authentication spinner options.
+ assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_NONE_TEXT)), TIMEOUT));
+ assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_MSCHAPV2_TEXT)), TIMEOUT));
+ assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_GTC_TEXT)), TIMEOUT));
+ }
+
+ @Suppress
+ @MediumTest
+ public void testCaCertSettings() throws Exception {
+ loadAddNetworkMenu();
+ selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
+
+ BySelector caCertSettingsBySelector =
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID).clazz(SPINNER_CLASS);
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, caCertSettingsBySelector);
+ assertEquals(CACERT_MENU_PLEASE_SELECT_TEXT, mDevice.wait(Until
+ .findObject(caCertSettingsBySelector), TIMEOUT).getChildren().get(0).getText());
+ mDevice.wait(Until.findObject(caCertSettingsBySelector), TIMEOUT).click();
+ Thread.sleep(SLEEP_TIME);
+
+ // Verify CA certificate spinner options.
+ assertNotNull(mDevice.wait(Until.findObject(
+ By.text(CACERT_MENU_PLEASE_SELECT_TEXT)), TIMEOUT));
+ assertNotNull(mDevice.wait(Until.findObject(
+ By.text(CACERT_MENU_USE_SYSTEM_CERTS_TEXT)), TIMEOUT));
+ assertNotNull(mDevice.wait(Until.findObject(
+ By.text(CACERT_MENU_DO_NOT_VALIDATE_TEXT)), TIMEOUT));
+
+ // Verify that a domain field and warning appear when the user selects the
+ // "Use system certificates" option.
+ mDevice.wait(Until.findObject(By.text(CACERT_MENU_USE_SYSTEM_CERTS_TEXT)), TIMEOUT).click();
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_DOMAIN_LAYOUT_RES_ID));
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_NO_DOMAIN_WARNING_RES_ID));
+
+ // Verify that a warning appears when the user chooses the "Do Not Validate" option.
+ mDevice.wait(Until.findObject(caCertSettingsBySelector), TIMEOUT).click();
+ mDevice.wait(Until.findObject(By.text(CACERT_MENU_DO_NOT_VALIDATE_TEXT)), TIMEOUT).click();
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_NO_CACERT_WARNING_RES_ID));
+ }
+
+ @Suppress
+ @MediumTest
+ public void testAddNetwork_NoSecurity() throws Exception {
+ loadAddNetworkMenu();
+ selectSecurityOption(SECURITY_OPTION_NONE_TEXT);
+
+ // Entering an SSID is enough to enable the submit button. // TODO THIS GUY
+ enterSSID(TEST_SSID);
+ assertTrue(mDevice.wait(Until
+ .findObject(By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+ }
+
+ @Suppress
+ @MediumTest
+ public void testAddNetwork_WEP() throws Exception {
+ loadAddNetworkMenu();
+ selectSecurityOption(SECURITY_OPTION_WEP_TEXT);
+ assertFalse(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+ // Verify that WEP fields appear.
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID));
+
+ // Entering an SSID alone does not enable the submit button.
+ enterSSID(TEST_SSID);
+ assertFalse(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+ // Submit button is only enabled after a password is entered.
+ enterPassword(TEST_PW_GE_8_CHAR);
+ assertTrue(mDevice.wait(Until
+ .findObject(By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+ }
+
+ @Suppress
+ @MediumTest
+ public void testAddNetwork_PSK() throws Exception {
+ loadAddNetworkMenu();
+ selectSecurityOption(SECURITY_OPTION_PSK_TEXT);
+ assertFalse(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+ // Verify that PSK fields appear.
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID));
+
+ // Entering an SSID alone does not enable the submit button.
+ enterSSID(TEST_SSID);
+ assertFalse(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+ // Entering an password that is too short does not enable submit button.
+ enterPassword(TEST_PW_LT_8_CHAR);
+ assertFalse(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+ // Submit button is only enabled after a password of valid length is entered.
+ enterPassword(TEST_PW_GE_8_CHAR);
+ assertTrue(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+ }
+
+ @Suppress
+ @MediumTest
+ public void testAddNetwork_EAP_PEAP() throws Exception {
+ loadAddNetworkMenu();
+ selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
+ assertFalse(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+ selectEAPMethod(EAP_METHOD_PEAP_TEXT);
+
+ // Verify that EAP-PEAP fields appear.
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID));
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID));
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID));
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID));
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID));
+
+ // Entering an SSID alone does not enable the submit button.
+ enterSSID(TEST_SSID);
+ assertFalse(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+ verifyCaCertificateSubmitConditions();
+ }
+
+ @Suppress
+ @MediumTest
+ public void testAddNetwork_EAP_TLS() throws Exception {
+ loadAddNetworkMenu();
+ selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
+ assertFalse(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+ selectEAPMethod(EAP_METHOD_TLS_TEXT);
+
+ // Verify that EAP-TLS fields appear.
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID));
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_USERCERT_RES_ID));
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID));
+
+ // Entering an SSID alone does not enable the submit button.
+ enterSSID(TEST_SSID);
+ assertFalse(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+ // Selecting the User certificate "Do not provide" option alone does not enable the submit
+ // button.
+ selectUserCertificateOption(USERCERT_MENU_DO_NOT_PROVIDE_TEXT);
+ assertFalse(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+ verifyCaCertificateSubmitConditions();
+ }
+
+ @Suppress
+ @MediumTest
+ public void testAddNetwork_EAP_TTLS() throws Exception {
+ loadAddNetworkMenu();
+ selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
+ assertFalse(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+ selectEAPMethod(EAP_METHOD_TTLS_TEXT);
+
+ // Verify that EAP-TLS fields appear.
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID));
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID));
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID));
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID));
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
+
+ // Entering an SSID alone does not enable the submit button.
+ enterSSID(TEST_SSID);
+ assertFalse(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+ verifyCaCertificateSubmitConditions();
+ }
+
+ @Suppress
+ @MediumTest
+ public void testAddNetwork_EAP_PWD() throws Exception {
+ loadAddNetworkMenu();
+ selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
+ assertFalse(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+ selectEAPMethod(EAP_METHOD_PWD_TEXT);
+
+ // Verify that EAP-TLS fields appear.
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID));
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
+
+ // Entering an SSID alone enables the submit button.
+ enterSSID(TEST_SSID);
+ assertTrue(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+ }
+
+ @Suppress
+ @MediumTest
+ public void testAddNetwork_EAP_SIM() throws Exception {
+ loadAddNetworkMenu();
+ selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
+ assertFalse(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+ selectEAPMethod(EAP_METHOD_SIM_TEXT);
+
+ // Entering an SSID alone enables the submit button.
+ enterSSID(TEST_SSID);
+ assertTrue(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+ }
+
+ @Suppress
+ @MediumTest
+ public void testAddNetwork_EAP_AKA() throws Exception {
+ loadAddNetworkMenu();
+ selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
+ assertFalse(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+ selectEAPMethod(EAP_METHOD_AKA_TEXT);
+
+ // Entering an SSID alone enables the submit button.
+ enterSSID(TEST_SSID);
+ assertTrue(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+ }
+
+ @Suppress
+ @MediumTest
+ public void testAddNetwork_EAP_AKA_PRIME() throws Exception {
+ loadAddNetworkMenu();
+ selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
+ assertFalse(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+ selectEAPMethod(EAP_METHOD_AKA_PRIME_TEXT);
+
+ // Entering an SSID alone enables the submit button.
+ enterSSID(TEST_SSID);
+ assertTrue(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+ }
+
+ private void verifyKeepWiFiOnDuringSleep(String settingToBeVerified, int settingValue)
+ throws Exception {
+ loadWiFiConfigureMenu();
+ mDevice.wait(Until.findObject(By.text("Keep Wi‑Fi on during sleep")), TIMEOUT)
+ .click();
+ mDevice.wait(Until.findObject(By.clazz("android.widget.CheckedTextView")
+ .text(settingToBeVerified)), TIMEOUT).click();
+ Thread.sleep(SLEEP_TIME);
+ int keepWiFiOnSetting =
+ Settings.Global.getInt(getInstrumentation().getContext().getContentResolver(),
+ Settings.Global.WIFI_SLEEP_POLICY);
+ assertEquals(settingValue, keepWiFiOnSetting);
+ }
+
+ private void verifyNetworkNotificationsOnOrOff(boolean verifyOn)
+ throws Exception {
+ // Enable network recommendations to enable the toggle switch for Network
+ // notifications
+ Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
+ Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, "1");
+ if (verifyOn) {
+ Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
+ Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, "0");
+ }
+ else {
+ Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
+ Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, "1");
+ }
+ loadWiFiConfigureMenu();
+ mDevice.wait(Until.findObject(By.text("Open network notification")), TIMEOUT)
+ .click();
+ Thread.sleep(SLEEP_TIME);
+ String wifiNotificationValue =
+ Settings.Global.getString(getInstrumentation().getContext().getContentResolver(),
+ Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON);
+ if (verifyOn) {
+ assertEquals("1", wifiNotificationValue);
+ }
+ else {
+ assertEquals("0", wifiNotificationValue);
+ }
+ }
+
+ private void verifyWiFiOnOrOff(boolean verifyOn) throws Exception {
+ String switchText = "On";
+ if (verifyOn) {
+ switchText = "Off";
+ }
+ loadWiFiSettingsPage(!verifyOn);
+ mDevice.wait(Until
+ .findObject(By.res(SETTINGS_PACKAGE, "switch_bar").text(switchText)), TIMEOUT)
+ .click();
+ Thread.sleep(SLEEP_TIME);
+ String wifiValue =
+ Settings.Global.getString(getInstrumentation().getContext().getContentResolver(),
+ Settings.Global.WIFI_ON);
+ if (verifyOn) {
+ // 1 is Enabled, 2 is Enabled while airplane mode is ON.
+ assertTrue(wifiValue.equals("1") || wifiValue.equals("2"));
+ }
+ else {
+ assertEquals("0", wifiValue);
+ }
+ }
+
+ private void verifyCaCertificateSubmitConditions() throws Exception {
+ // Selecting the CA certificate "Do not validate" option enables the submit button.
+ selectCaCertificateOption(CACERT_MENU_DO_NOT_VALIDATE_TEXT);
+ assertTrue(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+ // However, selecting the CA certificate "Use system certificates option" is not enough to
+ // enable the submit button.
+ selectCaCertificateOption(CACERT_MENU_USE_SYSTEM_CERTS_TEXT);
+ assertFalse(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+ // Submit button is only enabled after a domain is entered as well.
+ enterDomain(TEST_DOMAIN);
+ assertTrue(mDevice.wait(Until.findObject(
+ By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+ }
+
+ private void loadWiFiSettingsPage(boolean wifiEnabled) throws Exception {
+ WifiManager wifiManager = (WifiManager)getInstrumentation().getContext()
+ .getSystemService(Context.WIFI_SERVICE);
+ wifiManager.setWifiEnabled(wifiEnabled);
+ SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
+ Settings.ACTION_WIFI_SETTINGS);
+ }
+
+ private void loadWiFiConfigureMenu() throws Exception {
+ loadWiFiSettingsPage(false);
+ Thread.sleep(TIMEOUT);
+ mDevice.wait(Until.findObject(By.text(CONFIGURE_WIFI_PREFERENCE_TEXT)), TIMEOUT).click();
+ mDevice.wait(Until.findObject(
+ By.text(CONFIGURE_WIFI_ADVANCED_PREFERENCE_TEXT)), TIMEOUT).click();
+ }
+
+ private void loadAddNetworkMenu() throws Exception {
+ loadWiFiSettingsPage(true);
+ for (int attempts = 0; attempts < MAX_ADD_NETWORK_BUTTON_ATTEMPTS; ++attempts) {
+ try {
+ findOrScrollToObject(By.scrollable(true), By.text(ADD_NETWORK_PREFERENCE_TEXT))
+ .click();
+ } catch (StaleObjectException e) {
+ // The network list might have been updated between when the Add network button was
+ // found, and when it UI automator attempted to click on it. Retry.
+ continue;
+ }
+ // If we get here, we successfully clicked on the Add network button, so we are done.
+ Thread.sleep(SLEEP_TIME*5);
+ return;
+ }
+
+ fail("Failed to load Add Network Menu after " + MAX_ADD_NETWORK_BUTTON_ATTEMPTS
+ + " retries");
+ }
+
+ private void selectSecurityOption(String securityOption) throws Exception {
+ // We might not need to scroll to the security options if not enough add network menu
+ // options are visible.
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID)
+ .clazz(SPINNER_CLASS)).click();
+ Thread.sleep(SLEEP_TIME);
+ mDevice.wait(Until.findObject(By.text(securityOption)), TIMEOUT).click();
+ }
+
+ private void selectEAPMethod(String eapMethod) throws Exception {
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_EAP_METHOD_RES_ID).clazz(SPINNER_CLASS))
+ .click();
+ Thread.sleep(SLEEP_TIME);
+ findOrScrollToObject(SPINNER_OPTIONS_SCROLLABLE_BY_SELECTOR, By.text(eapMethod)).click();
+ }
+
+ private void selectUserCertificateOption(String userCertificateOption) throws Exception {
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_USERCERT_RES_ID).clazz(SPINNER_CLASS))
+ .click();
+ mDevice.wait(Until.findObject(By.text(userCertificateOption)), TIMEOUT).click();
+ }
+
+ private void selectCaCertificateOption(String caCertificateOption) throws Exception {
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID).clazz(SPINNER_CLASS))
+ .click();
+ mDevice.wait(Until.findObject(By.text(caCertificateOption)), TIMEOUT).click();
+ }
+
+ private void enterSSID(String ssid) throws Exception {
+ // We might not need to scroll to the SSID option if not enough add network menu options
+ // are visible.
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SSID_RES_ID).clazz(EDIT_TEXT_CLASS))
+ .setText(ssid);
+ }
+
+ private void enterPassword(String password) throws Exception {
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_RES_ID).clazz(EDIT_TEXT_CLASS))
+ .setText(password);
+ }
+
+ private void enterDomain(String domain) throws Exception {
+ findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+ By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_DOMAIN_RES_ID)).setText(domain);
+ }
+
+ // Use this if the UI object might or might not need to be scrolled to.
+ private UiObject2 findOrScrollToObject(BySelector scrollableSelector, BySelector objectSelector)
+ throws Exception {
+ UiObject2 object = mDevice.wait(Until.findObject(objectSelector), TIMEOUT);
+ if (object == null) {
+ object = scrollToObject(scrollableSelector, objectSelector);
+ }
+ return object;
+ }
+
+ private UiObject2 scrollToObject(BySelector scrollableSelector, BySelector objectSelector)
+ throws Exception {
+ UiObject2 scrollable = mDevice.wait(Until.findObject(scrollableSelector), TIMEOUT);
+ if (scrollable == null) {
+ fail("Could not find scrollable UI object identified by " + scrollableSelector);
+ }
+ UiObject2 found = null;
+ // Scroll all the way up first, then all the way down.
+ while (true) {
+ // Optimization: terminate if we find the object while scrolling up to reset, so
+ // we save the time spent scrolling down again.
+ boolean canScrollAgain = scrollable.scroll(Direction.UP, SCROLL_UP_PERCENT,
+ SCROLL_SPEED);
+ found = mDevice.findObject(objectSelector);
+ if (found != null) return found;
+ if (!canScrollAgain) break;
+ }
+ for (int attempts = 0; found == null && attempts < MAX_SCROLL_ATTEMPTS; ++attempts) {
+ // Return value of UiObject2.scroll() is not reliable, so do not use it in loop
+ // condition, in case it causes this loop to terminate prematurely.
+ scrollable.scroll(Direction.DOWN, SCROLL_DOWN_PERCENT, SCROLL_SPEED);
+ found = mDevice.findObject(objectSelector);
+ }
+ if (found == null) {
+ fail("Could not scroll to UI object identified by " + objectSelector);
+ }
+ return found;
+ }
+}
diff --git a/tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsTests.java b/tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsTests.java
index 1e3b978..64fa5fd 100644
--- a/tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsTests.java
+++ b/tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsTests.java
@@ -16,762 +16,109 @@
package com.android.settings.ui;
+import static com.android.settings.ui.testutils.SettingsTestUtils.SETTINGS_PACKAGE;
+import static com.google.common.truth.Truth.assertThat;
+
import android.content.Context;
-import android.content.Intent;
import android.net.wifi.WifiManager;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.Until;
import android.system.helpers.CommandsHelper;
import android.system.helpers.SettingsHelper;
-import android.support.test.uiautomator.By;
-import android.support.test.uiautomator.BySelector;
-import android.support.test.uiautomator.Direction;
-import android.support.test.uiautomator.StaleObjectException;
-import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObject2;
-import android.support.test.uiautomator.Until;
-import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
import android.util.Log;
-import junit.framework.AssertionFailedError;
-public class WirelessNetworkSettingsTests extends InstrumentationTestCase {
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Core tests for Wifi Settings.
+ */
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class WirelessNetworkSettingsTests {
// These back button presses are performed in tearDown() to exit Wifi
// Settings sub-menus that a test might finish in. This number should be
// high enough to account for the deepest sub-menu a test might enter.
private static final int NUM_BACK_BUTTON_PRESSES = 5;
- private static final int TIMEOUT = 2000;
+ private static final int TIMEOUT = 20000;
private static final int SLEEP_TIME = 500;
private static final String AIRPLANE_MODE_BROADCAST =
"am broadcast -a android.intent.action.AIRPLANE_MODE";
- private static final String TAG="WirelessNetworkSettingsTests";
+ private static final String TAG = "WirelessNetworkTests";
- // Note: The values of these variables might affect flakiness in tests that involve
- // scrolling. Adjust where necessary.
- private static final float SCROLL_UP_PERCENT = 10.0f;
- private static final float SCROLL_DOWN_PERCENT = 0.5f;
- private static final int MAX_SCROLL_ATTEMPTS = 10;
- private static final int MAX_ADD_NETWORK_BUTTON_ATTEMPTS = 3;
- private static final int SCROLL_SPEED = 2000;
-
- private static final String TEST_SSID = "testSsid";
- private static final String TEST_PW_GE_8_CHAR = "testPasswordGreaterThan8Char";
- private static final String TEST_PW_LT_8_CHAR = "lt8Char";
- private static final String TEST_DOMAIN = "testDomain.com";
-
- private static final String SETTINGS_PACKAGE = "com.android.settings";
-
- private static final String CHECKBOX_CLASS = "android.widget.CheckBox";
- private static final String SPINNER_CLASS = "android.widget.Spinner";
- private static final String EDIT_TEXT_CLASS = "android.widget.EditText";
- private static final String SCROLLVIEW_CLASS = "android.widget.ScrollView";
- private static final String LISTVIEW_CLASS = "android.widget.ListView";
-
- private static final String ADD_NETWORK_MENU_CANCEL_BUTTON_TEXT = "CANCEL";
- private static final String ADD_NETWORK_MENU_SAVE_BUTTON_TEXT = "SAVE";
- private static final String ADD_NETWORK_PREFERENCE_TEXT = "Add network";
- private static final String CONFIGURE_WIFI_PREFERENCE_TEXT = "Wi‑Fi preferences";
- private static final String CONFIGURE_WIFI_ADVANCED_PREFERENCE_TEXT = "Advanced";
- private static final String CACERT_MENU_PLEASE_SELECT_TEXT = "Please select";
- private static final String CACERT_MENU_USE_SYSTEM_CERTS_TEXT = "Use system certificates";
- private static final String CACERT_MENU_DO_NOT_VALIDATE_TEXT = "Do not validate";
- private static final String USERCERT_MENU_PLEASE_SELECT_TEXT = "Please select";
- private static final String USERCERT_MENU_DO_NOT_PROVIDE_TEXT = "Do not provide";
- private static final String SECURITY_OPTION_NONE_TEXT = "None";
- private static final String SECURITY_OPTION_WEP_TEXT = "WEP";
- private static final String SECURITY_OPTION_PSK_TEXT = "WPA/WPA2 PSK";
- private static final String SECURITY_OPTION_EAP_TEXT = "802.1x EAP";
- private static final String EAP_METHOD_PEAP_TEXT = "PEAP";
- private static final String EAP_METHOD_TLS_TEXT = "TLS";
- private static final String EAP_METHOD_TTLS_TEXT = "TTLS";
- private static final String EAP_METHOD_PWD_TEXT = "PWD";
- private static final String EAP_METHOD_SIM_TEXT = "SIM";
- private static final String EAP_METHOD_AKA_TEXT = "AKA";
- private static final String EAP_METHOD_AKA_PRIME_TEXT = "AKA'";
- private static final String PHASE2_MENU_NONE_TEXT = "None";
- private static final String PHASE2_MENU_MSCHAPV2_TEXT = "MSCHAPV2";
- private static final String PHASE2_MENU_GTC_TEXT = "GTC";
-
- private static final String ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID = "wifi_advanced_togglebox";
- private static final String ADD_NETWORK_MENU_IP_SETTINGS_RES_ID = "ip_settings";
- private static final String ADD_NETWORK_MENU_PROXY_SETTINGS_RES_ID = "proxy_settings";
- private static final String ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID = "security";
- private static final String ADD_NETWORK_MENU_EAP_METHOD_RES_ID = "method";
- private static final String ADD_NETWORK_MENU_SSID_RES_ID = "ssid";
- private static final String ADD_NETWORK_MENU_PHASE2_RES_ID = "phase2";
- private static final String ADD_NETWORK_MENU_CACERT_RES_ID = "ca_cert";
- private static final String ADD_NETWORK_MENU_USERCERT_RES_ID = "user_cert";
- private static final String ADD_NETWORK_MENU_NO_DOMAIN_WARNING_RES_ID = "no_domain_warning";
- private static final String ADD_NETWORK_MENU_NO_CACERT_WARNING_RES_ID = "no_ca_cert_warning";
- private static final String ADD_NETWORK_MENU_DOMAIN_LAYOUT_RES_ID = "l_domain";
- private static final String ADD_NETWORK_MENU_DOMAIN_RES_ID = "domain";
- private static final String ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID = "l_identity";
- private static final String ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID = "l_anonymous";
- private static final String ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID = "password_layout";
- private static final String ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID =
- "show_password_layout";
- private static final String ADD_NETWORK_MENU_PASSWORD_RES_ID = "password";
-
- private static final BySelector ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR =
- By.scrollable(true).clazz(SCROLLVIEW_CLASS);
- private static final BySelector SPINNER_OPTIONS_SCROLLABLE_BY_SELECTOR =
- By.scrollable(true).clazz(LISTVIEW_CLASS);
private UiDevice mDevice;
private CommandsHelper mCommandsHelper;
- @Override
+ @Before
public void setUp() throws Exception {
- super.setUp();
- mDevice = UiDevice.getInstance(getInstrumentation());
+
+ mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
try {
mDevice.setOrientationNatural();
} catch (RemoteException e) {
throw new RuntimeException("failed to freeze device orientation", e);
}
// Ensure airplane mode is OFF so that wifi can be enabled using WiFiManager.
- Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
+ Settings.Global.putString(InstrumentationRegistry.getTargetContext().getContentResolver(),
Settings.Global.AIRPLANE_MODE_ON, "0");
+
Log.d(TAG, "sending airplane mode broadcast to device");
- mCommandsHelper = CommandsHelper.getInstance();
+ mCommandsHelper = CommandsHelper.getInstance(InstrumentationRegistry.getInstrumentation());
mCommandsHelper.executeShellCommand(AIRPLANE_MODE_BROADCAST);
}
- @Override
- protected void tearDown() throws Exception {
+ @After
+ public void tearDown() {
// Exit all settings sub-menus.
for (int i = 0; i < NUM_BACK_BUTTON_PRESSES; ++i) {
mDevice.pressBack();
}
mDevice.pressHome();
- super.tearDown();
}
@Presubmit
- @MediumTest
+ @Test
public void testWiFiEnabled() throws Exception {
verifyWiFiOnOrOff(true);
}
@Presubmit
- @MediumTest
+ @Test
public void testWiFiDisabled() throws Exception {
verifyWiFiOnOrOff(false);
}
- @MediumTest
- public void testWifiMenuLoadConfigure() throws Exception {
- loadWiFiConfigureMenu();
- Thread.sleep(SLEEP_TIME);
- UiObject2 configureWiFiHeading = mDevice.wait(Until.findObject
- (By.text(CONFIGURE_WIFI_PREFERENCE_TEXT)), TIMEOUT);
- assertNotNull("Configure WiFi menu has not loaded correctly", configureWiFiHeading);
- }
-
- @MediumTest
- public void testNetworkNotificationsOn() throws Exception {
- verifyNetworkNotificationsOnOrOff(true);
- }
-
- @MediumTest
- public void testNetworkNotificationsOff() throws Exception {
- verifyNetworkNotificationsOnOrOff(false);
- }
-
- @MediumTest
- public void testAddNetworkMenu_Default() throws Exception {
- loadAddNetworkMenu();
-
- // Submit button should be disabled by default, while cancel button should be enabled.
- assertFalse(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
- assertTrue(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_CANCEL_BUTTON_TEXT)), TIMEOUT).isEnabled());
-
- // Check that the SSID field is defaults to the hint.
- assertEquals("Enter the SSID", mDevice.wait(Until.findObject(By
- .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SSID_RES_ID)
- .clazz(EDIT_TEXT_CLASS)), TIMEOUT*2)
- .getText());
-
- // Check Security defaults to None.
- assertEquals("None", mDevice.wait(Until.findObject(By
- .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID)
- .clazz(SPINNER_CLASS)), TIMEOUT)
- .getChildren().get(0).getText());
-
- // Check advanced options are collapsed by default.
- assertFalse(mDevice.wait(Until.findObject(By
- .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID)
- .clazz(CHECKBOX_CLASS)), TIMEOUT).isChecked());
-
- }
-
- @Suppress
- @MediumTest
- public void testAddNetworkMenu_Proxy() throws Exception {
- loadAddNetworkMenu();
-
- // Toggle advanced options.
- mDevice.wait(Until.findObject(By
- .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID)
- .clazz(CHECKBOX_CLASS)), TIMEOUT).click();
-
- // Verify Proxy defaults to None.
- BySelector proxySettingsBySelector =
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PROXY_SETTINGS_RES_ID)
- .clazz(SPINNER_CLASS);
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector);
- assertEquals("None", mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT)
- .getChildren().get(0).getText());
-
- // Verify that Proxy Manual fields appear.
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector);
- mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT).click();
- mDevice.wait(Until.findObject(By.text("Manual")), TIMEOUT).click();
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, "proxy_warning_limited_support"));
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, "proxy_hostname"));
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, "proxy_exclusionlist"));
-
- // Verify that Proxy Auto-Config options appear.
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector);
- mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT).click();
- mDevice.wait(Until.findObject(By.text("Proxy Auto-Config")), TIMEOUT).click();
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, "proxy_pac"));
- }
-
- @Suppress
- @MediumTest
- public void testAddNetworkMenu_IpSettings() throws Exception {
- loadAddNetworkMenu();
-
- // Toggle advanced options.
- mDevice.wait(Until.findObject(By
- .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID)
- .clazz(CHECKBOX_CLASS)), TIMEOUT).click();
-
- // Verify IP settings defaults to DHCP.
- BySelector ipSettingsBySelector =
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IP_SETTINGS_RES_ID).clazz(SPINNER_CLASS);
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, ipSettingsBySelector);
- assertEquals("DHCP", mDevice.wait(Until.findObject(ipSettingsBySelector), TIMEOUT)
- .getChildren().get(0).getText());
-
- // Verify that Static IP settings options appear.
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, ipSettingsBySelector).click();
- mDevice.wait(Until.findObject(By.text("Static")), TIMEOUT).click();
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, "ipaddress"));
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, "gateway"));
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, "network_prefix_length"));
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, "dns1"));
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, "dns2"));
- }
-
- @Suppress
- @MediumTest
- public void testPhase2Settings() throws Exception {
- loadAddNetworkMenu();
- selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
-
- BySelector phase2SettingsBySelector =
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID).clazz(SPINNER_CLASS);
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, phase2SettingsBySelector);
- assertEquals(PHASE2_MENU_NONE_TEXT, mDevice.wait(Until
- .findObject(phase2SettingsBySelector), TIMEOUT).getChildren().get(0).getText());
- mDevice.wait(Until.findObject(phase2SettingsBySelector), TIMEOUT).click();
- Thread.sleep(SLEEP_TIME);
-
- // Verify Phase 2 authentication spinner options.
- assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_NONE_TEXT)), TIMEOUT));
- assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_MSCHAPV2_TEXT)), TIMEOUT));
- assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_GTC_TEXT)), TIMEOUT));
- }
-
- @Suppress
- @MediumTest
- public void testCaCertSettings() throws Exception {
- loadAddNetworkMenu();
- selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
-
- BySelector caCertSettingsBySelector =
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID).clazz(SPINNER_CLASS);
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, caCertSettingsBySelector);
- assertEquals(CACERT_MENU_PLEASE_SELECT_TEXT, mDevice.wait(Until
- .findObject(caCertSettingsBySelector), TIMEOUT).getChildren().get(0).getText());
- mDevice.wait(Until.findObject(caCertSettingsBySelector), TIMEOUT).click();
- Thread.sleep(SLEEP_TIME);
-
- // Verify CA certificate spinner options.
- assertNotNull(mDevice.wait(Until.findObject(
- By.text(CACERT_MENU_PLEASE_SELECT_TEXT)), TIMEOUT));
- assertNotNull(mDevice.wait(Until.findObject(
- By.text(CACERT_MENU_USE_SYSTEM_CERTS_TEXT)), TIMEOUT));
- assertNotNull(mDevice.wait(Until.findObject(
- By.text(CACERT_MENU_DO_NOT_VALIDATE_TEXT)), TIMEOUT));
-
- // Verify that a domain field and warning appear when the user selects the
- // "Use system certificates" option.
- mDevice.wait(Until.findObject(By.text(CACERT_MENU_USE_SYSTEM_CERTS_TEXT)), TIMEOUT).click();
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_DOMAIN_LAYOUT_RES_ID));
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_NO_DOMAIN_WARNING_RES_ID));
-
- // Verify that a warning appears when the user chooses the "Do Not Validate" option.
- mDevice.wait(Until.findObject(caCertSettingsBySelector), TIMEOUT).click();
- mDevice.wait(Until.findObject(By.text(CACERT_MENU_DO_NOT_VALIDATE_TEXT)), TIMEOUT).click();
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_NO_CACERT_WARNING_RES_ID));
- }
-
- @Suppress
- @MediumTest
- public void testAddNetwork_NoSecurity() throws Exception {
- loadAddNetworkMenu();
- selectSecurityOption(SECURITY_OPTION_NONE_TEXT);
-
- // Entering an SSID is enough to enable the submit button. // TODO THIS GUY
- enterSSID(TEST_SSID);
- assertTrue(mDevice.wait(Until
- .findObject(By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
- }
-
- @Suppress
- @MediumTest
- public void testAddNetwork_WEP() throws Exception {
- loadAddNetworkMenu();
- selectSecurityOption(SECURITY_OPTION_WEP_TEXT);
- assertFalse(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
-
- // Verify that WEP fields appear.
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID));
-
- // Entering an SSID alone does not enable the submit button.
- enterSSID(TEST_SSID);
- assertFalse(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
-
- // Submit button is only enabled after a password is entered.
- enterPassword(TEST_PW_GE_8_CHAR);
- assertTrue(mDevice.wait(Until
- .findObject(By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
- }
-
- @Suppress
- @MediumTest
- public void testAddNetwork_PSK() throws Exception {
- loadAddNetworkMenu();
- selectSecurityOption(SECURITY_OPTION_PSK_TEXT);
- assertFalse(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
-
- // Verify that PSK fields appear.
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID));
-
- // Entering an SSID alone does not enable the submit button.
- enterSSID(TEST_SSID);
- assertFalse(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
-
- // Entering an password that is too short does not enable submit button.
- enterPassword(TEST_PW_LT_8_CHAR);
- assertFalse(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
-
- // Submit button is only enabled after a password of valid length is entered.
- enterPassword(TEST_PW_GE_8_CHAR);
- assertTrue(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
- }
-
- @Suppress
- @MediumTest
- public void testAddNetwork_EAP_PEAP() throws Exception {
- loadAddNetworkMenu();
- selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
- assertFalse(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
-
- selectEAPMethod(EAP_METHOD_PEAP_TEXT);
-
- // Verify that EAP-PEAP fields appear.
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID));
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID));
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID));
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID));
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID));
-
- // Entering an SSID alone does not enable the submit button.
- enterSSID(TEST_SSID);
- assertFalse(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
-
- verifyCaCertificateSubmitConditions();
- }
-
- @Suppress
- @MediumTest
- public void testAddNetwork_EAP_TLS() throws Exception {
- loadAddNetworkMenu();
- selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
- assertFalse(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
-
- selectEAPMethod(EAP_METHOD_TLS_TEXT);
-
- // Verify that EAP-TLS fields appear.
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID));
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_USERCERT_RES_ID));
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID));
-
- // Entering an SSID alone does not enable the submit button.
- enterSSID(TEST_SSID);
- assertFalse(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
-
- // Selecting the User certificate "Do not provide" option alone does not enable the submit
- // button.
- selectUserCertificateOption(USERCERT_MENU_DO_NOT_PROVIDE_TEXT);
- assertFalse(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
-
- verifyCaCertificateSubmitConditions();
- }
-
- @Suppress
- @MediumTest
- public void testAddNetwork_EAP_TTLS() throws Exception {
- loadAddNetworkMenu();
- selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
- assertFalse(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
-
- selectEAPMethod(EAP_METHOD_TTLS_TEXT);
-
- // Verify that EAP-TLS fields appear.
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID));
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID));
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID));
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID));
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
-
- // Entering an SSID alone does not enable the submit button.
- enterSSID(TEST_SSID);
- assertFalse(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
-
- verifyCaCertificateSubmitConditions();
- }
-
- @Suppress
- @MediumTest
- public void testAddNetwork_EAP_PWD() throws Exception {
- loadAddNetworkMenu();
- selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
- assertFalse(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
-
- selectEAPMethod(EAP_METHOD_PWD_TEXT);
-
- // Verify that EAP-TLS fields appear.
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID));
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
-
- // Entering an SSID alone enables the submit button.
- enterSSID(TEST_SSID);
- assertTrue(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
- }
-
- @Suppress
- @MediumTest
- public void testAddNetwork_EAP_SIM() throws Exception {
- loadAddNetworkMenu();
- selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
- assertFalse(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
-
- selectEAPMethod(EAP_METHOD_SIM_TEXT);
-
- // Entering an SSID alone enables the submit button.
- enterSSID(TEST_SSID);
- assertTrue(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
- }
-
- @Suppress
- @MediumTest
- public void testAddNetwork_EAP_AKA() throws Exception {
- loadAddNetworkMenu();
- selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
- assertFalse(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
-
- selectEAPMethod(EAP_METHOD_AKA_TEXT);
-
- // Entering an SSID alone enables the submit button.
- enterSSID(TEST_SSID);
- assertTrue(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
- }
-
- @Suppress
- @MediumTest
- public void testAddNetwork_EAP_AKA_PRIME() throws Exception {
- loadAddNetworkMenu();
- selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
- assertFalse(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
-
- selectEAPMethod(EAP_METHOD_AKA_PRIME_TEXT);
-
- // Entering an SSID alone enables the submit button.
- enterSSID(TEST_SSID);
- assertTrue(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
- }
-
- private void verifyKeepWiFiOnDuringSleep(String settingToBeVerified, int settingValue)
- throws Exception {
- loadWiFiConfigureMenu();
- mDevice.wait(Until.findObject(By.text("Keep Wi‑Fi on during sleep")), TIMEOUT)
- .click();
- mDevice.wait(Until.findObject(By.clazz("android.widget.CheckedTextView")
- .text(settingToBeVerified)), TIMEOUT).click();
- Thread.sleep(SLEEP_TIME);
- int keepWiFiOnSetting =
- Settings.Global.getInt(getInstrumentation().getContext().getContentResolver(),
- Settings.Global.WIFI_SLEEP_POLICY);
- assertEquals(settingValue, keepWiFiOnSetting);
- }
-
- private void verifyNetworkNotificationsOnOrOff(boolean verifyOn)
- throws Exception {
- // Enable network recommendations to enable the toggle switch for Network
- // notifications
- Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
- Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, "1");
- if (verifyOn) {
- Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
- Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, "0");
- }
- else {
- Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
- Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, "1");
- }
- loadWiFiConfigureMenu();
- mDevice.wait(Until.findObject(By.text("Open network notification")), TIMEOUT)
- .click();
- Thread.sleep(SLEEP_TIME);
- String wifiNotificationValue =
- Settings.Global.getString(getInstrumentation().getContext().getContentResolver(),
- Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON);
- if (verifyOn) {
- assertEquals("1", wifiNotificationValue);
- }
- else {
- assertEquals("0", wifiNotificationValue);
- }
- }
-
private void verifyWiFiOnOrOff(boolean verifyOn) throws Exception {
- String switchText = "On";
- if (verifyOn) {
- switchText = "Off";
- }
- loadWiFiSettingsPage(!verifyOn);
- mDevice.wait(Until
- .findObject(By.res(SETTINGS_PACKAGE, "switch_bar").text(switchText)), TIMEOUT)
- .click();
- Thread.sleep(SLEEP_TIME);
- String wifiValue =
- Settings.Global.getString(getInstrumentation().getContext().getContentResolver(),
- Settings.Global.WIFI_ON);
- if (verifyOn) {
- // 1 is Enabled, 2 is Enabled while airplane mode is ON.
- assertTrue(wifiValue.equals("1") || wifiValue.equals("2"));
- }
- else {
- assertEquals("0", wifiValue);
- }
- }
-
- private void verifyCaCertificateSubmitConditions() throws Exception {
- // Selecting the CA certificate "Do not validate" option enables the submit button.
- selectCaCertificateOption(CACERT_MENU_DO_NOT_VALIDATE_TEXT);
- assertTrue(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
-
- // However, selecting the CA certificate "Use system certificates option" is not enough to
- // enable the submit button.
- selectCaCertificateOption(CACERT_MENU_USE_SYSTEM_CERTS_TEXT);
- assertFalse(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
-
- // Submit button is only enabled after a domain is entered as well.
- enterDomain(TEST_DOMAIN);
- assertTrue(mDevice.wait(Until.findObject(
- By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+ loadWiFiSettingsPage(!verifyOn);
+ mDevice.wait(Until.findObject(By.res(SETTINGS_PACKAGE, "switch_widget")), TIMEOUT)
+ .click();
+ Thread.sleep(SLEEP_TIME);
+ final String wifiValue = Settings.Global.getString(
+ InstrumentationRegistry.getTargetContext().getContentResolver(),
+ Settings.Global.WIFI_ON);
+ if (verifyOn) {
+ // 1 is Enabled, 2 is Enabled while airplane mode is ON.
+ assertThat(wifiValue).isAnyOf("1", "2");
+ } else {
+ assertThat(wifiValue).isEqualTo("0");
+ }
}
private void loadWiFiSettingsPage(boolean wifiEnabled) throws Exception {
- WifiManager wifiManager = (WifiManager)getInstrumentation().getContext()
+ WifiManager wifiManager = (WifiManager) InstrumentationRegistry.getTargetContext()
.getSystemService(Context.WIFI_SERVICE);
wifiManager.setWifiEnabled(wifiEnabled);
- SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
+ SettingsHelper.launchSettingsPage(InstrumentationRegistry.getTargetContext(),
Settings.ACTION_WIFI_SETTINGS);
}
-
- private void loadWiFiConfigureMenu() throws Exception {
- loadWiFiSettingsPage(false);
- Thread.sleep(TIMEOUT);
- mDevice.wait(Until.findObject(By.text(CONFIGURE_WIFI_PREFERENCE_TEXT)), TIMEOUT).click();
- mDevice.wait(Until.findObject(
- By.text(CONFIGURE_WIFI_ADVANCED_PREFERENCE_TEXT)), TIMEOUT).click();
- }
-
- private void loadAddNetworkMenu() throws Exception {
- loadWiFiSettingsPage(true);
- for (int attempts = 0; attempts < MAX_ADD_NETWORK_BUTTON_ATTEMPTS; ++attempts) {
- try {
- findOrScrollToObject(By.scrollable(true), By.text(ADD_NETWORK_PREFERENCE_TEXT))
- .click();
- } catch (StaleObjectException e) {
- // The network list might have been updated between when the Add network button was
- // found, and when it UI automator attempted to click on it. Retry.
- continue;
- }
- // If we get here, we successfully clicked on the Add network button, so we are done.
- Thread.sleep(SLEEP_TIME*5);
- return;
- }
-
- fail("Failed to load Add Network Menu after " + MAX_ADD_NETWORK_BUTTON_ATTEMPTS
- + " retries");
- }
-
- private void selectSecurityOption(String securityOption) throws Exception {
- // We might not need to scroll to the security options if not enough add network menu
- // options are visible.
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID)
- .clazz(SPINNER_CLASS)).click();
- Thread.sleep(SLEEP_TIME);
- mDevice.wait(Until.findObject(By.text(securityOption)), TIMEOUT).click();
- }
-
- private void selectEAPMethod(String eapMethod) throws Exception {
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_EAP_METHOD_RES_ID).clazz(SPINNER_CLASS))
- .click();
- Thread.sleep(SLEEP_TIME);
- findOrScrollToObject(SPINNER_OPTIONS_SCROLLABLE_BY_SELECTOR, By.text(eapMethod)).click();
- }
-
- private void selectUserCertificateOption(String userCertificateOption) throws Exception {
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_USERCERT_RES_ID).clazz(SPINNER_CLASS))
- .click();
- mDevice.wait(Until.findObject(By.text(userCertificateOption)), TIMEOUT).click();
- }
-
- private void selectCaCertificateOption(String caCertificateOption) throws Exception {
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID).clazz(SPINNER_CLASS))
- .click();
- mDevice.wait(Until.findObject(By.text(caCertificateOption)), TIMEOUT).click();
- }
-
- private void enterSSID(String ssid) throws Exception {
- // We might not need to scroll to the SSID option if not enough add network menu options
- // are visible.
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SSID_RES_ID).clazz(EDIT_TEXT_CLASS))
- .setText(ssid);
- }
-
- private void enterPassword(String password) throws Exception {
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_RES_ID).clazz(EDIT_TEXT_CLASS))
- .setText(password);
- }
-
- private void enterDomain(String domain) throws Exception {
- findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
- By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_DOMAIN_RES_ID)).setText(domain);
- }
-
- // Use this if the UI object might or might not need to be scrolled to.
- private UiObject2 findOrScrollToObject(BySelector scrollableSelector, BySelector objectSelector)
- throws Exception {
- UiObject2 object = mDevice.wait(Until.findObject(objectSelector), TIMEOUT);
- if (object == null) {
- object = scrollToObject(scrollableSelector, objectSelector);
- }
- return object;
- }
-
- private UiObject2 scrollToObject(BySelector scrollableSelector, BySelector objectSelector)
- throws Exception {
- UiObject2 scrollable = mDevice.wait(Until.findObject(scrollableSelector), TIMEOUT);
- if (scrollable == null) {
- fail("Could not find scrollable UI object identified by " + scrollableSelector);
- }
- UiObject2 found = null;
- // Scroll all the way up first, then all the way down.
- while (true) {
- // Optimization: terminate if we find the object while scrolling up to reset, so
- // we save the time spent scrolling down again.
- boolean canScrollAgain = scrollable.scroll(Direction.UP, SCROLL_UP_PERCENT,
- SCROLL_SPEED);
- found = mDevice.findObject(objectSelector);
- if (found != null) return found;
- if (!canScrollAgain) break;
- }
- for (int attempts = 0; found == null && attempts < MAX_SCROLL_ATTEMPTS; ++attempts) {
- // Return value of UiObject2.scroll() is not reliable, so do not use it in loop
- // condition, in case it causes this loop to terminate prematurely.
- scrollable.scroll(Direction.DOWN, SCROLL_DOWN_PERCENT, SCROLL_SPEED);
- found = mDevice.findObject(objectSelector);
- }
- if (found == null) {
- fail("Could not scroll to UI object identified by " + objectSelector);
- }
- return found;
- }
}
diff --git a/tests/uitests/src/com/android/settings/ui/ZonePickerSettingsTest.java b/tests/uitests/src/com/android/settings/ui/ZonePickerSettingsTest.java
new file mode 100644
index 0000000..109c3bc
--- /dev/null
+++ b/tests/uitests/src/com/android/settings/ui/ZonePickerSettingsTest.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2018 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.ui;
+
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.provider.Settings;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.support.test.uiautomator.UiScrollable;
+import android.support.test.uiautomator.UiSelector;
+import android.support.test.uiautomator.Until;
+import android.system.helpers.SettingsHelper;
+import android.system.helpers.SettingsHelper.SettingsType;
+import android.widget.ListView;
+import android.widget.Spinner;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.TimeZone;
+
+import static com.android.settings.ui.testutils.SettingsTestUtils.SETTINGS_PACKAGE;
+import static com.android.settings.ui.testutils.SettingsTestUtils.TIMEOUT;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class ZonePickerSettingsTest {
+
+ private static final BySelector SELECTOR_SELECT_TIME_ZONE =
+ By.hasChild(By.text("Select time zone"));
+
+ private UiDevice mDevice;
+ private SettingsHelper mHelper;
+ private String mIsV2EnabledByDefault;
+ private int mIsAutoZoneEnabled;
+
+ @Before
+ public void setUp() throws Exception {
+ mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ mHelper = SettingsHelper.getInstance();
+ try {
+ mDevice.setOrientationNatural();
+ } catch (RemoteException e) {
+ throw new RuntimeException("failed to freeze device orientation", e);
+ }
+ mIsV2EnabledByDefault = mHelper.getStringSetting(SettingsType.GLOBAL,
+ "settings_zone_picker_v2");
+ mHelper.setStringSetting(SettingsType.GLOBAL, "settings_zone_picker_v2", "true");
+ mIsAutoZoneEnabled = mHelper.getIntSetting(SettingsType.GLOBAL,
+ Settings.Global.AUTO_TIME_ZONE);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ // Go back to home for next test.
+ mDevice.pressBack();
+ mDevice.pressBack();
+ mDevice.pressHome();
+ mDevice.waitForIdle(TIMEOUT * 2);
+ mHelper.setStringSetting(SettingsType.GLOBAL, "settings_zone_picker_v2",
+ mIsV2EnabledByDefault);
+ mHelper.setIntSetting(SettingsType.GLOBAL, Settings.Global.AUTO_TIME_ZONE,
+ mIsAutoZoneEnabled);
+ }
+
+ @Test
+ public void zonePickerDisabled() throws Exception {
+ mHelper.setIntSetting(SettingsType.GLOBAL, Settings.Global.AUTO_TIME_ZONE, 1);
+
+ SettingsHelper.launchSettingsPage(
+ InstrumentationRegistry.getContext(), Settings.ACTION_DATE_SETTINGS);
+ UiObject2 selectTimeZone = wait(SELECTOR_SELECT_TIME_ZONE);
+ assertFalse(selectTimeZone.isEnabled());
+ }
+
+ // Test 2 time zones with no DST
+ @Test
+ public void testSelectReykjavik() throws Exception {
+ testSelectTimeZone("Iceland", "Reykjavik", "GMT+00:00", "Atlantic/Reykjavik");
+ }
+
+ @Test
+ public void testSelectPhoenix() throws Exception {
+ testSelectTimeZone("United States", "Phoenix", "GMT-07:00", "America/Phoenix");
+ }
+
+ private void testSelectTimeZone(String region, String timezone, String expectedTimeZoneOffset,
+ String expectedTimeZoneId) throws Exception {
+ mHelper.setIntSetting(SettingsType.GLOBAL, Settings.Global.AUTO_TIME_ZONE, 0);
+
+ SettingsHelper.launchSettingsPage(
+ InstrumentationRegistry.getContext(), Settings.ACTION_DATE_SETTINGS);
+
+ UiObject2 selectTimeZone = wait(SELECTOR_SELECT_TIME_ZONE);
+ assertTrue(selectTimeZone.isEnabled());
+ selectTimeZone.click();
+
+ // Select region in the dropdown list
+ selectScrollableItem(selectDropDownInSpinner(By.clazz(Spinner.class)),
+ new UiSelector().textContains(region))
+ .click();
+
+ // Select time zone
+ selectScrollableItem(selectTimeZoneList(),
+ new UiSelector().textContains(timezone))
+ .click();
+
+ // The select button should include the GMT offset in the summary
+ BySelector summarySelector = By.res("android:id/summary");
+ UiObject2 selectedTimeZone = selectTimeZone.findObject(summarySelector);
+ assertUiObjectFound(selectedTimeZone, summarySelector);
+ assertTrue("Expect " + expectedTimeZoneOffset + " is shown for " + timezone,
+ selectedTimeZone.getText().startsWith(expectedTimeZoneOffset));
+
+ waitAndAssertTimeGetDefault(expectedTimeZoneId);
+ assertEquals("Time zone change in Settings should update persist.sys.timezone",
+ expectedTimeZoneId, SystemProperties.get("persist.sys.timezone"));
+ }
+
+ private static final long CHECK_DEFAULT_TIMEZONE_INTERVAL = 200L;
+ private static final long CHECK_DEFAULT_TIMEZONE_TIMEOUT = 3000L;
+
+ /**
+ * Wait for the broadcast ACTION_TIMEZONE_CHANGED propagated, and update the default TimeZone
+ * by ApplicationThread.
+ */
+ private static void waitAndAssertTimeGetDefault(String expectedTimeZoneId)
+ throws InterruptedException {
+ for (int i = 0; i < CHECK_DEFAULT_TIMEZONE_TIMEOUT / CHECK_DEFAULT_TIMEZONE_INTERVAL; i++) {
+ if (expectedTimeZoneId.equals(TimeZone.getDefault().getID())) {
+ return;
+ }
+ Thread.sleep(CHECK_DEFAULT_TIMEZONE_INTERVAL);
+ }
+
+ assertEquals(expectedTimeZoneId, TimeZone.getDefault().getID());
+ }
+
+ /**
+ * Perform click on {@link Spinner} and return the pop-up dropdown list.
+ * @return UiScrollable representing the pop-up dropdown after clicking on the spinner
+ */
+ private UiScrollable selectDropDownInSpinner(BySelector spinnerSelector)
+ throws UiObjectNotFoundException {
+ UiObject2 spinner = wait(spinnerSelector);
+ spinner.click();
+
+ UiSelector dropDownSelector = new UiSelector().className(ListView.class);
+ return new UiScrollable(dropDownSelector);
+ }
+
+ private UiScrollable selectTimeZoneList() {
+ return new UiScrollable(new UiSelector().resourceId(SETTINGS_PACKAGE + ":id/tz_list"));
+ }
+
+ /**
+ * Select the child object in the UiScrollable
+ * @throws UiObjectNotFoundException if scrollable or child is not found
+ */
+ private UiObject selectScrollableItem(UiScrollable scrollable, UiSelector childSelector)
+ throws UiObjectNotFoundException {
+ if (!scrollable.waitForExists(TIMEOUT)) {
+ throw newUiObjectNotFoundException(scrollable.getSelector());
+ }
+ scrollable.scrollIntoView(childSelector);
+
+ UiObject child = mDevice.findObject(childSelector);
+ assertUiObjectFound(child, childSelector);
+ return child;
+ }
+
+ /**
+ * @throws UiObjectNotFoundException if UiDevice.wait returns null
+ */
+ private UiObject2 wait(BySelector selector) throws UiObjectNotFoundException {
+ UiObject2 item = mDevice.wait(Until.findObject(selector), TIMEOUT);
+ assertUiObjectFound(item, selector);
+ return item;
+ }
+
+ private static void assertUiObjectFound(UiObject2 obj, BySelector selector)
+ throws UiObjectNotFoundException {
+ if (obj == null) {
+ throw newUiObjectNotFoundException(selector);
+ }
+ }
+
+
+ private static void assertUiObjectFound(UiObject obj, UiSelector selector)
+ throws UiObjectNotFoundException {
+ if (obj == null) {
+ throw newUiObjectNotFoundException(selector);
+ }
+ }
+
+ private static UiObjectNotFoundException newUiObjectNotFoundException(Object selector) {
+ return new UiObjectNotFoundException(
+ String.format("UI object not found: %s", selector.toString()));
+ }
+}
diff --git a/tests/unit/src/com/android/settings/applications/PackageUtilTest.java b/tests/unit/src/com/android/settings/applications/PackageUtilTest.java
deleted file mode 100644
index 0e3c402..0000000
--- a/tests/unit/src/com/android/settings/applications/PackageUtilTest.java
+++ /dev/null
@@ -1,94 +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.applications;
-
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
-import android.os.UserManager;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static junit.framework.Assert.assertEquals;
-import static org.mockito.Mockito.when;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-@Deprecated
-public class PackageUtilTest {
- private static final String ALL_USERS_APP_NAME = "com.google.allusers.app";
- private static final String ONE_USER_APP_NAME = "com.google.oneuser.app";
- private static final int USER1_ID = 1;
- private static final int USER2_ID = 11;
-
- @Mock
- private PackageManager mMockPackageManager;
- @Mock
- private UserManager mMockUserManager;
-
- private InstalledAppDetails.PackageUtil mPackageUtil;
- private List<UserInfo> mUserInfos;
-
- @Before
- public void setUp() throws PackageManager.NameNotFoundException {
- MockitoAnnotations.initMocks(this);
-
- mUserInfos = new ArrayList<>();
- mUserInfos.add(new UserInfo(USER1_ID, "lei", 0));
- mUserInfos.add(new UserInfo(USER2_ID, "yue", 0));
- when(mMockUserManager.getUsers(true)).thenReturn(mUserInfos);
-
- ApplicationInfo usersApp = new ApplicationInfo();
- usersApp.flags = ApplicationInfo.FLAG_INSTALLED;
-
- when(mMockPackageManager.getApplicationInfoAsUser(
- ALL_USERS_APP_NAME, PackageManager.GET_META_DATA, USER1_ID))
- .thenReturn(usersApp);
- when(mMockPackageManager.getApplicationInfoAsUser(
- ALL_USERS_APP_NAME, PackageManager.GET_META_DATA, USER2_ID))
- .thenReturn(usersApp);
-
- when(mMockPackageManager.getApplicationInfoAsUser(
- ONE_USER_APP_NAME, PackageManager.GET_META_DATA, USER1_ID))
- .thenReturn(usersApp);
-
- when(mMockPackageManager.getApplicationInfoAsUser(
- ONE_USER_APP_NAME, PackageManager.GET_META_DATA, USER2_ID))
- .thenThrow(new PackageManager.NameNotFoundException());
-
- mPackageUtil = new InstalledAppDetails.PackageUtil();
- }
-
- @Test
- public void testCountPackageInUsers_twoUsersInstalled_returnTwo() {
- assertEquals(2, mPackageUtil.countPackageInUsers(
- mMockPackageManager, mMockUserManager, ALL_USERS_APP_NAME));
- }
-
- @Test
- public void testCountPackageInUsers_oneUsersInstalled_returnOne() {
- assertEquals(1, mPackageUtil.countPackageInUsers(
- mMockPackageManager, mMockUserManager, ONE_USER_APP_NAME));
- }
-}
diff --git a/tests/unit/src/com/android/settings/CreateShortcutTest.java b/tests/unit/src/com/android/settings/shortcut/CreateShortcutTest.java
similarity index 90%
rename from tests/unit/src/com/android/settings/CreateShortcutTest.java
rename to tests/unit/src/com/android/settings/shortcut/CreateShortcutTest.java
index 4ae9bd7..5ec008b 100644
--- a/tests/unit/src/com/android/settings/CreateShortcutTest.java
+++ b/tests/unit/src/com/android/settings/shortcut/CreateShortcutTest.java
@@ -14,12 +14,10 @@
* limitations under the License.
*/
-package com.android.settings;
+package com.android.settings.shortcut;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist;
-import static android.support.test.espresso.matcher.ViewMatchers.withText;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.any;
@@ -39,9 +37,13 @@
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.support.test.InstrumentationRegistry;
+import android.support.test.espresso.matcher.ViewMatchers;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
+import com.android.settings.R;
+import com.android.settings.Settings;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -55,12 +57,6 @@
/**
* Tests for {@link CreateShortcutTest}
- *
- m SettingsTests &&
- adb install \
- -r -g ${ANDROID_PRODUCT_OUT}/data/app/SettingsTests/SettingsTests.apk &&
- adb shell am instrument -e class com.android.settings.CreateShortcutTest \
- -w com.android.settings.tests/android.support.test.runner.AndroidJUnitRunner
*/
@RunWith(AndroidJUnit4.class)
@SmallTest
@@ -71,8 +67,10 @@
private Instrumentation mInstrumentation;
private Context mContext;
- @Mock ShortcutManager mShortcutManager;
- @Captor ArgumentCaptor<List<ShortcutInfo>> mListCaptor;
+ @Mock
+ ShortcutManager mShortcutManager;
+ @Captor
+ ArgumentCaptor<List<ShortcutInfo>> mListCaptor;
@Before
public void setup() {
@@ -84,15 +82,17 @@
@Test
public void test_layoutDoesNotHaveCancelButton() {
mInstrumentation.startActivitySync(new Intent(Intent.ACTION_CREATE_SHORTCUT)
- .setClassName(mContext, CreateShortcut.class.getName()));
- onView(withText(R.string.cancel)).check(doesNotExist());
+ .setClassName(mContext, CreateShortcut.class.getName())
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+ onView(ViewMatchers.withText(R.string.cancel)).check(doesNotExist());
}
@Test
public void createResultIntent() {
CreateShortcut orgActivity = (CreateShortcut) mInstrumentation.startActivitySync(
new Intent(Intent.ACTION_CREATE_SHORTCUT)
- .setClassName(mContext, CreateShortcut.class.getName()));
+ .setClassName(mContext, CreateShortcut.class.getName())
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
CreateShortcut activity = spy(orgActivity);
doReturn(mShortcutManager).when(activity).getSystemService(eq(Context.SHORTCUT_SERVICE));