Snap for 4574286 from acd313e644 to pi-release
Change-Id: I2563cc15b37529a139a400c869f79ca9ac078a1c
This commit is contained in:
@@ -146,7 +146,7 @@
|
||||
android:parentActivityName="Settings">
|
||||
</activity>
|
||||
|
||||
<activity android:name="CreateShortcut"
|
||||
<activity android:name=".shortcut.CreateShortcut"
|
||||
android:label="@string/settings_shortcut">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.CREATE_SHORTCUT"/>
|
||||
@@ -1279,7 +1279,7 @@
|
||||
android:value="true" />
|
||||
</activity>
|
||||
|
||||
<activity android:name="Settings$SecuritySettingsActivity"
|
||||
<activity android:name=".Settings$SecurityDashboardActivity"
|
||||
android:label="@string/security_settings_title"
|
||||
android:icon="@drawable/ic_homepage_security"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||
@@ -1306,28 +1306,6 @@
|
||||
android:value="true" />
|
||||
</activity>
|
||||
|
||||
<!-- TODO(32953042) Merge with Settings$SecuritySettingsActivity -->
|
||||
<activity android:name="Settings$SecuritySettingsActivityV2"
|
||||
android:label="@string/security_settings_title"
|
||||
android:icon="@drawable/ic_homepage_security"
|
||||
android:enabled="false"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||
android:taskAffinity=""
|
||||
android:parentActivityName="Settings">
|
||||
<intent-filter android:priority="-1">
|
||||
<action android:name="android.settings.SECURITY_SETTINGS" />
|
||||
<action android:name="android.credentials.UNLOCK" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
<intent-filter android:priority="4">
|
||||
<action android:name="com.android.settings.action.SETTINGS" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="com.android.settings.category"
|
||||
android:value="com.android.settings.category.ia.homepage" />
|
||||
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
|
||||
android:value="com.android.settings.security.SecuritySettingsV2" />
|
||||
</activity>
|
||||
|
||||
<activity android:name="MonitoringCertInfoActivity"
|
||||
android:label=""
|
||||
android:theme="@style/Transparent"
|
||||
@@ -1358,16 +1336,6 @@
|
||||
android:value="true" />
|
||||
</activity>
|
||||
|
||||
<!-- Keep compatibility with old shortcuts. -->
|
||||
<activity-alias android:name="SecuritySettings"
|
||||
android:label="@string/security_settings_title"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||
android:exported="true"
|
||||
android:targetActivity="Settings$SecuritySettingsActivity">
|
||||
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
|
||||
android:value="com.android.settings.security.SecuritySettings" />
|
||||
</activity-alias>
|
||||
|
||||
<activity android:name="Settings$PrivacySettingsActivity"
|
||||
android:label="@string/privacy_settings_title"
|
||||
android:icon="@drawable/ic_settings_backup"
|
||||
@@ -1405,7 +1373,7 @@
|
||||
<activity android:name="Settings$DeviceAdminSettingsActivity"
|
||||
android:label="@string/device_admin_settings_title"
|
||||
android:taskAffinity="com.android.settings"
|
||||
android:parentActivityName="Settings$SecuritySettingsActivity">
|
||||
android:parentActivityName=".Settings$SecurityDashboardActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
@@ -1436,7 +1404,7 @@
|
||||
<activity android:name="Settings$UsageAccessSettingsActivity"
|
||||
android:label="@string/usage_access_title"
|
||||
android:taskAffinity="com.android.settings"
|
||||
android:parentActivityName="Settings$SecuritySettingsActivity">
|
||||
android:parentActivityName=".Settings$SecurityDashboardActivity">
|
||||
<intent-filter android:priority="1">
|
||||
<action android:name="android.settings.USAGE_ACCESS_SETTINGS" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
@@ -1574,7 +1542,7 @@
|
||||
<activity android:name="Settings$EnterprisePrivacySettingsActivity"
|
||||
android:label="@string/enterprise_privacy_settings"
|
||||
android:taskAffinity="com.android.settings"
|
||||
android:parentActivityName="Settings$SecuritySettingsActivity">
|
||||
android:parentActivityName=".Settings$SecurityDashboardActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.settings.ENTERPRISE_PRIVACY_SETTINGS" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
android:id="@+id/suggestion_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="18dp"
|
||||
android:paddingTop="14dp"
|
||||
android:paddingBottom="16dp"
|
||||
android:scrollbars="none"/>
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/suggestion_card"
|
||||
android:layout_width="328dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardPreventCornerOverlap="false"
|
||||
app:cardUseCompatPadding="true"
|
||||
@@ -65,7 +65,7 @@
|
||||
android:layout_marginEnd="12dp"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/TextAppearance.SuggestionTitleV2"
|
||||
android:ellipsize="marquee"
|
||||
android:ellipsize="end"
|
||||
android:fadingEdge="horizontal" />
|
||||
|
||||
<TextView
|
||||
|
||||
@@ -18,8 +18,9 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/suggestion_card"
|
||||
android:layout_width="328dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardPreventCornerOverlap="false"
|
||||
app:cardUseCompatPadding="true"
|
||||
app:cardElevation="2dp"
|
||||
app:cardCornerRadius="@dimen/suggestion_card_corner_radius">
|
||||
@@ -37,16 +38,17 @@
|
||||
|
||||
<ImageView
|
||||
android:id="@android:id/icon"
|
||||
android:layout_width="@dimen/dashboard_tile_image_size"
|
||||
android:layout_height="@dimen/dashboard_tile_image_size"
|
||||
android:layout_width="@dimen/suggestion_card_icon_size"
|
||||
android:layout_height="@dimen/suggestion_card_icon_size"
|
||||
style="@style/SuggestionCardIcon"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="8dp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/close_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:alpha="0.54"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
@@ -62,8 +64,8 @@
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/TextAppearance.TileTitle"
|
||||
android:ellipsize="marquee"
|
||||
android:textAppearance="@style/TextAppearance.SuggestionTitleV2"
|
||||
android:ellipsize="end"
|
||||
android:fadingEdge="horizontal" />
|
||||
|
||||
<TextView
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
<dimen name="support_escalation_card_padding_end">56dp</dimen>
|
||||
|
||||
<!-- Suggestion cards-->
|
||||
<dimen name="suggestion_card_width_one_card">380dp</dimen>
|
||||
<dimen name="suggestion_card_width_two_cards">184dp</dimen>
|
||||
<dimen name="suggestion_card_width_multiple_cards">176dp</dimen>
|
||||
<dimen name="suggestion_card_width_one_card">384dp</dimen>
|
||||
<dimen name="suggestion_card_width_two_cards">188dp</dimen>
|
||||
<dimen name="suggestion_card_width_multiple_cards">180dp</dimen>
|
||||
<dimen name="suggestion_card_padding_bottom_one_card">22dp</dimen>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -304,9 +304,9 @@
|
||||
|
||||
<!-- Suggestion cards size and padding -->
|
||||
<dimen name="suggestion_card_icon_size">24dp</dimen>
|
||||
<dimen name="suggestion_card_width_one_card">328dp</dimen>
|
||||
<dimen name="suggestion_card_width_two_cards">158dp</dimen>
|
||||
<dimen name="suggestion_card_width_multiple_cards">152dp</dimen>
|
||||
<dimen name="suggestion_card_width_one_card">332dp</dimen>
|
||||
<dimen name="suggestion_card_width_two_cards">162dp</dimen>
|
||||
<dimen name="suggestion_card_width_multiple_cards">156dp</dimen>
|
||||
<dimen name="suggestion_card_outer_margin">16dp</dimen>
|
||||
<dimen name="suggestion_card_inner_margin">12dp</dimen>
|
||||
<dimen name="suggestion_card_padding_bottom_one_card">16dp</dimen>
|
||||
|
||||
@@ -2579,6 +2579,7 @@
|
||||
|
||||
<!-- [CHAR LIMIT=30] Title of the preference that opens the Ambient display settings screen. -->
|
||||
<string name="ambient_display_screen_title">Ambient display</string>
|
||||
|
||||
<!-- [CHAR LIMIT=50] Summary of the preference that opens the Ambient display settings screen, when Ambient display is set to be always on -->
|
||||
<string name="ambient_display_screen_summary_always_on">Always on / Increased battery usage</string>
|
||||
<!-- [CHAR LIMIT=30] Summary of the preference that opens the Ambient display settings screen, when Ambient display is set to show when new notifications come in. -->
|
||||
@@ -6714,6 +6715,8 @@
|
||||
<string name="keywords_sim_status">network, mobile network state, service state, signal strength, mobile network type, roaming, iccid</string>
|
||||
<string name="keywords_model_and_hardware">serial number, hardware version</string>
|
||||
<string name="keywords_android_version">android security patch level, baseband version, kernel version</string>
|
||||
<!-- Search keyword for Ambient display settings screen. -->
|
||||
<string name="keywords_ambient_display_screen">Ambient display, Lock screen display</string>
|
||||
|
||||
<!-- NFC Wi-Fi pairing/setup strings-->
|
||||
|
||||
@@ -8777,6 +8780,9 @@
|
||||
<!-- [CHAR LIMIT=25] Title of developer tile to toggle layer trace -->
|
||||
<string name="layer_trace_quick_settings_title">Surface Trace</string>
|
||||
|
||||
<!-- Template for formatting country and language. eg Canada - French [CHAR LIMIT=NONE]-->
|
||||
<string name="support_country_format"><xliff:g id="country" example="Canada">%1$s</xliff:g> - <xliff:g id="language" example="French">%2$s</xliff:g></string>
|
||||
|
||||
<!-- [CHAR LIMIT=60] Title of work profile setting page -->
|
||||
<string name="managed_profile_settings_title">Work profile settings</string>
|
||||
<!-- [CHAR LIMIT=60] The preference title for enabling cross-profile remote contact search -->
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:key="ambient_display_preference_screen"
|
||||
settings:keywords="@string/keywords_ambient_display_screen"
|
||||
android:title="@string/ambient_display_screen_title">
|
||||
|
||||
<PreferenceCategory
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:key="app_data_usage_screen"
|
||||
android:title="@string/data_usage_app_summary_title">
|
||||
|
||||
<com.android.settings.datausage.SpinnerPreference
|
||||
@@ -50,15 +52,19 @@
|
||||
android:key="app_settings"
|
||||
android:title="@string/data_usage_app_settings" />
|
||||
|
||||
<SwitchPreference
|
||||
<com.android.settingslib.RestrictedSwitchPreference
|
||||
android:key="restrict_background"
|
||||
android:title="@string/data_usage_app_restrict_background"
|
||||
android:summary="@string/data_usage_app_restrict_background_summary" />
|
||||
android:summary="@string/data_usage_app_restrict_background_summary"
|
||||
settings:useAdditionalSummary="true"
|
||||
settings:restrictedSwitchSummary="@string/disabled_by_admin" />
|
||||
|
||||
<SwitchPreference
|
||||
<com.android.settingslib.RestrictedSwitchPreference
|
||||
android:key="unrestricted_data_saver"
|
||||
android:title="@string/unrestricted_app_title"
|
||||
android:summary="@string/unrestricted_app_summary" />
|
||||
android:summary="@string/unrestricted_app_summary"
|
||||
settings:useAdditionalSummary="true"
|
||||
settings:restrictedSwitchSummary="@string/disabled_by_admin" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
|
||||
@@ -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 AccessibilityContrastSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class AccessibilityDaltonizerSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class SecuritySettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class SecuritySettingsActivityV2 extends SettingsActivity { /* empty */ }
|
||||
public static class SecurityDashboardActivity extends SettingsActivity { /* empty */ }
|
||||
public static class UsageAccessSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class LocationSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class PrivacySettingsActivity extends SettingsActivity { /* empty */ }
|
||||
|
||||
@@ -802,20 +802,6 @@ public class SettingsActivity extends SettingsDrawerActivity
|
||||
!isConnectedDeviceV2Enabled && !UserManager.isDeviceInDemoMode(this) /* enabled */,
|
||||
isAdmin) || somethingChanged;
|
||||
|
||||
final boolean isSecurityV2Enabled = featureFactory.getSecurityFeatureProvider()
|
||||
.isSecuritySettingsV2Enabled(this);
|
||||
|
||||
// Enable new security page if v2 enabled
|
||||
somethingChanged = setTileEnabled(
|
||||
new ComponentName(packageName,Settings.SecuritySettingsActivityV2.class.getName()),
|
||||
isSecurityV2Enabled,
|
||||
isAdmin) || somethingChanged;
|
||||
// Enable old security page if v2 disabled
|
||||
somethingChanged = setTileEnabled(
|
||||
new ComponentName(packageName,Settings.SecuritySettingsActivity.class.getName()),
|
||||
!isSecurityV2Enabled,
|
||||
isAdmin) || somethingChanged;
|
||||
|
||||
somethingChanged = setTileEnabled(new ComponentName(packageName,
|
||||
Settings.SimSettingsActivity.class.getName()),
|
||||
Utils.showSimCardTile(this), isAdmin)
|
||||
|
||||
@@ -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.MATCH_DISABLED_COMPONENTS;
|
||||
|
||||
import com.android.settings.shortcut.CreateShortcut;
|
||||
|
||||
/**
|
||||
* Listens to {@link Intent.ACTION_PRE_BOOT_COMPLETED} and {@link Intent.ACTION_USER_INITIALIZED}
|
||||
* performs setup steps for a managed profile (disables the launcher icon of the Settings app,
|
||||
|
||||
@@ -16,18 +16,14 @@
|
||||
|
||||
package com.android.settings.applications.appinfo;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
@@ -35,7 +31,6 @@ import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
import android.util.Log;
|
||||
import android.webkit.IWebViewUpdateService;
|
||||
|
||||
import com.android.settings.R;
|
||||
@@ -71,16 +66,6 @@ public class AppActionButtonPreferenceController extends BasePreferenceControlle
|
||||
private UserManager mUserManager;
|
||||
private PackageManager mPm;
|
||||
|
||||
private final BroadcastReceiver mCheckKillProcessesReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
final boolean enabled = getResultCode() != Activity.RESULT_CANCELED;
|
||||
Log.d(TAG, "Got broadcast response: Restart status for "
|
||||
+ mParent.getAppEntry().info.packageName + " " + enabled);
|
||||
updateForceStopButton(enabled);
|
||||
}
|
||||
};
|
||||
|
||||
public AppActionButtonPreferenceController(Context context, AppInfoDashboardFragment parent,
|
||||
String packageName) {
|
||||
super(context, KEY_ACTION_BUTTONS);
|
||||
@@ -101,9 +86,7 @@ public class AppActionButtonPreferenceController extends BasePreferenceControlle
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mActionButtons = ((ActionButtonPreference) screen.findPreference(KEY_ACTION_BUTTONS))
|
||||
.setButton2Text(R.string.force_stop)
|
||||
.setButton2Positive(false)
|
||||
.setButton2Enabled(false);
|
||||
.setButton2Visible(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -140,7 +123,6 @@ public class AppActionButtonPreferenceController extends BasePreferenceControlle
|
||||
}
|
||||
}
|
||||
|
||||
checkForceStop(appEntry, packageInfo);
|
||||
initUninstallButtons(appEntry, packageInfo);
|
||||
}
|
||||
|
||||
@@ -269,41 +251,6 @@ public class AppActionButtonPreferenceController extends BasePreferenceControlle
|
||||
return disableable;
|
||||
}
|
||||
|
||||
private void updateForceStopButton(boolean enabled) {
|
||||
final boolean disallowedBySystem = RestrictedLockUtils.hasBaseUserRestriction(
|
||||
mContext, UserManager.DISALLOW_APPS_CONTROL, mUserId);
|
||||
mActionButtons
|
||||
.setButton2Enabled(disallowedBySystem ? false : enabled)
|
||||
.setButton2OnClickListener(
|
||||
disallowedBySystem ? null : v -> mParent.handleForceStopButtonClick());
|
||||
}
|
||||
|
||||
void checkForceStop(AppEntry appEntry, PackageInfo packageInfo) {
|
||||
if (mDpm.packageHasActiveAdmins(packageInfo.packageName)) {
|
||||
// User can't force stop device admin.
|
||||
Log.w(TAG, "User can't force stop device admin");
|
||||
updateForceStopButton(false);
|
||||
} else if (AppUtils.isInstant(packageInfo.applicationInfo)) {
|
||||
updateForceStopButton(false);
|
||||
mActionButtons.setButton2Visible(false);
|
||||
} else if ((appEntry.info.flags & ApplicationInfo.FLAG_STOPPED) == 0) {
|
||||
// If the app isn't explicitly stopped, then always show the
|
||||
// force stop button.
|
||||
Log.w(TAG, "App is not explicitly stopped");
|
||||
updateForceStopButton(true);
|
||||
} else {
|
||||
final Intent intent = new Intent(Intent.ACTION_QUERY_PACKAGE_RESTART,
|
||||
Uri.fromParts("package", appEntry.info.packageName, null));
|
||||
intent.putExtra(Intent.EXTRA_PACKAGES, new String[] { appEntry.info.packageName });
|
||||
intent.putExtra(Intent.EXTRA_UID, appEntry.info.uid);
|
||||
intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(appEntry.info.uid));
|
||||
Log.d(TAG, "Sending broadcast to query restart status for "
|
||||
+ appEntry.info.packageName);
|
||||
mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null,
|
||||
mCheckKillProcessesReceiver, null, Activity.RESULT_CANCELED, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean signaturesMatch(String pkg1, String pkg2) {
|
||||
if (pkg1 != null && pkg2 != null) {
|
||||
try {
|
||||
|
||||
@@ -19,7 +19,6 @@ package com.android.settings.applications.appinfo;
|
||||
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.DialogFragment;
|
||||
@@ -45,19 +44,15 @@ import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.DeviceAdminAdd;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.applications.LayoutPreference;
|
||||
import com.android.settings.applications.manageapplications.ManageApplications;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.widget.EntityHeaderController;
|
||||
import com.android.settings.widget.PreferenceCategoryController;
|
||||
import com.android.settings.wrapper.DevicePolicyManagerWrapper;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
@@ -89,6 +84,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
||||
// Menu identifiers
|
||||
private static final int UNINSTALL_ALL_USERS_MENU = 1;
|
||||
private static final int UNINSTALL_UPDATES = 2;
|
||||
static final int FORCE_STOP_MENU = 3;
|
||||
|
||||
// Result code identifiers
|
||||
@VisibleForTesting
|
||||
@@ -103,7 +99,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
||||
|
||||
// Dialog identifiers used in showDialog
|
||||
private static final int DLG_BASE = 0;
|
||||
private static final int DLG_FORCE_STOP = DLG_BASE + 1;
|
||||
static final int DLG_FORCE_STOP = DLG_BASE + 1;
|
||||
private static final int DLG_DISABLE = DLG_BASE + 2;
|
||||
private static final int DLG_SPECIAL_DISABLE = DLG_BASE + 3;
|
||||
|
||||
@@ -141,6 +137,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
||||
|
||||
private InstantAppButtonsPreferenceController mInstantAppButtonPreferenceController;
|
||||
private AppActionButtonPreferenceController mAppActionButtonPreferenceController;
|
||||
private ForceStopOptionsMenuController mForceStopOptionsMenuController;
|
||||
|
||||
/**
|
||||
* Callback to invoke when app info has been changed.
|
||||
@@ -172,6 +169,9 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
||||
return;
|
||||
}
|
||||
|
||||
mForceStopOptionsMenuController =
|
||||
new ForceStopOptionsMenuController(activity, this /* parent */, mDpm,
|
||||
mMetricsFeatureProvider, getLifecycle());
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@@ -268,6 +268,10 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
||||
return mAppEntry;
|
||||
}
|
||||
|
||||
void setAppEntry(ApplicationsState.AppEntry appEntry) {
|
||||
mAppEntry = appEntry;
|
||||
}
|
||||
|
||||
PackageInfo getPackageInfo() {
|
||||
if (mAppEntry == null) {
|
||||
retrieveAppEntry();
|
||||
@@ -275,6 +279,10 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
||||
return mPackageInfo;
|
||||
}
|
||||
|
||||
ApplicationsState getAppState() {
|
||||
return mState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPackageSizeChanged(String packageName) {
|
||||
if (!TextUtils.equals(packageName, mPackageName)) {
|
||||
@@ -315,6 +323,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
||||
if (mFinishing) {
|
||||
return;
|
||||
}
|
||||
super.onPrepareOptionsMenu(menu);
|
||||
menu.findItem(UNINSTALL_ALL_USERS_MENU).setVisible(shouldShowUninstallForAll(mAppEntry));
|
||||
mUpdatedSysApp = (mAppEntry.info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
|
||||
final MenuItem uninstallUpdatesItem = menu.findItem(UNINSTALL_UPDATES);
|
||||
@@ -335,7 +344,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
||||
uninstallPkg(mAppEntry.info.packageName, false, false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -465,18 +474,10 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
||||
})
|
||||
.setNegativeButton(R.string.dlg_cancel, null)
|
||||
.create();
|
||||
case DLG_FORCE_STOP:
|
||||
return new AlertDialog.Builder(getActivity())
|
||||
.setTitle(getActivity().getText(R.string.force_stop_dlg_title))
|
||||
.setMessage(getActivity().getText(R.string.force_stop_dlg_text))
|
||||
.setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
// Force stop
|
||||
forceStopPackage(mAppEntry.info.packageName);
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.dlg_cancel, null)
|
||||
.create();
|
||||
}
|
||||
final AlertDialog dialog = mForceStopOptionsMenuController.createDialog(id);
|
||||
if (dialog != null) {
|
||||
return dialog;
|
||||
}
|
||||
return mInstantAppButtonPreferenceController.createDialog(id);
|
||||
}
|
||||
@@ -493,21 +494,6 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
||||
mDisableAfterUninstall = andDisable;
|
||||
}
|
||||
|
||||
private void forceStopPackage(String pkgName) {
|
||||
mMetricsFeatureProvider.action(getContext(), MetricsEvent.ACTION_APP_FORCE_STOP, pkgName);
|
||||
final ActivityManager am = (ActivityManager) getActivity().getSystemService(
|
||||
Context.ACTIVITY_SERVICE);
|
||||
Log.d(TAG, "Stopping package " + pkgName);
|
||||
am.forceStopPackage(pkgName);
|
||||
final int userId = UserHandle.getUserId(mAppEntry.info.uid);
|
||||
mState.invalidatePackage(pkgName, userId);
|
||||
final AppEntry newEnt = mState.getEntry(pkgName, userId);
|
||||
if (newEnt != null) {
|
||||
mAppEntry = newEnt;
|
||||
}
|
||||
mAppActionButtonPreferenceController.checkForceStop(mAppEntry, mPackageInfo);
|
||||
}
|
||||
|
||||
public static void startAppInfoFragment(Class<?> fragment, int title,
|
||||
SettingsPreferenceFragment caller, AppEntry appEntry) {
|
||||
// start new fragment to display extended information
|
||||
@@ -568,20 +554,6 @@ 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 */
|
||||
private boolean isSingleUser() {
|
||||
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);
|
||||
final Intent intent = new Intent();
|
||||
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 BATTERY_SETTINGS_V2 = "settings_battery_v2";
|
||||
public static final String BATTERY_DISPLAY_APP_LIST = "settings_battery_display_app_list";
|
||||
public static final String SECURITY_SETTINGS_V2 = "settings_security_settings_v2";
|
||||
public static final String ZONE_PICKER_V2 = "settings_zone_picker_v2";
|
||||
public static final String SUGGESTION_UI_V2 = "settings_suggestion_ui_v2";
|
||||
public static final String ABOUT_PHONE_V2 = "settings_about_phone_v2";
|
||||
|
||||
@@ -116,7 +116,6 @@ import com.android.settings.print.PrintSettingsFragment;
|
||||
import com.android.settings.security.CryptKeeperSettings;
|
||||
import com.android.settings.security.LockscreenDashboardFragment;
|
||||
import com.android.settings.security.SecuritySettings;
|
||||
import com.android.settings.security.SecuritySettingsV2;
|
||||
import com.android.settings.sim.SimSettings;
|
||||
import com.android.settings.support.SupportDashboardActivity;
|
||||
import com.android.settings.system.ResetDashboardFragment;
|
||||
@@ -165,7 +164,6 @@ public class SettingsGateway {
|
||||
NotificationStation.class.getName(),
|
||||
LocationSettings.class.getName(),
|
||||
SecuritySettings.class.getName(),
|
||||
SecuritySettingsV2.class.getName(),
|
||||
UsageAccessDetails.class.getName(),
|
||||
PrivacySettings.class.getName(),
|
||||
DeviceAdminSettings.class.getName(),
|
||||
@@ -271,8 +269,7 @@ public class SettingsGateway {
|
||||
Settings.PowerUsageSummaryActivity.class.getName(),
|
||||
Settings.PowerUsageSummaryLegacyActivity.class.getName(),
|
||||
Settings.AccountDashboardActivity.class.getName(),
|
||||
Settings.SecuritySettingsActivity.class.getName(),
|
||||
Settings.SecuritySettingsActivityV2.class.getName(),
|
||||
Settings.SecurityDashboardActivity.class.getName(),
|
||||
Settings.AccessibilitySettingsActivity.class.getName(),
|
||||
Settings.SystemDashboardActivity.class.getName(),
|
||||
SupportDashboardActivity.class.getName(),
|
||||
|
||||
@@ -151,13 +151,10 @@ public class DashboardAdapterV2 extends RecyclerView.Adapter<DashboardAdapterV2.
|
||||
if (list.size() == 1) {
|
||||
// The only suggestion is dismissed, and the the empty suggestion container will
|
||||
// remain as the dashboard item. Need to refresh the dashboard list.
|
||||
final DashboardDataV2 prevData = mDashboardData;
|
||||
mDashboardData = new DashboardDataV2.Builder(prevData)
|
||||
.setSuggestions(null)
|
||||
.build();
|
||||
notifyDashboardDataChanged(prevData);
|
||||
setSuggestions(null);
|
||||
} else {
|
||||
mSuggestionAdapter.removeSuggestion(suggestion);
|
||||
notifyItemChanged(0, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ import com.android.settings.network.NetworkDashboardFragment;
|
||||
import com.android.settings.notification.ConfigureNotificationSettings;
|
||||
import com.android.settings.notification.SoundSettings;
|
||||
import com.android.settings.security.LockscreenDashboardFragment;
|
||||
import com.android.settings.security.SecuritySettingsV2;
|
||||
import com.android.settings.security.SecuritySettings;
|
||||
import com.android.settings.system.SystemDashboardFragment;
|
||||
import com.android.settingslib.drawer.CategoryKey;
|
||||
|
||||
@@ -77,7 +77,7 @@ public class DashboardFragmentRegistry {
|
||||
CategoryKey.CATEGORY_SOUND);
|
||||
PARENT_TO_CATEGORY_KEY_MAP.put(StorageDashboardFragment.class.getName(),
|
||||
CategoryKey.CATEGORY_STORAGE);
|
||||
PARENT_TO_CATEGORY_KEY_MAP.put(SecuritySettingsV2.class.getName(),
|
||||
PARENT_TO_CATEGORY_KEY_MAP.put(SecuritySettings.class.getName(),
|
||||
CategoryKey.CATEGORY_SECURITY);
|
||||
PARENT_TO_CATEGORY_KEY_MAP.put(AccountDetailDashboardFragment.class.getName(),
|
||||
CategoryKey.CATEGORY_ACCOUNT_DETAIL);
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.android.settings.dashboard.suggestions;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.os.Bundle;
|
||||
import android.service.settings.suggestions.Suggestion;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
@@ -34,6 +36,7 @@ import com.android.settings.R;
|
||||
import com.android.settings.dashboard.DashboardAdapterV2.DashboardItemHolder;
|
||||
import com.android.settings.dashboard.DashboardAdapterV2.IconCache;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
@@ -55,6 +58,7 @@ public class SuggestionAdapterV2 extends RecyclerView.Adapter<DashboardItemHolde
|
||||
private final MetricsFeatureProvider mMetricsFeatureProvider;
|
||||
private final IconCache mCache;
|
||||
private final ArrayList<String> mSuggestionsShownLogged;
|
||||
private final SuggestionFeatureProvider mSuggestionFeatureProvider;
|
||||
private final SuggestionControllerMixin mSuggestionControllerMixin;
|
||||
private final Callback mCallback;
|
||||
private final CardConfig mConfig;
|
||||
@@ -75,6 +79,7 @@ public class SuggestionAdapterV2 extends RecyclerView.Adapter<DashboardItemHolde
|
||||
mCache = new IconCache(context);
|
||||
final FeatureFactory factory = FeatureFactory.getFactory(context);
|
||||
mMetricsFeatureProvider = factory.getMetricsFeatureProvider();
|
||||
mSuggestionFeatureProvider = factory.getSuggestionFeatureProvider(context);
|
||||
mCallback = callback;
|
||||
if (savedInstanceState != null) {
|
||||
mSuggestions = savedInstanceState.getParcelableArrayList(STATE_SUGGESTION_LIST);
|
||||
@@ -109,7 +114,12 @@ public class SuggestionAdapterV2 extends RecyclerView.Adapter<DashboardItemHolde
|
||||
mSuggestionsShownLogged.add(id);
|
||||
}
|
||||
mConfig.setCardLayout(holder, suggestionCount, position);
|
||||
holder.icon.setImageDrawable(mCache.getIcon(suggestion.getIcon()));
|
||||
final Icon icon = suggestion.getIcon();
|
||||
final Drawable drawable = mCache.getIcon(icon);
|
||||
if (drawable != null && TextUtils.equals(icon.getResPackage(), mContext.getPackageName())) {
|
||||
drawable.setTint(Utils.getColorAccent(mContext));
|
||||
}
|
||||
holder.icon.setImageDrawable(drawable);
|
||||
holder.title.setText(suggestion.getTitle());
|
||||
holder.title.setSingleLine(suggestionCount == 1);
|
||||
|
||||
@@ -129,13 +139,13 @@ public class SuggestionAdapterV2 extends RecyclerView.Adapter<DashboardItemHolde
|
||||
|
||||
final ImageView closeButton = holder.itemView.findViewById(R.id.close_button);
|
||||
if (closeButton != null) {
|
||||
if (mCallback != null) {
|
||||
closeButton.setOnClickListener(v -> {
|
||||
closeButton.setOnClickListener(v -> {
|
||||
mSuggestionFeatureProvider.dismissSuggestion(
|
||||
mContext, mSuggestionControllerMixin, suggestion);
|
||||
if (mCallback != null) {
|
||||
mCallback.onSuggestionClosed(suggestion);
|
||||
});
|
||||
} else {
|
||||
closeButton.setOnClickListener(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
View clickHandler = holder.itemView;
|
||||
|
||||
@@ -33,7 +33,6 @@ import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v14.preference.SwitchPreference;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceCategory;
|
||||
import android.text.format.Formatter;
|
||||
@@ -48,6 +47,9 @@ import com.android.settings.R;
|
||||
import com.android.settings.applications.AppInfoBase;
|
||||
import com.android.settings.widget.EntityHeaderController;
|
||||
import com.android.settingslib.AppItem;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
import com.android.settingslib.RestrictedSwitchPreference;
|
||||
import com.android.settingslib.net.ChartData;
|
||||
import com.android.settingslib.net.ChartDataLoader;
|
||||
import com.android.settingslib.net.UidDetail;
|
||||
@@ -80,7 +82,7 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen
|
||||
private Preference mForegroundUsage;
|
||||
private Preference mBackgroundUsage;
|
||||
private Preference mAppSettings;
|
||||
private SwitchPreference mRestrictBackground;
|
||||
private RestrictedSwitchPreference mRestrictBackground;
|
||||
private PreferenceCategory mAppList;
|
||||
|
||||
private Drawable mIcon;
|
||||
@@ -97,7 +99,7 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen
|
||||
private AppItem mAppItem;
|
||||
private Intent mAppSettingsIntent;
|
||||
private SpinnerPreference mCycle;
|
||||
private SwitchPreference mUnrestrictedData;
|
||||
private RestrictedSwitchPreference mUnrestrictedData;
|
||||
private DataSaverBackend mDataSaverBackend;
|
||||
|
||||
@Override
|
||||
@@ -160,9 +162,11 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen
|
||||
removePreference(KEY_UNRESTRICTED_DATA);
|
||||
removePreference(KEY_RESTRICT_BACKGROUND);
|
||||
} else {
|
||||
mRestrictBackground = (SwitchPreference) findPreference(KEY_RESTRICT_BACKGROUND);
|
||||
mRestrictBackground = (RestrictedSwitchPreference) findPreference(
|
||||
KEY_RESTRICT_BACKGROUND);
|
||||
mRestrictBackground.setOnPreferenceChangeListener(this);
|
||||
mUnrestrictedData = (SwitchPreference) findPreference(KEY_UNRESTRICTED_DATA);
|
||||
mUnrestrictedData = (RestrictedSwitchPreference) findPreference(
|
||||
KEY_UNRESTRICTED_DATA);
|
||||
mUnrestrictedData.setOnPreferenceChangeListener(this);
|
||||
}
|
||||
mDataSaverBackend = new DataSaverBackend(getContext());
|
||||
@@ -261,8 +265,11 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen
|
||||
}
|
||||
|
||||
private void updatePrefs(boolean restrictBackground, boolean unrestrictData) {
|
||||
final EnforcedAdmin admin = RestrictedLockUtils.checkIfMeteredDataRestricted(
|
||||
getContext(), mPackageName, UserHandle.getUserId(mAppItem.key));
|
||||
if (mRestrictBackground != null) {
|
||||
mRestrictBackground.setChecked(!restrictBackground);
|
||||
mRestrictBackground.setDisabledByAdmin(admin);
|
||||
}
|
||||
if (mUnrestrictedData != null) {
|
||||
if (restrictBackground) {
|
||||
@@ -270,6 +277,7 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen
|
||||
} else {
|
||||
mUnrestrictedData.setVisible(true);
|
||||
mUnrestrictedData.setChecked(unrestrictData);
|
||||
mUnrestrictedData.setDisabledByAdmin(admin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class DataSaverPreference extends Preference implements DataSaverBackend.
|
||||
@Override
|
||||
public void onDetached() {
|
||||
super.onDetached();
|
||||
mDataSaverBackend.addListener(this);
|
||||
mDataSaverBackend.remListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
package com.android.settings.datausage;
|
||||
|
||||
import static com.android.settingslib.RestrictedLockUtils.checkIfMeteredDataRestricted;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
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.overlay.FeatureFactory;
|
||||
import com.android.settings.widget.AppSwitchPreference;
|
||||
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
import com.android.settingslib.RestrictedPreferenceHelper;
|
||||
import com.android.settingslib.applications.ApplicationsState;
|
||||
import com.android.settingslib.applications.ApplicationsState.AppEntry;
|
||||
import com.android.settingslib.applications.ApplicationsState.AppFilter;
|
||||
@@ -172,6 +176,8 @@ public class UnrestrictedDataAccess extends SettingsPreferenceFragment
|
||||
preference.setOnPreferenceChangeListener(this);
|
||||
getPreferenceScreen().addPreference(preference);
|
||||
} else {
|
||||
preference.setDisabledByAdmin(checkIfMeteredDataRestricted(getContext(),
|
||||
entry.info.packageName, UserHandle.getUserId(entry.info.uid)));
|
||||
preference.reuse();
|
||||
}
|
||||
preference.setOrder(i);
|
||||
@@ -242,16 +248,22 @@ public class UnrestrictedDataAccess extends SettingsPreferenceFragment
|
||||
return app != null && UserHandle.isApp(app.info.uid);
|
||||
}
|
||||
|
||||
private class AccessPreference extends AppSwitchPreference
|
||||
@VisibleForTesting
|
||||
class AccessPreference extends AppSwitchPreference
|
||||
implements DataSaverBackend.Listener {
|
||||
private final AppEntry mEntry;
|
||||
private final DataUsageState mState;
|
||||
private final RestrictedPreferenceHelper mHelper;
|
||||
|
||||
public AccessPreference(final Context context, AppEntry entry) {
|
||||
super(context);
|
||||
setWidgetLayoutResource(R.layout.restricted_switch_widget);
|
||||
mHelper = new RestrictedPreferenceHelper(context, this, null);
|
||||
mEntry = entry;
|
||||
mState = (DataUsageState) mEntry.extraInfo;
|
||||
mEntry.ensureLabel(getContext());
|
||||
setDisabledByAdmin(checkIfMeteredDataRestricted(context, entry.info.packageName,
|
||||
UserHandle.getUserId(entry.info.uid)));
|
||||
setState();
|
||||
if (mEntry.icon != null) {
|
||||
setIcon(mEntry.icon);
|
||||
@@ -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.
|
||||
private void setState() {
|
||||
setTitle(mEntry.label);
|
||||
if (mState != null) {
|
||||
setChecked(mState.isDataSaverWhitelisted);
|
||||
if (mState.isDataSaverBlacklisted) {
|
||||
if (isDisabledByAdmin()) {
|
||||
setSummary(R.string.disabled_by_admin);
|
||||
} else if (mState.isDataSaverBlacklisted) {
|
||||
setSummary(R.string.restrict_background_blacklisted);
|
||||
} else {
|
||||
setSummary("");
|
||||
@@ -323,10 +344,21 @@ public class UnrestrictedDataAccess extends SettingsPreferenceFragment
|
||||
}
|
||||
});
|
||||
}
|
||||
holder.findViewById(android.R.id.widget_frame)
|
||||
.setVisibility(mState != null && mState.isDataSaverBlacklisted
|
||||
? View.INVISIBLE : View.VISIBLE);
|
||||
final boolean disabledByAdmin = isDisabledByAdmin();
|
||||
final View widgetFrame = holder.findViewById(android.R.id.widget_frame);
|
||||
if (disabledByAdmin) {
|
||||
widgetFrame.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
widgetFrame.setVisibility(mState != null && mState.isDataSaverBlacklisted
|
||||
? View.INVISIBLE : View.VISIBLE);
|
||||
}
|
||||
super.onBindViewHolder(holder);
|
||||
|
||||
mHelper.onBindViewHolder(holder);
|
||||
holder.findViewById(R.id.restricted_icon).setVisibility(
|
||||
disabledByAdmin ? View.VISIBLE : View.GONE);
|
||||
holder.findViewById(android.R.id.switch_widget).setVisibility(
|
||||
disabledByAdmin ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -348,6 +380,19 @@ public class UnrestrictedDataAccess extends SettingsPreferenceFragment
|
||||
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.v7.preference.Preference;
|
||||
import android.support.v7.preference.Preference.OnPreferenceChangeListener;
|
||||
import android.support.v7.preference.Preference.OnPreferenceClickListener;
|
||||
import android.support.v7.preference.PreferenceGroup;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
import android.support.v7.preference.PreferenceViewHolder;
|
||||
@@ -921,49 +920,4 @@ 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.LocaleStore;
|
||||
|
||||
import com.android.settings.CreateShortcut;
|
||||
import com.android.settings.shortcut.CreateShortcut;
|
||||
import com.android.settings.R;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
|
||||
@@ -54,17 +54,6 @@ public class ManagedLockPasswordProvider {
|
||||
*/
|
||||
CharSequence getPickerOptionTitle(boolean forFingerprint) { return ""; }
|
||||
|
||||
/**
|
||||
* Gets resource id of the lock screen preference that should be displayed in security settings
|
||||
* if the current password quality is set to
|
||||
* {@link android.app.admin.DevicePolicyManager#PASSWORD_QUALITY_MANAGED}.
|
||||
* @param forProfile Whether the settings are shown for a user profile rather than a user.
|
||||
*/
|
||||
public int getResIdForLockUnlockScreen(boolean forProfile) {
|
||||
return forProfile ? R.xml.security_settings_password_profile
|
||||
: R.xml.security_settings_password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates intent that should be launched when user chooses managed password in the lock
|
||||
* settings picker.
|
||||
|
||||
@@ -21,7 +21,6 @@ import android.support.annotation.VisibleForTesting;
|
||||
import com.android.settings.DateTimeSettings;
|
||||
import com.android.settings.DisplaySettings;
|
||||
import com.android.settings.LegalSettings;
|
||||
import com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment;
|
||||
import com.android.settings.accessibility.AccessibilitySettings;
|
||||
import com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment;
|
||||
import com.android.settings.accessibility.MagnificationPreferenceFragment;
|
||||
@@ -42,6 +41,7 @@ import com.android.settings.development.DevelopmentSettingsDashboardFragment;
|
||||
import com.android.settings.deviceinfo.DeviceInfoSettings;
|
||||
import com.android.settings.deviceinfo.StorageDashboardFragment;
|
||||
import com.android.settings.deviceinfo.StorageSettings;
|
||||
import com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment;
|
||||
import com.android.settings.display.AmbientDisplaySettings;
|
||||
import com.android.settings.display.NightDisplaySettings;
|
||||
import com.android.settings.display.ScreenZoomSettings;
|
||||
@@ -75,7 +75,7 @@ import com.android.settings.print.PrintSettingsFragment;
|
||||
import com.android.settings.security.EncryptionAndCredential;
|
||||
import com.android.settings.security.LockscreenDashboardFragment;
|
||||
import com.android.settings.security.ScreenPinningSettings;
|
||||
import com.android.settings.security.SecuritySettingsV2;
|
||||
import com.android.settings.security.SecuritySettings;
|
||||
import com.android.settings.security.screenlock.ScreenLockSettings;
|
||||
import com.android.settings.sim.SimSettings;
|
||||
import com.android.settings.support.SupportDashboardActivity;
|
||||
@@ -132,7 +132,7 @@ public class SearchIndexableResourcesImpl implements SearchIndexableResources {
|
||||
addIndex(LanguageAndInputSettings.class);
|
||||
addIndex(LocationSettings.class);
|
||||
addIndex(ScanningSettings.class);
|
||||
addIndex(SecuritySettingsV2.class);
|
||||
addIndex(SecuritySettings.class);
|
||||
addIndex(ScreenLockSettings.class);
|
||||
addIndex(EncryptionAndCredential.class);
|
||||
addIndex(ScreenPinningSettings.class);
|
||||
|
||||
@@ -16,8 +16,7 @@
|
||||
|
||||
package com.android.settings.security;
|
||||
|
||||
import static com.android.settings.security
|
||||
.SecuritySettingsV2.SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE;
|
||||
import static com.android.settings.security.SecuritySettings.SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE;
|
||||
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.Context;
|
||||
@@ -37,7 +36,7 @@ public class ChangeProfileScreenLockPreferenceController extends
|
||||
private static final String KEY_UNLOCK_SET_OR_CHANGE_PROFILE = "unlock_set_or_change_profile";
|
||||
|
||||
public ChangeProfileScreenLockPreferenceController(Context context,
|
||||
SecuritySettingsV2 host) {
|
||||
SecuritySettings host) {
|
||||
super(context, host);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.android.settings.security;
|
||||
|
||||
import static com.android.settings.security.SecuritySettingsV2.SET_OR_CHANGE_LOCK_METHOD_REQUEST;
|
||||
import static com.android.settings.security.SecuritySettings.SET_OR_CHANGE_LOCK_METHOD_REQUEST;
|
||||
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.Context;
|
||||
@@ -45,7 +45,7 @@ public class ChangeScreenLockPreferenceController extends AbstractPreferenceCont
|
||||
private static final String KEY_UNLOCK_SET_OR_CHANGE = "unlock_set_or_change";
|
||||
|
||||
protected final DevicePolicyManager mDPM;
|
||||
protected final SecuritySettingsV2 mHost;
|
||||
protected final SecuritySettings mHost;
|
||||
protected final UserManager mUm;
|
||||
protected final LockPatternUtils mLockPatternUtils;
|
||||
|
||||
@@ -54,7 +54,7 @@ public class ChangeScreenLockPreferenceController extends AbstractPreferenceCont
|
||||
|
||||
protected RestrictedPreference mPreference;
|
||||
|
||||
public ChangeScreenLockPreferenceController(Context context, SecuritySettingsV2 host) {
|
||||
public ChangeScreenLockPreferenceController(Context context, SecuritySettings host) {
|
||||
super(context);
|
||||
mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
||||
mDPM = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||
|
||||
@@ -16,11 +16,10 @@
|
||||
|
||||
package com.android.settings.security;
|
||||
|
||||
import static com.android.settings.security
|
||||
.SecuritySettingsV2.SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE;
|
||||
import static com.android.settings.security.SecuritySettingsV2.UNIFY_LOCK_CONFIRM_DEVICE_REQUEST;
|
||||
import static com.android.settings.security.SecuritySettingsV2.UNIFY_LOCK_CONFIRM_PROFILE_REQUEST;
|
||||
import static com.android.settings.security.SecuritySettingsV2.UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST;
|
||||
import static com.android.settings.security.SecuritySettings.SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE;
|
||||
import static com.android.settings.security.SecuritySettings.UNIFY_LOCK_CONFIRM_DEVICE_REQUEST;
|
||||
import static com.android.settings.security.SecuritySettings.UNIFY_LOCK_CONFIRM_PROFILE_REQUEST;
|
||||
import static com.android.settings.security.SecuritySettings.UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
@@ -53,7 +52,7 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr
|
||||
private final UserManager mUm;
|
||||
private final LockPatternUtils mLockPatternUtils;
|
||||
private final int mProfileChallengeUserId;
|
||||
private final SecuritySettingsV2 mHost;
|
||||
private final SecuritySettings mHost;
|
||||
|
||||
private RestrictedSwitchPreference mUnifyProfile;
|
||||
|
||||
@@ -67,7 +66,7 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr
|
||||
mUnifyProfile = (RestrictedSwitchPreference) screen.findPreference(KEY_UNIFICATION);
|
||||
}
|
||||
|
||||
public LockUnificationPreferenceController(Context context, SecuritySettingsV2 host) {
|
||||
public LockUnificationPreferenceController(Context context, SecuritySettings host) {
|
||||
super(context);
|
||||
mHost = host;
|
||||
mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
||||
@@ -212,7 +211,7 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr
|
||||
mCurrentProfilePassword);
|
||||
mHost.startFragment(mHost, ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
|
||||
R.string.lock_settings_picker_title,
|
||||
SecuritySettingsV2.SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
|
||||
SecuritySettings.SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,26 +17,14 @@
|
||||
package com.android.settings.security;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
import android.util.FeatureFlagUtils;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.core.FeatureFlags;
|
||||
import com.android.settings.security.trustagent.TrustAgentManager;
|
||||
import com.android.settingslib.drawer.DashboardCategory;
|
||||
|
||||
|
||||
/** FeatureProvider for security. */
|
||||
public interface SecurityFeatureProvider {
|
||||
|
||||
default boolean isSecuritySettingsV2Enabled(Context context) {
|
||||
return FeatureFlagUtils.isEnabled(context, FeatureFlags.SECURITY_SETTINGS_V2);
|
||||
}
|
||||
|
||||
/** Update preferences with data from associated tiles. */
|
||||
void updatePreferences(Context context, PreferenceScreen preferenceScreen,
|
||||
DashboardCategory dashboardCategory);
|
||||
|
||||
/** Returns the {@link TrustAgentManager} bound to this {@link SecurityFeatureProvider}. */
|
||||
TrustAgentManager getTrustAgentManager();
|
||||
|
||||
|
||||
@@ -17,28 +17,9 @@
|
||||
package com.android.settings.security;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.IContentProvider;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.security.trustagent.TrustAgentManager;
|
||||
import com.android.settingslib.drawer.DashboardCategory;
|
||||
import com.android.settingslib.drawer.Tile;
|
||||
import com.android.settingslib.drawer.TileUtils;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/** Implementation for {@code SecurityFeatureProvider}. */
|
||||
public class SecurityFeatureProviderImpl implements SecurityFeatureProvider {
|
||||
@@ -46,150 +27,6 @@ public class SecurityFeatureProviderImpl implements SecurityFeatureProvider {
|
||||
private TrustAgentManager mTrustAgentManager;
|
||||
private LockPatternUtils mLockPatternUtils;
|
||||
|
||||
@VisibleForTesting
|
||||
static final Drawable DEFAULT_ICON = null;
|
||||
|
||||
@VisibleForTesting
|
||||
static Map<String, Pair<String, Integer>> sIconCache = new TreeMap<>();
|
||||
|
||||
@VisibleForTesting
|
||||
static Map<String, String> sSummaryCache = new TreeMap<>();
|
||||
|
||||
/** Update preferences with data from associated tiles. */
|
||||
public void updatePreferences(final Context context, final PreferenceScreen preferenceScreen,
|
||||
final DashboardCategory dashboardCategory) {
|
||||
if (preferenceScreen == null) {
|
||||
return;
|
||||
}
|
||||
int tilesCount = (dashboardCategory != null) ? dashboardCategory.getTilesCount() : 0;
|
||||
if (tilesCount == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
initPreferences(context, preferenceScreen, dashboardCategory);
|
||||
|
||||
// Fetching the summary and icon from the provider introduces latency, so do this on a
|
||||
// separate thread.
|
||||
ThreadUtils.postOnBackgroundThread(() ->
|
||||
updatePreferencesToRunOnWorkerThread(context, preferenceScreen, dashboardCategory));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static void initPreferences(Context context, PreferenceScreen preferenceScreen,
|
||||
DashboardCategory dashboardCategory) {
|
||||
int tilesCount = (dashboardCategory != null) ? dashboardCategory.getTilesCount() : 0;
|
||||
for (int i = 0; i < tilesCount; i++) {
|
||||
Tile tile = dashboardCategory.getTile(i);
|
||||
// If the tile does not have a key or appropriate meta data, skip it.
|
||||
if (TextUtils.isEmpty(tile.key) || (tile.metaData == null)) {
|
||||
continue;
|
||||
}
|
||||
Preference matchingPref = preferenceScreen.findPreference(tile.key);
|
||||
// If the tile does not have a matching preference, skip it.
|
||||
if (matchingPref == null) {
|
||||
continue;
|
||||
}
|
||||
// Either remove an icon by replacing them with nothing, or use the cached one since
|
||||
// there is a delay in fetching the injected icon, and we don't want an inappropriate
|
||||
// icon to be displayed while waiting for the injected icon.
|
||||
final String iconUri =
|
||||
tile.metaData.getString(TileUtils.META_DATA_PREFERENCE_ICON_URI, null);
|
||||
Drawable drawable = DEFAULT_ICON;
|
||||
if ((iconUri != null) && sIconCache.containsKey(iconUri)) {
|
||||
Pair<String, Integer> icon = sIconCache.get(iconUri);
|
||||
try {
|
||||
drawable = context.getPackageManager()
|
||||
.getResourcesForApplication(icon.first /* package name */)
|
||||
.getDrawable(icon.second /* res id */,
|
||||
context.getTheme());
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
// Ignore and just load the default icon.
|
||||
}
|
||||
}
|
||||
matchingPref.setIcon(drawable);
|
||||
// Either reserve room for the summary or load the cached one. This prevents the title
|
||||
// from shifting when the final summary is injected.
|
||||
final String summaryUri =
|
||||
tile.metaData.getString(TileUtils.META_DATA_PREFERENCE_SUMMARY_URI, null);
|
||||
String summary = context.getString(R.string.summary_placeholder);
|
||||
if ((summaryUri != null) && sSummaryCache.containsKey(summaryUri)) {
|
||||
summary = sSummaryCache.get(summaryUri);
|
||||
}
|
||||
matchingPref.setSummary(summary);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void updatePreferencesToRunOnWorkerThread(Context context, PreferenceScreen preferenceScreen,
|
||||
DashboardCategory dashboardCategory) {
|
||||
|
||||
int tilesCount = (dashboardCategory != null) ? dashboardCategory.getTilesCount() : 0;
|
||||
Map<String, IContentProvider> providerMap = new ArrayMap<>();
|
||||
for (int i = 0; i < tilesCount; i++) {
|
||||
Tile tile = dashboardCategory.getTile(i);
|
||||
// If the tile does not have a key or appropriate meta data, skip it.
|
||||
if (TextUtils.isEmpty(tile.key) || (tile.metaData == null)) {
|
||||
continue;
|
||||
}
|
||||
Preference matchingPref = preferenceScreen.findPreference(tile.key);
|
||||
// If the tile does not have a matching preference, skip it.
|
||||
if (matchingPref == null) {
|
||||
continue;
|
||||
}
|
||||
// Check if the tile has content providers for dynamically updatable content.
|
||||
final String iconUri =
|
||||
tile.metaData.getString(TileUtils.META_DATA_PREFERENCE_ICON_URI, null);
|
||||
final String summaryUri =
|
||||
tile.metaData.getString(TileUtils.META_DATA_PREFERENCE_SUMMARY_URI, null);
|
||||
if (!TextUtils.isEmpty(iconUri)) {
|
||||
String packageName = null;
|
||||
if (tile.intent != null) {
|
||||
Intent intent = tile.intent;
|
||||
if (!TextUtils.isEmpty(intent.getPackage())) {
|
||||
packageName = intent.getPackage();
|
||||
} else if (intent.getComponent() != null) {
|
||||
packageName = intent.getComponent().getPackageName();
|
||||
}
|
||||
}
|
||||
Pair<String, Integer> icon =
|
||||
TileUtils.getIconFromUri(context, packageName, iconUri, providerMap);
|
||||
if (icon != null) {
|
||||
sIconCache.put(iconUri, icon);
|
||||
// Icon is only returned if the icon belongs to Settings or the target app.
|
||||
// setIcon must be called on the UI thread.
|
||||
ThreadUtils.postOnMainThread(() -> {
|
||||
try {
|
||||
matchingPref.setIcon(context.getPackageManager()
|
||||
.getResourcesForApplication(icon.first /* package name */)
|
||||
.getDrawable(icon.second /* res id */,
|
||||
context.getTheme()));
|
||||
} catch (PackageManager.NameNotFoundException
|
||||
| Resources.NotFoundException e) {
|
||||
// Intentionally ignored. If icon resources cannot be found, do not
|
||||
// update.
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if (!TextUtils.isEmpty(summaryUri)) {
|
||||
String summary = TileUtils.getTextFromUri(context, summaryUri, providerMap,
|
||||
TileUtils.META_DATA_PREFERENCE_SUMMARY);
|
||||
sSummaryCache.put(summaryUri, summary);
|
||||
// setSummary must be called on UI thread.
|
||||
ThreadUtils.postOnMainThread(() -> {
|
||||
// Only update the summary if it has actually changed.
|
||||
if (summary == null) {
|
||||
if (matchingPref.getSummary() != null) {
|
||||
matchingPref.setSummary(summary);
|
||||
}
|
||||
} else if (!summary.equals(matchingPref.getSummary())) {
|
||||
matchingPref.setSummary(summary);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrustAgentManager getTrustAgentManager() {
|
||||
if (mTrustAgentManager == null) {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public void show(SecuritySettingsV2 host) {
|
||||
public void show(SecuritySettings host) {
|
||||
final FragmentManager manager = host.getChildFragmentManager();
|
||||
if (manager.findFragmentByTag(TAG_UNIFICATION_DIALOG) == null) {
|
||||
// Prevent opening multiple dialogs if tapped on button quickly
|
||||
@@ -50,7 +50,7 @@ public class UnificationConfirmationDialog extends InstrumentedDialogFragment {
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final SecuritySettingsV2 parentFragment = ((SecuritySettingsV2) getParentFragment());
|
||||
final SecuritySettings parentFragment = ((SecuritySettings) getParentFragment());
|
||||
final boolean compliant = getArguments().getBoolean(EXTRA_COMPLIANT);
|
||||
return new AlertDialog.Builder(getActivity())
|
||||
.setTitle(R.string.lock_settings_profile_unification_dialog_title)
|
||||
@@ -75,7 +75,7 @@ public class UnificationConfirmationDialog extends InstrumentedDialogFragment {
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
super.onDismiss(dialog);
|
||||
((SecuritySettingsV2) getParentFragment()).updateUnificationPreference();
|
||||
((SecuritySettings) getParentFragment()).updateUnificationPreference();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.android.settings.security.trustagent;
|
||||
|
||||
import static com.android.settings.security.SecuritySettingsV2.CHANGE_TRUST_AGENT_SETTINGS;
|
||||
import static com.android.settings.security.SecuritySettings.CHANGE_TRUST_AGENT_SETTINGS;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
@@ -35,7 +35,7 @@ import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.password.ChooseLockSettingsHelper;
|
||||
import com.android.settings.security.SecurityFeatureProvider;
|
||||
import com.android.settings.security.SecuritySettingsV2;
|
||||
import com.android.settings.security.SecuritySettings;
|
||||
import com.android.settingslib.RestrictedPreference;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
@@ -59,12 +59,12 @@ public class TrustAgentListPreferenceController extends AbstractPreferenceContro
|
||||
|
||||
private final LockPatternUtils mLockPatternUtils;
|
||||
private final TrustAgentManager mTrustAgentManager;
|
||||
private final SecuritySettingsV2 mHost;
|
||||
private final SecuritySettings mHost;
|
||||
|
||||
private Intent mTrustAgentClickIntent;
|
||||
private PreferenceCategory mSecurityCategory;
|
||||
|
||||
public TrustAgentListPreferenceController(Context context, SecuritySettingsV2 host,
|
||||
public TrustAgentListPreferenceController(Context context, SecuritySettings host,
|
||||
Lifecycle lifecycle) {
|
||||
super(context);
|
||||
final SecurityFeatureProvider provider = FeatureFactory.getFactory(context)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings;
|
||||
package com.android.settings.shortcut;
|
||||
|
||||
import android.app.LauncherActivity;
|
||||
import android.content.ComponentName;
|
||||
@@ -28,7 +28,9 @@ import android.content.pm.ShortcutManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Bitmap.Config;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.os.AsyncTask;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
@@ -40,6 +42,7 @@ import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Settings.TetherSettingsActivity;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
|
||||
@@ -65,7 +68,8 @@ public class CreateShortcut extends LauncherActivity {
|
||||
finish();
|
||||
}
|
||||
|
||||
protected Intent createResultIntent(Intent shortcutIntent, ResolveInfo resolveInfo,
|
||||
@VisibleForTesting
|
||||
Intent createResultIntent(Intent shortcutIntent, ResolveInfo resolveInfo,
|
||||
CharSequence label) {
|
||||
shortcutIntent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
|
||||
ShortcutManager sm = getSystemService(ShortcutManager.class);
|
||||
@@ -94,8 +98,8 @@ public class CreateShortcut extends LauncherActivity {
|
||||
|
||||
if (activityInfo.icon != 0) {
|
||||
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, createIcon(activityInfo.icon,
|
||||
R.layout.shortcut_badge,
|
||||
getResources().getDimensionPixelSize(R.dimen.shortcut_size)));
|
||||
R.layout.shortcut_badge,
|
||||
getResources().getDimensionPixelSize(R.dimen.shortcut_size)));
|
||||
}
|
||||
return intent;
|
||||
}
|
||||
@@ -112,7 +116,11 @@ public class CreateShortcut extends LauncherActivity {
|
||||
private Bitmap createIcon(int resource, int layoutRes, int size) {
|
||||
Context context = new ContextThemeWrapper(this, android.R.style.Theme_Material);
|
||||
View view = LayoutInflater.from(context).inflate(layoutRes, null);
|
||||
((ImageView) view.findViewById(android.R.id.icon)).setImageResource(resource);
|
||||
Drawable iconDrawable = getDrawable(resource);
|
||||
if (iconDrawable instanceof LayerDrawable) {
|
||||
iconDrawable = ((LayerDrawable) iconDrawable).getDrawable(1);
|
||||
}
|
||||
((ImageView) view.findViewById(android.R.id.icon)).setImageDrawable(iconDrawable);
|
||||
|
||||
int spec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
|
||||
view.measure(spec, spec);
|
||||
@@ -161,7 +161,7 @@ public class SavedAccessPointsWifiSettings extends SettingsPreferenceFragment
|
||||
final int accessPointsSize = accessPoints.size();
|
||||
for (int i = 0; i < accessPointsSize; ++i) {
|
||||
AccessPoint ap = accessPoints.get(i);
|
||||
String key = AccessPointPreference.generatePreferenceKey(ap);
|
||||
String key = ap.getKey();
|
||||
LongPressAccessPointPreference preference =
|
||||
(LongPressAccessPointPreference) getCachedPreference(key);
|
||||
if (preference == null) {
|
||||
|
||||
@@ -777,7 +777,7 @@ public class WifiSettings extends RestrictedSettingsFragment
|
||||
AccessPoint accessPoint = accessPoints.get(index);
|
||||
// Ignore access points that are out of range.
|
||||
if (accessPoint.isReachable()) {
|
||||
String key = AccessPointPreference.generatePreferenceKey(accessPoint);
|
||||
String key = accessPoint.getKey();
|
||||
hasAvailableAccessPoints = true;
|
||||
LongPressAccessPointPreference pref =
|
||||
(LongPressAccessPointPreference) getCachedPreference(key);
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
com.android.settings.display.ScreenZoomPreferenceFragmentForSetupWizard
|
||||
com.android.settings.search.indexing.FakeSettingsFragment
|
||||
com.android.settings.security.SecuritySettings
|
||||
com.android.settings.search.indexing.FakeSettingsFragment
|
||||
@@ -18,27 +18,18 @@ package com.android.settings.applications.appinfo;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
@@ -120,16 +111,14 @@ public class AppActionButtonPreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_shouldInitializeForceStopButton() {
|
||||
public void displayPreference_shouldSetButton2Invisible() {
|
||||
final PreferenceScreen screen = mock(PreferenceScreen.class);
|
||||
final ActionButtonPreference preference = spy(new ActionButtonPreference(mContext));
|
||||
when(screen.findPreference(mController.getPreferenceKey())).thenReturn(preference);
|
||||
|
||||
mController.displayPreference(screen);
|
||||
|
||||
verify(preference).setButton2Positive(false);
|
||||
verify(preference).setButton2Text(R.string.force_stop);
|
||||
verify(preference).setButton2Enabled(false);
|
||||
verify(preference).setButton2Visible(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -138,14 +127,12 @@ public class AppActionButtonPreferenceControllerTest {
|
||||
final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class);
|
||||
final ApplicationInfo info = new ApplicationInfo();
|
||||
appEntry.info = info;
|
||||
doNothing().when(mController).checkForceStop(appEntry, packageInfo);
|
||||
doNothing().when(mController).initUninstallButtons(appEntry, packageInfo);
|
||||
when(mFragment.getAppEntry()).thenReturn(appEntry);
|
||||
when(mFragment.getPackageInfo()).thenReturn(packageInfo);
|
||||
|
||||
mController.refreshUi();
|
||||
|
||||
verify(mController).checkForceStop(appEntry, packageInfo);
|
||||
verify(mController).initUninstallButtons(appEntry, packageInfo);
|
||||
}
|
||||
|
||||
@@ -198,71 +185,6 @@ public class AppActionButtonPreferenceControllerTest {
|
||||
assertThat(mController.initUninstallButtonForUserApp()).isFalse();
|
||||
}
|
||||
|
||||
// Tests that we don't show the force stop button for instant apps (they aren't allowed to run
|
||||
// when they aren't in the foreground).
|
||||
@Test
|
||||
public void checkForceStop_instantApps_shouldNotShowForceStop() {
|
||||
// Make this app appear to be instant.
|
||||
ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
|
||||
(InstantAppDataProvider) (i -> true));
|
||||
final PackageInfo packageInfo = mock(PackageInfo.class);
|
||||
final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class);
|
||||
final ApplicationInfo info = new ApplicationInfo();
|
||||
appEntry.info = info;
|
||||
|
||||
mController.checkForceStop(appEntry, packageInfo);
|
||||
|
||||
verify(mController.mActionButtons).setButton2Visible(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkForceStop_hasActiveAdmin_shouldDisableForceStop() {
|
||||
ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
|
||||
(InstantAppDataProvider) (i -> false));
|
||||
final String packageName = "Package1";
|
||||
final PackageInfo packageInfo = new PackageInfo();
|
||||
packageInfo.packageName = packageName;
|
||||
final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class);
|
||||
when(mDevicePolicyManager.packageHasActiveAdmins(packageName)).thenReturn(true);
|
||||
|
||||
mController.checkForceStop(appEntry, packageInfo);
|
||||
|
||||
verify(mController.mActionButtons).setButton2Enabled(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkForceStop_appRunning_shouldEnableForceStop() {
|
||||
ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
|
||||
(InstantAppDataProvider) (i -> false));
|
||||
final PackageInfo packageInfo = mock(PackageInfo.class);
|
||||
final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class);
|
||||
final ApplicationInfo info = new ApplicationInfo();
|
||||
appEntry.info = info;
|
||||
|
||||
mController.checkForceStop(appEntry, packageInfo);
|
||||
|
||||
verify(mController.mActionButtons).setButton2Enabled(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkForceStop_appStopped_shouldQueryPackageRestart() {
|
||||
ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
|
||||
(InstantAppDataProvider) (i -> false));
|
||||
final PackageInfo packageInfo = mock(PackageInfo.class);
|
||||
final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class);
|
||||
final ApplicationInfo info = new ApplicationInfo();
|
||||
appEntry.info = info;
|
||||
info.flags = ApplicationInfo.FLAG_STOPPED;
|
||||
info.packageName = "com.android.setting";
|
||||
|
||||
mController.checkForceStop(appEntry, packageInfo);
|
||||
|
||||
verify(mContext).sendOrderedBroadcastAsUser(argThat(intent-> intent != null
|
||||
&& intent.getAction().equals(Intent.ACTION_QUERY_PACKAGE_RESTART)),
|
||||
any(UserHandle.class), nullable(String.class), any(BroadcastReceiver.class),
|
||||
nullable(Handler.class), anyInt(), nullable(String.class), nullable(Bundle.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleDisableable_appIsHomeApp_buttonShouldNotWork() {
|
||||
final ApplicationInfo info = new ApplicationInfo();
|
||||
|
||||
@@ -42,7 +42,9 @@ import com.android.settings.R;
|
||||
import com.android.settings.TestConfig;
|
||||
import com.android.settings.applications.LayoutPreference;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settingslib.applications.AppUtils;
|
||||
import com.android.settingslib.applications.ApplicationsState;
|
||||
import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -53,6 +55,7 @@ import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||
@@ -103,7 +106,8 @@ public class AppHeaderViewPreferenceControllerTest {
|
||||
appEntry.info = info;
|
||||
when(mFragment.getAppEntry()).thenReturn(appEntry);
|
||||
when(mFragment.getPackageInfo()).thenReturn(packageInfo);
|
||||
|
||||
ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
|
||||
(InstantAppDataProvider) (i -> false));
|
||||
|
||||
final TextView title = mHeader.findViewById(R.id.entity_header_title);
|
||||
final TextView summary = mHeader.findViewById(R.id.entity_header_summary);
|
||||
|
||||
@@ -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.XmlParserUtils;
|
||||
import com.android.settings.security.SecuritySettings;
|
||||
import com.android.settings.security.SecuritySettingsV2;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
@@ -32,7 +31,6 @@ import org.robolectric.annotation.Config;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -47,25 +45,13 @@ public class XmlControllerAttributeTest {
|
||||
// List of classes that are too hard to mock in order to retrieve xml information.
|
||||
private final List<Class> illegalClasses = new ArrayList<>(
|
||||
Arrays.asList(
|
||||
SecuritySettings.class,
|
||||
SecuritySettingsV2.class
|
||||
SecuritySettings.class
|
||||
));
|
||||
|
||||
// List of XML that could be retrieved from the illegalClasses list.
|
||||
private final List<Integer> whitelistXml = new ArrayList<>(
|
||||
Arrays.asList(
|
||||
R.xml.security_settings_misc,
|
||||
R.xml.security_settings_lockscreen_profile,
|
||||
R.xml.security_settings_lockscreen,
|
||||
R.xml.security_settings_chooser,
|
||||
R.xml.security_settings_pattern_profile,
|
||||
R.xml.security_settings_pin_profile,
|
||||
R.xml.security_settings_password_profile,
|
||||
R.xml.security_settings_pattern,
|
||||
R.xml.security_settings_pin,
|
||||
R.xml.security_settings_password,
|
||||
R.xml.security_settings,
|
||||
R.xml.security_settings_status
|
||||
R.xml.security_dashboard_settings
|
||||
));
|
||||
|
||||
private static final String NO_VALID_CONSTRUCTOR_ERROR =
|
||||
|
||||
@@ -17,12 +17,19 @@ package com.android.settings.dashboard.suggestions;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.service.settings.suggestions.Suggestion;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -46,6 +53,7 @@ import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -200,7 +208,71 @@ public class SuggestionAdapterV2Test {
|
||||
mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
|
||||
mSuggestionHolder.itemView.findViewById(R.id.close_button).performClick();
|
||||
|
||||
verify(callback).onSuggestionClosed(suggestions.get(0));
|
||||
final Suggestion suggestion = suggestions.get(0);
|
||||
verify(mFeatureFactory.suggestionsFeatureProvider).dismissSuggestion(
|
||||
mActivity, mSuggestionControllerMixin, suggestion);
|
||||
verify(callback).onSuggestionClosed(suggestion);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindViewHolder_differentPackage_shouldNotTintIcon()
|
||||
throws PendingIntent.CanceledException {
|
||||
final Icon icon = mock(Icon.class);
|
||||
when(icon.getResPackage()).thenReturn("pkg1");
|
||||
when(mActivity.getPackageName()).thenReturn("pkg2");
|
||||
final Suggestion suggestion = new Suggestion.Builder("pkg1")
|
||||
.setPendingIntent(mock(PendingIntent.class))
|
||||
.setIcon(icon)
|
||||
.build();
|
||||
final List<Suggestion> suggestions = new ArrayList<>();
|
||||
suggestions.add(suggestion);
|
||||
mSuggestionAdapter = new SuggestionAdapterV2(mActivity, mSuggestionControllerMixin,
|
||||
null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
|
||||
mSuggestionAdapter.setSuggestions(suggestions);
|
||||
mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
|
||||
new FrameLayout(RuntimeEnvironment.application),
|
||||
mSuggestionAdapter.getItemViewType(0));
|
||||
DashboardAdapterV2.IconCache cache = mock(DashboardAdapterV2.IconCache.class);
|
||||
final Drawable drawable = mock(Drawable.class);
|
||||
when(cache.getIcon(icon)).thenReturn(drawable);
|
||||
ReflectionHelpers.setField(mSuggestionAdapter, "mCache", cache);
|
||||
|
||||
mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
|
||||
|
||||
verify(drawable, never()).setTint(anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindViewHolder_samePackage_shouldTintIcon()
|
||||
throws PendingIntent.CanceledException {
|
||||
final Icon icon = mock(Icon.class);
|
||||
final String packageName = "pkg1";
|
||||
when(icon.getResPackage()).thenReturn(packageName);
|
||||
when(mActivity.getPackageName()).thenReturn(packageName);
|
||||
final Suggestion suggestion = new Suggestion.Builder(packageName)
|
||||
.setPendingIntent(mock(PendingIntent.class))
|
||||
.setIcon(icon)
|
||||
.build();
|
||||
final List<Suggestion> suggestions = new ArrayList<>();
|
||||
suggestions.add(suggestion);
|
||||
mSuggestionAdapter = new SuggestionAdapterV2(mActivity, mSuggestionControllerMixin,
|
||||
null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
|
||||
mSuggestionAdapter.setSuggestions(suggestions);
|
||||
mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
|
||||
new FrameLayout(RuntimeEnvironment.application),
|
||||
mSuggestionAdapter.getItemViewType(0));
|
||||
DashboardAdapterV2.IconCache cache = mock(DashboardAdapterV2.IconCache.class);
|
||||
final Drawable drawable = mock(Drawable.class);
|
||||
when(cache.getIcon(icon)).thenReturn(drawable);
|
||||
ReflectionHelpers.setField(mSuggestionAdapter, "mCache", cache);
|
||||
TypedArray typedArray = mock(TypedArray.class);
|
||||
final int colorAccent = 1234;
|
||||
when(mActivity.obtainStyledAttributes(any())).thenReturn(typedArray);
|
||||
when(typedArray.getColor(anyInt(), anyInt())).thenReturn(colorAccent);
|
||||
|
||||
mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
|
||||
|
||||
verify(drawable).setTint(colorAccent);
|
||||
}
|
||||
|
||||
private void setupSuggestions(Context context, List<Suggestion> suggestions) {
|
||||
|
||||
@@ -29,8 +29,8 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.NetworkPolicyManager;
|
||||
import android.os.Bundle;
|
||||
import android.support.v14.preference.SwitchPreference;
|
||||
import android.support.v7.preference.PreferenceManager;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
import android.util.ArraySet;
|
||||
@@ -40,8 +40,11 @@ import com.android.settings.TestConfig;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
|
||||
import com.android.settings.testutils.shadow.ShadowRestrictedLockUtils;
|
||||
import com.android.settings.widget.EntityHeaderController;
|
||||
import com.android.settingslib.AppItem;
|
||||
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
import com.android.settingslib.RestrictedSwitchPreference;
|
||||
import com.android.settingslib.wrapper.PackageManagerWrapper;
|
||||
|
||||
import org.junit.After;
|
||||
@@ -57,7 +60,10 @@ import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
|
||||
shadows = ShadowEntityHeaderController.class)
|
||||
shadows = {
|
||||
ShadowEntityHeaderController.class,
|
||||
ShadowRestrictedLockUtils.class
|
||||
})
|
||||
public class AppDataUsageTest {
|
||||
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
@@ -134,7 +140,7 @@ public class AppDataUsageTest {
|
||||
public void changePreference_backgroundData_shouldUpdateUI() {
|
||||
mFragment = spy(new AppDataUsage());
|
||||
final AppItem appItem = new AppItem(123456789);
|
||||
final SwitchPreference pref = mock(SwitchPreference.class);
|
||||
final RestrictedSwitchPreference pref = mock(RestrictedSwitchPreference.class);
|
||||
final DataSaverBackend dataSaverBackend = mock(DataSaverBackend.class);
|
||||
ReflectionHelpers.setField(mFragment, "mAppItem", appItem);
|
||||
ReflectionHelpers.setField(mFragment, "mRestrictBackground", pref);
|
||||
@@ -146,4 +152,31 @@ public class AppDataUsageTest {
|
||||
|
||||
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;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.os.Process;
|
||||
import android.support.v7.preference.PreferenceManager;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.TestConfig;
|
||||
import com.android.settings.datausage.AppStateDataUsageBridge.DataUsageState;
|
||||
import com.android.settings.datausage.UnrestrictedDataAccess.AccessPreference;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settingslib.applications.ApplicationsState;
|
||||
import com.android.settings.testutils.shadow.ShadowRestrictedLockUtils;
|
||||
import com.android.settingslib.applications.ApplicationsState.AppEntry;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
|
||||
shadows = {
|
||||
ShadowRestrictedLockUtils.class
|
||||
})
|
||||
public class UnrestrictedDataAccessTest {
|
||||
|
||||
@Mock
|
||||
private ApplicationsState.AppEntry mAppEntry;
|
||||
private AppEntry mAppEntry;
|
||||
private UnrestrictedDataAccess mFragment;
|
||||
private FakeFeatureFactory mFeatureFactory;
|
||||
@Mock
|
||||
private PreferenceScreen mPreferenceScreen;
|
||||
@Mock
|
||||
private PreferenceManager mPreferenceManager;
|
||||
@Mock
|
||||
private DataSaverBackend mDataSaverBackend;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||
mFragment = new UnrestrictedDataAccess();
|
||||
mFragment = spy(new UnrestrictedDataAccess());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -80,4 +107,66 @@ public class UnrestrictedDataAccessTest {
|
||||
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
|
||||
private PreferenceScreen mScreen;
|
||||
@Mock
|
||||
private SecuritySettingsV2 mHost;
|
||||
private SecuritySettings mHost;
|
||||
|
||||
private FakeFeatureFactory mFeatureFactory;
|
||||
private Context mContext;
|
||||
|
||||
@@ -16,192 +16,51 @@
|
||||
|
||||
package com.android.settings.security;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.TestConfig;
|
||||
import com.android.settings.security.trustagent.TrustAgentManager;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.shadow.ShadowTileUtils;
|
||||
import com.android.settingslib.drawer.DashboardCategory;
|
||||
import com.android.settingslib.drawer.Tile;
|
||||
import com.android.settingslib.drawer.TileUtils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowLooper;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||
public class SecurityFeatureProviderImplTest {
|
||||
|
||||
private static final String MOCK_KEY = "key";
|
||||
private static final String MOCK_SUMMARY = "summary";
|
||||
private static final String URI_GET_SUMMARY = "content://package/text/summary";
|
||||
private static final String URI_GET_ICON = "content://package/icon/my_icon";
|
||||
|
||||
@Mock
|
||||
private Drawable mMockDrawable;
|
||||
@Mock
|
||||
private Context mContext;
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
@Mock
|
||||
private Resources mResources;
|
||||
|
||||
private SecurityFeatureProviderImpl mImpl;
|
||||
|
||||
@Before
|
||||
public void setUp() throws PackageManager.NameNotFoundException {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mImpl = new SecurityFeatureProviderImpl();
|
||||
when(mContext.getPackageManager()).thenReturn(mPackageManager);
|
||||
when(mPackageManager.getResourcesForApplication(anyString())).thenReturn(mResources);
|
||||
when(mResources.getDrawable(anyInt(), any())).thenReturn(mMockDrawable);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateTilesData_shouldNotProcessEmptyScreenOrTiles() {
|
||||
mImpl.updatePreferencesToRunOnWorkerThread(mContext, null, null);
|
||||
ShadowLooper.runUiThreadTasks();
|
||||
mImpl.updatePreferencesToRunOnWorkerThread(
|
||||
mContext, new PreferenceScreen(mContext, null), null);
|
||||
ShadowLooper.runUiThreadTasks();
|
||||
verifyNoMoreInteractions(mPackageManager);
|
||||
public void getTrustAgentManager_shouldReturnCache() {
|
||||
final TrustAgentManager m1 = mImpl.getTrustAgentManager();
|
||||
final TrustAgentManager m2 = mImpl.getTrustAgentManager();
|
||||
|
||||
assertThat(m1).isSameAs(m2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateTilesData_shouldNotProcessNonMatchingPreference() {
|
||||
DashboardCategory dashboardCategory = new DashboardCategory();
|
||||
dashboardCategory.addTile(new Tile());
|
||||
mImpl.updatePreferencesToRunOnWorkerThread(
|
||||
mContext, getPreferenceScreen(), dashboardCategory);
|
||||
ShadowLooper.runUiThreadTasks();
|
||||
verifyNoMoreInteractions(mPackageManager);
|
||||
public void getLockPatternUtils_shouldReturnCache() {
|
||||
final LockPatternUtils l1 = mImpl.getLockPatternUtils(mContext);
|
||||
final LockPatternUtils l2 = mImpl.getLockPatternUtils(mContext);
|
||||
|
||||
assertThat(l1).isSameAs(l2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateTilesData_shouldNotProcessMatchingPreferenceWithNoData() {
|
||||
mImpl.updatePreferencesToRunOnWorkerThread(
|
||||
mContext, getPreferenceScreen(), getDashboardCategory());
|
||||
ShadowLooper.runUiThreadTasks();
|
||||
verifyNoMoreInteractions(mPackageManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = {
|
||||
ShadowTileUtils.class,
|
||||
})
|
||||
public void updateTilesData_shouldUpdateMatchingPreference() {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(TileUtils.META_DATA_PREFERENCE_ICON_URI, URI_GET_ICON);
|
||||
bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY_URI, URI_GET_SUMMARY);
|
||||
|
||||
PreferenceScreen screen = getPreferenceScreen();
|
||||
DashboardCategory dashboardCategory = getDashboardCategory();
|
||||
dashboardCategory.getTile(0).intent = new Intent().setPackage("package");
|
||||
dashboardCategory.getTile(0).metaData = bundle;
|
||||
|
||||
mImpl.updatePreferencesToRunOnWorkerThread(mContext, screen, dashboardCategory);
|
||||
ShadowLooper.runUiThreadTasks();
|
||||
verify(screen.findPreference(MOCK_KEY)).setIcon(mMockDrawable);
|
||||
verify(screen.findPreference(MOCK_KEY)).setSummary(MOCK_SUMMARY);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = {
|
||||
ShadowTileUtils.class,
|
||||
})
|
||||
public void updateTilesData_shouldNotUpdateAlreadyUpdatedPreference() {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(TileUtils.META_DATA_PREFERENCE_ICON_URI, URI_GET_ICON);
|
||||
bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY_URI, URI_GET_SUMMARY);
|
||||
|
||||
PreferenceScreen screen = getPreferenceScreen();
|
||||
when(screen.findPreference(MOCK_KEY).getSummary()).thenReturn(MOCK_SUMMARY);
|
||||
when(screen.findPreference(MOCK_KEY).getIcon()).thenReturn(mMockDrawable);
|
||||
|
||||
DashboardCategory dashboardCategory = getDashboardCategory();
|
||||
dashboardCategory.getTile(0).intent = new Intent().setPackage("package");
|
||||
dashboardCategory.getTile(0).metaData = bundle;
|
||||
|
||||
mImpl.updatePreferencesToRunOnWorkerThread(mContext, screen, dashboardCategory);
|
||||
ShadowLooper.runUiThreadTasks();
|
||||
verify(screen.findPreference(MOCK_KEY), never()).setSummary(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initPreferences_shouldLoadDefaults() {
|
||||
PreferenceScreen screen = getPreferenceScreen();
|
||||
DashboardCategory dashboardCategory = getDashboardCategory();
|
||||
dashboardCategory.getTile(0).metaData = new Bundle();
|
||||
|
||||
mImpl.initPreferences(mContext, screen, dashboardCategory);
|
||||
verify(screen.findPreference(MOCK_KEY)).setIcon(SecurityFeatureProviderImpl.DEFAULT_ICON);
|
||||
verify(screen.findPreference(MOCK_KEY))
|
||||
.setSummary(mContext.getString(R.string.summary_placeholder));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = {
|
||||
ShadowTileUtils.class,
|
||||
})
|
||||
public void initPreferences_shouldLoadCached() {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(TileUtils.META_DATA_PREFERENCE_ICON_URI, URI_GET_ICON);
|
||||
bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY_URI, URI_GET_SUMMARY);
|
||||
|
||||
PreferenceScreen screen = getPreferenceScreen();
|
||||
DashboardCategory dashboardCategory = getDashboardCategory();
|
||||
dashboardCategory.getTile(0).metaData = bundle;
|
||||
|
||||
SecurityFeatureProviderImpl.sIconCache.put(
|
||||
URI_GET_ICON,
|
||||
ShadowTileUtils.getIconFromUri(null, null, null, null));
|
||||
SecurityFeatureProviderImpl.sSummaryCache.put(
|
||||
URI_GET_SUMMARY,
|
||||
MOCK_SUMMARY);
|
||||
|
||||
mImpl.initPreferences(mContext, screen, dashboardCategory);
|
||||
verify(screen.findPreference(MOCK_KEY)).setIcon(mMockDrawable);
|
||||
verify(screen.findPreference(MOCK_KEY)).setSummary(MOCK_SUMMARY);
|
||||
}
|
||||
|
||||
private PreferenceScreen getPreferenceScreen() {
|
||||
final PreferenceScreen screen = mock(PreferenceScreen.class);
|
||||
final Preference pref = mock(Preference.class);
|
||||
when(screen.findPreference(MOCK_KEY)).thenReturn(pref);
|
||||
when(pref.getKey()).thenReturn(MOCK_KEY);
|
||||
return screen;
|
||||
}
|
||||
|
||||
private static DashboardCategory getDashboardCategory() {
|
||||
DashboardCategory dashboardCategory = new DashboardCategory();
|
||||
Tile tile = new Tile();
|
||||
tile.key = MOCK_KEY;
|
||||
dashboardCategory.addTile(tile);
|
||||
return dashboardCategory;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,34 +16,18 @@
|
||||
|
||||
package com.android.settings.security;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.os.UserManager.EnforcingUser;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.TestConfig;
|
||||
import com.android.settings.dashboard.SummaryLoader;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.XmlTestUtils;
|
||||
import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
|
||||
import com.android.settings.testutils.shadow.ShadowUserManager;
|
||||
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
import com.android.settingslib.RestrictedSwitchPreference;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -51,123 +35,65 @@ import org.junit.runner.RunWith;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
|
||||
shadows = {
|
||||
ShadowLockPatternUtils.class,
|
||||
ShadowUserManager.class,
|
||||
})
|
||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||
public class SecuritySettingsTest {
|
||||
|
||||
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private Context mContext;
|
||||
@Mock
|
||||
private SummaryLoader mSummaryLoader;
|
||||
|
||||
@Mock
|
||||
private FingerprintManager mFingerprintManager;
|
||||
private SecuritySettings.SummaryProvider mSummaryProvider;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
FakeFeatureFactory.setupForTest();
|
||||
when(mContext.getSystemService(Context.FINGERPRINT_SERVICE))
|
||||
.thenReturn(mFingerprintManager);
|
||||
|
||||
mSummaryProvider = new SecuritySettings.SummaryProvider(mContext, mSummaryLoader);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitTrustAgentPreference_secure_shouldSetSummaryToNumberOfTrustAgent() {
|
||||
final Preference preference = mock(Preference.class);
|
||||
final PreferenceScreen screen = mock(PreferenceScreen.class);
|
||||
when(screen.findPreference(SecuritySettings.KEY_MANAGE_TRUST_AGENTS))
|
||||
.thenReturn(preference);
|
||||
final LockPatternUtils utils = mock(LockPatternUtils.class);
|
||||
when(utils.isSecure(anyInt())).thenReturn(true);
|
||||
final Context context = ShadowApplication.getInstance().getApplicationContext();
|
||||
final Activity activity = mock(Activity.class);
|
||||
when(activity.getResources()).thenReturn(context.getResources());
|
||||
final SecuritySettings securitySettings = spy(new SecuritySettings());
|
||||
when(securitySettings.getActivity()).thenReturn(activity);
|
||||
public void testSummaryProvider_notListening() {
|
||||
mSummaryProvider.setListening(false);
|
||||
|
||||
ReflectionHelpers.setField(securitySettings, "mLockPatternUtils", utils);
|
||||
|
||||
securitySettings.initTrustAgentPreference(screen, 0);
|
||||
verify(preference).setSummary(R.string.manage_trust_agents_summary);
|
||||
|
||||
securitySettings.initTrustAgentPreference(screen, 2);
|
||||
verify(preference).setSummary(context.getResources().getQuantityString(
|
||||
R.plurals.manage_trust_agents_summary_on, 2, 2));
|
||||
verifyNoMoreInteractions(mSummaryLoader);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonIndexableKeys_existInXmlLayout() {
|
||||
final Context context = spy(RuntimeEnvironment.application);
|
||||
UserManager manager = mock(UserManager.class);
|
||||
when(manager.isAdminUser()).thenReturn(false);
|
||||
doReturn(manager).when(context).getSystemService(Context.USER_SERVICE);
|
||||
final List<String> niks = SecuritySettings.SEARCH_INDEX_DATA_PROVIDER
|
||||
.getNonIndexableKeys(context);
|
||||
public void testSummaryProvider_hasFingerPrint_hasStaticSummary() {
|
||||
when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
|
||||
.thenReturn(true);
|
||||
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
|
||||
|
||||
final List<String> keys = XmlTestUtils.getKeysFromPreferenceXml(context,
|
||||
R.xml.security_settings_misc);
|
||||
keys.addAll(XmlTestUtils.getKeysFromPreferenceXml(context,
|
||||
R.xml.location_settings));
|
||||
keys.addAll(XmlTestUtils.getKeysFromPreferenceXml(context,
|
||||
R.xml.encryption_and_credential));
|
||||
mSummaryProvider.setListening(true);
|
||||
|
||||
assertThat(keys).containsAllIn(niks);
|
||||
verify(mContext).getString(R.string.security_dashboard_summary);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnifyLockRestriction() {
|
||||
// Set up instance under test.
|
||||
final Context context = spy(RuntimeEnvironment.application);
|
||||
final SecuritySettings securitySettings = spy(new SecuritySettings());
|
||||
when(securitySettings.getContext()).thenReturn(context);
|
||||
public void testSummaryProvider_noFpFeature_shouldSetSummaryWithNoFingerprint() {
|
||||
when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
|
||||
.thenReturn(false);
|
||||
|
||||
final int userId = 123;
|
||||
ReflectionHelpers.setField(securitySettings, "mProfileChallengeUserId", userId);
|
||||
mSummaryProvider.setListening(true);
|
||||
|
||||
final LockPatternUtils utils = mock(LockPatternUtils.class);
|
||||
when(utils.isSeparateProfileChallengeEnabled(userId)).thenReturn(true);
|
||||
ReflectionHelpers.setField(securitySettings, "mLockPatternUtils", utils);
|
||||
verify(mContext).getString(R.string.security_dashboard_summary_no_fingerprint);
|
||||
}
|
||||
|
||||
final RestrictedSwitchPreference unifyProfile = mock(RestrictedSwitchPreference.class);
|
||||
ReflectionHelpers.setField(securitySettings, "mUnifyProfile", unifyProfile);
|
||||
@Test
|
||||
public void testSummaryProvider_noFpHardware_shouldSetSummaryWithNoFingerprint() {
|
||||
when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
|
||||
.thenReturn(true);
|
||||
when(mFingerprintManager.isHardwareDetected()).thenReturn(false);
|
||||
|
||||
// Pretend that no admins enforce the restriction.
|
||||
ShadowUserManager.getShadow().setUserRestrictionSources(
|
||||
UserManager.DISALLOW_UNIFIED_PASSWORD,
|
||||
UserHandle.of(userId),
|
||||
Collections.emptyList());
|
||||
mSummaryProvider.setListening(true);
|
||||
|
||||
securitySettings.updateUnificationPreference();
|
||||
|
||||
verify(unifyProfile).setDisabledByAdmin(null);
|
||||
|
||||
reset(unifyProfile);
|
||||
|
||||
// Pretend that the restriction is enforced by several admins. Having just one would
|
||||
// require more mocking of implementation details.
|
||||
final EnforcingUser enforcer1 = new EnforcingUser(
|
||||
userId, UserManager.RESTRICTION_SOURCE_PROFILE_OWNER);
|
||||
final EnforcingUser enforcer2 = new EnforcingUser(
|
||||
UserHandle.USER_SYSTEM, UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
|
||||
ShadowUserManager.getShadow().setUserRestrictionSources(
|
||||
UserManager.DISALLOW_UNIFIED_PASSWORD,
|
||||
UserHandle.of(userId),
|
||||
Arrays.asList(enforcer1, enforcer2));
|
||||
|
||||
securitySettings.updateUnificationPreference();
|
||||
|
||||
verify(unifyProfile).setDisabledByAdmin(EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN);
|
||||
verify(mContext).getString(R.string.security_dashboard_summary_no_fingerprint);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.settings.TestConfig;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settings.security.SecuritySettingsV2;
|
||||
import com.android.settings.security.SecuritySettings;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
@@ -69,7 +69,7 @@ public class TrustAgentListPreferenceControllerTest {
|
||||
@Mock
|
||||
private PreferenceCategory mCategory;
|
||||
@Mock
|
||||
private SecuritySettingsV2 mFragment;
|
||||
private SecuritySettings mFragment;
|
||||
|
||||
private Lifecycle mLifecycle;
|
||||
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_SRC_FILES := $(call all-java-files-under, src)
|
||||
LOCAL_MODULE_TAGS := tests
|
||||
LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
|
||||
|
||||
LOCAL_JAVA_LIBRARIES := \
|
||||
android.test.runner \
|
||||
android.test.base
|
||||
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := \
|
||||
android-support-test \
|
||||
app-helpers-core \
|
||||
launcher-helper-lib \
|
||||
settings-helper \
|
||||
timeresult-helper-lib \
|
||||
ub-uiautomator \
|
||||
sysui-helper \
|
||||
metrics-helper-lib \
|
||||
platform-test-annotations \
|
||||
settings-helper \
|
||||
sysui-helper \
|
||||
timeresult-helper-lib \
|
||||
truth-prebuilt \
|
||||
ub-uiautomator \
|
||||
|
||||
#LOCAL_SDK_VERSION := current
|
||||
|
||||
|
||||
@@ -16,57 +16,55 @@
|
||||
|
||||
package com.android.settings.ui;
|
||||
|
||||
import static com.android.settings.ui.testutils.SettingsTestUtils.SETTINGS_PACKAGE;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static com.google.common.truth.Truth.assertWithMessage;
|
||||
|
||||
import android.app.Instrumentation;
|
||||
import android.content.Intent;
|
||||
import android.os.RemoteException;
|
||||
import android.provider.Settings;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.filters.SmallTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.support.test.uiautomator.By;
|
||||
import android.support.test.uiautomator.Direction;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.UiObject2;
|
||||
import android.support.test.uiautomator.Until;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
import android.test.suitebuilder.annotation.Suppress;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
/** Verifies basic functionality of the About Phone screen */
|
||||
public class AboutPhoneSettingsTests extends InstrumentationTestCase {
|
||||
private static final boolean LOCAL_LOGV = false;
|
||||
private static final String TAG = "AboutPhoneSettingsTest";
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class AboutPhoneSettingsTests {
|
||||
private static final int TIMEOUT = 2000;
|
||||
private static final String SETTINGS_PACKAGE = "com.android.settings";
|
||||
|
||||
private UiDevice mDevice;
|
||||
|
||||
// TODO: retrieve using name/ids from com.android.settings package
|
||||
private static final String[] sResourceTexts = {
|
||||
"Status",
|
||||
"Legal information",
|
||||
"Regulatory labels",
|
||||
"Model",
|
||||
"Android version",
|
||||
"Android security patch level",
|
||||
"Baseband version",
|
||||
"Kernel version",
|
||||
"Build number"
|
||||
"Phone number",
|
||||
"SIM status",
|
||||
"Model & hardware",
|
||||
"MEID",
|
||||
"Android version"
|
||||
};
|
||||
|
||||
private static final String[] sClickableResourceTexts = {
|
||||
"Status", "Legal information", "Regulatory labels",
|
||||
};
|
||||
private UiDevice mDevice;
|
||||
private Instrumentation mInstrumentation;
|
||||
|
||||
@Override
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
if (LOCAL_LOGV) {
|
||||
Log.d(TAG, "-------");
|
||||
}
|
||||
super.setUp();
|
||||
mDevice = UiDevice.getInstance(getInstrumentation());
|
||||
mInstrumentation = InstrumentationRegistry.getInstrumentation();
|
||||
mDevice = UiDevice.getInstance(mInstrumentation);
|
||||
try {
|
||||
mDevice.setOrientationNatural();
|
||||
} catch (RemoteException e) {
|
||||
@@ -82,84 +80,40 @@ public class AboutPhoneSettingsTests extends InstrumentationTestCase {
|
||||
UiObject2 view =
|
||||
mDevice.wait(
|
||||
Until.findObject(By.res(SETTINGS_PACKAGE + ":id/main_content")), TIMEOUT);
|
||||
assertNotNull("Could not find main About Phone screen", view);
|
||||
assertThat(view).isNotNull();
|
||||
view.scroll(Direction.UP, 1.0f);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
// Adding an extra pressBack so we exit About Phone Settings
|
||||
// and finish the test cleanly
|
||||
mDevice.pressBack();
|
||||
mDevice.pressHome(); // finish settings activity
|
||||
mDevice.waitForIdle(TIMEOUT * 2); // give UI time to finish animating
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllMenuEntriesExist() throws Exception {
|
||||
searchForItemsAndTakeAction(mDevice, sResourceTexts);
|
||||
}
|
||||
|
||||
private void launchAboutPhoneSettings(String aboutSetting) throws Exception {
|
||||
Intent aboutIntent = new Intent(aboutSetting);
|
||||
aboutIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
getInstrumentation().getContext().startActivity(aboutIntent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callable actions that can be taken when a UIObject2 is found
|
||||
*
|
||||
* @param device The current UiDevice
|
||||
* @param item The UiObject2 that was found and can be acted on
|
||||
*
|
||||
* @return {@code true} if the call was successful, and {@code false} otherwise
|
||||
*/
|
||||
public interface UIObject2Callback {
|
||||
boolean call(UiDevice device, UiObject2 item) throws Exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clicks the given item and then presses the Back button
|
||||
*
|
||||
* <p>Used to test whether a given UiObject2 can be successfully clicked.
|
||||
* Presses Back to restore state to the previous screen.
|
||||
*
|
||||
* @param device The device that can be used to press Back
|
||||
* @param item The item to click
|
||||
*
|
||||
* @return {@code true} if clicking the item succeeded, and {@code false} otherwise
|
||||
*/
|
||||
public class UiObject2Clicker implements UIObject2Callback {
|
||||
public boolean call(UiDevice device, UiObject2 item) throws Exception {
|
||||
item.click();
|
||||
Thread.sleep(TIMEOUT * 2); // give UI time to finish animating
|
||||
boolean pressWorked = device.pressBack();
|
||||
Thread.sleep(TIMEOUT * 2);
|
||||
return pressWorked;
|
||||
}
|
||||
InstrumentationRegistry.getTargetContext().startActivity(aboutIntent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes items found in the view and optionally takes some action.
|
||||
*
|
||||
* @param device The current UiDevice
|
||||
* @param itemsLeftToFind The items to search for in the current view
|
||||
* @param action Action to call on each item that is found; pass {@code null} to take no action
|
||||
*/
|
||||
private void removeItemsAndTakeAction(
|
||||
UiDevice device, ArrayList<String> itemsLeftToFind, UIObject2Callback action) throws Exception {
|
||||
private void removeItemsAndTakeAction(UiDevice device, ArrayList<String> itemsLeftToFind)
|
||||
throws Exception {
|
||||
for (Iterator<String> iterator = itemsLeftToFind.iterator(); iterator.hasNext(); ) {
|
||||
String itemText = iterator.next();
|
||||
UiObject2 item = device.wait(Until.findObject(By.text(itemText)), TIMEOUT);
|
||||
if (item != null) {
|
||||
if (LOCAL_LOGV) {
|
||||
Log.d(TAG, itemText + " is present");
|
||||
}
|
||||
iterator.remove();
|
||||
if (action != null) {
|
||||
boolean success = action.call(device, item);
|
||||
assertTrue("Calling action after " + itemText + " did not work", success);
|
||||
}
|
||||
} else {
|
||||
if (LOCAL_LOGV) {
|
||||
Log.d(TAG, "Could not find " + itemText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -169,25 +123,18 @@ public class AboutPhoneSettingsTests extends InstrumentationTestCase {
|
||||
*
|
||||
* <p>Will scroll down the screen until it has found all elements or reached the bottom.
|
||||
* This allows elements to be found and acted on even if they change order.
|
||||
*
|
||||
* @param device The current UiDevice
|
||||
* @param itemsToFind The items to search for in the current view
|
||||
* @param action Action to call on each item that is found; pass {@code null} to take no action
|
||||
*/
|
||||
public void searchForItemsAndTakeAction(UiDevice device, String[] itemsToFind, UIObject2Callback action)
|
||||
private void searchForItemsAndTakeAction(UiDevice device, String[] itemsToFind)
|
||||
throws Exception {
|
||||
|
||||
ArrayList<String> itemsLeftToFind = new ArrayList<String>(Arrays.asList(itemsToFind));
|
||||
assertFalse(
|
||||
"There must be at least one item to search for on the screen!",
|
||||
itemsLeftToFind.isEmpty());
|
||||
ArrayList<String> itemsLeftToFind = new ArrayList<>(Arrays.asList(itemsToFind));
|
||||
assertWithMessage("There must be at least one item to search for on the screen!")
|
||||
.that(itemsLeftToFind)
|
||||
.isNotEmpty();
|
||||
|
||||
if (LOCAL_LOGV) {
|
||||
Log.d(TAG, "items: " + TextUtils.join(", ", itemsLeftToFind));
|
||||
}
|
||||
boolean canScrollDown = true;
|
||||
while (canScrollDown && !itemsLeftToFind.isEmpty()) {
|
||||
removeItemsAndTakeAction(device, itemsLeftToFind, action);
|
||||
removeItemsAndTakeAction(device, itemsLeftToFind);
|
||||
|
||||
// when we've finished searching the current view, scroll down
|
||||
UiObject2 view =
|
||||
@@ -201,24 +148,11 @@ public class AboutPhoneSettingsTests extends InstrumentationTestCase {
|
||||
}
|
||||
}
|
||||
// check the last items once we have reached the bottom of the view
|
||||
removeItemsAndTakeAction(device, itemsLeftToFind, action);
|
||||
removeItemsAndTakeAction(device, itemsLeftToFind);
|
||||
|
||||
assertTrue(
|
||||
"The following items were not found on the screen: "
|
||||
+ TextUtils.join(", ", itemsLeftToFind),
|
||||
itemsLeftToFind.isEmpty());
|
||||
}
|
||||
|
||||
@MediumTest // UI interaction
|
||||
public void testAllMenuEntriesExist() throws Exception {
|
||||
searchForItemsAndTakeAction(mDevice, sResourceTexts, null);
|
||||
}
|
||||
|
||||
// Suppressing this test as it might be causing other test failures
|
||||
// Will verify that this test is the cause before proceeding with solution
|
||||
@Suppress
|
||||
@MediumTest // UI interaction
|
||||
public void testClickableEntriesCanBeClicked() throws Exception {
|
||||
searchForItemsAndTakeAction(mDevice, sClickableResourceTexts, new UiObject2Clicker());
|
||||
assertWithMessage("The following items were not found on the screen: "
|
||||
+ TextUtils.join(", ", itemsLeftToFind))
|
||||
.that(itemsLeftToFind)
|
||||
.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package com.android.settings.ui;
|
||||
|
||||
import static com.android.settings.ui.testutils.SettingsTestUtils.SETTINGS_PACKAGE;
|
||||
import static com.android.settings.ui.testutils.SettingsTestUtils.TIMEOUT;
|
||||
|
||||
import android.os.RemoteException;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.provider.Settings;
|
||||
@@ -36,9 +39,6 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static com.android.settings.ui.testutils.SettingsTestUtils.SETTINGS_PACKAGE;
|
||||
import static com.android.settings.ui.testutils.SettingsTestUtils.TIMEOUT;
|
||||
|
||||
@MediumTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class HomepageDisplayTests {
|
||||
@@ -52,19 +52,17 @@ public class HomepageDisplayTests {
|
||||
"Sound",
|
||||
"Storage",
|
||||
"Security & location",
|
||||
"Users & accounts",
|
||||
"Accounts",
|
||||
"Accessibility",
|
||||
"System",
|
||||
"Support & tips"
|
||||
};
|
||||
|
||||
private UiDevice mDevice;
|
||||
private SettingsHelper mSettingsHelper;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
|
||||
mSettingsHelper = new SettingsHelper();
|
||||
try {
|
||||
mDevice.setOrientationNatural();
|
||||
} catch (RemoteException e) {
|
||||
|
||||
@@ -66,7 +66,7 @@ public class SecuritySettingsLaunchTest {
|
||||
public void launchSecuritySettings() throws Exception {
|
||||
// Launch Settings
|
||||
SettingsHelper.launchSettingsPage(
|
||||
InstrumentationRegistry.getContext(), Settings.ACTION_SECURITY_SETTINGS);
|
||||
InstrumentationRegistry.getTargetContext(), Settings.ACTION_SECURITY_SETTINGS);
|
||||
mHelper.scrollVert(false);
|
||||
for (String category : CATEGORIES) {
|
||||
SettingsTestUtils.assertTitleMatch(mDevice, category);
|
||||
|
||||
@@ -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;
|
||||
|
||||
import static com.android.settings.ui.testutils.SettingsTestUtils.SETTINGS_PACKAGE;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.RemoteException;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.provider.Settings;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.support.test.uiautomator.By;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.Until;
|
||||
import android.system.helpers.CommandsHelper;
|
||||
import android.system.helpers.SettingsHelper;
|
||||
import android.support.test.uiautomator.By;
|
||||
import android.support.test.uiautomator.BySelector;
|
||||
import android.support.test.uiautomator.Direction;
|
||||
import android.support.test.uiautomator.StaleObjectException;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.UiObject2;
|
||||
import android.support.test.uiautomator.Until;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
import android.test.suitebuilder.annotation.Suppress;
|
||||
import android.util.Log;
|
||||
import junit.framework.AssertionFailedError;
|
||||
|
||||
public class WirelessNetworkSettingsTests extends InstrumentationTestCase {
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
/**
|
||||
* Core tests for Wifi Settings.
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@MediumTest
|
||||
public class WirelessNetworkSettingsTests {
|
||||
// These back button presses are performed in tearDown() to exit Wifi
|
||||
// Settings sub-menus that a test might finish in. This number should be
|
||||
// high enough to account for the deepest sub-menu a test might enter.
|
||||
private static final int NUM_BACK_BUTTON_PRESSES = 5;
|
||||
private static final int TIMEOUT = 2000;
|
||||
private static final int TIMEOUT = 20000;
|
||||
private static final int SLEEP_TIME = 500;
|
||||
private static final String AIRPLANE_MODE_BROADCAST =
|
||||
"am broadcast -a android.intent.action.AIRPLANE_MODE";
|
||||
private static final String TAG="WirelessNetworkSettingsTests";
|
||||
private static final String TAG = "WirelessNetworkTests";
|
||||
|
||||
// Note: The values of these variables might affect flakiness in tests that involve
|
||||
// scrolling. Adjust where necessary.
|
||||
private static final float SCROLL_UP_PERCENT = 10.0f;
|
||||
private static final float SCROLL_DOWN_PERCENT = 0.5f;
|
||||
private static final int MAX_SCROLL_ATTEMPTS = 10;
|
||||
private static final int MAX_ADD_NETWORK_BUTTON_ATTEMPTS = 3;
|
||||
private static final int SCROLL_SPEED = 2000;
|
||||
|
||||
private static final String TEST_SSID = "testSsid";
|
||||
private static final String TEST_PW_GE_8_CHAR = "testPasswordGreaterThan8Char";
|
||||
private static final String TEST_PW_LT_8_CHAR = "lt8Char";
|
||||
private static final String TEST_DOMAIN = "testDomain.com";
|
||||
|
||||
private static final String SETTINGS_PACKAGE = "com.android.settings";
|
||||
|
||||
private static final String CHECKBOX_CLASS = "android.widget.CheckBox";
|
||||
private static final String SPINNER_CLASS = "android.widget.Spinner";
|
||||
private static final String EDIT_TEXT_CLASS = "android.widget.EditText";
|
||||
private static final String SCROLLVIEW_CLASS = "android.widget.ScrollView";
|
||||
private static final String LISTVIEW_CLASS = "android.widget.ListView";
|
||||
|
||||
private static final String ADD_NETWORK_MENU_CANCEL_BUTTON_TEXT = "CANCEL";
|
||||
private static final String ADD_NETWORK_MENU_SAVE_BUTTON_TEXT = "SAVE";
|
||||
private static final String ADD_NETWORK_PREFERENCE_TEXT = "Add network";
|
||||
private static final String CONFIGURE_WIFI_PREFERENCE_TEXT = "Wi‑Fi preferences";
|
||||
private static final String CONFIGURE_WIFI_ADVANCED_PREFERENCE_TEXT = "Advanced";
|
||||
private static final String CACERT_MENU_PLEASE_SELECT_TEXT = "Please select";
|
||||
private static final String CACERT_MENU_USE_SYSTEM_CERTS_TEXT = "Use system certificates";
|
||||
private static final String CACERT_MENU_DO_NOT_VALIDATE_TEXT = "Do not validate";
|
||||
private static final String USERCERT_MENU_PLEASE_SELECT_TEXT = "Please select";
|
||||
private static final String USERCERT_MENU_DO_NOT_PROVIDE_TEXT = "Do not provide";
|
||||
private static final String SECURITY_OPTION_NONE_TEXT = "None";
|
||||
private static final String SECURITY_OPTION_WEP_TEXT = "WEP";
|
||||
private static final String SECURITY_OPTION_PSK_TEXT = "WPA/WPA2 PSK";
|
||||
private static final String SECURITY_OPTION_EAP_TEXT = "802.1x EAP";
|
||||
private static final String EAP_METHOD_PEAP_TEXT = "PEAP";
|
||||
private static final String EAP_METHOD_TLS_TEXT = "TLS";
|
||||
private static final String EAP_METHOD_TTLS_TEXT = "TTLS";
|
||||
private static final String EAP_METHOD_PWD_TEXT = "PWD";
|
||||
private static final String EAP_METHOD_SIM_TEXT = "SIM";
|
||||
private static final String EAP_METHOD_AKA_TEXT = "AKA";
|
||||
private static final String EAP_METHOD_AKA_PRIME_TEXT = "AKA'";
|
||||
private static final String PHASE2_MENU_NONE_TEXT = "None";
|
||||
private static final String PHASE2_MENU_MSCHAPV2_TEXT = "MSCHAPV2";
|
||||
private static final String PHASE2_MENU_GTC_TEXT = "GTC";
|
||||
|
||||
private static final String ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID = "wifi_advanced_togglebox";
|
||||
private static final String ADD_NETWORK_MENU_IP_SETTINGS_RES_ID = "ip_settings";
|
||||
private static final String ADD_NETWORK_MENU_PROXY_SETTINGS_RES_ID = "proxy_settings";
|
||||
private static final String ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID = "security";
|
||||
private static final String ADD_NETWORK_MENU_EAP_METHOD_RES_ID = "method";
|
||||
private static final String ADD_NETWORK_MENU_SSID_RES_ID = "ssid";
|
||||
private static final String ADD_NETWORK_MENU_PHASE2_RES_ID = "phase2";
|
||||
private static final String ADD_NETWORK_MENU_CACERT_RES_ID = "ca_cert";
|
||||
private static final String ADD_NETWORK_MENU_USERCERT_RES_ID = "user_cert";
|
||||
private static final String ADD_NETWORK_MENU_NO_DOMAIN_WARNING_RES_ID = "no_domain_warning";
|
||||
private static final String ADD_NETWORK_MENU_NO_CACERT_WARNING_RES_ID = "no_ca_cert_warning";
|
||||
private static final String ADD_NETWORK_MENU_DOMAIN_LAYOUT_RES_ID = "l_domain";
|
||||
private static final String ADD_NETWORK_MENU_DOMAIN_RES_ID = "domain";
|
||||
private static final String ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID = "l_identity";
|
||||
private static final String ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID = "l_anonymous";
|
||||
private static final String ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID = "password_layout";
|
||||
private static final String ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID =
|
||||
"show_password_layout";
|
||||
private static final String ADD_NETWORK_MENU_PASSWORD_RES_ID = "password";
|
||||
|
||||
private static final BySelector ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR =
|
||||
By.scrollable(true).clazz(SCROLLVIEW_CLASS);
|
||||
private static final BySelector SPINNER_OPTIONS_SCROLLABLE_BY_SELECTOR =
|
||||
By.scrollable(true).clazz(LISTVIEW_CLASS);
|
||||
|
||||
private UiDevice mDevice;
|
||||
private CommandsHelper mCommandsHelper;
|
||||
|
||||
@Override
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mDevice = UiDevice.getInstance(getInstrumentation());
|
||||
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
|
||||
try {
|
||||
mDevice.setOrientationNatural();
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException("failed to freeze device orientation", e);
|
||||
}
|
||||
// Ensure airplane mode is OFF so that wifi can be enabled using WiFiManager.
|
||||
Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
|
||||
Settings.Global.putString(InstrumentationRegistry.getTargetContext().getContentResolver(),
|
||||
Settings.Global.AIRPLANE_MODE_ON, "0");
|
||||
|
||||
Log.d(TAG, "sending airplane mode broadcast to device");
|
||||
mCommandsHelper = CommandsHelper.getInstance();
|
||||
mCommandsHelper = CommandsHelper.getInstance(InstrumentationRegistry.getInstrumentation());
|
||||
mCommandsHelper.executeShellCommand(AIRPLANE_MODE_BROADCAST);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
@After
|
||||
public void tearDown() {
|
||||
// Exit all settings sub-menus.
|
||||
for (int i = 0; i < NUM_BACK_BUTTON_PRESSES; ++i) {
|
||||
mDevice.pressBack();
|
||||
}
|
||||
mDevice.pressHome();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@Presubmit
|
||||
@MediumTest
|
||||
@Test
|
||||
public void testWiFiEnabled() throws Exception {
|
||||
verifyWiFiOnOrOff(true);
|
||||
}
|
||||
|
||||
@Presubmit
|
||||
@MediumTest
|
||||
@Test
|
||||
public void testWiFiDisabled() throws Exception {
|
||||
verifyWiFiOnOrOff(false);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testWifiMenuLoadConfigure() throws Exception {
|
||||
loadWiFiConfigureMenu();
|
||||
Thread.sleep(SLEEP_TIME);
|
||||
UiObject2 configureWiFiHeading = mDevice.wait(Until.findObject
|
||||
(By.text(CONFIGURE_WIFI_PREFERENCE_TEXT)), TIMEOUT);
|
||||
assertNotNull("Configure WiFi menu has not loaded correctly", configureWiFiHeading);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testNetworkNotificationsOn() throws Exception {
|
||||
verifyNetworkNotificationsOnOrOff(true);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testNetworkNotificationsOff() throws Exception {
|
||||
verifyNetworkNotificationsOnOrOff(false);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testAddNetworkMenu_Default() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
|
||||
// Submit button should be disabled by default, while cancel button should be enabled.
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
assertTrue(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_CANCEL_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
// Check that the SSID field is defaults to the hint.
|
||||
assertEquals("Enter the SSID", mDevice.wait(Until.findObject(By
|
||||
.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SSID_RES_ID)
|
||||
.clazz(EDIT_TEXT_CLASS)), TIMEOUT*2)
|
||||
.getText());
|
||||
|
||||
// Check Security defaults to None.
|
||||
assertEquals("None", mDevice.wait(Until.findObject(By
|
||||
.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID)
|
||||
.clazz(SPINNER_CLASS)), TIMEOUT)
|
||||
.getChildren().get(0).getText());
|
||||
|
||||
// Check advanced options are collapsed by default.
|
||||
assertFalse(mDevice.wait(Until.findObject(By
|
||||
.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID)
|
||||
.clazz(CHECKBOX_CLASS)), TIMEOUT).isChecked());
|
||||
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAddNetworkMenu_Proxy() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
|
||||
// Toggle advanced options.
|
||||
mDevice.wait(Until.findObject(By
|
||||
.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID)
|
||||
.clazz(CHECKBOX_CLASS)), TIMEOUT).click();
|
||||
|
||||
// Verify Proxy defaults to None.
|
||||
BySelector proxySettingsBySelector =
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PROXY_SETTINGS_RES_ID)
|
||||
.clazz(SPINNER_CLASS);
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector);
|
||||
assertEquals("None", mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT)
|
||||
.getChildren().get(0).getText());
|
||||
|
||||
// Verify that Proxy Manual fields appear.
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector);
|
||||
mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT).click();
|
||||
mDevice.wait(Until.findObject(By.text("Manual")), TIMEOUT).click();
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, "proxy_warning_limited_support"));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, "proxy_hostname"));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, "proxy_exclusionlist"));
|
||||
|
||||
// Verify that Proxy Auto-Config options appear.
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector);
|
||||
mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT).click();
|
||||
mDevice.wait(Until.findObject(By.text("Proxy Auto-Config")), TIMEOUT).click();
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, "proxy_pac"));
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAddNetworkMenu_IpSettings() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
|
||||
// Toggle advanced options.
|
||||
mDevice.wait(Until.findObject(By
|
||||
.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID)
|
||||
.clazz(CHECKBOX_CLASS)), TIMEOUT).click();
|
||||
|
||||
// Verify IP settings defaults to DHCP.
|
||||
BySelector ipSettingsBySelector =
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IP_SETTINGS_RES_ID).clazz(SPINNER_CLASS);
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, ipSettingsBySelector);
|
||||
assertEquals("DHCP", mDevice.wait(Until.findObject(ipSettingsBySelector), TIMEOUT)
|
||||
.getChildren().get(0).getText());
|
||||
|
||||
// Verify that Static IP settings options appear.
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, ipSettingsBySelector).click();
|
||||
mDevice.wait(Until.findObject(By.text("Static")), TIMEOUT).click();
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, "ipaddress"));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, "gateway"));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, "network_prefix_length"));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, "dns1"));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, "dns2"));
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testPhase2Settings() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
|
||||
|
||||
BySelector phase2SettingsBySelector =
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID).clazz(SPINNER_CLASS);
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, phase2SettingsBySelector);
|
||||
assertEquals(PHASE2_MENU_NONE_TEXT, mDevice.wait(Until
|
||||
.findObject(phase2SettingsBySelector), TIMEOUT).getChildren().get(0).getText());
|
||||
mDevice.wait(Until.findObject(phase2SettingsBySelector), TIMEOUT).click();
|
||||
Thread.sleep(SLEEP_TIME);
|
||||
|
||||
// Verify Phase 2 authentication spinner options.
|
||||
assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_NONE_TEXT)), TIMEOUT));
|
||||
assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_MSCHAPV2_TEXT)), TIMEOUT));
|
||||
assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_GTC_TEXT)), TIMEOUT));
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testCaCertSettings() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
|
||||
|
||||
BySelector caCertSettingsBySelector =
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID).clazz(SPINNER_CLASS);
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, caCertSettingsBySelector);
|
||||
assertEquals(CACERT_MENU_PLEASE_SELECT_TEXT, mDevice.wait(Until
|
||||
.findObject(caCertSettingsBySelector), TIMEOUT).getChildren().get(0).getText());
|
||||
mDevice.wait(Until.findObject(caCertSettingsBySelector), TIMEOUT).click();
|
||||
Thread.sleep(SLEEP_TIME);
|
||||
|
||||
// Verify CA certificate spinner options.
|
||||
assertNotNull(mDevice.wait(Until.findObject(
|
||||
By.text(CACERT_MENU_PLEASE_SELECT_TEXT)), TIMEOUT));
|
||||
assertNotNull(mDevice.wait(Until.findObject(
|
||||
By.text(CACERT_MENU_USE_SYSTEM_CERTS_TEXT)), TIMEOUT));
|
||||
assertNotNull(mDevice.wait(Until.findObject(
|
||||
By.text(CACERT_MENU_DO_NOT_VALIDATE_TEXT)), TIMEOUT));
|
||||
|
||||
// Verify that a domain field and warning appear when the user selects the
|
||||
// "Use system certificates" option.
|
||||
mDevice.wait(Until.findObject(By.text(CACERT_MENU_USE_SYSTEM_CERTS_TEXT)), TIMEOUT).click();
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_DOMAIN_LAYOUT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_NO_DOMAIN_WARNING_RES_ID));
|
||||
|
||||
// Verify that a warning appears when the user chooses the "Do Not Validate" option.
|
||||
mDevice.wait(Until.findObject(caCertSettingsBySelector), TIMEOUT).click();
|
||||
mDevice.wait(Until.findObject(By.text(CACERT_MENU_DO_NOT_VALIDATE_TEXT)), TIMEOUT).click();
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_NO_CACERT_WARNING_RES_ID));
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAddNetwork_NoSecurity() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
selectSecurityOption(SECURITY_OPTION_NONE_TEXT);
|
||||
|
||||
// Entering an SSID is enough to enable the submit button. // TODO THIS GUY
|
||||
enterSSID(TEST_SSID);
|
||||
assertTrue(mDevice.wait(Until
|
||||
.findObject(By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAddNetwork_WEP() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
selectSecurityOption(SECURITY_OPTION_WEP_TEXT);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
// Verify that WEP fields appear.
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID));
|
||||
|
||||
// Entering an SSID alone does not enable the submit button.
|
||||
enterSSID(TEST_SSID);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
// Submit button is only enabled after a password is entered.
|
||||
enterPassword(TEST_PW_GE_8_CHAR);
|
||||
assertTrue(mDevice.wait(Until
|
||||
.findObject(By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAddNetwork_PSK() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
selectSecurityOption(SECURITY_OPTION_PSK_TEXT);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
// Verify that PSK fields appear.
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID));
|
||||
|
||||
// Entering an SSID alone does not enable the submit button.
|
||||
enterSSID(TEST_SSID);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
// Entering an password that is too short does not enable submit button.
|
||||
enterPassword(TEST_PW_LT_8_CHAR);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
// Submit button is only enabled after a password of valid length is entered.
|
||||
enterPassword(TEST_PW_GE_8_CHAR);
|
||||
assertTrue(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAddNetwork_EAP_PEAP() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
selectEAPMethod(EAP_METHOD_PEAP_TEXT);
|
||||
|
||||
// Verify that EAP-PEAP fields appear.
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID));
|
||||
|
||||
// Entering an SSID alone does not enable the submit button.
|
||||
enterSSID(TEST_SSID);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
verifyCaCertificateSubmitConditions();
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAddNetwork_EAP_TLS() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
selectEAPMethod(EAP_METHOD_TLS_TEXT);
|
||||
|
||||
// Verify that EAP-TLS fields appear.
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_USERCERT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID));
|
||||
|
||||
// Entering an SSID alone does not enable the submit button.
|
||||
enterSSID(TEST_SSID);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
// Selecting the User certificate "Do not provide" option alone does not enable the submit
|
||||
// button.
|
||||
selectUserCertificateOption(USERCERT_MENU_DO_NOT_PROVIDE_TEXT);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
verifyCaCertificateSubmitConditions();
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAddNetwork_EAP_TTLS() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
selectEAPMethod(EAP_METHOD_TTLS_TEXT);
|
||||
|
||||
// Verify that EAP-TLS fields appear.
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
|
||||
|
||||
// Entering an SSID alone does not enable the submit button.
|
||||
enterSSID(TEST_SSID);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
verifyCaCertificateSubmitConditions();
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAddNetwork_EAP_PWD() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
selectEAPMethod(EAP_METHOD_PWD_TEXT);
|
||||
|
||||
// Verify that EAP-TLS fields appear.
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
|
||||
|
||||
// Entering an SSID alone enables the submit button.
|
||||
enterSSID(TEST_SSID);
|
||||
assertTrue(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAddNetwork_EAP_SIM() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
selectEAPMethod(EAP_METHOD_SIM_TEXT);
|
||||
|
||||
// Entering an SSID alone enables the submit button.
|
||||
enterSSID(TEST_SSID);
|
||||
assertTrue(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAddNetwork_EAP_AKA() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
selectEAPMethod(EAP_METHOD_AKA_TEXT);
|
||||
|
||||
// Entering an SSID alone enables the submit button.
|
||||
enterSSID(TEST_SSID);
|
||||
assertTrue(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAddNetwork_EAP_AKA_PRIME() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
selectEAPMethod(EAP_METHOD_AKA_PRIME_TEXT);
|
||||
|
||||
// Entering an SSID alone enables the submit button.
|
||||
enterSSID(TEST_SSID);
|
||||
assertTrue(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
}
|
||||
|
||||
private void verifyKeepWiFiOnDuringSleep(String settingToBeVerified, int settingValue)
|
||||
throws Exception {
|
||||
loadWiFiConfigureMenu();
|
||||
mDevice.wait(Until.findObject(By.text("Keep Wi‑Fi on during sleep")), TIMEOUT)
|
||||
.click();
|
||||
mDevice.wait(Until.findObject(By.clazz("android.widget.CheckedTextView")
|
||||
.text(settingToBeVerified)), TIMEOUT).click();
|
||||
Thread.sleep(SLEEP_TIME);
|
||||
int keepWiFiOnSetting =
|
||||
Settings.Global.getInt(getInstrumentation().getContext().getContentResolver(),
|
||||
Settings.Global.WIFI_SLEEP_POLICY);
|
||||
assertEquals(settingValue, keepWiFiOnSetting);
|
||||
}
|
||||
|
||||
private void verifyNetworkNotificationsOnOrOff(boolean verifyOn)
|
||||
throws Exception {
|
||||
// Enable network recommendations to enable the toggle switch for Network
|
||||
// notifications
|
||||
Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
|
||||
Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, "1");
|
||||
if (verifyOn) {
|
||||
Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
|
||||
Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, "0");
|
||||
}
|
||||
else {
|
||||
Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
|
||||
Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, "1");
|
||||
}
|
||||
loadWiFiConfigureMenu();
|
||||
mDevice.wait(Until.findObject(By.text("Open network notification")), TIMEOUT)
|
||||
.click();
|
||||
Thread.sleep(SLEEP_TIME);
|
||||
String wifiNotificationValue =
|
||||
Settings.Global.getString(getInstrumentation().getContext().getContentResolver(),
|
||||
Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON);
|
||||
if (verifyOn) {
|
||||
assertEquals("1", wifiNotificationValue);
|
||||
}
|
||||
else {
|
||||
assertEquals("0", wifiNotificationValue);
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyWiFiOnOrOff(boolean verifyOn) throws Exception {
|
||||
String switchText = "On";
|
||||
if (verifyOn) {
|
||||
switchText = "Off";
|
||||
}
|
||||
loadWiFiSettingsPage(!verifyOn);
|
||||
mDevice.wait(Until
|
||||
.findObject(By.res(SETTINGS_PACKAGE, "switch_bar").text(switchText)), TIMEOUT)
|
||||
.click();
|
||||
Thread.sleep(SLEEP_TIME);
|
||||
String wifiValue =
|
||||
Settings.Global.getString(getInstrumentation().getContext().getContentResolver(),
|
||||
Settings.Global.WIFI_ON);
|
||||
if (verifyOn) {
|
||||
// 1 is Enabled, 2 is Enabled while airplane mode is ON.
|
||||
assertTrue(wifiValue.equals("1") || wifiValue.equals("2"));
|
||||
}
|
||||
else {
|
||||
assertEquals("0", wifiValue);
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyCaCertificateSubmitConditions() throws Exception {
|
||||
// Selecting the CA certificate "Do not validate" option enables the submit button.
|
||||
selectCaCertificateOption(CACERT_MENU_DO_NOT_VALIDATE_TEXT);
|
||||
assertTrue(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
// However, selecting the CA certificate "Use system certificates option" is not enough to
|
||||
// enable the submit button.
|
||||
selectCaCertificateOption(CACERT_MENU_USE_SYSTEM_CERTS_TEXT);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
// Submit button is only enabled after a domain is entered as well.
|
||||
enterDomain(TEST_DOMAIN);
|
||||
assertTrue(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
loadWiFiSettingsPage(!verifyOn);
|
||||
mDevice.wait(Until.findObject(By.res(SETTINGS_PACKAGE, "switch_widget")), TIMEOUT)
|
||||
.click();
|
||||
Thread.sleep(SLEEP_TIME);
|
||||
final String wifiValue = Settings.Global.getString(
|
||||
InstrumentationRegistry.getTargetContext().getContentResolver(),
|
||||
Settings.Global.WIFI_ON);
|
||||
if (verifyOn) {
|
||||
// 1 is Enabled, 2 is Enabled while airplane mode is ON.
|
||||
assertThat(wifiValue).isAnyOf("1", "2");
|
||||
} else {
|
||||
assertThat(wifiValue).isEqualTo("0");
|
||||
}
|
||||
}
|
||||
|
||||
private void loadWiFiSettingsPage(boolean wifiEnabled) throws Exception {
|
||||
WifiManager wifiManager = (WifiManager)getInstrumentation().getContext()
|
||||
WifiManager wifiManager = (WifiManager) InstrumentationRegistry.getTargetContext()
|
||||
.getSystemService(Context.WIFI_SERVICE);
|
||||
wifiManager.setWifiEnabled(wifiEnabled);
|
||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
|
||||
SettingsHelper.launchSettingsPage(InstrumentationRegistry.getTargetContext(),
|
||||
Settings.ACTION_WIFI_SETTINGS);
|
||||
}
|
||||
|
||||
private void loadWiFiConfigureMenu() throws Exception {
|
||||
loadWiFiSettingsPage(false);
|
||||
Thread.sleep(TIMEOUT);
|
||||
mDevice.wait(Until.findObject(By.text(CONFIGURE_WIFI_PREFERENCE_TEXT)), TIMEOUT).click();
|
||||
mDevice.wait(Until.findObject(
|
||||
By.text(CONFIGURE_WIFI_ADVANCED_PREFERENCE_TEXT)), TIMEOUT).click();
|
||||
}
|
||||
|
||||
private void loadAddNetworkMenu() throws Exception {
|
||||
loadWiFiSettingsPage(true);
|
||||
for (int attempts = 0; attempts < MAX_ADD_NETWORK_BUTTON_ATTEMPTS; ++attempts) {
|
||||
try {
|
||||
findOrScrollToObject(By.scrollable(true), By.text(ADD_NETWORK_PREFERENCE_TEXT))
|
||||
.click();
|
||||
} catch (StaleObjectException e) {
|
||||
// The network list might have been updated between when the Add network button was
|
||||
// found, and when it UI automator attempted to click on it. Retry.
|
||||
continue;
|
||||
}
|
||||
// If we get here, we successfully clicked on the Add network button, so we are done.
|
||||
Thread.sleep(SLEEP_TIME*5);
|
||||
return;
|
||||
}
|
||||
|
||||
fail("Failed to load Add Network Menu after " + MAX_ADD_NETWORK_BUTTON_ATTEMPTS
|
||||
+ " retries");
|
||||
}
|
||||
|
||||
private void selectSecurityOption(String securityOption) throws Exception {
|
||||
// We might not need to scroll to the security options if not enough add network menu
|
||||
// options are visible.
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID)
|
||||
.clazz(SPINNER_CLASS)).click();
|
||||
Thread.sleep(SLEEP_TIME);
|
||||
mDevice.wait(Until.findObject(By.text(securityOption)), TIMEOUT).click();
|
||||
}
|
||||
|
||||
private void selectEAPMethod(String eapMethod) throws Exception {
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_EAP_METHOD_RES_ID).clazz(SPINNER_CLASS))
|
||||
.click();
|
||||
Thread.sleep(SLEEP_TIME);
|
||||
findOrScrollToObject(SPINNER_OPTIONS_SCROLLABLE_BY_SELECTOR, By.text(eapMethod)).click();
|
||||
}
|
||||
|
||||
private void selectUserCertificateOption(String userCertificateOption) throws Exception {
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_USERCERT_RES_ID).clazz(SPINNER_CLASS))
|
||||
.click();
|
||||
mDevice.wait(Until.findObject(By.text(userCertificateOption)), TIMEOUT).click();
|
||||
}
|
||||
|
||||
private void selectCaCertificateOption(String caCertificateOption) throws Exception {
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID).clazz(SPINNER_CLASS))
|
||||
.click();
|
||||
mDevice.wait(Until.findObject(By.text(caCertificateOption)), TIMEOUT).click();
|
||||
}
|
||||
|
||||
private void enterSSID(String ssid) throws Exception {
|
||||
// We might not need to scroll to the SSID option if not enough add network menu options
|
||||
// are visible.
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SSID_RES_ID).clazz(EDIT_TEXT_CLASS))
|
||||
.setText(ssid);
|
||||
}
|
||||
|
||||
private void enterPassword(String password) throws Exception {
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_RES_ID).clazz(EDIT_TEXT_CLASS))
|
||||
.setText(password);
|
||||
}
|
||||
|
||||
private void enterDomain(String domain) throws Exception {
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_DOMAIN_RES_ID)).setText(domain);
|
||||
}
|
||||
|
||||
// Use this if the UI object might or might not need to be scrolled to.
|
||||
private UiObject2 findOrScrollToObject(BySelector scrollableSelector, BySelector objectSelector)
|
||||
throws Exception {
|
||||
UiObject2 object = mDevice.wait(Until.findObject(objectSelector), TIMEOUT);
|
||||
if (object == null) {
|
||||
object = scrollToObject(scrollableSelector, objectSelector);
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
private UiObject2 scrollToObject(BySelector scrollableSelector, BySelector objectSelector)
|
||||
throws Exception {
|
||||
UiObject2 scrollable = mDevice.wait(Until.findObject(scrollableSelector), TIMEOUT);
|
||||
if (scrollable == null) {
|
||||
fail("Could not find scrollable UI object identified by " + scrollableSelector);
|
||||
}
|
||||
UiObject2 found = null;
|
||||
// Scroll all the way up first, then all the way down.
|
||||
while (true) {
|
||||
// Optimization: terminate if we find the object while scrolling up to reset, so
|
||||
// we save the time spent scrolling down again.
|
||||
boolean canScrollAgain = scrollable.scroll(Direction.UP, SCROLL_UP_PERCENT,
|
||||
SCROLL_SPEED);
|
||||
found = mDevice.findObject(objectSelector);
|
||||
if (found != null) return found;
|
||||
if (!canScrollAgain) break;
|
||||
}
|
||||
for (int attempts = 0; found == null && attempts < MAX_SCROLL_ATTEMPTS; ++attempts) {
|
||||
// Return value of UiObject2.scroll() is not reliable, so do not use it in loop
|
||||
// condition, in case it causes this loop to terminate prematurely.
|
||||
scrollable.scroll(Direction.DOWN, SCROLL_DOWN_PERCENT, SCROLL_SPEED);
|
||||
found = mDevice.findObject(objectSelector);
|
||||
}
|
||||
if (found == null) {
|
||||
fail("Could not scroll to UI object identified by " + objectSelector);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,12 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings;
|
||||
package com.android.settings.shortcut;
|
||||
|
||||
import static android.support.test.espresso.Espresso.onView;
|
||||
import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist;
|
||||
import static android.support.test.espresso.matcher.ViewMatchers.withText;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.Mockito.any;
|
||||
@@ -39,9 +37,13 @@ import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.content.pm.ShortcutManager;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.espresso.matcher.ViewMatchers;
|
||||
import android.support.test.filters.SmallTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Settings;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -55,12 +57,6 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* Tests for {@link CreateShortcutTest}
|
||||
*
|
||||
m SettingsTests &&
|
||||
adb install \
|
||||
-r -g ${ANDROID_PRODUCT_OUT}/data/app/SettingsTests/SettingsTests.apk &&
|
||||
adb shell am instrument -e class com.android.settings.CreateShortcutTest \
|
||||
-w com.android.settings.tests/android.support.test.runner.AndroidJUnitRunner
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
@@ -71,8 +67,10 @@ public class CreateShortcutTest {
|
||||
private Instrumentation mInstrumentation;
|
||||
private Context mContext;
|
||||
|
||||
@Mock ShortcutManager mShortcutManager;
|
||||
@Captor ArgumentCaptor<List<ShortcutInfo>> mListCaptor;
|
||||
@Mock
|
||||
ShortcutManager mShortcutManager;
|
||||
@Captor
|
||||
ArgumentCaptor<List<ShortcutInfo>> mListCaptor;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
@@ -84,15 +82,17 @@ public class CreateShortcutTest {
|
||||
@Test
|
||||
public void test_layoutDoesNotHaveCancelButton() {
|
||||
mInstrumentation.startActivitySync(new Intent(Intent.ACTION_CREATE_SHORTCUT)
|
||||
.setClassName(mContext, CreateShortcut.class.getName()));
|
||||
onView(withText(R.string.cancel)).check(doesNotExist());
|
||||
.setClassName(mContext, CreateShortcut.class.getName())
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
||||
onView(ViewMatchers.withText(R.string.cancel)).check(doesNotExist());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createResultIntent() {
|
||||
CreateShortcut orgActivity = (CreateShortcut) mInstrumentation.startActivitySync(
|
||||
new Intent(Intent.ACTION_CREATE_SHORTCUT)
|
||||
.setClassName(mContext, CreateShortcut.class.getName()));
|
||||
.setClassName(mContext, CreateShortcut.class.getName())
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
||||
CreateShortcut activity = spy(orgActivity);
|
||||
doReturn(mShortcutManager).when(activity).getSystemService(eq(Context.SHORTCUT_SERVICE));
|
||||
|
||||
Reference in New Issue
Block a user