Snap for 4574286 from acd313e644 to pi-release
Change-Id: I2563cc15b37529a139a400c869f79ca9ac078a1c
This commit is contained in:
@@ -146,7 +146,7 @@
|
|||||||
android:parentActivityName="Settings">
|
android:parentActivityName="Settings">
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity android:name="CreateShortcut"
|
<activity android:name=".shortcut.CreateShortcut"
|
||||||
android:label="@string/settings_shortcut">
|
android:label="@string/settings_shortcut">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.CREATE_SHORTCUT"/>
|
<action android:name="android.intent.action.CREATE_SHORTCUT"/>
|
||||||
@@ -1279,7 +1279,7 @@
|
|||||||
android:value="true" />
|
android:value="true" />
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity android:name="Settings$SecuritySettingsActivity"
|
<activity android:name=".Settings$SecurityDashboardActivity"
|
||||||
android:label="@string/security_settings_title"
|
android:label="@string/security_settings_title"
|
||||||
android:icon="@drawable/ic_homepage_security"
|
android:icon="@drawable/ic_homepage_security"
|
||||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||||
@@ -1306,28 +1306,6 @@
|
|||||||
android:value="true" />
|
android:value="true" />
|
||||||
</activity>
|
</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"
|
<activity android:name="MonitoringCertInfoActivity"
|
||||||
android:label=""
|
android:label=""
|
||||||
android:theme="@style/Transparent"
|
android:theme="@style/Transparent"
|
||||||
@@ -1358,16 +1336,6 @@
|
|||||||
android:value="true" />
|
android:value="true" />
|
||||||
</activity>
|
</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"
|
<activity android:name="Settings$PrivacySettingsActivity"
|
||||||
android:label="@string/privacy_settings_title"
|
android:label="@string/privacy_settings_title"
|
||||||
android:icon="@drawable/ic_settings_backup"
|
android:icon="@drawable/ic_settings_backup"
|
||||||
@@ -1405,7 +1373,7 @@
|
|||||||
<activity android:name="Settings$DeviceAdminSettingsActivity"
|
<activity android:name="Settings$DeviceAdminSettingsActivity"
|
||||||
android:label="@string/device_admin_settings_title"
|
android:label="@string/device_admin_settings_title"
|
||||||
android:taskAffinity="com.android.settings"
|
android:taskAffinity="com.android.settings"
|
||||||
android:parentActivityName="Settings$SecuritySettingsActivity">
|
android:parentActivityName=".Settings$SecurityDashboardActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
@@ -1436,7 +1404,7 @@
|
|||||||
<activity android:name="Settings$UsageAccessSettingsActivity"
|
<activity android:name="Settings$UsageAccessSettingsActivity"
|
||||||
android:label="@string/usage_access_title"
|
android:label="@string/usage_access_title"
|
||||||
android:taskAffinity="com.android.settings"
|
android:taskAffinity="com.android.settings"
|
||||||
android:parentActivityName="Settings$SecuritySettingsActivity">
|
android:parentActivityName=".Settings$SecurityDashboardActivity">
|
||||||
<intent-filter android:priority="1">
|
<intent-filter android:priority="1">
|
||||||
<action android:name="android.settings.USAGE_ACCESS_SETTINGS" />
|
<action android:name="android.settings.USAGE_ACCESS_SETTINGS" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
@@ -1574,7 +1542,7 @@
|
|||||||
<activity android:name="Settings$EnterprisePrivacySettingsActivity"
|
<activity android:name="Settings$EnterprisePrivacySettingsActivity"
|
||||||
android:label="@string/enterprise_privacy_settings"
|
android:label="@string/enterprise_privacy_settings"
|
||||||
android:taskAffinity="com.android.settings"
|
android:taskAffinity="com.android.settings"
|
||||||
android:parentActivityName="Settings$SecuritySettingsActivity">
|
android:parentActivityName=".Settings$SecurityDashboardActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.settings.ENTERPRISE_PRIVACY_SETTINGS" />
|
<action android:name="android.settings.ENTERPRISE_PRIVACY_SETTINGS" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
android:id="@+id/suggestion_list"
|
android:id="@+id/suggestion_list"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingTop="18dp"
|
android:paddingTop="14dp"
|
||||||
android:paddingBottom="16dp"
|
android:paddingBottom="16dp"
|
||||||
android:scrollbars="none"/>
|
android:scrollbars="none"/>
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:id="@+id/suggestion_card"
|
android:id="@+id/suggestion_card"
|
||||||
android:layout_width="328dp"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:cardPreventCornerOverlap="false"
|
app:cardPreventCornerOverlap="false"
|
||||||
app:cardUseCompatPadding="true"
|
app:cardUseCompatPadding="true"
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
android:layout_marginEnd="12dp"
|
android:layout_marginEnd="12dp"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:textAppearance="@style/TextAppearance.SuggestionTitleV2"
|
android:textAppearance="@style/TextAppearance.SuggestionTitleV2"
|
||||||
android:ellipsize="marquee"
|
android:ellipsize="end"
|
||||||
android:fadingEdge="horizontal" />
|
android:fadingEdge="horizontal" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|||||||
@@ -18,8 +18,9 @@
|
|||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:id="@+id/suggestion_card"
|
android:id="@+id/suggestion_card"
|
||||||
android:layout_width="328dp"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
app:cardPreventCornerOverlap="false"
|
||||||
app:cardUseCompatPadding="true"
|
app:cardUseCompatPadding="true"
|
||||||
app:cardElevation="2dp"
|
app:cardElevation="2dp"
|
||||||
app:cardCornerRadius="@dimen/suggestion_card_corner_radius">
|
app:cardCornerRadius="@dimen/suggestion_card_corner_radius">
|
||||||
@@ -37,16 +38,17 @@
|
|||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@android:id/icon"
|
android:id="@android:id/icon"
|
||||||
android:layout_width="@dimen/dashboard_tile_image_size"
|
android:layout_width="@dimen/suggestion_card_icon_size"
|
||||||
android:layout_height="@dimen/dashboard_tile_image_size"
|
android:layout_height="@dimen/suggestion_card_icon_size"
|
||||||
style="@style/SuggestionCardIcon"
|
style="@style/SuggestionCardIcon"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
android:layout_marginBottom="8dp" />
|
android:layout_marginBottom="8dp" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/close_button"
|
android:id="@+id/close_button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="18dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="18dp"
|
||||||
|
android:alpha="0.54"
|
||||||
android:layout_alignParentEnd="true"
|
android:layout_alignParentEnd="true"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
@@ -62,8 +64,8 @@
|
|||||||
android:layout_marginStart="12dp"
|
android:layout_marginStart="12dp"
|
||||||
android:layout_marginEnd="12dp"
|
android:layout_marginEnd="12dp"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:textAppearance="@style/TextAppearance.TileTitle"
|
android:textAppearance="@style/TextAppearance.SuggestionTitleV2"
|
||||||
android:ellipsize="marquee"
|
android:ellipsize="end"
|
||||||
android:fadingEdge="horizontal" />
|
android:fadingEdge="horizontal" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|||||||
@@ -23,9 +23,9 @@
|
|||||||
<dimen name="support_escalation_card_padding_end">56dp</dimen>
|
<dimen name="support_escalation_card_padding_end">56dp</dimen>
|
||||||
|
|
||||||
<!-- Suggestion cards-->
|
<!-- Suggestion cards-->
|
||||||
<dimen name="suggestion_card_width_one_card">380dp</dimen>
|
<dimen name="suggestion_card_width_one_card">384dp</dimen>
|
||||||
<dimen name="suggestion_card_width_two_cards">184dp</dimen>
|
<dimen name="suggestion_card_width_two_cards">188dp</dimen>
|
||||||
<dimen name="suggestion_card_width_multiple_cards">176dp</dimen>
|
<dimen name="suggestion_card_width_multiple_cards">180dp</dimen>
|
||||||
<dimen name="suggestion_card_padding_bottom_one_card">22dp</dimen>
|
<dimen name="suggestion_card_padding_bottom_one_card">22dp</dimen>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -304,9 +304,9 @@
|
|||||||
|
|
||||||
<!-- Suggestion cards size and padding -->
|
<!-- Suggestion cards size and padding -->
|
||||||
<dimen name="suggestion_card_icon_size">24dp</dimen>
|
<dimen name="suggestion_card_icon_size">24dp</dimen>
|
||||||
<dimen name="suggestion_card_width_one_card">328dp</dimen>
|
<dimen name="suggestion_card_width_one_card">332dp</dimen>
|
||||||
<dimen name="suggestion_card_width_two_cards">158dp</dimen>
|
<dimen name="suggestion_card_width_two_cards">162dp</dimen>
|
||||||
<dimen name="suggestion_card_width_multiple_cards">152dp</dimen>
|
<dimen name="suggestion_card_width_multiple_cards">156dp</dimen>
|
||||||
<dimen name="suggestion_card_outer_margin">16dp</dimen>
|
<dimen name="suggestion_card_outer_margin">16dp</dimen>
|
||||||
<dimen name="suggestion_card_inner_margin">12dp</dimen>
|
<dimen name="suggestion_card_inner_margin">12dp</dimen>
|
||||||
<dimen name="suggestion_card_padding_bottom_one_card">16dp</dimen>
|
<dimen name="suggestion_card_padding_bottom_one_card">16dp</dimen>
|
||||||
|
|||||||
@@ -2579,6 +2579,7 @@
|
|||||||
|
|
||||||
<!-- [CHAR LIMIT=30] Title of the preference that opens the Ambient display settings screen. -->
|
<!-- [CHAR LIMIT=30] Title of the preference that opens the Ambient display settings screen. -->
|
||||||
<string name="ambient_display_screen_title">Ambient display</string>
|
<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 -->
|
<!-- [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>
|
<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. -->
|
<!-- [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 +6715,8 @@
|
|||||||
<string name="keywords_sim_status">network, mobile network state, service state, signal strength, mobile network type, roaming, iccid</string>
|
<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_model_and_hardware">serial number, hardware version</string>
|
||||||
<string name="keywords_android_version">android security patch level, baseband version, kernel 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-->
|
<!-- NFC Wi-Fi pairing/setup strings-->
|
||||||
|
|
||||||
@@ -8777,6 +8780,9 @@
|
|||||||
<!-- [CHAR LIMIT=25] Title of developer tile to toggle layer trace -->
|
<!-- [CHAR LIMIT=25] Title of developer tile to toggle layer trace -->
|
||||||
<string name="layer_trace_quick_settings_title">Surface Trace</string>
|
<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 -->
|
<!-- [CHAR LIMIT=60] Title of work profile setting page -->
|
||||||
<string name="managed_profile_settings_title">Work profile settings</string>
|
<string name="managed_profile_settings_title">Work profile settings</string>
|
||||||
<!-- [CHAR LIMIT=60] The preference title for enabling cross-profile remote contact search -->
|
<!-- [CHAR LIMIT=60] The preference title for enabling cross-profile remote contact search -->
|
||||||
|
|||||||
@@ -17,7 +17,9 @@
|
|||||||
|
|
||||||
<PreferenceScreen
|
<PreferenceScreen
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||||
android:key="ambient_display_preference_screen"
|
android:key="ambient_display_preference_screen"
|
||||||
|
settings:keywords="@string/keywords_ambient_display_screen"
|
||||||
android:title="@string/ambient_display_screen_title">
|
android:title="@string/ambient_display_screen_title">
|
||||||
|
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
<PreferenceScreen
|
<PreferenceScreen
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
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">
|
android:title="@string/data_usage_app_summary_title">
|
||||||
|
|
||||||
<com.android.settings.datausage.SpinnerPreference
|
<com.android.settings.datausage.SpinnerPreference
|
||||||
@@ -50,15 +52,19 @@
|
|||||||
android:key="app_settings"
|
android:key="app_settings"
|
||||||
android:title="@string/data_usage_app_settings" />
|
android:title="@string/data_usage_app_settings" />
|
||||||
|
|
||||||
<SwitchPreference
|
<com.android.settingslib.RestrictedSwitchPreference
|
||||||
android:key="restrict_background"
|
android:key="restrict_background"
|
||||||
android:title="@string/data_usage_app_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:key="unrestricted_data_saver"
|
||||||
android:title="@string/unrestricted_app_title"
|
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>
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
|
||||||
@@ -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>
|
|
||||||
@@ -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>
|
|
||||||
@@ -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>
|
|
||||||
@@ -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>
|
|
||||||
@@ -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>
|
|
||||||
@@ -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>
|
|
||||||
@@ -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>
|
|
||||||
@@ -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>
|
|
||||||
@@ -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>
|
|
||||||
@@ -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>
|
|
||||||
@@ -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>
|
|
||||||
@@ -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>
|
|
||||||
@@ -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>
|
|
||||||
@@ -67,8 +67,7 @@ public class Settings extends SettingsActivity {
|
|||||||
public static class AccessibilityInversionSettingsActivity extends SettingsActivity { /* empty */ }
|
public static class AccessibilityInversionSettingsActivity extends SettingsActivity { /* empty */ }
|
||||||
public static class AccessibilityContrastSettingsActivity extends SettingsActivity { /* empty */ }
|
public static class AccessibilityContrastSettingsActivity extends SettingsActivity { /* empty */ }
|
||||||
public static class AccessibilityDaltonizerSettingsActivity extends SettingsActivity { /* empty */ }
|
public static class AccessibilityDaltonizerSettingsActivity extends SettingsActivity { /* empty */ }
|
||||||
public static class SecuritySettingsActivity extends SettingsActivity { /* empty */ }
|
public static class SecurityDashboardActivity extends SettingsActivity { /* empty */ }
|
||||||
public static class SecuritySettingsActivityV2 extends SettingsActivity { /* empty */ }
|
|
||||||
public static class UsageAccessSettingsActivity extends SettingsActivity { /* empty */ }
|
public static class UsageAccessSettingsActivity extends SettingsActivity { /* empty */ }
|
||||||
public static class LocationSettingsActivity extends SettingsActivity { /* empty */ }
|
public static class LocationSettingsActivity extends SettingsActivity { /* empty */ }
|
||||||
public static class PrivacySettingsActivity extends SettingsActivity { /* empty */ }
|
public static class PrivacySettingsActivity extends SettingsActivity { /* empty */ }
|
||||||
|
|||||||
@@ -802,20 +802,6 @@ public class SettingsActivity extends SettingsDrawerActivity
|
|||||||
!isConnectedDeviceV2Enabled && !UserManager.isDeviceInDemoMode(this) /* enabled */,
|
!isConnectedDeviceV2Enabled && !UserManager.isDeviceInDemoMode(this) /* enabled */,
|
||||||
isAdmin) || somethingChanged;
|
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,
|
somethingChanged = setTileEnabled(new ComponentName(packageName,
|
||||||
Settings.SimSettingsActivity.class.getName()),
|
Settings.SimSettingsActivity.class.getName()),
|
||||||
Utils.showSimCardTile(this), isAdmin)
|
Utils.showSimCardTile(this), isAdmin)
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ import static android.content.pm.PackageManager.GET_META_DATA;
|
|||||||
import static android.content.pm.PackageManager.GET_RESOLVED_FILTER;
|
import static android.content.pm.PackageManager.GET_RESOLVED_FILTER;
|
||||||
import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
|
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}
|
* 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,
|
* performs setup steps for a managed profile (disables the launcher icon of the Settings app,
|
||||||
|
|||||||
@@ -16,18 +16,14 @@
|
|||||||
|
|
||||||
package com.android.settings.applications.appinfo;
|
package com.android.settings.applications.appinfo;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
@@ -35,7 +31,6 @@ import android.os.UserHandle;
|
|||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.support.annotation.VisibleForTesting;
|
import android.support.annotation.VisibleForTesting;
|
||||||
import android.support.v7.preference.PreferenceScreen;
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
import android.util.Log;
|
|
||||||
import android.webkit.IWebViewUpdateService;
|
import android.webkit.IWebViewUpdateService;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
@@ -71,16 +66,6 @@ public class AppActionButtonPreferenceController extends BasePreferenceControlle
|
|||||||
private UserManager mUserManager;
|
private UserManager mUserManager;
|
||||||
private PackageManager mPm;
|
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,
|
public AppActionButtonPreferenceController(Context context, AppInfoDashboardFragment parent,
|
||||||
String packageName) {
|
String packageName) {
|
||||||
super(context, KEY_ACTION_BUTTONS);
|
super(context, KEY_ACTION_BUTTONS);
|
||||||
@@ -101,9 +86,7 @@ public class AppActionButtonPreferenceController extends BasePreferenceControlle
|
|||||||
public void displayPreference(PreferenceScreen screen) {
|
public void displayPreference(PreferenceScreen screen) {
|
||||||
super.displayPreference(screen);
|
super.displayPreference(screen);
|
||||||
mActionButtons = ((ActionButtonPreference) screen.findPreference(KEY_ACTION_BUTTONS))
|
mActionButtons = ((ActionButtonPreference) screen.findPreference(KEY_ACTION_BUTTONS))
|
||||||
.setButton2Text(R.string.force_stop)
|
.setButton2Visible(false);
|
||||||
.setButton2Positive(false)
|
|
||||||
.setButton2Enabled(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -140,7 +123,6 @@ public class AppActionButtonPreferenceController extends BasePreferenceControlle
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkForceStop(appEntry, packageInfo);
|
|
||||||
initUninstallButtons(appEntry, packageInfo);
|
initUninstallButtons(appEntry, packageInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,41 +251,6 @@ public class AppActionButtonPreferenceController extends BasePreferenceControlle
|
|||||||
return disableable;
|
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) {
|
private boolean signaturesMatch(String pkg1, String pkg2) {
|
||||||
if (pkg1 != null && pkg2 != null) {
|
if (pkg1 != null && pkg2 != null) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package com.android.settings.applications.appinfo;
|
|||||||
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.ActivityManager;
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.app.DialogFragment;
|
import android.app.DialogFragment;
|
||||||
@@ -45,19 +44,15 @@ import android.util.Log;
|
|||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
import com.android.settings.DeviceAdminAdd;
|
import com.android.settings.DeviceAdminAdd;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.SettingsActivity;
|
import com.android.settings.SettingsActivity;
|
||||||
import com.android.settings.SettingsPreferenceFragment;
|
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.applications.manageapplications.ManageApplications;
|
||||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||||
import com.android.settings.dashboard.DashboardFragment;
|
import com.android.settings.dashboard.DashboardFragment;
|
||||||
import com.android.settings.widget.EntityHeaderController;
|
|
||||||
import com.android.settings.widget.PreferenceCategoryController;
|
import com.android.settings.widget.PreferenceCategoryController;
|
||||||
import com.android.settings.wrapper.DevicePolicyManagerWrapper;
|
import com.android.settings.wrapper.DevicePolicyManagerWrapper;
|
||||||
import com.android.settingslib.RestrictedLockUtils;
|
import com.android.settingslib.RestrictedLockUtils;
|
||||||
@@ -89,6 +84,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
|||||||
// Menu identifiers
|
// Menu identifiers
|
||||||
private static final int UNINSTALL_ALL_USERS_MENU = 1;
|
private static final int UNINSTALL_ALL_USERS_MENU = 1;
|
||||||
private static final int UNINSTALL_UPDATES = 2;
|
private static final int UNINSTALL_UPDATES = 2;
|
||||||
|
static final int FORCE_STOP_MENU = 3;
|
||||||
|
|
||||||
// Result code identifiers
|
// Result code identifiers
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -103,7 +99,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
|||||||
|
|
||||||
// Dialog identifiers used in showDialog
|
// Dialog identifiers used in showDialog
|
||||||
private static final int DLG_BASE = 0;
|
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_DISABLE = DLG_BASE + 2;
|
||||||
private static final int DLG_SPECIAL_DISABLE = DLG_BASE + 3;
|
private static final int DLG_SPECIAL_DISABLE = DLG_BASE + 3;
|
||||||
|
|
||||||
@@ -141,6 +137,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
|||||||
|
|
||||||
private InstantAppButtonsPreferenceController mInstantAppButtonPreferenceController;
|
private InstantAppButtonsPreferenceController mInstantAppButtonPreferenceController;
|
||||||
private AppActionButtonPreferenceController mAppActionButtonPreferenceController;
|
private AppActionButtonPreferenceController mAppActionButtonPreferenceController;
|
||||||
|
private ForceStopOptionsMenuController mForceStopOptionsMenuController;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback to invoke when app info has been changed.
|
* Callback to invoke when app info has been changed.
|
||||||
@@ -172,6 +169,9 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mForceStopOptionsMenuController =
|
||||||
|
new ForceStopOptionsMenuController(activity, this /* parent */, mDpm,
|
||||||
|
mMetricsFeatureProvider, getLifecycle());
|
||||||
setHasOptionsMenu(true);
|
setHasOptionsMenu(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,6 +268,10 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
|||||||
return mAppEntry;
|
return mAppEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setAppEntry(ApplicationsState.AppEntry appEntry) {
|
||||||
|
mAppEntry = appEntry;
|
||||||
|
}
|
||||||
|
|
||||||
PackageInfo getPackageInfo() {
|
PackageInfo getPackageInfo() {
|
||||||
if (mAppEntry == null) {
|
if (mAppEntry == null) {
|
||||||
retrieveAppEntry();
|
retrieveAppEntry();
|
||||||
@@ -275,6 +279,10 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
|||||||
return mPackageInfo;
|
return mPackageInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ApplicationsState getAppState() {
|
||||||
|
return mState;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPackageSizeChanged(String packageName) {
|
public void onPackageSizeChanged(String packageName) {
|
||||||
if (!TextUtils.equals(packageName, mPackageName)) {
|
if (!TextUtils.equals(packageName, mPackageName)) {
|
||||||
@@ -315,6 +323,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
|||||||
if (mFinishing) {
|
if (mFinishing) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
super.onPrepareOptionsMenu(menu);
|
||||||
menu.findItem(UNINSTALL_ALL_USERS_MENU).setVisible(shouldShowUninstallForAll(mAppEntry));
|
menu.findItem(UNINSTALL_ALL_USERS_MENU).setVisible(shouldShowUninstallForAll(mAppEntry));
|
||||||
mUpdatedSysApp = (mAppEntry.info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
|
mUpdatedSysApp = (mAppEntry.info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
|
||||||
final MenuItem uninstallUpdatesItem = menu.findItem(UNINSTALL_UPDATES);
|
final MenuItem uninstallUpdatesItem = menu.findItem(UNINSTALL_UPDATES);
|
||||||
@@ -335,7 +344,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
|||||||
uninstallPkg(mAppEntry.info.packageName, false, false);
|
uninstallPkg(mAppEntry.info.packageName, false, false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -465,18 +474,10 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
|||||||
})
|
})
|
||||||
.setNegativeButton(R.string.dlg_cancel, null)
|
.setNegativeButton(R.string.dlg_cancel, null)
|
||||||
.create();
|
.create();
|
||||||
case DLG_FORCE_STOP:
|
}
|
||||||
return new AlertDialog.Builder(getActivity())
|
final AlertDialog dialog = mForceStopOptionsMenuController.createDialog(id);
|
||||||
.setTitle(getActivity().getText(R.string.force_stop_dlg_title))
|
if (dialog != null) {
|
||||||
.setMessage(getActivity().getText(R.string.force_stop_dlg_text))
|
return dialog;
|
||||||
.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();
|
|
||||||
}
|
}
|
||||||
return mInstantAppButtonPreferenceController.createDialog(id);
|
return mInstantAppButtonPreferenceController.createDialog(id);
|
||||||
}
|
}
|
||||||
@@ -493,21 +494,6 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
|||||||
mDisableAfterUninstall = andDisable;
|
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,
|
public static void startAppInfoFragment(Class<?> fragment, int title,
|
||||||
SettingsPreferenceFragment caller, AppEntry appEntry) {
|
SettingsPreferenceFragment caller, AppEntry appEntry) {
|
||||||
// start new fragment to display extended information
|
// start new fragment to display extended information
|
||||||
@@ -568,20 +554,6 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 */
|
/** Returns whether there is only one user on this device, not including the system-only user */
|
||||||
private boolean isSingleUser() {
|
private boolean isSingleUser() {
|
||||||
final int userCount = mUserManager.getUserCount();
|
final int userCount = mUserManager.getUserCount();
|
||||||
@@ -679,7 +651,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setIntentAndFinish(boolean finish, boolean appChanged) {
|
void setIntentAndFinish(boolean finish, boolean appChanged) {
|
||||||
if (localLOGV) Log.i(TAG, "appChanged="+appChanged);
|
if (localLOGV) Log.i(TAG, "appChanged="+appChanged);
|
||||||
final Intent intent = new Intent();
|
final Intent intent = new Intent();
|
||||||
intent.putExtra(ManageApplications.APP_CHG, appChanged);
|
intent.putExtra(ManageApplications.APP_CHG, appChanged);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -24,7 +24,6 @@ public class FeatureFlags {
|
|||||||
public static final String CONNECTED_DEVICE_V2 = "settings_connected_device_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_SETTINGS_V2 = "settings_battery_v2";
|
||||||
public static final String BATTERY_DISPLAY_APP_LIST = "settings_battery_display_app_list";
|
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 ZONE_PICKER_V2 = "settings_zone_picker_v2";
|
||||||
public static final String SUGGESTION_UI_V2 = "settings_suggestion_ui_v2";
|
public static final String SUGGESTION_UI_V2 = "settings_suggestion_ui_v2";
|
||||||
public static final String ABOUT_PHONE_V2 = "settings_about_phone_v2";
|
public static final String ABOUT_PHONE_V2 = "settings_about_phone_v2";
|
||||||
|
|||||||
@@ -116,7 +116,6 @@ import com.android.settings.print.PrintSettingsFragment;
|
|||||||
import com.android.settings.security.CryptKeeperSettings;
|
import com.android.settings.security.CryptKeeperSettings;
|
||||||
import com.android.settings.security.LockscreenDashboardFragment;
|
import com.android.settings.security.LockscreenDashboardFragment;
|
||||||
import com.android.settings.security.SecuritySettings;
|
import com.android.settings.security.SecuritySettings;
|
||||||
import com.android.settings.security.SecuritySettingsV2;
|
|
||||||
import com.android.settings.sim.SimSettings;
|
import com.android.settings.sim.SimSettings;
|
||||||
import com.android.settings.support.SupportDashboardActivity;
|
import com.android.settings.support.SupportDashboardActivity;
|
||||||
import com.android.settings.system.ResetDashboardFragment;
|
import com.android.settings.system.ResetDashboardFragment;
|
||||||
@@ -165,7 +164,6 @@ public class SettingsGateway {
|
|||||||
NotificationStation.class.getName(),
|
NotificationStation.class.getName(),
|
||||||
LocationSettings.class.getName(),
|
LocationSettings.class.getName(),
|
||||||
SecuritySettings.class.getName(),
|
SecuritySettings.class.getName(),
|
||||||
SecuritySettingsV2.class.getName(),
|
|
||||||
UsageAccessDetails.class.getName(),
|
UsageAccessDetails.class.getName(),
|
||||||
PrivacySettings.class.getName(),
|
PrivacySettings.class.getName(),
|
||||||
DeviceAdminSettings.class.getName(),
|
DeviceAdminSettings.class.getName(),
|
||||||
@@ -271,8 +269,7 @@ public class SettingsGateway {
|
|||||||
Settings.PowerUsageSummaryActivity.class.getName(),
|
Settings.PowerUsageSummaryActivity.class.getName(),
|
||||||
Settings.PowerUsageSummaryLegacyActivity.class.getName(),
|
Settings.PowerUsageSummaryLegacyActivity.class.getName(),
|
||||||
Settings.AccountDashboardActivity.class.getName(),
|
Settings.AccountDashboardActivity.class.getName(),
|
||||||
Settings.SecuritySettingsActivity.class.getName(),
|
Settings.SecurityDashboardActivity.class.getName(),
|
||||||
Settings.SecuritySettingsActivityV2.class.getName(),
|
|
||||||
Settings.AccessibilitySettingsActivity.class.getName(),
|
Settings.AccessibilitySettingsActivity.class.getName(),
|
||||||
Settings.SystemDashboardActivity.class.getName(),
|
Settings.SystemDashboardActivity.class.getName(),
|
||||||
SupportDashboardActivity.class.getName(),
|
SupportDashboardActivity.class.getName(),
|
||||||
|
|||||||
@@ -151,13 +151,10 @@ public class DashboardAdapterV2 extends RecyclerView.Adapter<DashboardAdapterV2.
|
|||||||
if (list.size() == 1) {
|
if (list.size() == 1) {
|
||||||
// The only suggestion is dismissed, and the the empty suggestion container will
|
// The only suggestion is dismissed, and the the empty suggestion container will
|
||||||
// remain as the dashboard item. Need to refresh the dashboard list.
|
// remain as the dashboard item. Need to refresh the dashboard list.
|
||||||
final DashboardDataV2 prevData = mDashboardData;
|
setSuggestions(null);
|
||||||
mDashboardData = new DashboardDataV2.Builder(prevData)
|
|
||||||
.setSuggestions(null)
|
|
||||||
.build();
|
|
||||||
notifyDashboardDataChanged(prevData);
|
|
||||||
} else {
|
} else {
|
||||||
mSuggestionAdapter.removeSuggestion(suggestion);
|
mSuggestionAdapter.removeSuggestion(suggestion);
|
||||||
|
notifyItemChanged(0, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import com.android.settings.network.NetworkDashboardFragment;
|
|||||||
import com.android.settings.notification.ConfigureNotificationSettings;
|
import com.android.settings.notification.ConfigureNotificationSettings;
|
||||||
import com.android.settings.notification.SoundSettings;
|
import com.android.settings.notification.SoundSettings;
|
||||||
import com.android.settings.security.LockscreenDashboardFragment;
|
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.settings.system.SystemDashboardFragment;
|
||||||
import com.android.settingslib.drawer.CategoryKey;
|
import com.android.settingslib.drawer.CategoryKey;
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ public class DashboardFragmentRegistry {
|
|||||||
CategoryKey.CATEGORY_SOUND);
|
CategoryKey.CATEGORY_SOUND);
|
||||||
PARENT_TO_CATEGORY_KEY_MAP.put(StorageDashboardFragment.class.getName(),
|
PARENT_TO_CATEGORY_KEY_MAP.put(StorageDashboardFragment.class.getName(),
|
||||||
CategoryKey.CATEGORY_STORAGE);
|
CategoryKey.CATEGORY_STORAGE);
|
||||||
PARENT_TO_CATEGORY_KEY_MAP.put(SecuritySettingsV2.class.getName(),
|
PARENT_TO_CATEGORY_KEY_MAP.put(SecuritySettings.class.getName(),
|
||||||
CategoryKey.CATEGORY_SECURITY);
|
CategoryKey.CATEGORY_SECURITY);
|
||||||
PARENT_TO_CATEGORY_KEY_MAP.put(AccountDetailDashboardFragment.class.getName(),
|
PARENT_TO_CATEGORY_KEY_MAP.put(AccountDetailDashboardFragment.class.getName(),
|
||||||
CategoryKey.CATEGORY_ACCOUNT_DETAIL);
|
CategoryKey.CATEGORY_ACCOUNT_DETAIL);
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ package com.android.settings.dashboard.suggestions;
|
|||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.graphics.drawable.Icon;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.service.settings.suggestions.Suggestion;
|
import android.service.settings.suggestions.Suggestion;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
@@ -34,6 +36,7 @@ import com.android.settings.R;
|
|||||||
import com.android.settings.dashboard.DashboardAdapterV2.DashboardItemHolder;
|
import com.android.settings.dashboard.DashboardAdapterV2.DashboardItemHolder;
|
||||||
import com.android.settings.dashboard.DashboardAdapterV2.IconCache;
|
import com.android.settings.dashboard.DashboardAdapterV2.IconCache;
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
|
import com.android.settingslib.Utils;
|
||||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||||
@@ -55,6 +58,7 @@ public class SuggestionAdapterV2 extends RecyclerView.Adapter<DashboardItemHolde
|
|||||||
private final MetricsFeatureProvider mMetricsFeatureProvider;
|
private final MetricsFeatureProvider mMetricsFeatureProvider;
|
||||||
private final IconCache mCache;
|
private final IconCache mCache;
|
||||||
private final ArrayList<String> mSuggestionsShownLogged;
|
private final ArrayList<String> mSuggestionsShownLogged;
|
||||||
|
private final SuggestionFeatureProvider mSuggestionFeatureProvider;
|
||||||
private final SuggestionControllerMixin mSuggestionControllerMixin;
|
private final SuggestionControllerMixin mSuggestionControllerMixin;
|
||||||
private final Callback mCallback;
|
private final Callback mCallback;
|
||||||
private final CardConfig mConfig;
|
private final CardConfig mConfig;
|
||||||
@@ -75,6 +79,7 @@ public class SuggestionAdapterV2 extends RecyclerView.Adapter<DashboardItemHolde
|
|||||||
mCache = new IconCache(context);
|
mCache = new IconCache(context);
|
||||||
final FeatureFactory factory = FeatureFactory.getFactory(context);
|
final FeatureFactory factory = FeatureFactory.getFactory(context);
|
||||||
mMetricsFeatureProvider = factory.getMetricsFeatureProvider();
|
mMetricsFeatureProvider = factory.getMetricsFeatureProvider();
|
||||||
|
mSuggestionFeatureProvider = factory.getSuggestionFeatureProvider(context);
|
||||||
mCallback = callback;
|
mCallback = callback;
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
mSuggestions = savedInstanceState.getParcelableArrayList(STATE_SUGGESTION_LIST);
|
mSuggestions = savedInstanceState.getParcelableArrayList(STATE_SUGGESTION_LIST);
|
||||||
@@ -109,7 +114,12 @@ public class SuggestionAdapterV2 extends RecyclerView.Adapter<DashboardItemHolde
|
|||||||
mSuggestionsShownLogged.add(id);
|
mSuggestionsShownLogged.add(id);
|
||||||
}
|
}
|
||||||
mConfig.setCardLayout(holder, suggestionCount, position);
|
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.setText(suggestion.getTitle());
|
||||||
holder.title.setSingleLine(suggestionCount == 1);
|
holder.title.setSingleLine(suggestionCount == 1);
|
||||||
|
|
||||||
@@ -129,13 +139,13 @@ public class SuggestionAdapterV2 extends RecyclerView.Adapter<DashboardItemHolde
|
|||||||
|
|
||||||
final ImageView closeButton = holder.itemView.findViewById(R.id.close_button);
|
final ImageView closeButton = holder.itemView.findViewById(R.id.close_button);
|
||||||
if (closeButton != null) {
|
if (closeButton != null) {
|
||||||
if (mCallback != null) {
|
closeButton.setOnClickListener(v -> {
|
||||||
closeButton.setOnClickListener(v -> {
|
mSuggestionFeatureProvider.dismissSuggestion(
|
||||||
|
mContext, mSuggestionControllerMixin, suggestion);
|
||||||
|
if (mCallback != null) {
|
||||||
mCallback.onSuggestionClosed(suggestion);
|
mCallback.onSuggestionClosed(suggestion);
|
||||||
});
|
}
|
||||||
} else {
|
});
|
||||||
closeButton.setOnClickListener(null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
View clickHandler = holder.itemView;
|
View clickHandler = holder.itemView;
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import android.os.Bundle;
|
|||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.support.annotation.VisibleForTesting;
|
import android.support.annotation.VisibleForTesting;
|
||||||
import android.support.v14.preference.SwitchPreference;
|
|
||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
import android.support.v7.preference.PreferenceCategory;
|
import android.support.v7.preference.PreferenceCategory;
|
||||||
import android.text.format.Formatter;
|
import android.text.format.Formatter;
|
||||||
@@ -48,6 +47,9 @@ import com.android.settings.R;
|
|||||||
import com.android.settings.applications.AppInfoBase;
|
import com.android.settings.applications.AppInfoBase;
|
||||||
import com.android.settings.widget.EntityHeaderController;
|
import com.android.settings.widget.EntityHeaderController;
|
||||||
import com.android.settingslib.AppItem;
|
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.ChartData;
|
||||||
import com.android.settingslib.net.ChartDataLoader;
|
import com.android.settingslib.net.ChartDataLoader;
|
||||||
import com.android.settingslib.net.UidDetail;
|
import com.android.settingslib.net.UidDetail;
|
||||||
@@ -80,7 +82,7 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen
|
|||||||
private Preference mForegroundUsage;
|
private Preference mForegroundUsage;
|
||||||
private Preference mBackgroundUsage;
|
private Preference mBackgroundUsage;
|
||||||
private Preference mAppSettings;
|
private Preference mAppSettings;
|
||||||
private SwitchPreference mRestrictBackground;
|
private RestrictedSwitchPreference mRestrictBackground;
|
||||||
private PreferenceCategory mAppList;
|
private PreferenceCategory mAppList;
|
||||||
|
|
||||||
private Drawable mIcon;
|
private Drawable mIcon;
|
||||||
@@ -97,7 +99,7 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen
|
|||||||
private AppItem mAppItem;
|
private AppItem mAppItem;
|
||||||
private Intent mAppSettingsIntent;
|
private Intent mAppSettingsIntent;
|
||||||
private SpinnerPreference mCycle;
|
private SpinnerPreference mCycle;
|
||||||
private SwitchPreference mUnrestrictedData;
|
private RestrictedSwitchPreference mUnrestrictedData;
|
||||||
private DataSaverBackend mDataSaverBackend;
|
private DataSaverBackend mDataSaverBackend;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -160,9 +162,11 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen
|
|||||||
removePreference(KEY_UNRESTRICTED_DATA);
|
removePreference(KEY_UNRESTRICTED_DATA);
|
||||||
removePreference(KEY_RESTRICT_BACKGROUND);
|
removePreference(KEY_RESTRICT_BACKGROUND);
|
||||||
} else {
|
} else {
|
||||||
mRestrictBackground = (SwitchPreference) findPreference(KEY_RESTRICT_BACKGROUND);
|
mRestrictBackground = (RestrictedSwitchPreference) findPreference(
|
||||||
|
KEY_RESTRICT_BACKGROUND);
|
||||||
mRestrictBackground.setOnPreferenceChangeListener(this);
|
mRestrictBackground.setOnPreferenceChangeListener(this);
|
||||||
mUnrestrictedData = (SwitchPreference) findPreference(KEY_UNRESTRICTED_DATA);
|
mUnrestrictedData = (RestrictedSwitchPreference) findPreference(
|
||||||
|
KEY_UNRESTRICTED_DATA);
|
||||||
mUnrestrictedData.setOnPreferenceChangeListener(this);
|
mUnrestrictedData.setOnPreferenceChangeListener(this);
|
||||||
}
|
}
|
||||||
mDataSaverBackend = new DataSaverBackend(getContext());
|
mDataSaverBackend = new DataSaverBackend(getContext());
|
||||||
@@ -261,8 +265,11 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updatePrefs(boolean restrictBackground, boolean unrestrictData) {
|
private void updatePrefs(boolean restrictBackground, boolean unrestrictData) {
|
||||||
|
final EnforcedAdmin admin = RestrictedLockUtils.checkIfMeteredDataRestricted(
|
||||||
|
getContext(), mPackageName, UserHandle.getUserId(mAppItem.key));
|
||||||
if (mRestrictBackground != null) {
|
if (mRestrictBackground != null) {
|
||||||
mRestrictBackground.setChecked(!restrictBackground);
|
mRestrictBackground.setChecked(!restrictBackground);
|
||||||
|
mRestrictBackground.setDisabledByAdmin(admin);
|
||||||
}
|
}
|
||||||
if (mUnrestrictedData != null) {
|
if (mUnrestrictedData != null) {
|
||||||
if (restrictBackground) {
|
if (restrictBackground) {
|
||||||
@@ -270,6 +277,7 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen
|
|||||||
} else {
|
} else {
|
||||||
mUnrestrictedData.setVisible(true);
|
mUnrestrictedData.setVisible(true);
|
||||||
mUnrestrictedData.setChecked(unrestrictData);
|
mUnrestrictedData.setChecked(unrestrictData);
|
||||||
|
mUnrestrictedData.setDisabledByAdmin(admin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class DataSaverPreference extends Preference implements DataSaverBackend.
|
|||||||
@Override
|
@Override
|
||||||
public void onDetached() {
|
public void onDetached() {
|
||||||
super.onDetached();
|
super.onDetached();
|
||||||
mDataSaverBackend.addListener(this);
|
mDataSaverBackend.remListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
package com.android.settings.datausage;
|
package com.android.settings.datausage;
|
||||||
|
|
||||||
|
import static com.android.settingslib.RestrictedLockUtils.checkIfMeteredDataRestricted;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -37,6 +39,8 @@ import com.android.settings.core.FeatureFlags;
|
|||||||
import com.android.settings.datausage.AppStateDataUsageBridge.DataUsageState;
|
import com.android.settings.datausage.AppStateDataUsageBridge.DataUsageState;
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
import com.android.settings.widget.AppSwitchPreference;
|
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;
|
||||||
import com.android.settingslib.applications.ApplicationsState.AppEntry;
|
import com.android.settingslib.applications.ApplicationsState.AppEntry;
|
||||||
import com.android.settingslib.applications.ApplicationsState.AppFilter;
|
import com.android.settingslib.applications.ApplicationsState.AppFilter;
|
||||||
@@ -172,6 +176,8 @@ public class UnrestrictedDataAccess extends SettingsPreferenceFragment
|
|||||||
preference.setOnPreferenceChangeListener(this);
|
preference.setOnPreferenceChangeListener(this);
|
||||||
getPreferenceScreen().addPreference(preference);
|
getPreferenceScreen().addPreference(preference);
|
||||||
} else {
|
} else {
|
||||||
|
preference.setDisabledByAdmin(checkIfMeteredDataRestricted(getContext(),
|
||||||
|
entry.info.packageName, UserHandle.getUserId(entry.info.uid)));
|
||||||
preference.reuse();
|
preference.reuse();
|
||||||
}
|
}
|
||||||
preference.setOrder(i);
|
preference.setOrder(i);
|
||||||
@@ -242,16 +248,22 @@ public class UnrestrictedDataAccess extends SettingsPreferenceFragment
|
|||||||
return app != null && UserHandle.isApp(app.info.uid);
|
return app != null && UserHandle.isApp(app.info.uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AccessPreference extends AppSwitchPreference
|
@VisibleForTesting
|
||||||
|
class AccessPreference extends AppSwitchPreference
|
||||||
implements DataSaverBackend.Listener {
|
implements DataSaverBackend.Listener {
|
||||||
private final AppEntry mEntry;
|
private final AppEntry mEntry;
|
||||||
private final DataUsageState mState;
|
private final DataUsageState mState;
|
||||||
|
private final RestrictedPreferenceHelper mHelper;
|
||||||
|
|
||||||
public AccessPreference(final Context context, AppEntry entry) {
|
public AccessPreference(final Context context, AppEntry entry) {
|
||||||
super(context);
|
super(context);
|
||||||
|
setWidgetLayoutResource(R.layout.restricted_switch_widget);
|
||||||
|
mHelper = new RestrictedPreferenceHelper(context, this, null);
|
||||||
mEntry = entry;
|
mEntry = entry;
|
||||||
mState = (DataUsageState) mEntry.extraInfo;
|
mState = (DataUsageState) mEntry.extraInfo;
|
||||||
mEntry.ensureLabel(getContext());
|
mEntry.ensureLabel(getContext());
|
||||||
|
setDisabledByAdmin(checkIfMeteredDataRestricted(context, entry.info.packageName,
|
||||||
|
UserHandle.getUserId(entry.info.uid)));
|
||||||
setState();
|
setState();
|
||||||
if (mEntry.icon != null) {
|
if (mEntry.icon != null) {
|
||||||
setIcon(mEntry.icon);
|
setIcon(mEntry.icon);
|
||||||
@@ -291,12 +303,21 @@ public class UnrestrictedDataAccess extends SettingsPreferenceFragment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void performClick() {
|
||||||
|
if (!mHelper.performClick()) {
|
||||||
|
super.performClick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Sets UI state based on whitelist/blacklist status.
|
// Sets UI state based on whitelist/blacklist status.
|
||||||
private void setState() {
|
private void setState() {
|
||||||
setTitle(mEntry.label);
|
setTitle(mEntry.label);
|
||||||
if (mState != null) {
|
if (mState != null) {
|
||||||
setChecked(mState.isDataSaverWhitelisted);
|
setChecked(mState.isDataSaverWhitelisted);
|
||||||
if (mState.isDataSaverBlacklisted) {
|
if (isDisabledByAdmin()) {
|
||||||
|
setSummary(R.string.disabled_by_admin);
|
||||||
|
} else if (mState.isDataSaverBlacklisted) {
|
||||||
setSummary(R.string.restrict_background_blacklisted);
|
setSummary(R.string.restrict_background_blacklisted);
|
||||||
} else {
|
} else {
|
||||||
setSummary("");
|
setSummary("");
|
||||||
@@ -323,10 +344,21 @@ public class UnrestrictedDataAccess extends SettingsPreferenceFragment
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
holder.findViewById(android.R.id.widget_frame)
|
final boolean disabledByAdmin = isDisabledByAdmin();
|
||||||
.setVisibility(mState != null && mState.isDataSaverBlacklisted
|
final View widgetFrame = holder.findViewById(android.R.id.widget_frame);
|
||||||
? View.INVISIBLE : View.VISIBLE);
|
if (disabledByAdmin) {
|
||||||
|
widgetFrame.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
widgetFrame.setVisibility(mState != null && mState.isDataSaverBlacklisted
|
||||||
|
? View.INVISIBLE : View.VISIBLE);
|
||||||
|
}
|
||||||
super.onBindViewHolder(holder);
|
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
|
@Override
|
||||||
@@ -348,6 +380,19 @@ public class UnrestrictedDataAccess extends SettingsPreferenceFragment
|
|||||||
reuse();
|
reuse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDisabledByAdmin(EnforcedAdmin admin) {
|
||||||
|
mHelper.setDisabledByAdmin(admin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDisabledByAdmin() {
|
||||||
|
return mHelper.isDisabledByAdmin();
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public AppEntry getEntryForTest() {
|
||||||
|
return mEntry;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ import android.os.UserManager;
|
|||||||
import android.support.annotation.VisibleForTesting;
|
import android.support.annotation.VisibleForTesting;
|
||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
import android.support.v7.preference.Preference.OnPreferenceChangeListener;
|
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.PreferenceGroup;
|
||||||
import android.support.v7.preference.PreferenceScreen;
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
import android.support.v7.preference.PreferenceViewHolder;
|
import android.support.v7.preference.PreferenceViewHolder;
|
||||||
@@ -921,49 +920,4 @@ public class FingerprintSettings extends SubSettings {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import android.widget.CompoundButton;
|
|||||||
import com.android.internal.app.LocalePicker;
|
import com.android.internal.app.LocalePicker;
|
||||||
import com.android.internal.app.LocaleStore;
|
import com.android.internal.app.LocaleStore;
|
||||||
|
|
||||||
import com.android.settings.CreateShortcut;
|
import com.android.settings.shortcut.CreateShortcut;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
|
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
|
|||||||
@@ -54,17 +54,6 @@ public class ManagedLockPasswordProvider {
|
|||||||
*/
|
*/
|
||||||
CharSequence getPickerOptionTitle(boolean forFingerprint) { return ""; }
|
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
|
* Creates intent that should be launched when user chooses managed password in the lock
|
||||||
* settings picker.
|
* settings picker.
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import android.support.annotation.VisibleForTesting;
|
|||||||
import com.android.settings.DateTimeSettings;
|
import com.android.settings.DateTimeSettings;
|
||||||
import com.android.settings.DisplaySettings;
|
import com.android.settings.DisplaySettings;
|
||||||
import com.android.settings.LegalSettings;
|
import com.android.settings.LegalSettings;
|
||||||
import com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment;
|
|
||||||
import com.android.settings.accessibility.AccessibilitySettings;
|
import com.android.settings.accessibility.AccessibilitySettings;
|
||||||
import com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment;
|
import com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment;
|
||||||
import com.android.settings.accessibility.MagnificationPreferenceFragment;
|
import com.android.settings.accessibility.MagnificationPreferenceFragment;
|
||||||
@@ -42,6 +41,7 @@ import com.android.settings.development.DevelopmentSettingsDashboardFragment;
|
|||||||
import com.android.settings.deviceinfo.DeviceInfoSettings;
|
import com.android.settings.deviceinfo.DeviceInfoSettings;
|
||||||
import com.android.settings.deviceinfo.StorageDashboardFragment;
|
import com.android.settings.deviceinfo.StorageDashboardFragment;
|
||||||
import com.android.settings.deviceinfo.StorageSettings;
|
import com.android.settings.deviceinfo.StorageSettings;
|
||||||
|
import com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment;
|
||||||
import com.android.settings.display.AmbientDisplaySettings;
|
import com.android.settings.display.AmbientDisplaySettings;
|
||||||
import com.android.settings.display.NightDisplaySettings;
|
import com.android.settings.display.NightDisplaySettings;
|
||||||
import com.android.settings.display.ScreenZoomSettings;
|
import com.android.settings.display.ScreenZoomSettings;
|
||||||
@@ -75,7 +75,7 @@ import com.android.settings.print.PrintSettingsFragment;
|
|||||||
import com.android.settings.security.EncryptionAndCredential;
|
import com.android.settings.security.EncryptionAndCredential;
|
||||||
import com.android.settings.security.LockscreenDashboardFragment;
|
import com.android.settings.security.LockscreenDashboardFragment;
|
||||||
import com.android.settings.security.ScreenPinningSettings;
|
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.security.screenlock.ScreenLockSettings;
|
||||||
import com.android.settings.sim.SimSettings;
|
import com.android.settings.sim.SimSettings;
|
||||||
import com.android.settings.support.SupportDashboardActivity;
|
import com.android.settings.support.SupportDashboardActivity;
|
||||||
@@ -132,7 +132,7 @@ public class SearchIndexableResourcesImpl implements SearchIndexableResources {
|
|||||||
addIndex(LanguageAndInputSettings.class);
|
addIndex(LanguageAndInputSettings.class);
|
||||||
addIndex(LocationSettings.class);
|
addIndex(LocationSettings.class);
|
||||||
addIndex(ScanningSettings.class);
|
addIndex(ScanningSettings.class);
|
||||||
addIndex(SecuritySettingsV2.class);
|
addIndex(SecuritySettings.class);
|
||||||
addIndex(ScreenLockSettings.class);
|
addIndex(ScreenLockSettings.class);
|
||||||
addIndex(EncryptionAndCredential.class);
|
addIndex(EncryptionAndCredential.class);
|
||||||
addIndex(ScreenPinningSettings.class);
|
addIndex(ScreenPinningSettings.class);
|
||||||
|
|||||||
@@ -16,8 +16,7 @@
|
|||||||
|
|
||||||
package com.android.settings.security;
|
package com.android.settings.security;
|
||||||
|
|
||||||
import static com.android.settings.security
|
import static com.android.settings.security.SecuritySettings.SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE;
|
||||||
.SecuritySettingsV2.SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE;
|
|
||||||
|
|
||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -37,7 +36,7 @@ public class ChangeProfileScreenLockPreferenceController extends
|
|||||||
private static final String KEY_UNLOCK_SET_OR_CHANGE_PROFILE = "unlock_set_or_change_profile";
|
private static final String KEY_UNLOCK_SET_OR_CHANGE_PROFILE = "unlock_set_or_change_profile";
|
||||||
|
|
||||||
public ChangeProfileScreenLockPreferenceController(Context context,
|
public ChangeProfileScreenLockPreferenceController(Context context,
|
||||||
SecuritySettingsV2 host) {
|
SecuritySettings host) {
|
||||||
super(context, host);
|
super(context, host);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package com.android.settings.security;
|
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.app.admin.DevicePolicyManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -45,7 +45,7 @@ public class ChangeScreenLockPreferenceController extends AbstractPreferenceCont
|
|||||||
private static final String KEY_UNLOCK_SET_OR_CHANGE = "unlock_set_or_change";
|
private static final String KEY_UNLOCK_SET_OR_CHANGE = "unlock_set_or_change";
|
||||||
|
|
||||||
protected final DevicePolicyManager mDPM;
|
protected final DevicePolicyManager mDPM;
|
||||||
protected final SecuritySettingsV2 mHost;
|
protected final SecuritySettings mHost;
|
||||||
protected final UserManager mUm;
|
protected final UserManager mUm;
|
||||||
protected final LockPatternUtils mLockPatternUtils;
|
protected final LockPatternUtils mLockPatternUtils;
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ public class ChangeScreenLockPreferenceController extends AbstractPreferenceCont
|
|||||||
|
|
||||||
protected RestrictedPreference mPreference;
|
protected RestrictedPreference mPreference;
|
||||||
|
|
||||||
public ChangeScreenLockPreferenceController(Context context, SecuritySettingsV2 host) {
|
public ChangeScreenLockPreferenceController(Context context, SecuritySettings host) {
|
||||||
super(context);
|
super(context);
|
||||||
mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
||||||
mDPM = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
|
mDPM = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||||
|
|||||||
@@ -16,11 +16,10 @@
|
|||||||
|
|
||||||
package com.android.settings.security;
|
package com.android.settings.security;
|
||||||
|
|
||||||
import static com.android.settings.security
|
import static com.android.settings.security.SecuritySettings.SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE;
|
||||||
.SecuritySettingsV2.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.SecuritySettingsV2.UNIFY_LOCK_CONFIRM_DEVICE_REQUEST;
|
import static com.android.settings.security.SecuritySettings.UNIFY_LOCK_CONFIRM_PROFILE_REQUEST;
|
||||||
import static com.android.settings.security.SecuritySettingsV2.UNIFY_LOCK_CONFIRM_PROFILE_REQUEST;
|
import static com.android.settings.security.SecuritySettings.UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST;
|
||||||
import static com.android.settings.security.SecuritySettingsV2.UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
@@ -53,7 +52,7 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr
|
|||||||
private final UserManager mUm;
|
private final UserManager mUm;
|
||||||
private final LockPatternUtils mLockPatternUtils;
|
private final LockPatternUtils mLockPatternUtils;
|
||||||
private final int mProfileChallengeUserId;
|
private final int mProfileChallengeUserId;
|
||||||
private final SecuritySettingsV2 mHost;
|
private final SecuritySettings mHost;
|
||||||
|
|
||||||
private RestrictedSwitchPreference mUnifyProfile;
|
private RestrictedSwitchPreference mUnifyProfile;
|
||||||
|
|
||||||
@@ -67,7 +66,7 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr
|
|||||||
mUnifyProfile = (RestrictedSwitchPreference) screen.findPreference(KEY_UNIFICATION);
|
mUnifyProfile = (RestrictedSwitchPreference) screen.findPreference(KEY_UNIFICATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LockUnificationPreferenceController(Context context, SecuritySettingsV2 host) {
|
public LockUnificationPreferenceController(Context context, SecuritySettings host) {
|
||||||
super(context);
|
super(context);
|
||||||
mHost = host;
|
mHost = host;
|
||||||
mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
||||||
@@ -212,7 +211,7 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr
|
|||||||
mCurrentProfilePassword);
|
mCurrentProfilePassword);
|
||||||
mHost.startFragment(mHost, ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
|
mHost.startFragment(mHost, ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
|
||||||
R.string.lock_settings_picker_title,
|
R.string.lock_settings_picker_title,
|
||||||
SecuritySettingsV2.SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
|
SecuritySettings.SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,26 +17,14 @@
|
|||||||
package com.android.settings.security;
|
package com.android.settings.security;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.support.v7.preference.PreferenceScreen;
|
|
||||||
import android.util.FeatureFlagUtils;
|
|
||||||
|
|
||||||
import com.android.internal.widget.LockPatternUtils;
|
import com.android.internal.widget.LockPatternUtils;
|
||||||
import com.android.settings.core.FeatureFlags;
|
|
||||||
import com.android.settings.security.trustagent.TrustAgentManager;
|
import com.android.settings.security.trustagent.TrustAgentManager;
|
||||||
import com.android.settingslib.drawer.DashboardCategory;
|
|
||||||
|
|
||||||
|
|
||||||
/** FeatureProvider for security. */
|
/** FeatureProvider for security. */
|
||||||
public interface SecurityFeatureProvider {
|
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}. */
|
/** Returns the {@link TrustAgentManager} bound to this {@link SecurityFeatureProvider}. */
|
||||||
TrustAgentManager getTrustAgentManager();
|
TrustAgentManager getTrustAgentManager();
|
||||||
|
|
||||||
|
|||||||
@@ -17,28 +17,9 @@
|
|||||||
package com.android.settings.security;
|
package com.android.settings.security;
|
||||||
|
|
||||||
import android.content.Context;
|
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.internal.widget.LockPatternUtils;
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settings.security.trustagent.TrustAgentManager;
|
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}. */
|
/** Implementation for {@code SecurityFeatureProvider}. */
|
||||||
public class SecurityFeatureProviderImpl implements SecurityFeatureProvider {
|
public class SecurityFeatureProviderImpl implements SecurityFeatureProvider {
|
||||||
@@ -46,150 +27,6 @@ public class SecurityFeatureProviderImpl implements SecurityFeatureProvider {
|
|||||||
private TrustAgentManager mTrustAgentManager;
|
private TrustAgentManager mTrustAgentManager;
|
||||||
private LockPatternUtils mLockPatternUtils;
|
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
|
@Override
|
||||||
public TrustAgentManager getTrustAgentManager() {
|
public TrustAgentManager getTrustAgentManager() {
|
||||||
if (mTrustAgentManager == null) {
|
if (mTrustAgentManager == null) {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -40,7 +40,7 @@ public class UnificationConfirmationDialog extends InstrumentedDialogFragment {
|
|||||||
return dialog;
|
return dialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void show(SecuritySettingsV2 host) {
|
public void show(SecuritySettings host) {
|
||||||
final FragmentManager manager = host.getChildFragmentManager();
|
final FragmentManager manager = host.getChildFragmentManager();
|
||||||
if (manager.findFragmentByTag(TAG_UNIFICATION_DIALOG) == null) {
|
if (manager.findFragmentByTag(TAG_UNIFICATION_DIALOG) == null) {
|
||||||
// Prevent opening multiple dialogs if tapped on button quickly
|
// Prevent opening multiple dialogs if tapped on button quickly
|
||||||
@@ -50,7 +50,7 @@ public class UnificationConfirmationDialog extends InstrumentedDialogFragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
final SecuritySettingsV2 parentFragment = ((SecuritySettingsV2) getParentFragment());
|
final SecuritySettings parentFragment = ((SecuritySettings) getParentFragment());
|
||||||
final boolean compliant = getArguments().getBoolean(EXTRA_COMPLIANT);
|
final boolean compliant = getArguments().getBoolean(EXTRA_COMPLIANT);
|
||||||
return new AlertDialog.Builder(getActivity())
|
return new AlertDialog.Builder(getActivity())
|
||||||
.setTitle(R.string.lock_settings_profile_unification_dialog_title)
|
.setTitle(R.string.lock_settings_profile_unification_dialog_title)
|
||||||
@@ -75,7 +75,7 @@ public class UnificationConfirmationDialog extends InstrumentedDialogFragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onDismiss(DialogInterface dialog) {
|
public void onDismiss(DialogInterface dialog) {
|
||||||
super.onDismiss(dialog);
|
super.onDismiss(dialog);
|
||||||
((SecuritySettingsV2) getParentFragment()).updateUnificationPreference();
|
((SecuritySettings) getParentFragment()).updateUnificationPreference();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package com.android.settings.security.trustagent;
|
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.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -35,7 +35,7 @@ import com.android.settings.core.PreferenceControllerMixin;
|
|||||||
import com.android.settings.overlay.FeatureFactory;
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
import com.android.settings.password.ChooseLockSettingsHelper;
|
import com.android.settings.password.ChooseLockSettingsHelper;
|
||||||
import com.android.settings.security.SecurityFeatureProvider;
|
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.RestrictedPreference;
|
||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
@@ -59,12 +59,12 @@ public class TrustAgentListPreferenceController extends AbstractPreferenceContro
|
|||||||
|
|
||||||
private final LockPatternUtils mLockPatternUtils;
|
private final LockPatternUtils mLockPatternUtils;
|
||||||
private final TrustAgentManager mTrustAgentManager;
|
private final TrustAgentManager mTrustAgentManager;
|
||||||
private final SecuritySettingsV2 mHost;
|
private final SecuritySettings mHost;
|
||||||
|
|
||||||
private Intent mTrustAgentClickIntent;
|
private Intent mTrustAgentClickIntent;
|
||||||
private PreferenceCategory mSecurityCategory;
|
private PreferenceCategory mSecurityCategory;
|
||||||
|
|
||||||
public TrustAgentListPreferenceController(Context context, SecuritySettingsV2 host,
|
public TrustAgentListPreferenceController(Context context, SecuritySettings host,
|
||||||
Lifecycle lifecycle) {
|
Lifecycle lifecycle) {
|
||||||
super(context);
|
super(context);
|
||||||
final SecurityFeatureProvider provider = FeatureFactory.getFactory(context)
|
final SecurityFeatureProvider provider = FeatureFactory.getFactory(context)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings;
|
package com.android.settings.shortcut;
|
||||||
|
|
||||||
import android.app.LauncherActivity;
|
import android.app.LauncherActivity;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
@@ -28,7 +28,9 @@ import android.content.pm.ShortcutManager;
|
|||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Bitmap.Config;
|
import android.graphics.Bitmap.Config;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.graphics.drawable.Icon;
|
import android.graphics.drawable.Icon;
|
||||||
|
import android.graphics.drawable.LayerDrawable;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.support.annotation.VisibleForTesting;
|
import android.support.annotation.VisibleForTesting;
|
||||||
@@ -40,6 +42,7 @@ import android.widget.ImageView;
|
|||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto;
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
|
import com.android.settings.R;
|
||||||
import com.android.settings.Settings.TetherSettingsActivity;
|
import com.android.settings.Settings.TetherSettingsActivity;
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
|
|
||||||
@@ -65,7 +68,8 @@ public class CreateShortcut extends LauncherActivity {
|
|||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Intent createResultIntent(Intent shortcutIntent, ResolveInfo resolveInfo,
|
@VisibleForTesting
|
||||||
|
Intent createResultIntent(Intent shortcutIntent, ResolveInfo resolveInfo,
|
||||||
CharSequence label) {
|
CharSequence label) {
|
||||||
shortcutIntent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
|
shortcutIntent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
|
||||||
ShortcutManager sm = getSystemService(ShortcutManager.class);
|
ShortcutManager sm = getSystemService(ShortcutManager.class);
|
||||||
@@ -94,8 +98,8 @@ public class CreateShortcut extends LauncherActivity {
|
|||||||
|
|
||||||
if (activityInfo.icon != 0) {
|
if (activityInfo.icon != 0) {
|
||||||
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, createIcon(activityInfo.icon,
|
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, createIcon(activityInfo.icon,
|
||||||
R.layout.shortcut_badge,
|
R.layout.shortcut_badge,
|
||||||
getResources().getDimensionPixelSize(R.dimen.shortcut_size)));
|
getResources().getDimensionPixelSize(R.dimen.shortcut_size)));
|
||||||
}
|
}
|
||||||
return intent;
|
return intent;
|
||||||
}
|
}
|
||||||
@@ -112,7 +116,11 @@ public class CreateShortcut extends LauncherActivity {
|
|||||||
private Bitmap createIcon(int resource, int layoutRes, int size) {
|
private Bitmap createIcon(int resource, int layoutRes, int size) {
|
||||||
Context context = new ContextThemeWrapper(this, android.R.style.Theme_Material);
|
Context context = new ContextThemeWrapper(this, android.R.style.Theme_Material);
|
||||||
View view = LayoutInflater.from(context).inflate(layoutRes, null);
|
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);
|
int spec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
|
||||||
view.measure(spec, spec);
|
view.measure(spec, spec);
|
||||||
@@ -161,7 +161,7 @@ public class SavedAccessPointsWifiSettings extends SettingsPreferenceFragment
|
|||||||
final int accessPointsSize = accessPoints.size();
|
final int accessPointsSize = accessPoints.size();
|
||||||
for (int i = 0; i < accessPointsSize; ++i) {
|
for (int i = 0; i < accessPointsSize; ++i) {
|
||||||
AccessPoint ap = accessPoints.get(i);
|
AccessPoint ap = accessPoints.get(i);
|
||||||
String key = AccessPointPreference.generatePreferenceKey(ap);
|
String key = ap.getKey();
|
||||||
LongPressAccessPointPreference preference =
|
LongPressAccessPointPreference preference =
|
||||||
(LongPressAccessPointPreference) getCachedPreference(key);
|
(LongPressAccessPointPreference) getCachedPreference(key);
|
||||||
if (preference == null) {
|
if (preference == null) {
|
||||||
|
|||||||
@@ -777,7 +777,7 @@ public class WifiSettings extends RestrictedSettingsFragment
|
|||||||
AccessPoint accessPoint = accessPoints.get(index);
|
AccessPoint accessPoint = accessPoints.get(index);
|
||||||
// Ignore access points that are out of range.
|
// Ignore access points that are out of range.
|
||||||
if (accessPoint.isReachable()) {
|
if (accessPoint.isReachable()) {
|
||||||
String key = AccessPointPreference.generatePreferenceKey(accessPoint);
|
String key = accessPoint.getKey();
|
||||||
hasAvailableAccessPoints = true;
|
hasAvailableAccessPoints = true;
|
||||||
LongPressAccessPointPreference pref =
|
LongPressAccessPointPreference pref =
|
||||||
(LongPressAccessPointPreference) getCachedPreference(key);
|
(LongPressAccessPointPreference) getCachedPreference(key);
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
com.android.settings.display.ScreenZoomPreferenceFragmentForSetupWizard
|
com.android.settings.display.ScreenZoomPreferenceFragmentForSetupWizard
|
||||||
com.android.settings.search.indexing.FakeSettingsFragment
|
com.android.settings.search.indexing.FakeSettingsFragment
|
||||||
com.android.settings.security.SecuritySettings
|
|
||||||
@@ -18,27 +18,18 @@ package com.android.settings.applications.appinfo;
|
|||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
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.doNothing;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.UserInfo;
|
import android.content.pm.UserInfo;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.UserHandle;
|
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.support.v7.preference.PreferenceScreen;
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
|
|
||||||
@@ -120,16 +111,14 @@ public class AppActionButtonPreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void displayPreference_shouldInitializeForceStopButton() {
|
public void displayPreference_shouldSetButton2Invisible() {
|
||||||
final PreferenceScreen screen = mock(PreferenceScreen.class);
|
final PreferenceScreen screen = mock(PreferenceScreen.class);
|
||||||
final ActionButtonPreference preference = spy(new ActionButtonPreference(mContext));
|
final ActionButtonPreference preference = spy(new ActionButtonPreference(mContext));
|
||||||
when(screen.findPreference(mController.getPreferenceKey())).thenReturn(preference);
|
when(screen.findPreference(mController.getPreferenceKey())).thenReturn(preference);
|
||||||
|
|
||||||
mController.displayPreference(screen);
|
mController.displayPreference(screen);
|
||||||
|
|
||||||
verify(preference).setButton2Positive(false);
|
verify(preference).setButton2Visible(false);
|
||||||
verify(preference).setButton2Text(R.string.force_stop);
|
|
||||||
verify(preference).setButton2Enabled(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -138,14 +127,12 @@ public class AppActionButtonPreferenceControllerTest {
|
|||||||
final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class);
|
final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class);
|
||||||
final ApplicationInfo info = new ApplicationInfo();
|
final ApplicationInfo info = new ApplicationInfo();
|
||||||
appEntry.info = info;
|
appEntry.info = info;
|
||||||
doNothing().when(mController).checkForceStop(appEntry, packageInfo);
|
|
||||||
doNothing().when(mController).initUninstallButtons(appEntry, packageInfo);
|
doNothing().when(mController).initUninstallButtons(appEntry, packageInfo);
|
||||||
when(mFragment.getAppEntry()).thenReturn(appEntry);
|
when(mFragment.getAppEntry()).thenReturn(appEntry);
|
||||||
when(mFragment.getPackageInfo()).thenReturn(packageInfo);
|
when(mFragment.getPackageInfo()).thenReturn(packageInfo);
|
||||||
|
|
||||||
mController.refreshUi();
|
mController.refreshUi();
|
||||||
|
|
||||||
verify(mController).checkForceStop(appEntry, packageInfo);
|
|
||||||
verify(mController).initUninstallButtons(appEntry, packageInfo);
|
verify(mController).initUninstallButtons(appEntry, packageInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,71 +185,6 @@ public class AppActionButtonPreferenceControllerTest {
|
|||||||
assertThat(mController.initUninstallButtonForUserApp()).isFalse();
|
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
|
@Test
|
||||||
public void handleDisableable_appIsHomeApp_buttonShouldNotWork() {
|
public void handleDisableable_appIsHomeApp_buttonShouldNotWork() {
|
||||||
final ApplicationInfo info = new ApplicationInfo();
|
final ApplicationInfo info = new ApplicationInfo();
|
||||||
|
|||||||
@@ -42,7 +42,9 @@ import com.android.settings.R;
|
|||||||
import com.android.settings.TestConfig;
|
import com.android.settings.TestConfig;
|
||||||
import com.android.settings.applications.LayoutPreference;
|
import com.android.settings.applications.LayoutPreference;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
import com.android.settingslib.applications.AppUtils;
|
||||||
import com.android.settingslib.applications.ApplicationsState;
|
import com.android.settingslib.applications.ApplicationsState;
|
||||||
|
import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -53,6 +55,7 @@ import org.mockito.MockitoAnnotations;
|
|||||||
import org.robolectric.Robolectric;
|
import org.robolectric.Robolectric;
|
||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
|
import org.robolectric.util.ReflectionHelpers;
|
||||||
|
|
||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||||
@@ -103,7 +106,8 @@ public class AppHeaderViewPreferenceControllerTest {
|
|||||||
appEntry.info = info;
|
appEntry.info = info;
|
||||||
when(mFragment.getAppEntry()).thenReturn(appEntry);
|
when(mFragment.getAppEntry()).thenReturn(appEntry);
|
||||||
when(mFragment.getPackageInfo()).thenReturn(packageInfo);
|
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 title = mHeader.findViewById(R.id.entity_header_title);
|
||||||
final TextView summary = mHeader.findViewById(R.id.entity_header_summary);
|
final TextView summary = mHeader.findViewById(R.id.entity_header_summary);
|
||||||
|
|||||||
@@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -19,7 +19,6 @@ import com.android.settings.search.SearchFeatureProvider;
|
|||||||
import com.android.settings.search.SearchFeatureProviderImpl;
|
import com.android.settings.search.SearchFeatureProviderImpl;
|
||||||
import com.android.settings.search.XmlParserUtils;
|
import com.android.settings.search.XmlParserUtils;
|
||||||
import com.android.settings.security.SecuritySettings;
|
import com.android.settings.security.SecuritySettings;
|
||||||
import com.android.settings.security.SecuritySettingsV2;
|
|
||||||
import com.android.settings.testutils.FakeFeatureFactory;
|
import com.android.settings.testutils.FakeFeatureFactory;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
@@ -32,7 +31,6 @@ import org.robolectric.annotation.Config;
|
|||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -47,25 +45,13 @@ public class XmlControllerAttributeTest {
|
|||||||
// List of classes that are too hard to mock in order to retrieve xml information.
|
// List of classes that are too hard to mock in order to retrieve xml information.
|
||||||
private final List<Class> illegalClasses = new ArrayList<>(
|
private final List<Class> illegalClasses = new ArrayList<>(
|
||||||
Arrays.asList(
|
Arrays.asList(
|
||||||
SecuritySettings.class,
|
SecuritySettings.class
|
||||||
SecuritySettingsV2.class
|
|
||||||
));
|
));
|
||||||
|
|
||||||
// List of XML that could be retrieved from the illegalClasses list.
|
// List of XML that could be retrieved from the illegalClasses list.
|
||||||
private final List<Integer> whitelistXml = new ArrayList<>(
|
private final List<Integer> whitelistXml = new ArrayList<>(
|
||||||
Arrays.asList(
|
Arrays.asList(
|
||||||
R.xml.security_settings_misc,
|
R.xml.security_dashboard_settings
|
||||||
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
|
|
||||||
));
|
));
|
||||||
|
|
||||||
private static final String NO_VALID_CONSTRUCTOR_ERROR =
|
private static final String NO_VALID_CONSTRUCTOR_ERROR =
|
||||||
|
|||||||
@@ -17,12 +17,19 @@ package com.android.settings.dashboard.suggestions;
|
|||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
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.mock;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.Context;
|
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.service.settings.suggestions.Suggestion;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -46,6 +53,7 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
|
import org.robolectric.util.ReflectionHelpers;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -200,7 +208,71 @@ public class SuggestionAdapterV2Test {
|
|||||||
mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
|
mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
|
||||||
mSuggestionHolder.itemView.findViewById(R.id.close_button).performClick();
|
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) {
|
private void setupSuggestions(Context context, List<Suggestion> suggestions) {
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ import static org.mockito.Mockito.verify;
|
|||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.net.NetworkPolicyManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v14.preference.SwitchPreference;
|
|
||||||
import android.support.v7.preference.PreferenceManager;
|
import android.support.v7.preference.PreferenceManager;
|
||||||
import android.support.v7.preference.PreferenceScreen;
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
@@ -40,8 +40,11 @@ import com.android.settings.TestConfig;
|
|||||||
import com.android.settings.testutils.FakeFeatureFactory;
|
import com.android.settings.testutils.FakeFeatureFactory;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
|
import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
|
||||||
|
import com.android.settings.testutils.shadow.ShadowRestrictedLockUtils;
|
||||||
import com.android.settings.widget.EntityHeaderController;
|
import com.android.settings.widget.EntityHeaderController;
|
||||||
import com.android.settingslib.AppItem;
|
import com.android.settingslib.AppItem;
|
||||||
|
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||||
|
import com.android.settingslib.RestrictedSwitchPreference;
|
||||||
import com.android.settingslib.wrapper.PackageManagerWrapper;
|
import com.android.settingslib.wrapper.PackageManagerWrapper;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
@@ -57,7 +60,10 @@ import org.robolectric.util.ReflectionHelpers;
|
|||||||
|
|
||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
|
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
|
||||||
shadows = ShadowEntityHeaderController.class)
|
shadows = {
|
||||||
|
ShadowEntityHeaderController.class,
|
||||||
|
ShadowRestrictedLockUtils.class
|
||||||
|
})
|
||||||
public class AppDataUsageTest {
|
public class AppDataUsageTest {
|
||||||
|
|
||||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||||
@@ -134,7 +140,7 @@ public class AppDataUsageTest {
|
|||||||
public void changePreference_backgroundData_shouldUpdateUI() {
|
public void changePreference_backgroundData_shouldUpdateUI() {
|
||||||
mFragment = spy(new AppDataUsage());
|
mFragment = spy(new AppDataUsage());
|
||||||
final AppItem appItem = new AppItem(123456789);
|
final AppItem appItem = new AppItem(123456789);
|
||||||
final SwitchPreference pref = mock(SwitchPreference.class);
|
final RestrictedSwitchPreference pref = mock(RestrictedSwitchPreference.class);
|
||||||
final DataSaverBackend dataSaverBackend = mock(DataSaverBackend.class);
|
final DataSaverBackend dataSaverBackend = mock(DataSaverBackend.class);
|
||||||
ReflectionHelpers.setField(mFragment, "mAppItem", appItem);
|
ReflectionHelpers.setField(mFragment, "mAppItem", appItem);
|
||||||
ReflectionHelpers.setField(mFragment, "mRestrictBackground", pref);
|
ReflectionHelpers.setField(mFragment, "mRestrictBackground", pref);
|
||||||
@@ -146,4 +152,31 @@ public class AppDataUsageTest {
|
|||||||
|
|
||||||
verify(mFragment).updatePrefs();
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,41 +16,68 @@
|
|||||||
package com.android.settings.datausage;
|
package com.android.settings.datausage;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
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.ArgumentMatchers.nullable;
|
||||||
import static org.mockito.Matchers.eq;
|
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 static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.os.Process;
|
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.internal.logging.nano.MetricsProto;
|
||||||
|
import com.android.settings.R;
|
||||||
import com.android.settings.TestConfig;
|
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.FakeFeatureFactory;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
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.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
|
import org.robolectric.util.ReflectionHelpers;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
@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 {
|
public class UnrestrictedDataAccessTest {
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private ApplicationsState.AppEntry mAppEntry;
|
private AppEntry mAppEntry;
|
||||||
private UnrestrictedDataAccess mFragment;
|
private UnrestrictedDataAccess mFragment;
|
||||||
private FakeFeatureFactory mFeatureFactory;
|
private FakeFeatureFactory mFeatureFactory;
|
||||||
|
@Mock
|
||||||
|
private PreferenceScreen mPreferenceScreen;
|
||||||
|
@Mock
|
||||||
|
private PreferenceManager mPreferenceManager;
|
||||||
|
@Mock
|
||||||
|
private DataSaverBackend mDataSaverBackend;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mFeatureFactory = FakeFeatureFactory.setupForTest();
|
mFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||||
mFragment = new UnrestrictedDataAccess();
|
mFragment = spy(new UnrestrictedDataAccess());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -80,4 +107,66 @@ public class UnrestrictedDataAccessTest {
|
|||||||
eq(MetricsProto.MetricsEvent.APP_SPECIAL_PERMISSION_UNL_DATA_DENY), eq("app"));
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ public class LockUnificationPreferenceControllerTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private PreferenceScreen mScreen;
|
private PreferenceScreen mScreen;
|
||||||
@Mock
|
@Mock
|
||||||
private SecuritySettingsV2 mHost;
|
private SecuritySettings mHost;
|
||||||
|
|
||||||
private FakeFeatureFactory mFeatureFactory;
|
private FakeFeatureFactory mFeatureFactory;
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
|
|||||||
@@ -16,192 +16,51 @@
|
|||||||
|
|
||||||
package com.android.settings.security;
|
package com.android.settings.security;
|
||||||
|
|
||||||
import static org.mockito.Matchers.any;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
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 android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.PackageManager;
|
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.TestConfig;
|
||||||
|
import com.android.settings.security.trustagent.TrustAgentManager;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
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.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
import org.robolectric.shadows.ShadowLooper;
|
|
||||||
|
|
||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||||
public class SecurityFeatureProviderImplTest {
|
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;
|
private Context mContext;
|
||||||
@Mock
|
|
||||||
private PackageManager mPackageManager;
|
|
||||||
@Mock
|
|
||||||
private Resources mResources;
|
|
||||||
|
|
||||||
private SecurityFeatureProviderImpl mImpl;
|
private SecurityFeatureProviderImpl mImpl;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws PackageManager.NameNotFoundException {
|
public void setUp() throws PackageManager.NameNotFoundException {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mContext = spy(RuntimeEnvironment.application);
|
mContext = RuntimeEnvironment.application;
|
||||||
mImpl = new SecurityFeatureProviderImpl();
|
mImpl = new SecurityFeatureProviderImpl();
|
||||||
when(mContext.getPackageManager()).thenReturn(mPackageManager);
|
|
||||||
when(mPackageManager.getResourcesForApplication(anyString())).thenReturn(mResources);
|
|
||||||
when(mResources.getDrawable(anyInt(), any())).thenReturn(mMockDrawable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void updateTilesData_shouldNotProcessEmptyScreenOrTiles() {
|
public void getTrustAgentManager_shouldReturnCache() {
|
||||||
mImpl.updatePreferencesToRunOnWorkerThread(mContext, null, null);
|
final TrustAgentManager m1 = mImpl.getTrustAgentManager();
|
||||||
ShadowLooper.runUiThreadTasks();
|
final TrustAgentManager m2 = mImpl.getTrustAgentManager();
|
||||||
mImpl.updatePreferencesToRunOnWorkerThread(
|
|
||||||
mContext, new PreferenceScreen(mContext, null), null);
|
assertThat(m1).isSameAs(m2);
|
||||||
ShadowLooper.runUiThreadTasks();
|
|
||||||
verifyNoMoreInteractions(mPackageManager);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void updateTilesData_shouldNotProcessNonMatchingPreference() {
|
public void getLockPatternUtils_shouldReturnCache() {
|
||||||
DashboardCategory dashboardCategory = new DashboardCategory();
|
final LockPatternUtils l1 = mImpl.getLockPatternUtils(mContext);
|
||||||
dashboardCategory.addTile(new Tile());
|
final LockPatternUtils l2 = mImpl.getLockPatternUtils(mContext);
|
||||||
mImpl.updatePreferencesToRunOnWorkerThread(
|
|
||||||
mContext, getPreferenceScreen(), dashboardCategory);
|
assertThat(l1).isSameAs(l2);
|
||||||
ShadowLooper.runUiThreadTasks();
|
|
||||||
verifyNoMoreInteractions(mPackageManager);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,34 +16,18 @@
|
|||||||
|
|
||||||
package com.android.settings.security;
|
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.verify;
|
||||||
|
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.UserHandle;
|
import android.content.pm.PackageManager;
|
||||||
import android.os.UserManager;
|
import android.hardware.fingerprint.FingerprintManager;
|
||||||
import android.os.UserManager.EnforcingUser;
|
|
||||||
import android.support.v7.preference.Preference;
|
|
||||||
import android.support.v7.preference.PreferenceScreen;
|
|
||||||
|
|
||||||
import com.android.internal.widget.LockPatternUtils;
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.TestConfig;
|
import com.android.settings.TestConfig;
|
||||||
import com.android.settings.dashboard.SummaryLoader;
|
import com.android.settings.dashboard.SummaryLoader;
|
||||||
import com.android.settings.testutils.FakeFeatureFactory;
|
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
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.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -51,123 +35,65 @@ import org.junit.runner.RunWith;
|
|||||||
import org.mockito.Answers;
|
import org.mockito.Answers;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.robolectric.RuntimeEnvironment;
|
|
||||||
import org.robolectric.annotation.Config;
|
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)
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
|
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||||
shadows = {
|
|
||||||
ShadowLockPatternUtils.class,
|
|
||||||
ShadowUserManager.class,
|
|
||||||
})
|
|
||||||
public class SecuritySettingsTest {
|
public class SecuritySettingsTest {
|
||||||
|
|
||||||
|
|
||||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
@Mock
|
@Mock
|
||||||
private SummaryLoader mSummaryLoader;
|
private SummaryLoader mSummaryLoader;
|
||||||
|
@Mock
|
||||||
|
private FingerprintManager mFingerprintManager;
|
||||||
private SecuritySettings.SummaryProvider mSummaryProvider;
|
private SecuritySettings.SummaryProvider mSummaryProvider;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
FakeFeatureFactory.setupForTest();
|
when(mContext.getSystemService(Context.FINGERPRINT_SERVICE))
|
||||||
|
.thenReturn(mFingerprintManager);
|
||||||
|
|
||||||
mSummaryProvider = new SecuritySettings.SummaryProvider(mContext, mSummaryLoader);
|
mSummaryProvider = new SecuritySettings.SummaryProvider(mContext, mSummaryLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInitTrustAgentPreference_secure_shouldSetSummaryToNumberOfTrustAgent() {
|
public void testSummaryProvider_notListening() {
|
||||||
final Preference preference = mock(Preference.class);
|
mSummaryProvider.setListening(false);
|
||||||
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);
|
|
||||||
|
|
||||||
ReflectionHelpers.setField(securitySettings, "mLockPatternUtils", utils);
|
verifyNoMoreInteractions(mSummaryLoader);
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNonIndexableKeys_existInXmlLayout() {
|
public void testSummaryProvider_hasFingerPrint_hasStaticSummary() {
|
||||||
final Context context = spy(RuntimeEnvironment.application);
|
when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
|
||||||
UserManager manager = mock(UserManager.class);
|
.thenReturn(true);
|
||||||
when(manager.isAdminUser()).thenReturn(false);
|
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
|
||||||
doReturn(manager).when(context).getSystemService(Context.USER_SERVICE);
|
|
||||||
final List<String> niks = SecuritySettings.SEARCH_INDEX_DATA_PROVIDER
|
|
||||||
.getNonIndexableKeys(context);
|
|
||||||
|
|
||||||
final List<String> keys = XmlTestUtils.getKeysFromPreferenceXml(context,
|
mSummaryProvider.setListening(true);
|
||||||
R.xml.security_settings_misc);
|
|
||||||
keys.addAll(XmlTestUtils.getKeysFromPreferenceXml(context,
|
|
||||||
R.xml.location_settings));
|
|
||||||
keys.addAll(XmlTestUtils.getKeysFromPreferenceXml(context,
|
|
||||||
R.xml.encryption_and_credential));
|
|
||||||
|
|
||||||
assertThat(keys).containsAllIn(niks);
|
verify(mContext).getString(R.string.security_dashboard_summary);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUnifyLockRestriction() {
|
public void testSummaryProvider_noFpFeature_shouldSetSummaryWithNoFingerprint() {
|
||||||
// Set up instance under test.
|
when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
|
||||||
final Context context = spy(RuntimeEnvironment.application);
|
.thenReturn(false);
|
||||||
final SecuritySettings securitySettings = spy(new SecuritySettings());
|
|
||||||
when(securitySettings.getContext()).thenReturn(context);
|
|
||||||
|
|
||||||
final int userId = 123;
|
mSummaryProvider.setListening(true);
|
||||||
ReflectionHelpers.setField(securitySettings, "mProfileChallengeUserId", userId);
|
|
||||||
|
|
||||||
final LockPatternUtils utils = mock(LockPatternUtils.class);
|
verify(mContext).getString(R.string.security_dashboard_summary_no_fingerprint);
|
||||||
when(utils.isSeparateProfileChallengeEnabled(userId)).thenReturn(true);
|
}
|
||||||
ReflectionHelpers.setField(securitySettings, "mLockPatternUtils", utils);
|
|
||||||
|
|
||||||
final RestrictedSwitchPreference unifyProfile = mock(RestrictedSwitchPreference.class);
|
@Test
|
||||||
ReflectionHelpers.setField(securitySettings, "mUnifyProfile", unifyProfile);
|
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.
|
mSummaryProvider.setListening(true);
|
||||||
ShadowUserManager.getShadow().setUserRestrictionSources(
|
|
||||||
UserManager.DISALLOW_UNIFIED_PASSWORD,
|
|
||||||
UserHandle.of(userId),
|
|
||||||
Collections.emptyList());
|
|
||||||
|
|
||||||
securitySettings.updateUnificationPreference();
|
verify(mContext).getString(R.string.security_dashboard_summary_no_fingerprint);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -40,7 +40,7 @@ import android.support.v7.preference.PreferenceScreen;
|
|||||||
import com.android.internal.widget.LockPatternUtils;
|
import com.android.internal.widget.LockPatternUtils;
|
||||||
import com.android.settings.TestConfig;
|
import com.android.settings.TestConfig;
|
||||||
import com.android.settings.core.PreferenceControllerMixin;
|
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.FakeFeatureFactory;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
@@ -69,7 +69,7 @@ public class TrustAgentListPreferenceControllerTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private PreferenceCategory mCategory;
|
private PreferenceCategory mCategory;
|
||||||
@Mock
|
@Mock
|
||||||
private SecuritySettingsV2 mFragment;
|
private SecuritySettings mFragment;
|
||||||
|
|
||||||
private Lifecycle mLifecycle;
|
private Lifecycle mLifecycle;
|
||||||
private LifecycleOwner mLifecycleOwner;
|
private LifecycleOwner mLifecycleOwner;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,16 +19,22 @@ LOCAL_PACKAGE_NAME := SettingsUITests
|
|||||||
LOCAL_COMPATIBILITY_SUITE := device-tests
|
LOCAL_COMPATIBILITY_SUITE := device-tests
|
||||||
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
||||||
LOCAL_MODULE_TAGS := tests
|
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 := \
|
LOCAL_STATIC_JAVA_LIBRARIES := \
|
||||||
|
android-support-test \
|
||||||
app-helpers-core \
|
app-helpers-core \
|
||||||
launcher-helper-lib \
|
launcher-helper-lib \
|
||||||
settings-helper \
|
|
||||||
timeresult-helper-lib \
|
|
||||||
ub-uiautomator \
|
|
||||||
sysui-helper \
|
|
||||||
metrics-helper-lib \
|
metrics-helper-lib \
|
||||||
platform-test-annotations \
|
platform-test-annotations \
|
||||||
|
settings-helper \
|
||||||
|
sysui-helper \
|
||||||
|
timeresult-helper-lib \
|
||||||
|
truth-prebuilt \
|
||||||
|
ub-uiautomator \
|
||||||
|
|
||||||
#LOCAL_SDK_VERSION := current
|
#LOCAL_SDK_VERSION := current
|
||||||
|
|
||||||
|
|||||||
@@ -16,57 +16,55 @@
|
|||||||
|
|
||||||
package com.android.settings.ui;
|
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.content.Intent;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.provider.Settings;
|
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.By;
|
||||||
import android.support.test.uiautomator.Direction;
|
import android.support.test.uiautomator.Direction;
|
||||||
import android.support.test.uiautomator.UiDevice;
|
import android.support.test.uiautomator.UiDevice;
|
||||||
import android.support.test.uiautomator.UiObject2;
|
import android.support.test.uiautomator.UiObject2;
|
||||||
import android.support.test.uiautomator.Until;
|
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.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.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
/** Verifies basic functionality of the About Phone screen */
|
/** Verifies basic functionality of the About Phone screen */
|
||||||
public class AboutPhoneSettingsTests extends InstrumentationTestCase {
|
@RunWith(AndroidJUnit4.class)
|
||||||
private static final boolean LOCAL_LOGV = false;
|
@SmallTest
|
||||||
private static final String TAG = "AboutPhoneSettingsTest";
|
public class AboutPhoneSettingsTests {
|
||||||
private static final int TIMEOUT = 2000;
|
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
|
// TODO: retrieve using name/ids from com.android.settings package
|
||||||
private static final String[] sResourceTexts = {
|
private static final String[] sResourceTexts = {
|
||||||
"Status",
|
"Phone number",
|
||||||
"Legal information",
|
"SIM status",
|
||||||
"Regulatory labels",
|
"Model & hardware",
|
||||||
"Model",
|
"MEID",
|
||||||
"Android version",
|
"Android version"
|
||||||
"Android security patch level",
|
|
||||||
"Baseband version",
|
|
||||||
"Kernel version",
|
|
||||||
"Build number"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final String[] sClickableResourceTexts = {
|
private UiDevice mDevice;
|
||||||
"Status", "Legal information", "Regulatory labels",
|
private Instrumentation mInstrumentation;
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
if (LOCAL_LOGV) {
|
mInstrumentation = InstrumentationRegistry.getInstrumentation();
|
||||||
Log.d(TAG, "-------");
|
mDevice = UiDevice.getInstance(mInstrumentation);
|
||||||
}
|
|
||||||
super.setUp();
|
|
||||||
mDevice = UiDevice.getInstance(getInstrumentation());
|
|
||||||
try {
|
try {
|
||||||
mDevice.setOrientationNatural();
|
mDevice.setOrientationNatural();
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@@ -82,84 +80,40 @@ public class AboutPhoneSettingsTests extends InstrumentationTestCase {
|
|||||||
UiObject2 view =
|
UiObject2 view =
|
||||||
mDevice.wait(
|
mDevice.wait(
|
||||||
Until.findObject(By.res(SETTINGS_PACKAGE + ":id/main_content")), TIMEOUT);
|
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);
|
view.scroll(Direction.UP, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@After
|
||||||
protected void tearDown() throws Exception {
|
public void tearDown() throws Exception {
|
||||||
// Adding an extra pressBack so we exit About Phone Settings
|
// Adding an extra pressBack so we exit About Phone Settings
|
||||||
// and finish the test cleanly
|
// and finish the test cleanly
|
||||||
mDevice.pressBack();
|
mDevice.pressBack();
|
||||||
mDevice.pressHome(); // finish settings activity
|
mDevice.pressHome(); // finish settings activity
|
||||||
mDevice.waitForIdle(TIMEOUT * 2); // give UI time to finish animating
|
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 {
|
private void launchAboutPhoneSettings(String aboutSetting) throws Exception {
|
||||||
Intent aboutIntent = new Intent(aboutSetting);
|
Intent aboutIntent = new Intent(aboutSetting);
|
||||||
aboutIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
aboutIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
getInstrumentation().getContext().startActivity(aboutIntent);
|
InstrumentationRegistry.getTargetContext().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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes items found in the view and optionally takes some action.
|
* 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(
|
private void removeItemsAndTakeAction(UiDevice device, ArrayList<String> itemsLeftToFind)
|
||||||
UiDevice device, ArrayList<String> itemsLeftToFind, UIObject2Callback action) throws Exception {
|
throws Exception {
|
||||||
for (Iterator<String> iterator = itemsLeftToFind.iterator(); iterator.hasNext(); ) {
|
for (Iterator<String> iterator = itemsLeftToFind.iterator(); iterator.hasNext(); ) {
|
||||||
String itemText = iterator.next();
|
String itemText = iterator.next();
|
||||||
UiObject2 item = device.wait(Until.findObject(By.text(itemText)), TIMEOUT);
|
UiObject2 item = device.wait(Until.findObject(By.text(itemText)), TIMEOUT);
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
if (LOCAL_LOGV) {
|
|
||||||
Log.d(TAG, itemText + " is present");
|
|
||||||
}
|
|
||||||
iterator.remove();
|
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 @@ public class AboutPhoneSettingsTests extends InstrumentationTestCase {
|
|||||||
*
|
*
|
||||||
* <p>Will scroll down the screen until it has found all elements or reached the bottom.
|
* <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.
|
* 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 {
|
throws Exception {
|
||||||
|
|
||||||
ArrayList<String> itemsLeftToFind = new ArrayList<String>(Arrays.asList(itemsToFind));
|
ArrayList<String> itemsLeftToFind = new ArrayList<>(Arrays.asList(itemsToFind));
|
||||||
assertFalse(
|
assertWithMessage("There must be at least one item to search for on the screen!")
|
||||||
"There must be at least one item to search for on the screen!",
|
.that(itemsLeftToFind)
|
||||||
itemsLeftToFind.isEmpty());
|
.isNotEmpty();
|
||||||
|
|
||||||
if (LOCAL_LOGV) {
|
|
||||||
Log.d(TAG, "items: " + TextUtils.join(", ", itemsLeftToFind));
|
|
||||||
}
|
|
||||||
boolean canScrollDown = true;
|
boolean canScrollDown = true;
|
||||||
while (canScrollDown && !itemsLeftToFind.isEmpty()) {
|
while (canScrollDown && !itemsLeftToFind.isEmpty()) {
|
||||||
removeItemsAndTakeAction(device, itemsLeftToFind, action);
|
removeItemsAndTakeAction(device, itemsLeftToFind);
|
||||||
|
|
||||||
// when we've finished searching the current view, scroll down
|
// when we've finished searching the current view, scroll down
|
||||||
UiObject2 view =
|
UiObject2 view =
|
||||||
@@ -201,24 +148,11 @@ public class AboutPhoneSettingsTests extends InstrumentationTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// check the last items once we have reached the bottom of the view
|
// check the last items once we have reached the bottom of the view
|
||||||
removeItemsAndTakeAction(device, itemsLeftToFind, action);
|
removeItemsAndTakeAction(device, itemsLeftToFind);
|
||||||
|
|
||||||
assertTrue(
|
assertWithMessage("The following items were not found on the screen: "
|
||||||
"The following items were not found on the screen: "
|
+ TextUtils.join(", ", itemsLeftToFind))
|
||||||
+ TextUtils.join(", ", itemsLeftToFind),
|
.that(itemsLeftToFind)
|
||||||
itemsLeftToFind.isEmpty());
|
.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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,9 @@
|
|||||||
|
|
||||||
package com.android.settings.ui;
|
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.os.RemoteException;
|
||||||
import android.platform.test.annotations.Presubmit;
|
import android.platform.test.annotations.Presubmit;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
@@ -36,9 +39,6 @@ import org.junit.Before;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
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
|
@MediumTest
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
public class HomepageDisplayTests {
|
public class HomepageDisplayTests {
|
||||||
@@ -52,19 +52,17 @@ public class HomepageDisplayTests {
|
|||||||
"Sound",
|
"Sound",
|
||||||
"Storage",
|
"Storage",
|
||||||
"Security & location",
|
"Security & location",
|
||||||
"Users & accounts",
|
"Accounts",
|
||||||
"Accessibility",
|
"Accessibility",
|
||||||
"System",
|
"System",
|
||||||
"Support & tips"
|
"Support & tips"
|
||||||
};
|
};
|
||||||
|
|
||||||
private UiDevice mDevice;
|
private UiDevice mDevice;
|
||||||
private SettingsHelper mSettingsHelper;
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
|
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
|
||||||
mSettingsHelper = new SettingsHelper();
|
|
||||||
try {
|
try {
|
||||||
mDevice.setOrientationNatural();
|
mDevice.setOrientationNatural();
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ public class SecuritySettingsLaunchTest {
|
|||||||
public void launchSecuritySettings() throws Exception {
|
public void launchSecuritySettings() throws Exception {
|
||||||
// Launch Settings
|
// Launch Settings
|
||||||
SettingsHelper.launchSettingsPage(
|
SettingsHelper.launchSettingsPage(
|
||||||
InstrumentationRegistry.getContext(), Settings.ACTION_SECURITY_SETTINGS);
|
InstrumentationRegistry.getTargetContext(), Settings.ACTION_SECURITY_SETTINGS);
|
||||||
mHelper.scrollVert(false);
|
mHelper.scrollVert(false);
|
||||||
for (String category : CATEGORIES) {
|
for (String category : CATEGORIES) {
|
||||||
SettingsTestUtils.assertTitleMatch(mDevice, category);
|
SettingsTestUtils.assertTitleMatch(mDevice, category);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,762 +16,109 @@
|
|||||||
|
|
||||||
package com.android.settings.ui;
|
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.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.platform.test.annotations.Presubmit;
|
import android.platform.test.annotations.Presubmit;
|
||||||
import android.provider.Settings;
|
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.CommandsHelper;
|
||||||
import android.system.helpers.SettingsHelper;
|
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.MediumTest;
|
||||||
import android.test.suitebuilder.annotation.Suppress;
|
|
||||||
import android.util.Log;
|
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
|
// These back button presses are performed in tearDown() to exit Wifi
|
||||||
// Settings sub-menus that a test might finish in. This number should be
|
// 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.
|
// 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 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 int SLEEP_TIME = 500;
|
||||||
private static final String AIRPLANE_MODE_BROADCAST =
|
private static final String AIRPLANE_MODE_BROADCAST =
|
||||||
"am broadcast -a android.intent.action.AIRPLANE_MODE";
|
"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 UiDevice mDevice;
|
||||||
private CommandsHelper mCommandsHelper;
|
private CommandsHelper mCommandsHelper;
|
||||||
|
|
||||||
@Override
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
super.setUp();
|
|
||||||
mDevice = UiDevice.getInstance(getInstrumentation());
|
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
|
||||||
try {
|
try {
|
||||||
mDevice.setOrientationNatural();
|
mDevice.setOrientationNatural();
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
throw new RuntimeException("failed to freeze device orientation", e);
|
throw new RuntimeException("failed to freeze device orientation", e);
|
||||||
}
|
}
|
||||||
// Ensure airplane mode is OFF so that wifi can be enabled using WiFiManager.
|
// 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");
|
Settings.Global.AIRPLANE_MODE_ON, "0");
|
||||||
|
|
||||||
Log.d(TAG, "sending airplane mode broadcast to device");
|
Log.d(TAG, "sending airplane mode broadcast to device");
|
||||||
mCommandsHelper = CommandsHelper.getInstance();
|
mCommandsHelper = CommandsHelper.getInstance(InstrumentationRegistry.getInstrumentation());
|
||||||
mCommandsHelper.executeShellCommand(AIRPLANE_MODE_BROADCAST);
|
mCommandsHelper.executeShellCommand(AIRPLANE_MODE_BROADCAST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@After
|
||||||
protected void tearDown() throws Exception {
|
public void tearDown() {
|
||||||
// Exit all settings sub-menus.
|
// Exit all settings sub-menus.
|
||||||
for (int i = 0; i < NUM_BACK_BUTTON_PRESSES; ++i) {
|
for (int i = 0; i < NUM_BACK_BUTTON_PRESSES; ++i) {
|
||||||
mDevice.pressBack();
|
mDevice.pressBack();
|
||||||
}
|
}
|
||||||
mDevice.pressHome();
|
mDevice.pressHome();
|
||||||
super.tearDown();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Presubmit
|
@Presubmit
|
||||||
@MediumTest
|
@Test
|
||||||
public void testWiFiEnabled() throws Exception {
|
public void testWiFiEnabled() throws Exception {
|
||||||
verifyWiFiOnOrOff(true);
|
verifyWiFiOnOrOff(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Presubmit
|
@Presubmit
|
||||||
@MediumTest
|
@Test
|
||||||
public void testWiFiDisabled() throws Exception {
|
public void testWiFiDisabled() throws Exception {
|
||||||
verifyWiFiOnOrOff(false);
|
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 {
|
private void verifyWiFiOnOrOff(boolean verifyOn) throws Exception {
|
||||||
String switchText = "On";
|
loadWiFiSettingsPage(!verifyOn);
|
||||||
if (verifyOn) {
|
mDevice.wait(Until.findObject(By.res(SETTINGS_PACKAGE, "switch_widget")), TIMEOUT)
|
||||||
switchText = "Off";
|
.click();
|
||||||
}
|
Thread.sleep(SLEEP_TIME);
|
||||||
loadWiFiSettingsPage(!verifyOn);
|
final String wifiValue = Settings.Global.getString(
|
||||||
mDevice.wait(Until
|
InstrumentationRegistry.getTargetContext().getContentResolver(),
|
||||||
.findObject(By.res(SETTINGS_PACKAGE, "switch_bar").text(switchText)), TIMEOUT)
|
Settings.Global.WIFI_ON);
|
||||||
.click();
|
if (verifyOn) {
|
||||||
Thread.sleep(SLEEP_TIME);
|
// 1 is Enabled, 2 is Enabled while airplane mode is ON.
|
||||||
String wifiValue =
|
assertThat(wifiValue).isAnyOf("1", "2");
|
||||||
Settings.Global.getString(getInstrumentation().getContext().getContentResolver(),
|
} else {
|
||||||
Settings.Global.WIFI_ON);
|
assertThat(wifiValue).isEqualTo("0");
|
||||||
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 {
|
private void loadWiFiSettingsPage(boolean wifiEnabled) throws Exception {
|
||||||
WifiManager wifiManager = (WifiManager)getInstrumentation().getContext()
|
WifiManager wifiManager = (WifiManager) InstrumentationRegistry.getTargetContext()
|
||||||
.getSystemService(Context.WIFI_SERVICE);
|
.getSystemService(Context.WIFI_SERVICE);
|
||||||
wifiManager.setWifiEnabled(wifiEnabled);
|
wifiManager.setWifiEnabled(wifiEnabled);
|
||||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
|
SettingsHelper.launchSettingsPage(InstrumentationRegistry.getTargetContext(),
|
||||||
Settings.ACTION_WIFI_SETTINGS);
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,12 +14,10 @@
|
|||||||
* limitations under the License.
|
* 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.Espresso.onView;
|
||||||
import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist;
|
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.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
@@ -39,9 +37,13 @@ import android.content.pm.ResolveInfo;
|
|||||||
import android.content.pm.ShortcutInfo;
|
import android.content.pm.ShortcutInfo;
|
||||||
import android.content.pm.ShortcutManager;
|
import android.content.pm.ShortcutManager;
|
||||||
import android.support.test.InstrumentationRegistry;
|
import android.support.test.InstrumentationRegistry;
|
||||||
|
import android.support.test.espresso.matcher.ViewMatchers;
|
||||||
import android.support.test.filters.SmallTest;
|
import android.support.test.filters.SmallTest;
|
||||||
import android.support.test.runner.AndroidJUnit4;
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.Settings;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@@ -55,12 +57,6 @@ import java.util.List;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link CreateShortcutTest}
|
* 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)
|
@RunWith(AndroidJUnit4.class)
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@@ -71,8 +67,10 @@ public class CreateShortcutTest {
|
|||||||
private Instrumentation mInstrumentation;
|
private Instrumentation mInstrumentation;
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
|
|
||||||
@Mock ShortcutManager mShortcutManager;
|
@Mock
|
||||||
@Captor ArgumentCaptor<List<ShortcutInfo>> mListCaptor;
|
ShortcutManager mShortcutManager;
|
||||||
|
@Captor
|
||||||
|
ArgumentCaptor<List<ShortcutInfo>> mListCaptor;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
@@ -84,15 +82,17 @@ public class CreateShortcutTest {
|
|||||||
@Test
|
@Test
|
||||||
public void test_layoutDoesNotHaveCancelButton() {
|
public void test_layoutDoesNotHaveCancelButton() {
|
||||||
mInstrumentation.startActivitySync(new Intent(Intent.ACTION_CREATE_SHORTCUT)
|
mInstrumentation.startActivitySync(new Intent(Intent.ACTION_CREATE_SHORTCUT)
|
||||||
.setClassName(mContext, CreateShortcut.class.getName()));
|
.setClassName(mContext, CreateShortcut.class.getName())
|
||||||
onView(withText(R.string.cancel)).check(doesNotExist());
|
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
||||||
|
onView(ViewMatchers.withText(R.string.cancel)).check(doesNotExist());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createResultIntent() {
|
public void createResultIntent() {
|
||||||
CreateShortcut orgActivity = (CreateShortcut) mInstrumentation.startActivitySync(
|
CreateShortcut orgActivity = (CreateShortcut) mInstrumentation.startActivitySync(
|
||||||
new Intent(Intent.ACTION_CREATE_SHORTCUT)
|
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);
|
CreateShortcut activity = spy(orgActivity);
|
||||||
doReturn(mShortcutManager).when(activity).getSystemService(eq(Context.SHORTCUT_SERVICE));
|
doReturn(mShortcutManager).when(activity).getSystemService(eq(Context.SHORTCUT_SERVICE));
|
||||||
|
|
||||||
Reference in New Issue
Block a user