fix: 引入Settings的Module
This commit is contained in:
112
Settings/tests/robotests/Android.bp
Normal file
112
Settings/tests/robotests/Android.bp
Normal file
@@ -0,0 +1,112 @@
|
||||
package {
|
||||
default_team: "trendy_team_android_settings_app",
|
||||
// See: http://go/android-license-faq
|
||||
// A large-scale-change added 'default_applicable_licenses' to import
|
||||
// all of the 'license_kinds' from "packages_apps_Settings_license"
|
||||
// to get the below license kinds:
|
||||
// SPDX-license-identifier-Apache-2.0
|
||||
default_applicable_licenses: ["packages_apps_Settings_license"],
|
||||
}
|
||||
|
||||
// Build SettingsRoboTestStub.apk which includes test-only resources.
|
||||
android_app {
|
||||
name: "SettingsRoboTestStub",
|
||||
defaults: [
|
||||
"SettingsLibDefaults",
|
||||
"SettingsLib-search-defaults",
|
||||
],
|
||||
platform_apis: true,
|
||||
certificate: "platform",
|
||||
privileged: true,
|
||||
use_resource_processor: true,
|
||||
resource_dirs: ["res"],
|
||||
|
||||
static_libs: [
|
||||
"Settings-core",
|
||||
"androidx.fragment_fragment-testing",
|
||||
"frameworks-base-testutils",
|
||||
"androidx.fragment_fragment",
|
||||
"androidx.lifecycle_lifecycle-runtime-testing",
|
||||
"kotlinx_coroutines_test",
|
||||
],
|
||||
|
||||
aaptflags: ["--extra-packages com.android.settings"],
|
||||
|
||||
libs: [
|
||||
"telephony-common",
|
||||
"ims-common",
|
||||
],
|
||||
uses_libs: ["org.apache.http.legacy"],
|
||||
optional_uses_libs: [
|
||||
"androidx.window.extensions",
|
||||
"androidx.window.sidecar",
|
||||
],
|
||||
}
|
||||
|
||||
// Settings Robolectric test target.
|
||||
android_robolectric_test {
|
||||
name: "SettingsRoboTests",
|
||||
srcs: [
|
||||
"src/**/*.java",
|
||||
"src/**/*.kt",
|
||||
],
|
||||
|
||||
// test_suites attribute is not needed. This module will be configured in ATP GCL file.
|
||||
|
||||
static_libs: [
|
||||
"Robolectric_shadows_androidx_fragment_upstream",
|
||||
"Settings_robolectric_meta_service_file",
|
||||
"SettingsLib-robo-testutils",
|
||||
"Settings-robo-testutils",
|
||||
"android.webkit.flags-aconfig-java",
|
||||
"androidx.test.core",
|
||||
"androidx.test.espresso.core",
|
||||
"androidx.test.ext.junit",
|
||||
"androidx.test.rules",
|
||||
"androidx.test.runner",
|
||||
"flag-junit",
|
||||
"flag-junit-base",
|
||||
"aconfig_settings_flags_lib",
|
||||
"platform-test-annotations",
|
||||
"Settings-testutils2",
|
||||
"notification_flags_lib",
|
||||
"com_android_server_accessibility_flags_lib",
|
||||
"testables",
|
||||
],
|
||||
|
||||
libs: [
|
||||
"ims-common",
|
||||
"android.test.mock",
|
||||
],
|
||||
|
||||
java_resource_dirs: [
|
||||
"config",
|
||||
"resources",
|
||||
],
|
||||
|
||||
instrumentation_for: "SettingsRoboTestStub",
|
||||
|
||||
test_options: {
|
||||
timeout: 36000,
|
||||
shards: 10,
|
||||
},
|
||||
|
||||
coverage_libs: [
|
||||
"Settings-core",
|
||||
"SettingsLib",
|
||||
"SettingsLib-search",
|
||||
],
|
||||
|
||||
upstream: true,
|
||||
}
|
||||
|
||||
java_library {
|
||||
name: "Settings-robo-testutils",
|
||||
srcs: ["testutils/**/*.java"],
|
||||
libs: [
|
||||
"Robolectric_all-target_upstream",
|
||||
"Settings-core",
|
||||
"mockito-robolectric-prebuilt",
|
||||
"truth",
|
||||
],
|
||||
}
|
||||
28
Settings/tests/robotests/AndroidManifest.xml
Normal file
28
Settings/tests/robotests/AndroidManifest.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2022 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.
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
|
||||
coreApp="true"
|
||||
package="com.android.settings">
|
||||
<uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
|
||||
|
||||
<application>
|
||||
<activity android:name="com.android.settings.security.TestActivity" android:exported="true" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
2
Settings/tests/robotests/OWNERS
Normal file
2
Settings/tests/robotests/OWNERS
Normal file
@@ -0,0 +1,2 @@
|
||||
# We do not guard tests - everyone is welcomed to contribute to tests.
|
||||
per-file *.java=*
|
||||
24
Settings/tests/robotests/README.md
Normal file
24
Settings/tests/robotests/README.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# Running Settings Robolectric tests
|
||||
|
||||
|
||||
## The full suite
|
||||
```
|
||||
$ croot
|
||||
$ make RunSettingsRoboTests
|
||||
```
|
||||
|
||||
## Running a single test class
|
||||
|
||||
```
|
||||
$ croot
|
||||
$ make RunSettingsRoboTests ROBOTEST_FILTER=<ClassName>
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
make RunSettingsRoboTests ROBOTEST_FILTER=CodeInspectionTest
|
||||
```
|
||||
|
||||
You can also use partial class name in ROBOTEST_FILTER. If the partial class name matches
|
||||
multiple file names, all of them will be executed.
|
||||
BIN
Settings/tests/robotests/assets/empty_payload_ota.zip
Normal file
BIN
Settings/tests/robotests/assets/empty_payload_ota.zip
Normal file
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
com.android.settings.applications.appinfo.AppButtonsPreferenceController
|
||||
com.android.settings.applications.appinfo.AppBatteryPreferenceController
|
||||
com.android.settings.applications.appinfo.AppHeaderViewPreferenceController
|
||||
com.android.settings.applications.appinfo.AppMemoryPreferenceController
|
||||
com.android.settings.applications.appinfo.InstantAppButtonsPreferenceController
|
||||
com.android.settings.bluetooth.BluetoothDeviceNamePreferenceController
|
||||
com.android.settings.bluetooth.BluetoothDeviceRenamePreferenceController
|
||||
com.android.settings.datausage.DataUsageSummaryPreferenceController
|
||||
com.android.settings.datausage.WifiDataUsageSummaryPreferenceController
|
||||
com.android.settings.fuelgauge.RestrictAppPreferenceController
|
||||
com.android.settings.fuelgauge.batterysaver.BatterySaverButtonPreferenceController
|
||||
com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController
|
||||
com.android.settings.security.VisiblePatternProfilePreferenceController
|
||||
com.android.settings.wifi.details2.WifiMeteredPreferenceController2
|
||||
@@ -0,0 +1,94 @@
|
||||
com.android.settings.accessibility.AccessibilitySettingsForSetupWizard
|
||||
com.android.settings.accessibility.ToggleAccessibilityServicePreferenceFragment
|
||||
com.android.settings.accessibility.ToggleScreenMagnificationPreferenceFragment
|
||||
com.android.settings.accessibility.ToggleScreenMagnificationPreferenceFragmentForSetupWizard
|
||||
com.android.settings.accessibility.ToggleScreenReaderPreferenceFragmentForSetupWizard
|
||||
com.android.settings.accessibility.ToggleSelectToSpeakPreferenceFragmentForSetupWizard
|
||||
com.android.settings.accounts.AccountDetailDashboardFragment
|
||||
com.android.settings.accounts.AccountPersonalDashboardFragment
|
||||
com.android.settings.accounts.AccountWorkProfileDashboardFragment
|
||||
com.android.settings.accounts.AccountSyncSettings
|
||||
com.android.settings.accounts.ChooseAccountFragment
|
||||
com.android.settings.applications.appinfo.AppInfoDashboardFragment
|
||||
com.android.settings.applications.appinfo.DrawOverlayDetails
|
||||
com.android.settings.applications.appinfo.ExternalSourcesDetails
|
||||
com.android.settings.applications.appinfo.WriteSettingsDetails
|
||||
com.android.settings.applications.AppLaunchSettings
|
||||
com.android.settings.applications.AppStorageSettings
|
||||
com.android.settings.applications.ProcessStatsDetail
|
||||
com.android.settings.applications.ProcessStatsSummary
|
||||
com.android.settings.applications.ProcessStatsUi
|
||||
com.android.settings.applications.RunningServices
|
||||
com.android.settings.applications.specialaccess.pictureinpicture.PictureInPictureDetails
|
||||
com.android.settings.applications.specialaccess.zenaccess.ZenAccessDetails
|
||||
com.android.settings.applications.UsageAccessDetails
|
||||
com.android.settings.backup.ToggleBackupSettingFragment
|
||||
com.android.settings.biometrics.fingerprint.FingerprintSettings$FingerprintSettingsFragment
|
||||
com.android.settings.bluetooth.BluetoothDeviceDetailsFragment
|
||||
com.android.settings.bluetooth.BluetoothPairingDetail
|
||||
com.android.settings.bluetooth.DevicePickerFragment
|
||||
com.android.settings.dashboard.profileselector.ProfileSelectAccountFragment
|
||||
com.android.settings.dashboard.profileselector.ProfileSelectManageApplications
|
||||
com.android.settings.dashboard.profileselector.ProfileSelectLocationFragment
|
||||
com.android.settings.datausage.AppDataUsage
|
||||
com.android.settings.datausage.DataUsageList
|
||||
com.android.settings.datausage.DataUsageSummary
|
||||
com.android.settings.datetime.timezone.TimeZoneSettings
|
||||
com.android.settings.development.compat.PlatformCompatDashboard
|
||||
com.android.settings.deviceinfo.PublicVolumeSettings
|
||||
com.android.settings.deviceinfo.StorageDashboardNoHeaderFragment
|
||||
com.android.settings.deviceinfo.legal.ModuleLicensesDashboard
|
||||
com.android.settings.enterprise.ApplicationListFragment$AdminGrantedPermissionCamera
|
||||
com.android.settings.enterprise.ApplicationListFragment$AdminGrantedPermissionLocation
|
||||
com.android.settings.enterprise.ApplicationListFragment$AdminGrantedPermissionMicrophone
|
||||
com.android.settings.enterprise.ApplicationListFragment$EnterpriseInstalledPackages
|
||||
com.android.settings.enterprise.EnterpriseSetDefaultAppsListFragment
|
||||
com.android.settings.fuelgauge.AdvancedPowerUsageDetail
|
||||
com.android.settings.fuelgauge.InactiveApps
|
||||
com.android.settings.fuelgauge.RestrictedAppDetails
|
||||
com.android.settings.IccLockSettings
|
||||
com.android.settings.inputmethod.InputMethodAndSubtypeEnabler
|
||||
com.android.settings.inputmethod.KeyboardLayoutPickerFragment
|
||||
com.android.settings.inputmethod.SpellCheckersSettings
|
||||
com.android.settings.location.LocationPersonalSettings
|
||||
com.android.settings.location.LocationWorkProfileSettings
|
||||
com.android.settings.network.apn.ApnEditor
|
||||
com.android.settings.network.apn.ApnSettings
|
||||
com.android.settings.network.telephony.NetworkSelectSettings
|
||||
com.android.settings.notification.app.AppNotificationSettings
|
||||
com.android.settings.notification.app.ChannelNotificationSettings
|
||||
com.android.settings.notification.history.NotificationStation
|
||||
com.android.settings.notification.RedactionInterstitial$RedactionInterstitialFragment
|
||||
com.android.settings.notification.zen.ZenModeEventRuleSettings
|
||||
com.android.settings.notification.zen.ZenModeScheduleRuleSettings
|
||||
com.android.settings.notification.zen.ZenCustomRuleNotificationsSettings
|
||||
com.android.settings.notification.zen.ZenCustomRuleCallsSettings
|
||||
com.android.settings.notification.zen.ZenCustomRuleConfigSettings
|
||||
com.android.settings.notification.zen.ZenCustomRuleSettings
|
||||
com.android.settings.notification.zen.ZenCustomRuleBlockedEffectsSettings
|
||||
com.android.settings.notification.zen.ZenCustomRuleMessagesSettings
|
||||
com.android.settings.password.ChooseLockGeneric$ChooseLockGenericFragment
|
||||
com.android.settings.password.SetupChooseLockGeneric$InternalActivity$InternalSetupChooseLockGenericFragment
|
||||
com.android.settings.password.SetupChooseLockGeneric$SetupChooseLockGenericFragment
|
||||
com.android.settings.print.PrintJobSettingsFragment
|
||||
com.android.settings.print.PrintServiceSettingsFragment
|
||||
com.android.settings.SetupRedactionInterstitial$SetupRedactionInterstitialFragment
|
||||
com.android.settings.shortcut.CreateShortcut
|
||||
com.android.settings.TestingSettings
|
||||
com.android.settings.UserCredentialsSettings
|
||||
com.android.settings.users.AppRestrictionsFragment
|
||||
com.android.settings.users.RestrictedProfileSettings
|
||||
com.android.settings.users.UserDetailsSettings
|
||||
com.android.settings.vpn2.AppManagementFragment
|
||||
com.android.settings.vpn2.VpnSettings
|
||||
com.android.settings.wallpaper.WallpaperTypeSettings
|
||||
com.android.settings.wifi.ChangeWifiStateDetails
|
||||
com.android.settings.wifi.calling.WifiCallingSettingsForSub
|
||||
com.android.settings.wifi.details.WifiNetworkDetailsFragment
|
||||
com.android.settings.wifi.dpp.WifiNetworkListFragment
|
||||
com.android.settings.wifi.p2p.WifiP2pSettings
|
||||
com.android.settings.wifi.savedaccesspoints.SavedAccessPointsWifiSettings
|
||||
com.android.settings.wifi.WifiInfo
|
||||
com.android.settings.applications.specialaccess.notificationaccess.NotificationAccessDetails
|
||||
com.android.settings.wifi.details2.WifiNetworkDetailsFragment2
|
||||
com.android.settings.wifi.savedaccesspoints2.SavedAccessPointsWifiSettings2
|
||||
@@ -0,0 +1,9 @@
|
||||
com.android.settings.deletionhelper.ActivationWarningFragment
|
||||
com.android.settings.applications.appops.AppOpsCategory
|
||||
com.android.settings.CustomListPreference$CustomListPreferenceDialogFragment
|
||||
com.android.settings.password.SaveAndFinishWorker
|
||||
com.android.settings.RestrictedListPreference$RestrictedListPreferenceDialogFragment
|
||||
com.android.settings.password.ConfirmDeviceCredentialBaseFragment$LastTryDialog
|
||||
com.android.settings.password.CredentialCheckResultTracker
|
||||
com.android.settings.dashboard.profileselector.ProfileSelectDialog
|
||||
com.android.settings.panel.PanelFragment
|
||||
@@ -0,0 +1 @@
|
||||
com.android.settings.search.FakeSettingsFragment
|
||||
@@ -0,0 +1,20 @@
|
||||
com.android.settings.accessibility.AccessibilitySlicePreferenceController
|
||||
com.android.settings.accessibility.MagnificationAlwaysOnPreferenceController
|
||||
com.android.settings.accessibility.MagnificationFollowTypingPreferenceController
|
||||
com.android.settings.accessibility.MagnificationJoystickPreferenceController
|
||||
com.android.settings.accessibility.ReduceBrightColorsIntensityPreferenceController
|
||||
com.android.settings.accessibility.ReduceBrightColorsPersistencePreferenceController
|
||||
com.android.settings.biometrics.face.FaceSettingsAttentionPreferenceController
|
||||
com.android.settings.core.TogglePreferenceControllerTest$FakeToggle
|
||||
com.android.settings.display.DeviceStateAutoRotateSettingController
|
||||
com.android.settings.display.SmartAutoRotatePreferenceController
|
||||
com.android.settings.gestures.OneHandedMainSwitchPreferenceController
|
||||
com.android.settings.network.telephony.AutoDataSwitchPreferenceController
|
||||
com.android.settings.network.telephony.Enhanced4gBasePreferenceController
|
||||
com.android.settings.network.telephony.MmsMessagePreferenceController
|
||||
com.android.settings.notification.RingVolumePreferenceController
|
||||
com.android.settings.testutils.FakeInvalidSliderController
|
||||
com.android.settings.testutils.FakeSliderController
|
||||
com.android.settings.testutils.FakeToggleController
|
||||
com.android.settings.users.GuestTelephonyPreferenceController
|
||||
com.android.settings.wifi.details2.WifiAutoConnectPreferenceController2
|
||||
BIN
Settings/tests/robotests/assets/no_payload_ota.zip
Normal file
BIN
Settings/tests/robotests/assets/no_payload_ota.zip
Normal file
Binary file not shown.
BIN
Settings/tests/robotests/assets/no_properties_ota.zip
Normal file
BIN
Settings/tests/robotests/assets/no_properties_ota.zip
Normal file
Binary file not shown.
BIN
Settings/tests/robotests/assets/valid_ota.zip
Normal file
BIN
Settings/tests/robotests/assets/valid_ota.zip
Normal file
Binary file not shown.
5
Settings/tests/robotests/config/robolectric.properties
Normal file
5
Settings/tests/robotests/config/robolectric.properties
Normal file
@@ -0,0 +1,5 @@
|
||||
sdk=NEWEST_SDK
|
||||
shadows=\
|
||||
com.android.settings.testutils.shadow.ShadowThreadUtils \
|
||||
com.android.settings.network.ShadowServiceManagerExtend
|
||||
instrumentedPackages=androidx.preference
|
||||
16
Settings/tests/robotests/new_tests_hook.sh
Normal file
16
Settings/tests/robotests/new_tests_hook.sh
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script detects the presence of new robolectric java tests within
|
||||
# commits to be uploaded. If a new file is detected the script will print an
|
||||
# error message and return an error code. Intended to be used as a repo hook.
|
||||
|
||||
new_robolectric_tests=$(
|
||||
git diff --name-status $REPO_LREV | grep "^A.*tests/robotests.*\.java")
|
||||
if [ $new_robolectric_tests != "" ]
|
||||
then
|
||||
echo "New Robolectric unit tests detected. Please submit junit tests" \
|
||||
"instead, in the tests/junit directory." \
|
||||
"See go/android-platform-robolectric-cleanup."
|
||||
echo $new_robolectric_tests
|
||||
exit 1
|
||||
fi
|
||||
@@ -0,0 +1,79 @@
|
||||
<?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.
|
||||
-->
|
||||
|
||||
<com.google.android.setupdesign.GlifLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/setup_wizard_layout"
|
||||
style="?attr/fingerprint_layout_theme"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:clipToPadding="false"
|
||||
android:clipChildren="false">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="@dimen/fingerprint_find_sensor_graphic_size"
|
||||
android:layout_height="@dimen/fingerprint_find_sensor_graphic_size"
|
||||
android:layout_gravity="center_horizontal|bottom">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/fingerprint_sensor_location_animation"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:contentDescription="@string/security_settings_fingerprint_enroll_find_sensor_content_description"
|
||||
android:src="@drawable/fingerprint_sensor_location"
|
||||
android:scaleType="centerInside"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
style="@style/SudContentFrame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:clipToPadding="false"
|
||||
android:clipChildren="false">
|
||||
|
||||
<TextView
|
||||
style="@style/SudDescription.Glif"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/sud_description_glif_margin_top"
|
||||
android:text="@string/security_settings_fingerprint_enroll_find_sensor_message"/>
|
||||
|
||||
<View
|
||||
android:layout_height="0dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<Button
|
||||
style="@style/SudGlifButton.Secondary"
|
||||
android:id="@+id/next_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:layout_gravity="end"
|
||||
android:text="@string/fingerprint_enroll_button_next" />
|
||||
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
</com.google.android.setupdesign.GlifLayout>
|
||||
134
Settings/tests/robotests/res/layout/main_clear.xml
Normal file
134
Settings/tests/robotests/res/layout/main_clear.xml
Normal file
@@ -0,0 +1,134 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2021 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.
|
||||
-->
|
||||
|
||||
<com.google.android.setupdesign.GlifLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/setup_wizard_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:theme="@style/GlifV3Theme.Footer"
|
||||
android:orientation="vertical"
|
||||
android:icon="@drawable/ic_delete_accent"
|
||||
app:sucHeaderText="@string/main_clear_title">
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/main_clear_scrollview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/main_clear_container"
|
||||
style="@style/SudContentFrame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
style="@style/TextAppearance.SudGlifItemSummary"
|
||||
android:id="@+id/sud_layout_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/main_clear_desc"/>
|
||||
<TextView
|
||||
android:id="@+id/also_erases_external"
|
||||
style="@style/TextAppearance.SudGlifItemSummary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
android:text="@string/main_clear_desc_also_erases_external"/>
|
||||
<TextView
|
||||
android:id="@+id/also_erases_esim"
|
||||
style="@style/TextAppearance.SudGlifItemSummary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
android:text="@string/main_clear_desc_also_erases_esim"/>
|
||||
<TextView
|
||||
android:id="@+id/accounts_label"
|
||||
style="@style/TextAppearance.SudGlifItemSummary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
android:text="@string/main_clear_accounts"/>
|
||||
<LinearLayout
|
||||
android:id="@+id/accounts"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
<!-- Do not add any children here as they will be removed in the MainClear.java
|
||||
code. A list of accounts will be inserted programmatically. -->
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
android:id="@+id/other_users_present"
|
||||
style="@style/TextAppearance.SudGlifItemSummary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
android:text="@string/main_clear_other_users_present"/>
|
||||
<TextView
|
||||
android:id="@+id/no_cancel_mobile_plan"
|
||||
style="@style/TextAppearance.SudGlifItemSummary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
android:text="@string/main_clear_desc_no_cancel_mobile_plan"/>
|
||||
<TextView
|
||||
android:id="@+id/erase_external_option_text"
|
||||
style="@style/TextAppearance.SudGlifItemSummary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/main_clear_desc_erase_external_storage"/>
|
||||
<LinearLayout
|
||||
android:id="@+id/erase_external_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:focusable="true"
|
||||
android:clickable="true">
|
||||
<CheckBox
|
||||
android:id="@+id/erase_external"
|
||||
style="@style/SudCheckBox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:focusable="false"
|
||||
android:clickable="false"
|
||||
android:duplicateParentState="true"/>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:orientation="vertical">
|
||||
<TextView
|
||||
style="@style/TextAppearance.SudGlifItemTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/erase_external_storage"/>
|
||||
<TextView
|
||||
style="@style/TextAppearance.SudGlifItemSummary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/erase_external_storage_description"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/reset_esim_checkbox"/>
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
</com.google.android.setupdesign.GlifLayout>
|
||||
40
Settings/tests/robotests/res/layout/main_clear_confirm.xml
Normal file
40
Settings/tests/robotests/res/layout/main_clear_confirm.xml
Normal file
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2021 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.
|
||||
-->
|
||||
<com.google.android.setupdesign.GlifLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:theme="@style/SudThemeGlifV3.DayNight"
|
||||
android:orientation="vertical"
|
||||
android:id="@+id/setup_wizard_layout"
|
||||
android:icon="@drawable/ic_delete_accent"
|
||||
app:sucHeaderText="@string/main_clear_confirm_title">
|
||||
|
||||
<LinearLayout
|
||||
style="@style/SudContentFrame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sud_layout_description"
|
||||
style="@style/SudItemTitle.GlifDescription"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/main_clear_final_desc"/>
|
||||
</LinearLayout>
|
||||
</com.google.android.setupdesign.GlifLayout>
|
||||
58
Settings/tests/robotests/res/layout/preference.xml
Normal file
58
Settings/tests/robotests/res/layout/preference.xml
Normal file
@@ -0,0 +1,58 @@
|
||||
<?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.
|
||||
-->
|
||||
|
||||
<!-- A test preference layout containing all required widgets -->
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:id="@android:id/icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:ellipsize="marquee"
|
||||
android:fadingEdge="horizontal" />
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@android:id/title"
|
||||
android:layout_alignStart="@android:id/title"
|
||||
android:visibility="gone"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:maxLines="10" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@android:id/widget_frame"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:minWidth="58dip"
|
||||
android:gravity="end|center_vertical"
|
||||
android:orientation="vertical" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<!-- Since Robolectric can't inflate @*android:layout/alert_dialog_button_bar_material in
|
||||
../res/layout/wifi_add_network_view.xml, so this Layout overrides button bar part. -->
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
layout="@layout/wifi_dialog"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true">
|
||||
<Button
|
||||
android:id="@android:id/button2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
<Button
|
||||
android:id="@android:id/button1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
BIN
Settings/tests/robotests/res/raw/sample_video.mp4
Normal file
BIN
Settings/tests/robotests/res/raw/sample_video.mp4
Normal file
Binary file not shown.
20
Settings/tests/robotests/res/values-mcc998/config.xml
Normal file
20
Settings/tests/robotests/res/values-mcc998/config.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<!-- List of packages that should be allowlisted for slice uri access. Do not translate -->
|
||||
<string-array name="slice_allowlist_package_names" translatable="false"/>
|
||||
</resources>
|
||||
103
Settings/tests/robotests/res/values-mcc999/config.xml
Normal file
103
Settings/tests/robotests/res/values-mcc999/config.xml
Normal file
@@ -0,0 +1,103 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<bool name="config_enableColorTemperature">false</bool>
|
||||
<bool name="config_show_camera_laser_sensor">false</bool>
|
||||
<bool name="config_show_connectivity_monitor">false</bool>
|
||||
<bool name="config_additional_system_update_setting_enable">true</bool>
|
||||
<bool name="config_show_wifi_settings">false</bool>
|
||||
<bool name="config_show_toggle_airplane">false</bool>
|
||||
<bool name="config_show_private_dns_settings">false</bool>
|
||||
<bool name="config_show_app_info_settings_memory">true</bool>
|
||||
<bool name="config_show_app_info_settings_battery">false</bool>
|
||||
<bool name="config_show_high_power_apps">false</bool>
|
||||
<bool name="config_show_alarm_volume">false</bool>
|
||||
<bool name="config_show_charging_sounds">false</bool>
|
||||
<bool name="config_show_media_volume">false</bool>
|
||||
<bool name="config_show_notification_ringtone">false</bool>
|
||||
<bool name="config_show_notification_volume">false</bool>
|
||||
<bool name="config_show_screen_locking_sounds">false</bool>
|
||||
<bool name="config_show_touch_sounds">false</bool>
|
||||
<bool name="config_show_encryption_and_credentials_encryption_status">false</bool>
|
||||
<bool name="config_show_premium_sms">false</bool>
|
||||
<bool name="config_show_data_saver">false</bool>
|
||||
<bool name="config_show_enabled_vr_listeners">false</bool>
|
||||
<bool name="config_location_mode_available">false</bool>
|
||||
<bool name="config_show_location_scanning">false</bool>
|
||||
<bool name="config_show_location_services">false</bool>
|
||||
<bool name="config_show_manage_device_admin">false</bool>
|
||||
<bool name="config_show_unlock_set_or_change">false</bool>
|
||||
<bool name="config_show_screen_pinning_settings">false</bool>
|
||||
<bool name="config_show_manage_trust_agents">false</bool>
|
||||
<bool name="config_show_show_password">false</bool>
|
||||
<bool name="config_show_trust_agent_click_intent">false</bool>
|
||||
<bool name="config_show_wallpaper_attribution">false</bool>
|
||||
<bool name="config_show_assist_and_voice_input">false</bool>
|
||||
<bool name="config_show_phone_language">false</bool>
|
||||
<bool name="config_show_virtual_keyboard_pref">false</bool>
|
||||
<bool name="config_show_physical_keyboard_pref">false</bool>
|
||||
<bool name="config_show_tts_settings_summary">false</bool>
|
||||
<bool name="config_show_pointer_speed">false</bool>
|
||||
<bool name="config_show_vibrate_input_devices">false</bool>
|
||||
<bool name="config_show_reset_dashboard">false</bool>
|
||||
<bool name="config_show_device_model">false</bool>
|
||||
<bool name="config_show_top_level_accessibility">false</bool>
|
||||
<bool name="config_show_top_level_battery">false</bool>
|
||||
<bool name="config_show_top_level_connected_devices">false</bool>
|
||||
<bool name="config_show_top_level_display">false</bool>
|
||||
<bool name="config_show_wifi_ip_address">false</bool>
|
||||
<bool name="config_show_wifi_mac_address">false</bool>
|
||||
<bool name="config_disable_uninstall_update">true</bool>
|
||||
<bool name="config_show_device_name">false</bool>
|
||||
<bool name="config_use_legacy_suggestion">false</bool>
|
||||
<bool name="config_show_avatar_in_homepage">true</bool>
|
||||
<bool name="config_show_branded_account_in_device_info">false</bool>
|
||||
<bool name="config_show_emergency_info_in_device_info">false</bool>
|
||||
<bool name="config_show_smooth_display">false</bool>
|
||||
<bool name="config_settingsintelligence_slice_supported">true</bool>
|
||||
|
||||
<!-- Whether or not extra preview panels should be used for screen zoom setting. -->
|
||||
<bool name="config_enable_extra_screen_zoom_preview">false</bool>
|
||||
|
||||
<!-- Whether dismissal timestamp should be kept before deletion -->
|
||||
<bool name="config_keep_contextual_card_dismissal_timestamp">true</bool>
|
||||
|
||||
<!-- List of a11y components on the device allowed to be enabled by Settings Slices -->
|
||||
<string-array name="config_settings_slices_accessibility_components" translatable="false">
|
||||
<item>fake_package/fake_service</item>
|
||||
</string-array>
|
||||
|
||||
<!-- List of packages that should be allowlisted for slice uri access. Do not translate -->
|
||||
<string-array name="slice_allowlist_package_names" translatable="false">
|
||||
<item>com.android.settings.slice_allowlist_package</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Email address for the homepage contextual cards feedback -->
|
||||
<string name="config_contextual_card_feedback_email" translatable="false">test@test.test</string>
|
||||
|
||||
<!-- Grayscale settings intent -->
|
||||
<string name="config_grayscale_settings_intent" translatable="false">intent:#Intent;action=test.test;end</string>
|
||||
|
||||
<!-- List containing the injected tile keys which are suppressed. -->
|
||||
<string-array name="config_suppress_injected_tile_keys" translatable="false">
|
||||
<item>injected_tile_key</item>
|
||||
<item>injected_tile_key2</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Uri to query non-public Slice Uris. -->
|
||||
<string name="config_non_public_slice_query_uri" translatable="false">content://com.android.settings.slices/test</string>
|
||||
</resources>
|
||||
24
Settings/tests/robotests/res/values/config.xml
Normal file
24
Settings/tests/robotests/res/values/config.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<!-- Whether or not new device intro suggestion is supported for this device -->
|
||||
<bool name="config_enableColorTemperature">true</bool>
|
||||
<bool name="config_show_camera_laser_sensor">true</bool>
|
||||
<bool name="config_show_connectivity_monitor">true</bool>
|
||||
<bool name="config_show_smooth_display">true</bool>
|
||||
<bool name="config_show_location_services">true</bool>
|
||||
</resources>
|
||||
22
Settings/tests/robotests/res/values/themes.xml
Normal file
22
Settings/tests/robotests/res/values/themes.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<resources>
|
||||
<style name="Theme.Settings" parent="@android:style/Theme.DeviceDefault.Settings">
|
||||
<!-- For AndroidX AlertDialogs -->
|
||||
<item name="alertDialogTheme">@style/Theme.AppCompat.DayNight.Dialog.Alert</item>
|
||||
</style>
|
||||
|
||||
<!-- Override the main app's style for ActionPrimaryButton to get around lack of new style
|
||||
support in robolectric -->
|
||||
<style name="ActionPrimaryButton" parent="android:Widget.DeviceDefault.Button"/>
|
||||
|
||||
<!-- Test version of Theme.Settings.Home. Needed to build homepage activity in Robolectric -->
|
||||
<style name="Theme.Settings.Home" parent="Theme.AppCompat.DayNight.NoActionBar">
|
||||
<item name="colorPrimary">#ffffff</item>
|
||||
<item name="colorPrimaryDark">#ffffff</item>
|
||||
<item name="colorAccent">#ffffff</item>
|
||||
<item name="preferenceTheme">@style/SettingsPreferenceTheme</item>
|
||||
<item name="android:windowLightStatusBar">true</item>
|
||||
<!-- Define this color for material design -->
|
||||
<item name="colorPrimaryVariant">@android:color/white</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:key="fake_title_key"
|
||||
android:title="screen_title">
|
||||
|
||||
<Preference
|
||||
android:key="key1"
|
||||
android:title="title"
|
||||
android:icon="@drawable/ic_android"
|
||||
android:summary="summary1"
|
||||
settings:controller="com.android.settings.core.BadPreferenceController"/>
|
||||
|
||||
<Preference
|
||||
android:key="key2"
|
||||
android:title="title"
|
||||
android:icon="@drawable/ic_android"
|
||||
android:summary="summary2"
|
||||
settings:controller="com.android.settings.slices.FakePreferenceController"/>
|
||||
|
||||
</PreferenceScreen>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2019 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">
|
||||
<com.android.settings.widget.SeekBarPreference
|
||||
android:key="seek_bar"
|
||||
android:title="seek_bar_title"/>
|
||||
</PreferenceScreen >
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/battery_saver_schedule_settings_title"
|
||||
settings:staticPreferenceLocation="append">
|
||||
</PreferenceScreen >
|
||||
64
Settings/tests/robotests/res/xml-mcc999/display_settings.xml
Normal file
64
Settings/tests/robotests/res/xml-mcc999/display_settings.xml
Normal file
@@ -0,0 +1,64 @@
|
||||
<?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.
|
||||
-->
|
||||
|
||||
<!--
|
||||
WARNING: This resource file is used to test Settings Search indexing.
|
||||
If you change something in here, please run the settings robotests and
|
||||
make sure they still pass.
|
||||
-->
|
||||
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:title="page_title"
|
||||
settings:keywords="keywords">
|
||||
|
||||
<Preference
|
||||
android:key="pref_key_1"
|
||||
android:title="pref_title_1"
|
||||
android:summary="summary_1"
|
||||
settings:keywords="keywords1, keywords2, keywords3" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="pref_key_2"
|
||||
android:title="pref_title_2"
|
||||
android:summary="summary_2"
|
||||
settings:keywords="keywords1, keywords2, keywords3" />
|
||||
|
||||
<Preference
|
||||
android:key="pref_key_3"
|
||||
android:title="pref_title_3"
|
||||
android:summary="summary_3"
|
||||
android:icon="@drawable/ic_android"
|
||||
settings:keywords="keywords1, keywords2, keywords3" />
|
||||
|
||||
<ListPreference
|
||||
android:key="pref_key_4"
|
||||
android:title="pref_title_4"
|
||||
android:summary="summary_4"
|
||||
android:entries="@array/mvno_type_entries"
|
||||
android:entryValues="@array/mvno_type_values"
|
||||
settings:keywords="keywords1, keywords2, keywords3" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:key="pref_key_5"
|
||||
android:title="pref_title_5"
|
||||
android:summaryOn="summary_on"
|
||||
android:summaryOff="summary_off"
|
||||
settings:searchable="false"
|
||||
settings:keywords="keywords1, keywords2, keywords3" />
|
||||
</PreferenceScreen>
|
||||
@@ -0,0 +1,32 @@
|
||||
<?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"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:key="fake_title_key"
|
||||
android:title="screen_title">
|
||||
|
||||
<Preference
|
||||
android:key="key"
|
||||
android:title="title"
|
||||
android:icon="@drawable/ic_android"
|
||||
android:summary="summary"
|
||||
settings:highlightableMenuKey="menu_key"
|
||||
settings:controller="com.android.settings.slices.FakePreferenceController"
|
||||
settings:keywords="a, b, c"
|
||||
settings:unavailableSliceSubtitle="subtitleOfUnavailableSlice"/>
|
||||
|
||||
</PreferenceScreen>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:key="fake_title_key"
|
||||
android:title="screen_title">
|
||||
|
||||
<Preference
|
||||
android:key="key1"
|
||||
android:title="title"
|
||||
android:icon="@drawable/ic_android"
|
||||
android:summary="summary"
|
||||
settings:controller="com.android.settings.slices.FakePreferenceController"
|
||||
settings:keywords="keyword"/>
|
||||
|
||||
<Preference
|
||||
android:key="key2"
|
||||
android:title="title"
|
||||
android:icon="@drawable/ic_android"
|
||||
android:summary="summary"
|
||||
settings:controller="com.android.settings.slices.FakePreferenceController"
|
||||
settings:keywords="keyword"
|
||||
settings:unavailableSliceSubtitle="subtitleOfUnavailable"/>
|
||||
|
||||
</PreferenceScreen>
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2019 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">
|
||||
<com.android.settings.widget.SeekBarPreference
|
||||
android:key="seek_bar"
|
||||
android:selectable="true"
|
||||
android:title="seek_bar_title"/>
|
||||
</PreferenceScreen >
|
||||
32
Settings/tests/robotests/res/xml-mcc999/video_preference.xml
Normal file
32
Settings/tests/robotests/res/xml-mcc999/video_preference.xml
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2019 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">
|
||||
<com.android.settings.widget.VideoPreference
|
||||
android:key="video1"
|
||||
settings:animation="@raw/face_education"
|
||||
settings:preview="@drawable/face_enroll_intro_illustration"
|
||||
android:title="seek_bar_title"/>
|
||||
<com.android.settings.widget.VideoPreference
|
||||
android:key="video2"
|
||||
settings:animation="@raw/face_education"
|
||||
settings:preview="@drawable/face_enroll_intro_illustration"
|
||||
settings:vectorAnimation="@drawable/face_enroll_intro_illustration"
|
||||
android:title="seek_bar_title"/>
|
||||
</PreferenceScreen >
|
||||
@@ -0,0 +1 @@
|
||||
org.robolectric.android.internal.RobolectricThreadChecker
|
||||
@@ -0,0 +1 @@
|
||||
org.robolectric.android.internal.LocalActivityInvoker
|
||||
@@ -0,0 +1 @@
|
||||
org.robolectric.android.internal.LocalPermissionGranter
|
||||
@@ -0,0 +1 @@
|
||||
org.robolectric.android.internal.LocalControlledLooper
|
||||
@@ -0,0 +1 @@
|
||||
org.robolectric.android.internal.LocalUiController
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings;
|
||||
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.Context;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
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.shadows.ShadowSettings;
|
||||
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public final class AirplaneModeEnablerTest {
|
||||
|
||||
private Context mContext;
|
||||
|
||||
@Mock
|
||||
private AirplaneModeChangedListener mAirplaneModeChangedListener;
|
||||
private AirplaneModeEnabler mAirplaneModeEnabler;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = RuntimeEnvironment.application.getBaseContext();
|
||||
mAirplaneModeEnabler = new AirplaneModeEnabler(mContext,
|
||||
mAirplaneModeChangedListener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onRadioPowerStateChanged_beenInvoke_invokeOnAirplaneModeChanged() {
|
||||
mAirplaneModeEnabler.start();
|
||||
|
||||
ShadowSettings.setAirplaneMode(true);
|
||||
|
||||
mAirplaneModeEnabler.mPhoneStateListener.onRadioPowerStateChanged(
|
||||
TelephonyManager.RADIO_POWER_OFF);
|
||||
|
||||
verify(mAirplaneModeChangedListener, times(1)).onAirplaneModeChanged(true);
|
||||
}
|
||||
|
||||
private class AirplaneModeChangedListener
|
||||
implements AirplaneModeEnabler.OnAirplaneModeChangedListener {
|
||||
public void onAirplaneModeChanged(boolean isAirplaneModeOn) {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.android.settings;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.testutils.XmlTestUtils;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class DisplaySettingsTest {
|
||||
|
||||
@Test
|
||||
public void testPreferenceControllers_getPreferenceKeys_existInPreferenceScreen() {
|
||||
final Context context = ApplicationProvider.getApplicationContext();
|
||||
final DisplaySettings fragment = new DisplaySettings();
|
||||
final List<String> preferenceScreenKeys = XmlTestUtils.getKeysFromPreferenceXml(context,
|
||||
fragment.getPreferenceScreenResId());
|
||||
final List<String> preferenceKeys = new ArrayList<>();
|
||||
|
||||
for (AbstractPreferenceController controller : fragment.createPreferenceControllers(context)) {
|
||||
preferenceKeys.add(controller.getPreferenceKey());
|
||||
}
|
||||
// Nightmode is currently hidden
|
||||
preferenceKeys.remove("night_mode");
|
||||
|
||||
assertThat(preferenceScreenKeys).containsAtLeastElementsIn(preferenceKeys);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Intent;
|
||||
|
||||
import com.android.settings.testutils.shadow.ShadowHelpUtils;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowActivity;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = ShadowHelpUtils.class)
|
||||
public class HelpTrampolineTest {
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
ShadowHelpUtils.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void launchHelp_noExtra_shouldDoNothing() {
|
||||
final Intent intent = new Intent().setClassName(
|
||||
RuntimeEnvironment.application.getPackageName(), HelpTrampoline.class.getName());
|
||||
|
||||
Robolectric.buildActivity(HelpTrampoline.class, intent).create().get();
|
||||
|
||||
assertThat(ShadowHelpUtils.isGetHelpIntentCalled()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void launchHelp_hasExtra_shouldLaunchHelp() {
|
||||
final Intent intent = new Intent().setClassName(
|
||||
RuntimeEnvironment.application.getPackageName(), HelpTrampoline.class.getName())
|
||||
.putExtra(Intent.EXTRA_TEXT, "help_url_upgrading");
|
||||
final ShadowActivity shadow = Shadows.
|
||||
shadowOf(Robolectric.buildActivity(HelpTrampoline.class, intent).create().get());
|
||||
final Intent launchedIntent = shadow.getNextStartedActivity();
|
||||
|
||||
assertThat(ShadowHelpUtils.isGetHelpIntentCalled()).isTrue();
|
||||
assertThat(launchedIntent).isNotNull();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.settings;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settings.testutils.XmlTestUtils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class LegalSettingsTest {
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getNonIndexableKeys_existInXmlLayout() {
|
||||
final Context context = RuntimeEnvironment.application;
|
||||
final List<String> niks =
|
||||
LegalSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(context);
|
||||
|
||||
final List<String> keys = XmlTestUtils.getKeysFromPreferenceXml(context, R.xml.about_legal);
|
||||
|
||||
assertThat(keys).containsAtLeastElementsIn(niks);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.app.admin.FactoryResetProtectionPolicy;
|
||||
import android.content.Context;
|
||||
import android.service.persistentdata.PersistentDataBlockManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {
|
||||
com.android.settings.testutils.shadow.ShadowFragment.class,
|
||||
})
|
||||
public class MainClearConfirmTest {
|
||||
|
||||
private FragmentActivity mActivity;
|
||||
|
||||
@Mock
|
||||
private FragmentActivity mMockActivity;
|
||||
|
||||
@Mock
|
||||
private DevicePolicyManager mDevicePolicyManager;
|
||||
|
||||
@Mock
|
||||
private PersistentDataBlockManager mPersistentDataBlockManager;
|
||||
|
||||
private MainClearConfirm mMainClearConfirm;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mActivity = Robolectric.setupActivity(FragmentActivity.class);
|
||||
mMainClearConfirm = spy(new MainClearConfirm());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setSubtitle_eraseEsim() {
|
||||
MainClearConfirm mainClearConfirm = new MainClearConfirm();
|
||||
mainClearConfirm.mEraseEsims = true;
|
||||
mainClearConfirm.mContentView =
|
||||
LayoutInflater.from(mActivity).inflate(R.layout.main_clear_confirm, null);
|
||||
|
||||
mainClearConfirm.setSubtitle();
|
||||
|
||||
assertThat(((TextView) mainClearConfirm.mContentView
|
||||
.findViewById(R.id.sud_layout_description)).getText())
|
||||
.isEqualTo(mActivity.getString(R.string.main_clear_final_desc_esim));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setSubtitle_notEraseEsim() {
|
||||
MainClearConfirm mainClearConfirm = new MainClearConfirm();
|
||||
mainClearConfirm.mEraseEsims = false;
|
||||
mainClearConfirm.mContentView =
|
||||
LayoutInflater.from(mActivity).inflate(R.layout.main_clear_confirm, null);
|
||||
|
||||
mainClearConfirm.setSubtitle();
|
||||
|
||||
assertThat(((TextView) mainClearConfirm.mContentView
|
||||
.findViewById(R.id.sud_layout_description)).getText())
|
||||
.isEqualTo(mActivity.getString(R.string.main_clear_final_desc));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldWipePersistentDataBlock_noPersistentDataBlockManager_shouldReturnFalse() {
|
||||
assertThat(mMainClearConfirm.shouldWipePersistentDataBlock(null)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldWipePersistentDataBlock_deviceIsStillBeingProvisioned_shouldReturnFalse() {
|
||||
doReturn(true).when(mMainClearConfirm).isDeviceStillBeingProvisioned();
|
||||
|
||||
assertThat(mMainClearConfirm.shouldWipePersistentDataBlock(
|
||||
mPersistentDataBlockManager)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldWipePersistentDataBlock_oemUnlockAllowed_shouldReturnFalse() {
|
||||
doReturn(false).when(mMainClearConfirm).isDeviceStillBeingProvisioned();
|
||||
doReturn(true).when(mMainClearConfirm).isOemUnlockedAllowed();
|
||||
|
||||
assertThat(mMainClearConfirm.shouldWipePersistentDataBlock(
|
||||
mPersistentDataBlockManager)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldWipePersistentDataBlock_frpPolicyNotSupported_shouldReturnFalse() {
|
||||
when(mMainClearConfirm.getActivity()).thenReturn(mMockActivity);
|
||||
|
||||
doReturn(false).when(mMainClearConfirm).isDeviceStillBeingProvisioned();
|
||||
doReturn(false).when(mMainClearConfirm).isOemUnlockedAllowed();
|
||||
when(mMockActivity.getSystemService(Context.DEVICE_POLICY_SERVICE))
|
||||
.thenReturn(mDevicePolicyManager);
|
||||
when(mDevicePolicyManager.isFactoryResetProtectionPolicySupported()).thenReturn(false);
|
||||
|
||||
assertThat(mMainClearConfirm.shouldWipePersistentDataBlock(
|
||||
mPersistentDataBlockManager)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldWipePersistentDataBlock_hasFactoryResetProtectionPolicy_shouldReturnFalse() {
|
||||
when(mMainClearConfirm.getActivity()).thenReturn(mMockActivity);
|
||||
|
||||
doReturn(false).when(mMainClearConfirm).isDeviceStillBeingProvisioned();
|
||||
doReturn(false).when(mMainClearConfirm).isOemUnlockedAllowed();
|
||||
ArrayList<String> accounts = new ArrayList<>();
|
||||
accounts.add("test");
|
||||
FactoryResetProtectionPolicy frp = new FactoryResetProtectionPolicy.Builder()
|
||||
.setFactoryResetProtectionAccounts(accounts)
|
||||
.setFactoryResetProtectionEnabled(true)
|
||||
.build();
|
||||
when(mMockActivity.getSystemService(Context.DEVICE_POLICY_SERVICE))
|
||||
.thenReturn(mDevicePolicyManager);
|
||||
when(mDevicePolicyManager.isFactoryResetProtectionPolicySupported()).thenReturn(true);
|
||||
when(mDevicePolicyManager.getFactoryResetProtectionPolicy(null)).thenReturn(frp);
|
||||
when(mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile()).thenReturn(true);
|
||||
|
||||
assertThat(mMainClearConfirm.shouldWipePersistentDataBlock(
|
||||
mPersistentDataBlockManager)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldWipePersistentDataBlock_isNotOrganizationOwnedDevice_shouldReturnTrue() {
|
||||
when(mMainClearConfirm.getActivity()).thenReturn(mMockActivity);
|
||||
|
||||
doReturn(false).when(mMainClearConfirm).isDeviceStillBeingProvisioned();
|
||||
doReturn(false).when(mMainClearConfirm).isOemUnlockedAllowed();
|
||||
|
||||
when(mMockActivity.getSystemService(Context.DEVICE_POLICY_SERVICE))
|
||||
.thenReturn(mDevicePolicyManager);
|
||||
when(mDevicePolicyManager.isFactoryResetProtectionPolicySupported()).thenReturn(true);
|
||||
when(mDevicePolicyManager.getFactoryResetProtectionPolicy(null)).thenReturn(null);
|
||||
when(mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile()).thenReturn(false);
|
||||
|
||||
assertThat(mMainClearConfirm.shouldWipePersistentDataBlock(
|
||||
mPersistentDataBlockManager)).isTrue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,477 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.app.Activity;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ScrollView;
|
||||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import com.android.settings.testutils.shadow.ShadowUserManager;
|
||||
import com.android.settings.testutils.shadow.ShadowUtils;
|
||||
import com.android.settingslib.development.DevelopmentSettingsEnabler;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
import org.robolectric.shadows.ShadowActivity;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {
|
||||
ShadowUtils.class,
|
||||
ShadowUserManager.class,
|
||||
com.android.settings.testutils.shadow.ShadowFragment.class,
|
||||
})
|
||||
public class MainClearTest {
|
||||
|
||||
private static final String TEST_ACCOUNT_TYPE = "android.test.account.type";
|
||||
private static final String TEST_CONFIRMATION_PACKAGE = "android.test.conf.pkg";
|
||||
private static final String TEST_CONFIRMATION_CLASS = "android.test.conf.pkg.ConfActivity";
|
||||
private static final String TEST_ACCOUNT_NAME = "test@example.com";
|
||||
|
||||
@Mock
|
||||
private ScrollView mScrollView;
|
||||
@Mock
|
||||
private LinearLayout mLinearLayout;
|
||||
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
|
||||
@Mock
|
||||
private AccountManager mAccountManager;
|
||||
|
||||
@Mock
|
||||
private FragmentActivity mMockActivity;
|
||||
|
||||
@Mock
|
||||
private Intent mMockIntent;
|
||||
|
||||
private MainClear mMainClear;
|
||||
private ShadowActivity mShadowActivity;
|
||||
private FragmentActivity mActivity;
|
||||
private ShadowUserManager mShadowUserManager;
|
||||
private View mContentView;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mMainClear = spy(new MainClear() {
|
||||
@Override
|
||||
boolean showAnySubscriptionInfo(Context context) { return true; }
|
||||
});
|
||||
mActivity = Robolectric.setupActivity(FragmentActivity.class);
|
||||
mShadowActivity = Shadows.shadowOf(mActivity);
|
||||
UserManager userManager = mActivity.getSystemService(UserManager.class);
|
||||
mShadowUserManager = Shadow.extract(userManager);
|
||||
mShadowUserManager.setIsAdminUser(true);
|
||||
mContentView = LayoutInflater.from(mActivity).inflate(R.layout.main_clear, null);
|
||||
|
||||
// Make scrollView only have one child
|
||||
when(mScrollView.getChildAt(0)).thenReturn(mLinearLayout);
|
||||
when(mScrollView.getChildCount()).thenReturn(1);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
mShadowUserManager.setIsAdminUser(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowFinalConfirmation_eraseEsimVisible_eraseEsimChecked() {
|
||||
final Context context = mock(Context.class);
|
||||
when(mMainClear.getContext()).thenReturn(context);
|
||||
|
||||
mMainClear.mEsimStorage = mContentView.findViewById(R.id.erase_esim);
|
||||
mMainClear.mExternalStorage = mContentView.findViewById(R.id.erase_external);
|
||||
mMainClear.mEsimStorageContainer = mContentView.findViewById(R.id.erase_esim_container);
|
||||
mMainClear.mEsimStorageContainer.setVisibility(View.VISIBLE);
|
||||
mMainClear.mEsimStorage.setChecked(true);
|
||||
mMainClear.showFinalConfirmation();
|
||||
|
||||
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
|
||||
|
||||
verify(context).startActivity(intent.capture());
|
||||
assertThat(intent.getValue().getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS)
|
||||
.getBoolean(MainClear.ERASE_ESIMS_EXTRA, false))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowFinalConfirmation_eraseEsimVisible_eraseEsimUnchecked() {
|
||||
final Context context = mock(Context.class);
|
||||
when(mMainClear.getContext()).thenReturn(context);
|
||||
|
||||
mMainClear.mEsimStorage = mContentView.findViewById(R.id.erase_esim);
|
||||
mMainClear.mExternalStorage = mContentView.findViewById(R.id.erase_external);
|
||||
mMainClear.mEsimStorageContainer = mContentView.findViewById(R.id.erase_esim_container);
|
||||
mMainClear.mEsimStorageContainer.setVisibility(View.VISIBLE);
|
||||
mMainClear.mEsimStorage.setChecked(false);
|
||||
mMainClear.showFinalConfirmation();
|
||||
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
|
||||
|
||||
verify(context).startActivity(intent.capture());
|
||||
assertThat(intent.getValue().getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS)
|
||||
.getBoolean(MainClear.ERASE_ESIMS_EXTRA, false))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowFinalConfirmation_eraseEsimGone_eraseEsimChecked() {
|
||||
final Context context = mock(Context.class);
|
||||
when(mMainClear.getContext()).thenReturn(context);
|
||||
|
||||
mMainClear.mEsimStorage = mContentView.findViewById(R.id.erase_esim);
|
||||
mMainClear.mExternalStorage = mContentView.findViewById(R.id.erase_external);
|
||||
mMainClear.mEsimStorageContainer = mContentView.findViewById(R.id.erase_esim_container);
|
||||
mMainClear.mEsimStorageContainer.setVisibility(View.GONE);
|
||||
mMainClear.mEsimStorage.setChecked(true);
|
||||
mMainClear.showFinalConfirmation();
|
||||
|
||||
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
|
||||
|
||||
verify(context).startActivity(intent.capture());
|
||||
assertThat(intent.getValue().getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS)
|
||||
.getBoolean(MainClear.ERASE_ESIMS_EXTRA, false))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowFinalConfirmation_eraseEsimGone_eraseEsimUnchecked() {
|
||||
final Context context = mock(Context.class);
|
||||
when(mMainClear.getContext()).thenReturn(context);
|
||||
|
||||
mMainClear.mEsimStorage = mContentView.findViewById(R.id.erase_esim);
|
||||
mMainClear.mExternalStorage = mContentView.findViewById(R.id.erase_external);
|
||||
mMainClear.mEsimStorageContainer = mContentView.findViewById(R.id.erase_esim_container);
|
||||
mMainClear.mEsimStorageContainer.setVisibility(View.GONE);
|
||||
mMainClear.mEsimStorage.setChecked(false);
|
||||
mMainClear.showFinalConfirmation();
|
||||
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
|
||||
|
||||
verify(context).startActivity(intent.capture());
|
||||
assertThat(intent.getValue().getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS)
|
||||
.getBoolean(MainClear.ERASE_ESIMS_EXTRA, false))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowWipeEuicc_euiccDisabled() {
|
||||
prepareEuiccState(
|
||||
false /* isEuiccEnabled */,
|
||||
true /* isEuiccProvisioned */,
|
||||
false /* isDeveloper */);
|
||||
assertThat(mMainClear.showWipeEuicc()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowWipeEuicc_euiccEnabled_unprovisioned() {
|
||||
prepareEuiccState(
|
||||
true /* isEuiccEnabled */,
|
||||
false /* isEuiccProvisioned */,
|
||||
false /* isDeveloper */);
|
||||
assertThat(mMainClear.showWipeEuicc()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowWipeEuicc_euiccEnabled_provisioned() {
|
||||
prepareEuiccState(
|
||||
true /* isEuiccEnabled */,
|
||||
true /* isEuiccProvisioned */,
|
||||
false /* isDeveloper */);
|
||||
assertThat(mMainClear.showWipeEuicc()).isTrue();
|
||||
}
|
||||
|
||||
@Ignore("b/313566998")
|
||||
@Test
|
||||
public void testShowWipeEuicc_developerMode_unprovisioned() {
|
||||
prepareEuiccState(
|
||||
true /* isEuiccEnabled */,
|
||||
false /* isEuiccProvisioned */,
|
||||
true /* isDeveloper */);
|
||||
assertThat(mMainClear.showWipeEuicc()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEsimRecheckBoxDefaultChecked() {
|
||||
assertThat(((CheckBox) mContentView.findViewById(R.id.erase_esim)).isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasReachedBottom_NotScrollDown_returnFalse() {
|
||||
initScrollView(100, 0, 200);
|
||||
|
||||
assertThat(mMainClear.hasReachedBottom(mScrollView)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasReachedBottom_CanNotScroll_returnTrue() {
|
||||
initScrollView(100, 0, 80);
|
||||
|
||||
assertThat(mMainClear.hasReachedBottom(mScrollView)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasReachedBottom_ScrollToBottom_returnTrue() {
|
||||
initScrollView(100, 100, 200);
|
||||
|
||||
assertThat(mMainClear.hasReachedBottom(mScrollView)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitiateMainClear_inDemoMode_sendsIntent() {
|
||||
ShadowUtils.setIsDemoUser(true);
|
||||
|
||||
final ComponentName componentName =
|
||||
ComponentName.unflattenFromString("com.android.retaildemo/.DeviceAdminReceiver");
|
||||
ShadowUtils.setDeviceOwnerComponent(componentName);
|
||||
|
||||
mMainClear.mInitiateListener.onClick(mContentView);
|
||||
final Intent intent = mShadowActivity.getNextStartedActivity();
|
||||
assertThat(Intent.ACTION_FACTORY_RESET).isEqualTo(intent.getAction());
|
||||
assertThat(componentName).isNotNull();
|
||||
assertThat(componentName.getPackageName()).isEqualTo(intent.getPackage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnActivityResultInternal_invalideRequest() {
|
||||
int invalidRequestCode = -1;
|
||||
doReturn(false).when(mMainClear).isValidRequestCode(eq(invalidRequestCode));
|
||||
|
||||
mMainClear.onActivityResultInternal(invalidRequestCode, Activity.RESULT_OK, null);
|
||||
|
||||
verify(mMainClear, times(1)).isValidRequestCode(eq(invalidRequestCode));
|
||||
verify(mMainClear, times(0)).establishInitialState();
|
||||
verify(mMainClear, times(0)).getAccountConfirmationIntent();
|
||||
verify(mMainClear, times(0)).showFinalConfirmation();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnActivityResultInternal_resultCanceled() {
|
||||
doReturn(true).when(mMainClear).isValidRequestCode(eq(MainClear.KEYGUARD_REQUEST));
|
||||
doNothing().when(mMainClear).establishInitialState();
|
||||
|
||||
mMainClear
|
||||
.onActivityResultInternal(MainClear.KEYGUARD_REQUEST, Activity.RESULT_CANCELED,
|
||||
null);
|
||||
|
||||
verify(mMainClear, times(1)).isValidRequestCode(eq(MainClear.KEYGUARD_REQUEST));
|
||||
verify(mMainClear, times(1)).establishInitialState();
|
||||
verify(mMainClear, times(0)).getAccountConfirmationIntent();
|
||||
verify(mMainClear, times(0)).showFinalConfirmation();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnActivityResultInternal_keyguardRequestTriggeringConfirmAccount() {
|
||||
doReturn(true).when(mMainClear).isValidRequestCode(eq(MainClear.KEYGUARD_REQUEST));
|
||||
doReturn(mMockIntent).when(mMainClear).getAccountConfirmationIntent();
|
||||
doNothing().when(mMainClear).showAccountCredentialConfirmation(eq(mMockIntent));
|
||||
|
||||
mMainClear
|
||||
.onActivityResultInternal(MainClear.KEYGUARD_REQUEST, Activity.RESULT_OK, null);
|
||||
|
||||
verify(mMainClear, times(1)).isValidRequestCode(eq(MainClear.KEYGUARD_REQUEST));
|
||||
verify(mMainClear, times(0)).establishInitialState();
|
||||
verify(mMainClear, times(1)).getAccountConfirmationIntent();
|
||||
verify(mMainClear, times(1)).showAccountCredentialConfirmation(eq(mMockIntent));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnActivityResultInternal_keyguardRequestTriggeringShowFinal() {
|
||||
doReturn(true).when(mMainClear).isValidRequestCode(eq(MainClear.KEYGUARD_REQUEST));
|
||||
doReturn(null).when(mMainClear).getAccountConfirmationIntent();
|
||||
doNothing().when(mMainClear).showFinalConfirmation();
|
||||
|
||||
mMainClear
|
||||
.onActivityResultInternal(MainClear.KEYGUARD_REQUEST, Activity.RESULT_OK, null);
|
||||
|
||||
verify(mMainClear, times(1)).isValidRequestCode(eq(MainClear.KEYGUARD_REQUEST));
|
||||
verify(mMainClear, times(0)).establishInitialState();
|
||||
verify(mMainClear, times(1)).getAccountConfirmationIntent();
|
||||
verify(mMainClear, times(1)).showFinalConfirmation();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnActivityResultInternal_confirmRequestTriggeringShowFinal() {
|
||||
doReturn(true).when(mMainClear)
|
||||
.isValidRequestCode(eq(MainClear.CREDENTIAL_CONFIRM_REQUEST));
|
||||
doNothing().when(mMainClear).showFinalConfirmation();
|
||||
|
||||
mMainClear.onActivityResultInternal(
|
||||
MainClear.CREDENTIAL_CONFIRM_REQUEST, Activity.RESULT_OK, null);
|
||||
|
||||
verify(mMainClear, times(1))
|
||||
.isValidRequestCode(eq(MainClear.CREDENTIAL_CONFIRM_REQUEST));
|
||||
verify(mMainClear, times(0)).establishInitialState();
|
||||
verify(mMainClear, times(0)).getAccountConfirmationIntent();
|
||||
verify(mMainClear, times(1)).showFinalConfirmation();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAccountConfirmationIntent_unsupported() {
|
||||
when(mMainClear.getActivity()).thenReturn(mActivity);
|
||||
/* Using the default resources, account confirmation shouldn't trigger */
|
||||
assertThat(mMainClear.getAccountConfirmationIntent()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAccountConfirmationIntent_no_relevant_accounts() {
|
||||
when(mMainClear.getActivity()).thenReturn(mMockActivity);
|
||||
when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE);
|
||||
when(mMockActivity.getString(R.string.account_confirmation_package))
|
||||
.thenReturn(TEST_CONFIRMATION_PACKAGE);
|
||||
when(mMockActivity.getString(R.string.account_confirmation_class))
|
||||
.thenReturn(TEST_CONFIRMATION_CLASS);
|
||||
|
||||
Account[] accounts = new Account[0];
|
||||
when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
|
||||
when(mAccountManager.getAccountsByType(TEST_ACCOUNT_TYPE)).thenReturn(accounts);
|
||||
assertThat(mMainClear.getAccountConfirmationIntent()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAccountConfirmationIntent_unresolved() {
|
||||
when(mMainClear.getActivity()).thenReturn(mMockActivity);
|
||||
when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE);
|
||||
when(mMockActivity.getString(R.string.account_confirmation_package))
|
||||
.thenReturn(TEST_CONFIRMATION_PACKAGE);
|
||||
when(mMockActivity.getString(R.string.account_confirmation_class))
|
||||
.thenReturn(TEST_CONFIRMATION_CLASS);
|
||||
Account[] accounts = new Account[]{new Account(TEST_ACCOUNT_NAME, TEST_ACCOUNT_TYPE)};
|
||||
when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
|
||||
when(mAccountManager.getAccountsByType(TEST_ACCOUNT_TYPE)).thenReturn(accounts);
|
||||
// The package manager should not resolve the confirmation intent targeting the non-existent
|
||||
// confirmation package.
|
||||
when(mMockActivity.getPackageManager()).thenReturn(mPackageManager);
|
||||
assertThat(mMainClear.getAccountConfirmationIntent()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTryShowAccountConfirmation_ok() {
|
||||
when(mMainClear.getActivity()).thenReturn(mMockActivity);
|
||||
// Only try to show account confirmation if the appropriate resource overlays are available.
|
||||
when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE);
|
||||
when(mMockActivity.getString(R.string.account_confirmation_package))
|
||||
.thenReturn(TEST_CONFIRMATION_PACKAGE);
|
||||
when(mMockActivity.getString(R.string.account_confirmation_class))
|
||||
.thenReturn(TEST_CONFIRMATION_CLASS);
|
||||
// Add accounts to trigger the search for a resolving intent.
|
||||
Account[] accounts = new Account[]{new Account(TEST_ACCOUNT_NAME, TEST_ACCOUNT_TYPE)};
|
||||
when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
|
||||
when(mAccountManager.getAccountsByType(TEST_ACCOUNT_TYPE)).thenReturn(accounts);
|
||||
// The package manager should not resolve the confirmation intent targeting the non-existent
|
||||
// confirmation package.
|
||||
when(mMockActivity.getPackageManager()).thenReturn(mPackageManager);
|
||||
|
||||
ActivityInfo activityInfo = new ActivityInfo();
|
||||
activityInfo.packageName = TEST_CONFIRMATION_PACKAGE;
|
||||
ResolveInfo resolveInfo = new ResolveInfo();
|
||||
resolveInfo.activityInfo = activityInfo;
|
||||
when(mPackageManager.resolveActivity(any(), eq(0))).thenReturn(resolveInfo);
|
||||
|
||||
Intent actualIntent = mMainClear.getAccountConfirmationIntent();
|
||||
assertThat(TEST_CONFIRMATION_PACKAGE).isEqualTo(
|
||||
actualIntent.getComponent().getPackageName());
|
||||
assertThat(TEST_CONFIRMATION_CLASS).isEqualTo(actualIntent.getComponent().getClassName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowAccountCredentialConfirmation() {
|
||||
// Finally mock out the startActivityForResultCall
|
||||
doNothing().when(mMainClear)
|
||||
.startActivityForResult(eq(mMockIntent),
|
||||
eq(MainClear.CREDENTIAL_CONFIRM_REQUEST));
|
||||
mMainClear.showAccountCredentialConfirmation(mMockIntent);
|
||||
verify(mMainClear, times(1))
|
||||
.startActivityForResult(eq(mMockIntent),
|
||||
eq(MainClear.CREDENTIAL_CONFIRM_REQUEST));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsValidRequestCode() {
|
||||
assertThat(mMainClear.isValidRequestCode(MainClear.KEYGUARD_REQUEST)).isTrue();
|
||||
assertThat(mMainClear.isValidRequestCode(MainClear.CREDENTIAL_CONFIRM_REQUEST))
|
||||
.isTrue();
|
||||
assertThat(mMainClear.isValidRequestCode(0)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnGlobalLayout_shouldNotRemoveListener() {
|
||||
final ViewTreeObserver viewTreeObserver = mock(ViewTreeObserver.class);
|
||||
mMainClear.mScrollView = mScrollView;
|
||||
doNothing().when(mMainClear).onGlobalLayout();
|
||||
doReturn(true).when(mMainClear).hasReachedBottom(any());
|
||||
when(mScrollView.getViewTreeObserver()).thenReturn(viewTreeObserver);
|
||||
|
||||
mMainClear.onGlobalLayout();
|
||||
|
||||
verify(viewTreeObserver, never()).removeOnGlobalLayoutListener(mMainClear);
|
||||
}
|
||||
|
||||
private void prepareEuiccState(
|
||||
boolean isEuiccEnabled, boolean isEuiccProvisioned, boolean isDeveloper) {
|
||||
doReturn(mActivity).when(mMainClear).getContext();
|
||||
doReturn(isEuiccEnabled).when(mMainClear).isEuiccEnabled(any());
|
||||
ContentResolver cr = mActivity.getContentResolver();
|
||||
Settings.Global.putInt(cr, Settings.Global.EUICC_PROVISIONED, isEuiccProvisioned ? 1 : 0);
|
||||
DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(mActivity, isDeveloper);
|
||||
}
|
||||
|
||||
private void initScrollView(int height, int scrollY, int childBottom) {
|
||||
when(mScrollView.getHeight()).thenReturn(height);
|
||||
when(mScrollView.getScrollY()).thenReturn(scrollY);
|
||||
when(mLinearLayout.getBottom()).thenReturn(childBottom);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings;
|
||||
|
||||
import static android.view.HapticFeedbackConstants.CLOCK_TICK;
|
||||
import static android.view.HapticFeedbackConstants.CONTEXT_CLICK;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.SeekBar;
|
||||
|
||||
import com.android.settings.testutils.shadow.ShadowInteractionJankMonitor;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {ShadowInteractionJankMonitor.class})
|
||||
public class PointerSpeedPreferenceTest {
|
||||
|
||||
private Context mContext;
|
||||
private AttributeSet mAttrs;
|
||||
private SeekBar mSeekBar;
|
||||
private PointerSpeedPreference mPointerSpeedPreference;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mSeekBar = new SeekBar(mContext, mAttrs);
|
||||
mPointerSpeedPreference = new PointerSpeedPreference(mContext, mAttrs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onProgressChanged_minimumValue_clockTickFeedbackPerformed() {
|
||||
mSeekBar.performHapticFeedback(CONTEXT_CLICK);
|
||||
mPointerSpeedPreference.onProgressChanged(mSeekBar, 0, true);
|
||||
|
||||
assertThat(shadowOf(mSeekBar).lastHapticFeedbackPerformed()).isEqualTo(CLOCK_TICK);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
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.Context;
|
||||
import android.os.Looper;
|
||||
import android.view.LayoutInflater;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
|
||||
import com.android.settings.testutils.shadow.ShadowRecoverySystem;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.annotation.LooperMode;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@LooperMode(LooperMode.Mode.LEGACY)
|
||||
@Config(shadows = {ShadowRecoverySystem.class, ShadowBluetoothAdapter.class})
|
||||
public class ResetNetworkConfirmTest {
|
||||
|
||||
private static final String TEST_PACKAGE = "com.android.settings";
|
||||
|
||||
private FragmentActivity mActivity;
|
||||
|
||||
@Mock
|
||||
private ResetNetworkConfirm mResetNetworkConfirm;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mResetNetworkConfirm = new ResetNetworkConfirm();
|
||||
mActivity = spy(Robolectric.setupActivity(FragmentActivity.class));
|
||||
mResetNetworkConfirm.mActivity = mActivity;
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
ShadowRecoverySystem.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResetNetworkData_notResetEsim() {
|
||||
mResetNetworkConfirm.mResetNetworkRequest =
|
||||
new ResetNetworkRequest(ResetNetworkRequest.RESET_NONE);
|
||||
mResetNetworkConfirm.mResetSubscriptionContract =
|
||||
new ResetSubscriptionContract(mActivity,
|
||||
mResetNetworkConfirm.mResetNetworkRequest) {
|
||||
@Override
|
||||
public void onSubscriptionInactive(int subscriptionId) {
|
||||
mActivity.onBackPressed();
|
||||
}
|
||||
};
|
||||
|
||||
mResetNetworkConfirm.mFinalClickListener.onClick(null /* View */);
|
||||
Robolectric.getBackgroundThreadScheduler().advanceToLastPostedRunnable();
|
||||
|
||||
assertThat(ShadowRecoverySystem.getWipeEuiccCalledCount()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setSubtitle_eraseEsim() {
|
||||
mResetNetworkConfirm.mResetNetworkRequest =
|
||||
new ResetNetworkRequest(ResetNetworkRequest.RESET_NONE);
|
||||
mResetNetworkConfirm.mResetNetworkRequest.setResetEsim(TEST_PACKAGE);
|
||||
|
||||
mResetNetworkConfirm.mContentView =
|
||||
LayoutInflater.from(mActivity).inflate(R.layout.reset_network_confirm, null);
|
||||
|
||||
mResetNetworkConfirm.setSubtitle();
|
||||
|
||||
assertThat(((TextView) mResetNetworkConfirm.mContentView
|
||||
.findViewById(R.id.reset_network_confirm)).getText())
|
||||
.isEqualTo(mActivity.getString(R.string.reset_network_final_desc_esim));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setSubtitle_notEraseEsim() {
|
||||
mResetNetworkConfirm.mResetNetworkRequest =
|
||||
new ResetNetworkRequest(ResetNetworkRequest.RESET_NONE);
|
||||
|
||||
mResetNetworkConfirm.mContentView =
|
||||
LayoutInflater.from(mActivity).inflate(R.layout.reset_network_confirm, null);
|
||||
|
||||
mResetNetworkConfirm.setSubtitle();
|
||||
|
||||
assertThat(((TextView) mResetNetworkConfirm.mContentView
|
||||
.findViewById(R.id.reset_network_confirm)).getText())
|
||||
.isEqualTo(mActivity.getString(R.string.reset_network_final_desc));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class ResetNetworkTest {
|
||||
private Activity mActivity;
|
||||
private ResetNetwork mResetNetwork;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mActivity = Robolectric.setupActivity(Activity.class);
|
||||
mResetNetwork = spy(new ResetNetwork());
|
||||
when(mResetNetwork.getContext()).thenReturn(mActivity);
|
||||
mResetNetwork.mEsimContainer = new View(mActivity);
|
||||
mResetNetwork.mEsimCheckbox = new CheckBox(mActivity);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void showFinalConfirmation_checkboxVisible_eraseEsimChecked() {
|
||||
mResetNetwork.mEsimContainer.setVisibility(View.VISIBLE);
|
||||
mResetNetwork.mEsimCheckbox.setChecked(true);
|
||||
|
||||
mResetNetwork.showFinalConfirmation();
|
||||
|
||||
Intent intent = shadowOf(mActivity).getNextStartedActivity();
|
||||
assertThat(intent.getStringExtra(ResetNetworkRequest.KEY_ESIM_PACKAGE))
|
||||
.isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void showFinalConfirmation_checkboxVisible_eraseEsimUnchecked() {
|
||||
mResetNetwork.mEsimContainer.setVisibility(View.VISIBLE);
|
||||
mResetNetwork.mEsimCheckbox.setChecked(false);
|
||||
|
||||
mResetNetwork.showFinalConfirmation();
|
||||
|
||||
Intent intent = shadowOf(mActivity).getNextStartedActivity();
|
||||
assertThat(intent.getStringExtra(ResetNetworkRequest.KEY_ESIM_PACKAGE))
|
||||
.isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void showFinalConfirmation_checkboxGone_eraseEsimChecked() {
|
||||
mResetNetwork.mEsimContainer.setVisibility(View.GONE);
|
||||
mResetNetwork.mEsimCheckbox.setChecked(true);
|
||||
|
||||
mResetNetwork.showFinalConfirmation();
|
||||
|
||||
Intent intent = shadowOf(mActivity).getNextStartedActivity();
|
||||
assertThat(intent.getStringExtra(ResetNetworkRequest.KEY_ESIM_PACKAGE))
|
||||
.isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void showFinalConfirmation_checkboxGone_eraseEsimUnchecked() {
|
||||
mResetNetwork.mEsimContainer.setVisibility(View.GONE);
|
||||
mResetNetwork.mEsimCheckbox.setChecked(false);
|
||||
|
||||
mResetNetwork.showFinalConfirmation();
|
||||
|
||||
Intent intent = shadowOf(mActivity).getNextStartedActivity();
|
||||
assertThat(intent.getStringExtra(ResetNetworkRequest.KEY_ESIM_PACKAGE))
|
||||
.isNull();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.robolectric.RuntimeEnvironment.application;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.KeyguardManager;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.android.settings.testutils.shadow.ShadowUserManager;
|
||||
import com.android.settingslib.RestrictedPreferenceHelper;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowKeyguardManager;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {ShadowUserManager.class, ShadowKeyguardManager.class})
|
||||
public class RestrictedListPreferenceTest {
|
||||
private static final int PROFILE_USER_ID = 11;
|
||||
// From UnlaunchableAppActivity
|
||||
private static final int UNLAUNCHABLE_REASON_QUIET_MODE = 1;
|
||||
private static final String EXTRA_UNLAUNCHABLE_REASON = "unlaunchable_reason";
|
||||
|
||||
private Activity mActivity;
|
||||
private ShadowUserManager mShadowUserManager;
|
||||
private ShadowKeyguardManager mShadowKeyguardManager;
|
||||
private RestrictedListPreference mPreference;
|
||||
private RestrictedPreferenceHelper mMockHelper;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mActivity = Robolectric.setupActivity(Activity.class);
|
||||
mShadowKeyguardManager =
|
||||
Shadows.shadowOf(application.getSystemService(KeyguardManager.class));
|
||||
mMockHelper = mock(RestrictedPreferenceHelper.class);
|
||||
mShadowUserManager = ShadowUserManager.getShadow();
|
||||
|
||||
AttributeSet attributeSet = Robolectric.buildAttributeSet().build();
|
||||
mPreference = new RestrictedListPreference(mActivity, attributeSet);
|
||||
mPreference.setProfileUserId(PROFILE_USER_ID);
|
||||
ReflectionHelpers.setField(mPreference, "mHelper", mMockHelper);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void performClick_profileLocked() {
|
||||
mPreference.setRequiresActiveUnlockedProfile(true);
|
||||
mShadowUserManager.setQuietModeEnabled(false);
|
||||
mShadowKeyguardManager.setIsDeviceLocked(PROFILE_USER_ID, true);
|
||||
// Device has to be marked as secure so the real KeyguardManager will create a non-null
|
||||
// intent.
|
||||
mShadowKeyguardManager.setIsDeviceSecure(PROFILE_USER_ID, true);
|
||||
mPreference.performClick();
|
||||
// Make sure that the performClick method on the helper is never reached.
|
||||
verify(mMockHelper, never()).performClick();
|
||||
// Assert that a CONFIRM_DEVICE_CREDENTIAL intent has been started.
|
||||
Intent started = Shadows.shadowOf(mActivity).getNextStartedActivity();
|
||||
assertThat(started.getExtras().getInt(Intent.EXTRA_USER_ID)).isEqualTo(PROFILE_USER_ID);
|
||||
assertThat(started.getAction())
|
||||
.isEqualTo(KeyguardManager.ACTION_CONFIRM_DEVICE_CREDENTIAL_WITH_USER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void performClick_profileDisabled() {
|
||||
mPreference.setRequiresActiveUnlockedProfile(true);
|
||||
mShadowUserManager.setQuietModeEnabled(true);
|
||||
mShadowKeyguardManager.setIsDeviceLocked(PROFILE_USER_ID, false);
|
||||
mPreference.performClick();
|
||||
// Make sure that the performClick method on the helper is never reached.
|
||||
verify(mMockHelper, never()).performClick();
|
||||
// Assert that a new intent for enabling the work profile is started.
|
||||
Intent started = Shadows.shadowOf(mActivity).getNextStartedActivity();
|
||||
Bundle extras = started.getExtras();
|
||||
int reason = extras.getInt(EXTRA_UNLAUNCHABLE_REASON);
|
||||
assertThat(reason).isEqualTo(UNLAUNCHABLE_REASON_QUIET_MODE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void performClick_profileAvailable() {
|
||||
// Verify that the helper's perfomClick method is called if the profile is
|
||||
// available and unlocked.
|
||||
mPreference.setRequiresActiveUnlockedProfile(true);
|
||||
mShadowUserManager.setQuietModeEnabled(false);
|
||||
mShadowKeyguardManager.setIsDeviceLocked(PROFILE_USER_ID, false);
|
||||
when(mMockHelper.performClick()).thenReturn(true);
|
||||
mPreference.performClick();
|
||||
verify(mMockHelper).performClick();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void performClick_profileLockedAndUnlockedProfileNotRequired() {
|
||||
// Verify that even if the profile is disabled, if the Preference class does not
|
||||
// require it than the regular flow takes place.
|
||||
mPreference.setRequiresActiveUnlockedProfile(false);
|
||||
mShadowUserManager.setQuietModeEnabled(true);
|
||||
when(mMockHelper.performClick()).thenReturn(true);
|
||||
mPreference.performClick();
|
||||
verify(mMockHelper).performClick();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class RestrictedSettingsFragmentTest {
|
||||
|
||||
@Mock
|
||||
private AlertDialog mAlertDialog;
|
||||
private RestrictedSettingsFragment mFragment;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onActivityResult_dismissesDialogOnOk() {
|
||||
mFragment = new RestrictedSettingsFragment("fake_key") {
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
doReturn(true).when(mAlertDialog).isShowing();
|
||||
mFragment.mActionDisabledDialog = mAlertDialog;
|
||||
mFragment.onActivityResult(RestrictedSettingsFragment.REQUEST_PIN_CHALLENGE,
|
||||
Activity.RESULT_OK,
|
||||
null);
|
||||
|
||||
// dialog should be gone
|
||||
verify(mAlertDialog, times(1)).setOnDismissListener(isNull());
|
||||
verify(mAlertDialog, times(1)).dismiss();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings;
|
||||
|
||||
import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
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.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
|
||||
import com.android.settings.core.OnActivityResultListener;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.shadow.ShadowUserManager;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = ShadowUserManager.class)
|
||||
public class SettingsActivityTest {
|
||||
|
||||
@Mock
|
||||
private FragmentManager mFragmentManager;
|
||||
@Mock
|
||||
private ActivityManager.TaskDescription mTaskDescription;
|
||||
private SettingsActivity mActivity;
|
||||
private Context mContext;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mActivity = spy(Robolectric.buildActivity(SettingsActivity.class).create().get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void launchSettingFragment_nullExtraShowFragment_shouldNotCrash() {
|
||||
when(mActivity.getSupportFragmentManager()).thenReturn(mFragmentManager);
|
||||
doReturn(mContext.getContentResolver()).when(mActivity).getContentResolver();
|
||||
when(mFragmentManager.beginTransaction()).thenReturn(mock(FragmentTransaction.class));
|
||||
doReturn(RuntimeEnvironment.application.getClassLoader()).when(mActivity).getClassLoader();
|
||||
|
||||
mActivity.launchSettingFragment(null, mock(Intent.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setTaskDescription_shouldUpdateIcon() {
|
||||
mActivity.setTaskDescription(mTaskDescription);
|
||||
|
||||
verify(mTaskDescription).setIcon(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSharedPreferences_intentExtraIsNull_shouldNotCrash() {
|
||||
final Intent intent = new Intent();
|
||||
intent.putExtra(EXTRA_SHOW_FRAGMENT, (String)null);
|
||||
doReturn(intent).when(mActivity).getIntent();
|
||||
doReturn(mContext.getPackageName()).when(mActivity).getPackageName();
|
||||
FakeFeatureFactory.setupForTest();
|
||||
|
||||
mActivity.getSharedPreferences(mContext.getPackageName() + "_preferences", 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onActivityResult_shouldDelegateToListener() {
|
||||
final List<Fragment> fragments = new ArrayList<>();
|
||||
fragments.add(new Fragment());
|
||||
fragments.add(new ListenerFragment());
|
||||
|
||||
final FragmentManager manager = mock(FragmentManager.class);
|
||||
when(mActivity.getSupportFragmentManager()).thenReturn(manager);
|
||||
when(manager.getFragments()).thenReturn(fragments);
|
||||
|
||||
mActivity.onActivityResult(0, 0, new Intent());
|
||||
|
||||
assertThat(((ListenerFragment) fragments.get(1)).mOnActivityResultCalled).isTrue();
|
||||
}
|
||||
|
||||
public static class ListenerFragment extends Fragment implements OnActivityResultListener {
|
||||
|
||||
private boolean mOnActivityResultCalled;
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
mOnActivityResultCalled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
package com.android.settings;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Dialog;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class SettingsDialogFragmentTest {
|
||||
|
||||
private static final int DIALOG_ID = 15;
|
||||
|
||||
@Mock
|
||||
private DialogCreatableFragment mDialogCreatable;
|
||||
private SettingsPreferenceFragment.SettingsDialogFragment mDialogFragment;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMetrics_shouldGetMetricFromDialogCreatable() {
|
||||
when(mDialogCreatable.getDialogMetricsCategory(DIALOG_ID)).thenReturn(1);
|
||||
|
||||
mDialogFragment = SettingsPreferenceFragment.SettingsDialogFragment.newInstance(
|
||||
mDialogCreatable, DIALOG_ID);
|
||||
mDialogFragment.onAttach(RuntimeEnvironment.application);
|
||||
mDialogFragment.getMetricsCategory();
|
||||
|
||||
// getDialogMetricsCategory called in onAttach, and explicitly in test.
|
||||
verify(mDialogCreatable, times(2)).getDialogMetricsCategory(DIALOG_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetInvalidMetricsValue_shouldCrash() {
|
||||
when(mDialogCreatable.getDialogMetricsCategory(DIALOG_ID)).thenReturn(-1);
|
||||
|
||||
try {
|
||||
mDialogFragment = SettingsPreferenceFragment.SettingsDialogFragment.newInstance(
|
||||
mDialogCreatable, DIALOG_ID);
|
||||
mDialogFragment.onAttach(RuntimeEnvironment.application);
|
||||
fail("Should fail with IllegalStateException");
|
||||
} catch (IllegalStateException e) {
|
||||
// getDialogMetricsCategory called in constructor
|
||||
verify(mDialogCreatable).getDialogMetricsCategory(DIALOG_ID);
|
||||
}
|
||||
}
|
||||
|
||||
public static class DialogCreatableFragment extends Fragment implements DialogCreatable {
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(int dialogId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDialogMetricsCategory(int dialogId) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.settings;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class SettingsDumpServiceTest {
|
||||
|
||||
private static final String PACKAGE_BROWSER = "com.android.test.browser";
|
||||
private static final String PACKAGE_NULL = "android";
|
||||
private static final int ANOMALY_VERSION = 2;
|
||||
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
@Mock
|
||||
private ResolveInfo mResolveInfo;
|
||||
private TestService mTestService;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
when(mPackageManager.resolveActivity(TestService.BROWSER_INTENT,
|
||||
PackageManager.MATCH_DEFAULT_ONLY)).thenReturn(mResolveInfo);
|
||||
mTestService = spy(new TestService());
|
||||
mTestService.setPackageManager(mPackageManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDumpDefaultBrowser_DefaultBrowser_ReturnBrowserName() {
|
||||
mResolveInfo.activityInfo = new ActivityInfo();
|
||||
mResolveInfo.activityInfo.packageName = PACKAGE_BROWSER;
|
||||
|
||||
assertThat(mTestService.dumpDefaultBrowser()).isEqualTo(PACKAGE_BROWSER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDumpDefaultBrowser_NoDefault_ReturnNull() {
|
||||
mResolveInfo.activityInfo = new ActivityInfo();
|
||||
mResolveInfo.activityInfo.packageName = PACKAGE_NULL;
|
||||
|
||||
assertThat(mTestService.dumpDefaultBrowser()).isEqualTo(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDump_printServiceAsKey() {
|
||||
mResolveInfo.activityInfo = new ActivityInfo();
|
||||
mResolveInfo.activityInfo.packageName = PACKAGE_BROWSER;
|
||||
StringWriter stringWriter = new StringWriter();
|
||||
PrintWriter printWriter = new PrintWriter(stringWriter);
|
||||
|
||||
mTestService.dump(null, printWriter, null);
|
||||
|
||||
assertThat(stringWriter.toString())
|
||||
.contains("{\"" + SettingsDumpService.KEY_SERVICE + "\":");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test service used to pass in the mock {@link PackageManager}
|
||||
*/
|
||||
private class TestService extends SettingsDumpService {
|
||||
private PackageManager mPm;
|
||||
|
||||
public void setPackageManager(PackageManager pm) {
|
||||
mPm = pm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PackageManager getPackageManager() {
|
||||
return mPm;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
|
||||
import android.content.pm.ShortcutManager;
|
||||
|
||||
import java.util.Collections;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class SettingsInitializeTest {
|
||||
|
||||
private Context mContext;
|
||||
private SettingsInitialize mSettingsInitialize;
|
||||
private ShortcutManager mShortcutManager;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mSettingsInitialize = new SettingsInitialize();
|
||||
mShortcutManager = (ShortcutManager) mContext.getSystemService(Context.SHORTCUT_SERVICE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refreshExistingShortcuts_shouldUpdateLaunchIntentFlagsForExistingShortcut() {
|
||||
final String id = "test_shortcut_id";
|
||||
final Intent intent = new Intent(Intent.ACTION_DEFAULT);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
|
||||
final ShortcutInfo info = new ShortcutInfo.Builder(mContext, id)
|
||||
.setShortLabel("test123")
|
||||
.setIntent(intent)
|
||||
.build();
|
||||
|
||||
mShortcutManager.addDynamicShortcuts(Collections.singletonList(info));
|
||||
mShortcutManager.requestPinShortcut(info, null);
|
||||
|
||||
mSettingsInitialize.refreshExistingShortcuts(mContext);
|
||||
|
||||
final List<ShortcutInfo> updatedShortcuts = mShortcutManager.getPinnedShortcuts();
|
||||
assertThat(updatedShortcuts).hasSize(1);
|
||||
final ShortcutInfo updateInfo = updatedShortcuts.get(0);
|
||||
assertThat(updateInfo.getId()).isEqualTo(id);
|
||||
final int flags = updateInfo.getIntent().getFlags();
|
||||
// The original flag should be removed
|
||||
assertThat(flags & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED).isEqualTo(0);
|
||||
// The new flags should be set
|
||||
assertThat(flags & Intent.FLAG_ACTIVITY_NEW_TASK).isEqualTo(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
assertThat(flags & Intent.FLAG_ACTIVITY_CLEAR_TOP).isEqualTo(
|
||||
Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refreshExistingShortcuts_shouldNotUpdateImmutableShortcut() {
|
||||
final String id = "test_shortcut_id";
|
||||
final ShortcutInfo info = new ShortcutInfo.Builder(mContext, id)
|
||||
.setShortLabel("test123")
|
||||
.setIntent(new Intent(Intent.ACTION_DEFAULT))
|
||||
.build();
|
||||
info.addFlags(ShortcutInfo.FLAG_IMMUTABLE);
|
||||
|
||||
mShortcutManager.addDynamicShortcuts(Collections.singletonList(info));
|
||||
mShortcutManager.requestPinShortcut(info, null);
|
||||
|
||||
mSettingsInitialize.refreshExistingShortcuts(mContext);
|
||||
|
||||
final List<ShortcutInfo> updatedShortcuts = mShortcutManager.getPinnedShortcuts();
|
||||
assertThat(updatedShortcuts).hasSize(1);
|
||||
assertThat(updatedShortcuts.get(0)).isSameInstanceAs(info);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.android.controller.ActivityController;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class SettingsLicenseActivityTest {
|
||||
|
||||
private ActivityController<SettingsLicenseActivity> mActivityController;
|
||||
private SettingsLicenseActivity mActivity;
|
||||
private Application mApplication;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mApplication = RuntimeEnvironment.application;
|
||||
mActivityController = Robolectric.buildActivity(SettingsLicenseActivity.class);
|
||||
mActivity = spy(mActivityController.get());
|
||||
}
|
||||
|
||||
private void assertEqualIntents(Intent actual, Intent expected) {
|
||||
assertThat(actual.getAction()).isEqualTo(expected.getAction());
|
||||
assertThat(actual.getDataString()).isEqualTo(expected.getDataString());
|
||||
assertThat(actual.getType()).isEqualTo(expected.getType());
|
||||
assertThat(actual.getCategories()).isEqualTo(expected.getCategories());
|
||||
assertThat(actual.getPackage()).isEqualTo(expected.getPackage());
|
||||
assertThat(actual.getFlags()).isEqualTo(expected.getFlags());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnCreateWithValidHtmlFile() {
|
||||
doReturn(true).when(mActivity).isFileValid(any());
|
||||
mActivity.onCreate(null);
|
||||
|
||||
final Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setDataAndType(Uri.parse("file:///system/etc/NOTICE.html.gz"), "text/html");
|
||||
intent.putExtra(Intent.EXTRA_TITLE, mActivity.getString(
|
||||
R.string.settings_license_activity_title));
|
||||
intent.addCategory(Intent.CATEGORY_DEFAULT);
|
||||
intent.setPackage("com.android.htmlviewer");
|
||||
|
||||
assertEqualIntents(Shadows.shadowOf(mApplication).getNextStartedActivity(), intent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnCreateWithGeneratedHtmlFile() {
|
||||
doReturn(Uri.parse("content://com.android.settings.files/my_cache/generated_test.html"))
|
||||
.when(mActivity).getUriFromGeneratedHtmlFile(any());
|
||||
|
||||
mActivity.onCreate(null);
|
||||
mActivity.onLoadFinished(null, new File("/generated_test.html"));
|
||||
|
||||
final Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setDataAndType(
|
||||
Uri.parse("content://com.android.settings.files/my_cache/generated_test.html"),
|
||||
"text/html");
|
||||
intent.putExtra(Intent.EXTRA_TITLE, mActivity.getString(
|
||||
R.string.settings_license_activity_title));
|
||||
intent.addFlags(
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
|
||||
intent.addCategory(Intent.CATEGORY_DEFAULT);
|
||||
intent.setPackage("com.android.htmlviewer");
|
||||
|
||||
assertEqualIntents(Shadows.shadowOf(mApplication).getNextStartedActivity(), intent);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.widget.WorkOnlyCategory;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {
|
||||
com.android.settings.testutils.shadow.ShadowFragment.class,
|
||||
})
|
||||
public class SettingsPreferenceFragmentTest {
|
||||
|
||||
private static final int ITEM_COUNT = 5;
|
||||
|
||||
@Mock
|
||||
private FragmentActivity mActivity;
|
||||
@Mock
|
||||
private View mListContainer;
|
||||
@Mock
|
||||
private PreferenceScreen mPreferenceScreen;
|
||||
private Context mContext;
|
||||
private TestFragment mFragment;
|
||||
private TestFragment2 mFragment2;
|
||||
private View mEmptyView;
|
||||
private int mInitDeviceProvisionedValue;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
FakeFeatureFactory.setupForTest();
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mFragment = spy(new TestFragment());
|
||||
mFragment2 = spy(new TestFragment2());
|
||||
doReturn(mActivity).when(mFragment).getActivity();
|
||||
when(mFragment.getContext()).thenReturn(mContext);
|
||||
when(mFragment2.getContext()).thenReturn(mContext);
|
||||
|
||||
mEmptyView = new View(mContext);
|
||||
ReflectionHelpers.setField(mFragment, "mEmptyView", mEmptyView);
|
||||
|
||||
doReturn(ITEM_COUNT).when(mPreferenceScreen).getPreferenceCount();
|
||||
|
||||
mInitDeviceProvisionedValue = Settings.Global.getInt(mContext.getContentResolver(),
|
||||
Settings.Global.DEVICE_PROVISIONED, 0);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.DEVICE_PROVISIONED, mInitDeviceProvisionedValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removePreference_nested_shouldRemove() {
|
||||
final String key = "test_key";
|
||||
final PreferenceScreen mScreen = spy(new PreferenceScreen(mContext, null));
|
||||
when(mScreen.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
|
||||
|
||||
final PreferenceCategory nestedCategory = new ProgressCategory(mContext);
|
||||
final Preference preference = new Preference(mContext);
|
||||
preference.setKey(key);
|
||||
preference.setPersistent(false);
|
||||
|
||||
mScreen.addPreference(nestedCategory);
|
||||
nestedCategory.addPreference(preference);
|
||||
|
||||
assertThat(mFragment.removePreference(mScreen, key)).isTrue();
|
||||
assertThat(nestedCategory.getPreferenceCount()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removePreference_flat_shouldRemove() {
|
||||
final String key = "test_key";
|
||||
final PreferenceScreen mScreen = spy(new PreferenceScreen(mContext, null));
|
||||
when(mScreen.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
|
||||
|
||||
final Preference preference = mock(Preference.class);
|
||||
when(preference.getKey()).thenReturn(key);
|
||||
|
||||
mScreen.addPreference(preference);
|
||||
|
||||
assertThat(mFragment.removePreference(mScreen, key)).isTrue();
|
||||
assertThat(mScreen.getPreferenceCount()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removePreference_doNotExist_shouldNotRemove() {
|
||||
final String key = "test_key";
|
||||
final PreferenceScreen mScreen = spy(new PreferenceScreen(mContext, null));
|
||||
when(mScreen.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
|
||||
|
||||
final Preference preference = mock(Preference.class);
|
||||
when(preference.getKey()).thenReturn(key);
|
||||
|
||||
mScreen.addPreference(preference);
|
||||
|
||||
assertThat(mFragment.removePreference(mScreen, "not" + key)).isFalse();
|
||||
assertThat(mScreen.getPreferenceCount()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateEmptyView_containerInvisible_emptyViewVisible() {
|
||||
doReturn(View.INVISIBLE).when(mListContainer).getVisibility();
|
||||
doReturn(mListContainer).when(mActivity).findViewById(android.R.id.list_container);
|
||||
doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen();
|
||||
|
||||
mFragment.updateEmptyView();
|
||||
|
||||
assertThat(mEmptyView.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateEmptyView_containerNull_emptyViewGone() {
|
||||
doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen();
|
||||
|
||||
mFragment.updateEmptyView();
|
||||
|
||||
assertThat(mEmptyView.getVisibility()).isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreate_hasExtraFragmentKey_shouldExpandPreferences() {
|
||||
doReturn(mContext.getTheme()).when(mActivity).getTheme();
|
||||
doReturn(mContext.getResources()).when(mFragment).getResources();
|
||||
doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen();
|
||||
final Bundle bundle = new Bundle();
|
||||
bundle.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, "test_key");
|
||||
when(mFragment.getArguments()).thenReturn(bundle);
|
||||
|
||||
mFragment.onCreate(null /* icicle */);
|
||||
|
||||
verify(mPreferenceScreen).setInitialExpandedChildrenCount(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreate_noPreferenceScreen_shouldNotCrash() {
|
||||
doReturn(mContext.getTheme()).when(mActivity).getTheme();
|
||||
doReturn(mContext.getResources()).when(mFragment).getResources();
|
||||
doReturn(null).when(mFragment).getPreferenceScreen();
|
||||
final Bundle bundle = new Bundle();
|
||||
bundle.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, "test_key");
|
||||
when(mFragment.getArguments()).thenReturn(bundle);
|
||||
|
||||
mFragment.onCreate(null /* icicle */);
|
||||
// no crash
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkAvailablePrefs_selfAvialbalePreferenceNotAvailable_shouldHidePreference() {
|
||||
doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen();
|
||||
final WorkOnlyCategory workOnlyCategory = mock(WorkOnlyCategory.class);
|
||||
when(mPreferenceScreen.getPreferenceCount()).thenReturn(1);
|
||||
when(mPreferenceScreen.getPreference(0)).thenReturn(workOnlyCategory);
|
||||
when(workOnlyCategory.isAvailable(any(Context.class))).thenReturn(false);
|
||||
|
||||
mFragment.checkAvailablePrefs(mPreferenceScreen);
|
||||
|
||||
verify(mPreferenceScreen, never()).removePreference(workOnlyCategory);
|
||||
verify(workOnlyCategory).setVisible(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void showPinnedHeader_shouldBeVisible() {
|
||||
mFragment.mPinnedHeaderFrameLayout = new FrameLayout(mContext);
|
||||
|
||||
mFragment.showPinnedHeader(true);
|
||||
|
||||
assertThat(mFragment.mPinnedHeaderFrameLayout.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hidePinnedHeader_shouldBeInvisible() {
|
||||
mFragment.mPinnedHeaderFrameLayout = new FrameLayout(mContext);
|
||||
|
||||
mFragment.showPinnedHeader(false);
|
||||
|
||||
assertThat(mFragment.mPinnedHeaderFrameLayout.getVisibility()).isEqualTo(View.INVISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onAttach_shouldNotSkipForSUWAndDeviceIsProvisioned_notCallFinish() {
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.DEVICE_PROVISIONED, 1);
|
||||
|
||||
mFragment.onAttach(mContext);
|
||||
|
||||
verify(mFragment, never()).finish();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onAttach_shouldNotSkipForSUWAndDeviceIsNotProvisioned_notCallFinish() {
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.DEVICE_PROVISIONED, 0);
|
||||
|
||||
mFragment.onAttach(mContext);
|
||||
|
||||
verify(mFragment, never()).finish();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onAttach_shouldSkipForSUWAndDeviceIsDeviceProvisioned_notCallFinish() {
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.DEVICE_PROVISIONED, 1);
|
||||
|
||||
mFragment2.onAttach(mContext);
|
||||
|
||||
verify(mFragment2, never()).finish();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onAttach_shouldSkipForSUWAndDeviceProvisioned_notCallFinish() {
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.DEVICE_PROVISIONED, 0);
|
||||
|
||||
mFragment2.onAttach(mContext);
|
||||
|
||||
verify(mFragment2, times(1)).finish();
|
||||
}
|
||||
|
||||
public static class TestFragment extends SettingsPreferenceFragment {
|
||||
|
||||
@Override
|
||||
protected boolean shouldSkipForInitialSUW() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TestFragment2 extends SettingsPreferenceFragment {
|
||||
|
||||
@Override
|
||||
protected boolean shouldSkipForInitialSUW() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.sysprop.SetupWizardProperties;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.google.android.setupcompat.partnerconfig.PartnerConfigHelper;
|
||||
import com.google.android.setupcompat.util.WizardManagerHelper;
|
||||
import com.google.android.setupdesign.util.ThemeHelper;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class SetupWizardUtilsTest {
|
||||
|
||||
private Context mContext;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
PartnerConfigHelper.resetInstance();
|
||||
mContext = ApplicationProvider.getApplicationContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopySetupExtras() {
|
||||
Intent fromIntent = new Intent();
|
||||
final String theme = "TEST_THEME";
|
||||
fromIntent.putExtra(WizardManagerHelper.EXTRA_THEME, theme);
|
||||
fromIntent.putExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, true);
|
||||
Intent toIntent = new Intent();
|
||||
SetupWizardUtils.copySetupExtras(fromIntent, toIntent);
|
||||
|
||||
assertThat(theme).isEqualTo(toIntent.getStringExtra(WizardManagerHelper.EXTRA_THEME));
|
||||
assertThat(toIntent.getBooleanExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, false))
|
||||
.isTrue();
|
||||
assertThat(toIntent.getBooleanExtra(WizardManagerHelper.EXTRA_IS_FIRST_RUN, true))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopyLifecycleExtra() {
|
||||
Intent fromIntent = new Intent();
|
||||
final String theme = "TEST_THEME";
|
||||
fromIntent.putExtra(WizardManagerHelper.EXTRA_THEME, theme);
|
||||
fromIntent.putExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, true);
|
||||
Bundle dstBundle = new Bundle();
|
||||
dstBundle = SetupWizardUtils.copyLifecycleExtra(fromIntent.getExtras(), dstBundle);
|
||||
|
||||
assertThat(dstBundle).isNotNull();
|
||||
assertThat(dstBundle.getString(WizardManagerHelper.EXTRA_THEME)).isNull();
|
||||
assertThat(dstBundle.getBoolean(WizardManagerHelper.EXTRA_IS_SETUP_FLOW))
|
||||
.isTrue();
|
||||
assertThat(dstBundle.getBoolean(WizardManagerHelper.EXTRA_IS_FIRST_RUN))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTheme_withIntentExtra_shouldReturnTheme() {
|
||||
SetupWizardProperties.theme(ThemeHelper.THEME_GLIF);
|
||||
Intent intent = createSetupWizardIntent();
|
||||
intent.putExtra(WizardManagerHelper.EXTRA_THEME, ThemeHelper.THEME_GLIF_V2);
|
||||
|
||||
assertThat(SetupWizardUtils.getTheme(mContext, intent))
|
||||
.isEqualTo(R.style.GlifV2Theme);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTheme_withEmptyIntent_shouldReturnSystemProperty() {
|
||||
SetupWizardProperties.theme(ThemeHelper.THEME_GLIF_V2_LIGHT);
|
||||
Intent intent = createSetupWizardIntent();
|
||||
|
||||
assertThat(SetupWizardUtils.getTheme(mContext, intent))
|
||||
.isEqualTo(R.style.GlifV2Theme_Light);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTheme_whenSuwDayNightEnabledAndWithIntentExtra_shouldReturnDayNightTheme() {
|
||||
FakePartnerContentProvider provider =
|
||||
Robolectric.setupContentProvider(
|
||||
FakePartnerContentProvider.class, "com.google.android.setupwizard.partner");
|
||||
provider.injectFakeDayNightEnabledResult(true);
|
||||
SetupWizardProperties.theme(ThemeHelper.THEME_GLIF_V2_LIGHT);
|
||||
Intent intent = createSetupWizardIntent();
|
||||
intent.putExtra(WizardManagerHelper.EXTRA_THEME, ThemeHelper.THEME_GLIF_V2);
|
||||
|
||||
assertThat(SetupWizardUtils.getTheme(mContext, intent))
|
||||
.isEqualTo(R.style.GlifV2Theme_DayNight);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTheme_glifV3Light_shouldReturnLightTheme() {
|
||||
SetupWizardProperties.theme(ThemeHelper.THEME_GLIF_V3_LIGHT);
|
||||
Intent intent = createSetupWizardIntent();
|
||||
|
||||
assertThat(SetupWizardUtils.getTheme(mContext, intent))
|
||||
.isEqualTo(R.style.GlifV3Theme_Light);
|
||||
assertThat(SetupWizardUtils.getTransparentTheme(mContext, intent))
|
||||
.isEqualTo(R.style.GlifV3Theme_Light_Transparent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTheme_glifV3_shouldReturnTheme() {
|
||||
SetupWizardProperties.theme(ThemeHelper.THEME_GLIF_V3);
|
||||
Intent intent = createSetupWizardIntent();
|
||||
|
||||
assertThat(SetupWizardUtils.getTheme(mContext, intent))
|
||||
.isEqualTo(R.style.GlifV3Theme);
|
||||
assertThat(SetupWizardUtils.getTransparentTheme(mContext, intent))
|
||||
.isEqualTo(R.style.GlifV3Theme_Transparent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTheme_whenSuwDayNightDisabledAndGlifV2_shouldReturnLightTheme() {
|
||||
FakePartnerContentProvider provider =
|
||||
Robolectric.setupContentProvider(
|
||||
FakePartnerContentProvider.class, "com.google.android.setupwizard.partner");
|
||||
provider.injectFakeDayNightEnabledResult(false);
|
||||
SetupWizardProperties.theme(ThemeHelper.THEME_GLIF_V2_LIGHT);
|
||||
Intent intent = createSetupWizardIntent();
|
||||
|
||||
assertThat(SetupWizardUtils.getTheme(mContext, intent))
|
||||
.isEqualTo(R.style.GlifV2Theme_Light);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTheme_whenSuwDayNightEnabledAndGlifV2_shouldReturnDayNightTheme() {
|
||||
FakePartnerContentProvider provider =
|
||||
Robolectric.setupContentProvider(
|
||||
FakePartnerContentProvider.class, "com.google.android.setupwizard.partner");
|
||||
provider.injectFakeDayNightEnabledResult(true);
|
||||
SetupWizardProperties.theme(ThemeHelper.THEME_GLIF_V2_LIGHT);
|
||||
Intent intent = createSetupWizardIntent();
|
||||
|
||||
assertThat(SetupWizardUtils.getTheme(mContext, intent))
|
||||
.isEqualTo(R.style.GlifV2Theme_DayNight);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTheme_whenSuwDayNightDisabledAndGlifV3_shouldReturnTheme() {
|
||||
FakePartnerContentProvider provider =
|
||||
Robolectric.setupContentProvider(
|
||||
FakePartnerContentProvider.class, "com.google.android.setupwizard.partner");
|
||||
provider.injectFakeDayNightEnabledResult(false);
|
||||
SetupWizardProperties.theme(ThemeHelper.THEME_GLIF_V3);
|
||||
Intent intent = createSetupWizardIntent();
|
||||
|
||||
assertThat(SetupWizardUtils.getTheme(mContext, intent))
|
||||
.isEqualTo(R.style.GlifV3Theme);
|
||||
assertThat(SetupWizardUtils.getTransparentTheme(mContext, intent))
|
||||
.isEqualTo(R.style.GlifV3Theme_Transparent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTheme_whenSuwDayNightEnabledAndGlifV3_shouldReturnDayNightTheme() {
|
||||
FakePartnerContentProvider provider =
|
||||
Robolectric.setupContentProvider(
|
||||
FakePartnerContentProvider.class, "com.google.android.setupwizard.partner");
|
||||
provider.injectFakeDayNightEnabledResult(true);
|
||||
SetupWizardProperties.theme(ThemeHelper.THEME_GLIF_V3);
|
||||
Intent intent = createSetupWizardIntent();
|
||||
|
||||
assertThat(SetupWizardUtils.getTheme(mContext, intent))
|
||||
.isEqualTo(R.style.GlifV3Theme_DayNight);
|
||||
assertThat(SetupWizardUtils.getTransparentTheme(mContext, intent))
|
||||
.isEqualTo(R.style.GlifV3Theme_DayNight_Transparent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTheme_nonSuw_shouldReturnTheme() {
|
||||
SetupWizardProperties.theme(ThemeHelper.THEME_GLIF_V3_LIGHT);
|
||||
Intent intent = new Intent();
|
||||
|
||||
assertThat(SetupWizardUtils.getTheme(mContext, intent)).isEqualTo(R.style.GlifV3Theme);
|
||||
assertThat(SetupWizardUtils.getTransparentTheme(mContext, intent))
|
||||
.isEqualTo(R.style.GlifV3Theme_Transparent);
|
||||
}
|
||||
|
||||
private Intent createSetupWizardIntent() {
|
||||
return new Intent()
|
||||
.putExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, true)
|
||||
.putExtra(WizardManagerHelper.EXTRA_IS_FIRST_RUN, true);
|
||||
}
|
||||
|
||||
private static final class FakePartnerContentProvider extends ContentProvider {
|
||||
|
||||
private final Bundle mFakeProviderDayNightEnabledResultBundle = new Bundle();
|
||||
|
||||
@Override
|
||||
public boolean onCreate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor query(
|
||||
@NonNull Uri uri,
|
||||
@Nullable String[] projection,
|
||||
@Nullable String selection,
|
||||
@Nullable String[] selectionArgs,
|
||||
@Nullable String sortOrder) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getType(@NonNull Uri uri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int delete(
|
||||
@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(
|
||||
@NonNull Uri uri,
|
||||
@Nullable ContentValues values,
|
||||
@Nullable String selection,
|
||||
@Nullable String[] selectionArgs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle call(String method, String arg, Bundle extras) {
|
||||
if (TextUtils.equals(method, "isSuwDayNightEnabled")) {
|
||||
return mFakeProviderDayNightEnabledResultBundle;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public FakePartnerContentProvider injectFakeDayNightEnabledResult(boolean dayNightEnabled) {
|
||||
mFakeProviderDayNightEnabledResultBundle.putBoolean(
|
||||
"isSuwDayNightEnabled", dayNightEnabled);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
package com.android.settings;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class SummaryPreferenceTest {
|
||||
|
||||
private PreferenceViewHolder mHolder;
|
||||
private SummaryPreference mPreference;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
final Context context = RuntimeEnvironment.application;
|
||||
mPreference = new SummaryPreference(context, null);
|
||||
|
||||
LayoutInflater inflater = LayoutInflater.from(context);
|
||||
final View view =
|
||||
inflater.inflate(mPreference.getLayoutResource(), new LinearLayout(context), false);
|
||||
|
||||
mHolder = PreferenceViewHolder.createInstanceForTests(view);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void disableChart_shouldNotRender() {
|
||||
mPreference.setChartEnabled(false);
|
||||
mPreference.onBindViewHolder(mHolder);
|
||||
|
||||
final TextView textView1 = (TextView) mHolder.findViewById(android.R.id.text1);
|
||||
assertThat(textView1.getText()).isEqualTo("");
|
||||
|
||||
final TextView textView2 = (TextView) mHolder.findViewById(android.R.id.text2);
|
||||
assertThat(textView2.getText()).isEqualTo("");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableChart_shouldRender() {
|
||||
final String testLabel1 = "label1";
|
||||
final String testLabel2 = "label2";
|
||||
mPreference.setChartEnabled(true);
|
||||
mPreference.setLabels(testLabel1, testLabel2);
|
||||
mPreference.onBindViewHolder(mHolder);
|
||||
|
||||
final TextView textView1 = (TextView) mHolder.findViewById(android.R.id.text1);
|
||||
assertThat(textView1.getText()).isEqualTo(testLabel1);
|
||||
|
||||
final TextView textView2 = (TextView) mHolder.findViewById(android.R.id.text2);
|
||||
assertThat(textView2.getText()).isEqualTo(testLabel2);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
|
||||
package com.android.settings;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.provider.Settings;
|
||||
|
||||
/**
|
||||
* Convenience methods and constants for testing.
|
||||
*/
|
||||
public class TestUtils {
|
||||
public static final long KILOBYTE = 1024L; // TODO: Change to 1000 in O Robolectric.
|
||||
public static final long MEGABYTE = KILOBYTE * KILOBYTE;
|
||||
public static final long GIGABYTE = KILOBYTE * MEGABYTE;
|
||||
|
||||
public static void setScheduledLevel(Context context, int scheduledLevel) {
|
||||
Settings.Global.putInt(context.getContentResolver(),
|
||||
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, scheduledLevel);
|
||||
}
|
||||
|
||||
public static int getScheduledLevel(Context context) {
|
||||
return Settings.Global.getInt(context.getContentResolver(),
|
||||
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, /*defaultValue*/ 0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.Shadows;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class TestingSettingsBroadcastReceiverTest {
|
||||
|
||||
private Context mContext;
|
||||
private Application mApplication;
|
||||
private TestingSettingsBroadcastReceiver mReceiver;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mApplication = RuntimeEnvironment.application;
|
||||
mReceiver = new TestingSettingsBroadcastReceiver();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onReceive_nullIntent_shouldNotCrash() {
|
||||
final Intent intent = new Intent();
|
||||
|
||||
mReceiver.onReceive(mContext, null);
|
||||
mReceiver.onReceive(mContext, intent);
|
||||
|
||||
final Intent next = Shadows.shadowOf(mApplication).getNextStartedActivity();
|
||||
assertThat(next).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onReceive_wrongIntent_shouldNotStartActivity() {
|
||||
final Intent intent = new Intent();
|
||||
intent.setAction("");
|
||||
|
||||
mReceiver.onReceive(mContext, intent);
|
||||
|
||||
final Intent next = Shadows.shadowOf(mApplication).getNextStartedActivity();
|
||||
assertThat(next).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onReceive_correctIntent_shouldStartActivity() {
|
||||
final Intent intent = new Intent();
|
||||
intent.setAction(TelephonyManager.ACTION_SECRET_CODE);
|
||||
|
||||
mReceiver.onReceive(mContext, intent);
|
||||
|
||||
final Intent next = Shadows.shadowOf(mApplication).getNextStartedActivity();
|
||||
assertThat(next).isNotNull();
|
||||
final String dest = next.getComponent().getClassName();
|
||||
assertThat(dest).isEqualTo(Settings.TestingSettingsActivity.class.getName());
|
||||
}
|
||||
}
|
||||
441
Settings/tests/robotests/src/com/android/settings/UtilsTest.java
Normal file
441
Settings/tests/robotests/src/com/android/settings/UtilsTest.java
Normal file
@@ -0,0 +1,441 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
|
||||
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.app.ActionBar;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.app.admin.DevicePolicyResourcesManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.VectorDrawable;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.LinkAddress;
|
||||
import android.net.LinkProperties;
|
||||
import android.net.Network;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.os.storage.DiskInfo;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.os.storage.VolumeInfo;
|
||||
import android.util.IconDrawableFactory;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowBinder;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = ShadowLockPatternUtils.class)
|
||||
public class UtilsTest {
|
||||
|
||||
private static final String PACKAGE_NAME = "com.android.app";
|
||||
private static final int USER_ID = 1;
|
||||
|
||||
@Mock
|
||||
private WifiManager wifiManager;
|
||||
@Mock
|
||||
private Network network;
|
||||
@Mock
|
||||
private ConnectivityManager connectivityManager;
|
||||
@Mock
|
||||
private DevicePolicyManager mDevicePolicyManager;
|
||||
@Mock
|
||||
private DevicePolicyResourcesManager mDevicePolicyResourcesManager;
|
||||
@Mock
|
||||
private UserManager mMockUserManager;
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
@Mock
|
||||
private IconDrawableFactory mIconDrawableFactory;
|
||||
@Mock
|
||||
private ApplicationInfo mApplicationInfo;
|
||||
private Context mContext;
|
||||
private UserManager mUserManager;
|
||||
private static final int FLAG_SYSTEM = 0x00000000;
|
||||
private static final int FLAG_MAIN = 0x00004000;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
|
||||
when(mContext.getSystemService(WifiManager.class)).thenReturn(wifiManager);
|
||||
when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE))
|
||||
.thenReturn(connectivityManager);
|
||||
when(mContext.getPackageManager()).thenReturn(mPackageManager);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
ShadowLockPatternUtils.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getWifiIpAddresses_succeeds() throws Exception {
|
||||
when(wifiManager.getCurrentNetwork()).thenReturn(network);
|
||||
LinkAddress address = new LinkAddress(InetAddress.getByName("127.0.0.1"), 0);
|
||||
LinkProperties lp = new LinkProperties();
|
||||
lp.addLinkAddress(address);
|
||||
when(connectivityManager.getLinkProperties(network)).thenReturn(lp);
|
||||
|
||||
assertThat(Utils.getWifiIpAddresses(mContext)).isEqualTo("127.0.0.1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getWifiIpAddresses_nullLinkProperties() {
|
||||
when(wifiManager.getCurrentNetwork()).thenReturn(network);
|
||||
// Explicitly set the return value to null for readability sake.
|
||||
when(connectivityManager.getLinkProperties(network)).thenReturn(null);
|
||||
|
||||
assertThat(Utils.getWifiIpAddresses(mContext)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getWifiIpAddresses_nullNetwork() {
|
||||
// Explicitly set the return value to null for readability sake.
|
||||
when(wifiManager.getCurrentNetwork()).thenReturn(null);
|
||||
|
||||
assertThat(Utils.getWifiIpAddresses(mContext)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initializeVolumeDoesntBreakOnNullVolume() {
|
||||
VolumeInfo info = new VolumeInfo("id", 0, new DiskInfo("id", 0), "");
|
||||
StorageManager storageManager = mock(StorageManager.class, RETURNS_DEEP_STUBS);
|
||||
when(storageManager.findVolumeById(anyString())).thenReturn(info);
|
||||
|
||||
Utils.maybeInitializeVolume(storageManager, new Bundle());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isProfileOrDeviceOwner_deviceOwnerApp_returnTrue() {
|
||||
when(mDevicePolicyManager.isDeviceOwnerAppOnAnyUser(PACKAGE_NAME)).thenReturn(true);
|
||||
|
||||
assertThat(
|
||||
Utils.isProfileOrDeviceOwner(mMockUserManager, mDevicePolicyManager, PACKAGE_NAME))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isProfileOrDeviceOwner_profileOwnerApp_returnTrue() {
|
||||
final List<UserInfo> userInfos = new ArrayList<>();
|
||||
userInfos.add(new UserInfo());
|
||||
|
||||
when(mMockUserManager.getUsers()).thenReturn(userInfos);
|
||||
when(mDevicePolicyManager.getProfileOwnerAsUser(userInfos.get(0).id))
|
||||
.thenReturn(new ComponentName(PACKAGE_NAME, ""));
|
||||
|
||||
assertThat(
|
||||
Utils.isProfileOrDeviceOwner(mMockUserManager, mDevicePolicyManager, PACKAGE_NAME))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setEditTextCursorPosition_shouldGetExpectedEditTextLenght() {
|
||||
final EditText editText = new EditText(mContext);
|
||||
final CharSequence text = "test";
|
||||
editText.setText(text, TextView.BufferType.EDITABLE);
|
||||
final int length = editText.getText().length();
|
||||
Utils.setEditTextCursorPosition(editText);
|
||||
|
||||
assertThat(editText.getSelectionEnd()).isEqualTo(length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createIconWithDrawable_BitmapDrawable() {
|
||||
final Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
|
||||
final BitmapDrawable drawable = new BitmapDrawable(mContext.getResources(), bitmap);
|
||||
|
||||
final IconCompat icon = Utils.createIconWithDrawable(drawable);
|
||||
|
||||
assertThat(icon.getBitmap()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createIconWithDrawable_ColorDrawable() {
|
||||
final ColorDrawable drawable = new ColorDrawable(Color.BLACK);
|
||||
|
||||
final IconCompat icon = Utils.createIconWithDrawable(drawable);
|
||||
|
||||
assertThat(icon.getBitmap()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createIconWithDrawable_VectorDrawable() {
|
||||
final VectorDrawable drawable = VectorDrawable.create(mContext.getResources(),
|
||||
R.drawable.ic_settings_accent);
|
||||
|
||||
final IconCompat icon = Utils.createIconWithDrawable(drawable);
|
||||
|
||||
assertThat(icon.getBitmap()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getBadgedIcon_usePackageNameAndUserId()
|
||||
throws PackageManager.NameNotFoundException {
|
||||
doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfoAsUser(
|
||||
PACKAGE_NAME, PackageManager.GET_META_DATA, USER_ID);
|
||||
|
||||
Utils.getBadgedIcon(mIconDrawableFactory, mPackageManager, PACKAGE_NAME, USER_ID);
|
||||
|
||||
// Verify that it uses the correct user id
|
||||
verify(mPackageManager).getApplicationInfoAsUser(eq(PACKAGE_NAME), anyInt(), eq(USER_ID));
|
||||
verify(mIconDrawableFactory).getBadgedIcon(mApplicationInfo, USER_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isPackageEnabled_appEnabled_returnTrue()
|
||||
throws PackageManager.NameNotFoundException{
|
||||
mApplicationInfo.enabled = true;
|
||||
when(mPackageManager.getApplicationInfo(PACKAGE_NAME, 0)).thenReturn(mApplicationInfo);
|
||||
|
||||
assertThat(Utils.isPackageEnabled(mContext, PACKAGE_NAME)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isPackageEnabled_appDisabled_returnTrue()
|
||||
throws PackageManager.NameNotFoundException{
|
||||
mApplicationInfo.enabled = false;
|
||||
when(mPackageManager.getApplicationInfo(PACKAGE_NAME, 0)).thenReturn(mApplicationInfo);
|
||||
|
||||
assertThat(Utils.isPackageEnabled(mContext, PACKAGE_NAME)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isPackageEnabled_noApp_returnFalse() {
|
||||
assertThat(Utils.isPackageEnabled(mContext, PACKAGE_NAME)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setActionBarShadowAnimation_nullParameters_shouldNotCrash() {
|
||||
// no crash here
|
||||
Utils.setActionBarShadowAnimation(null, null, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setActionBarShadowAnimation_shouldSetElevationToZero() {
|
||||
final FragmentActivity activity = Robolectric.setupActivity(FragmentActivity.class);
|
||||
final ActionBar actionBar = activity.getActionBar();
|
||||
|
||||
Utils.setActionBarShadowAnimation(activity, activity.getLifecycle(),
|
||||
new ScrollView(mContext));
|
||||
|
||||
assertThat(actionBar.getElevation()).isEqualTo(0.f);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSettingsIntelligence_IsSI_returnTrue() {
|
||||
final String siPackageName = mContext.getString(
|
||||
R.string.config_settingsintelligence_package_name);
|
||||
ShadowBinder.setCallingUid(USER_ID);
|
||||
when(mPackageManager.getPackagesForUid(USER_ID)).thenReturn(new String[]{siPackageName});
|
||||
|
||||
assertThat(Utils.isSettingsIntelligence(mContext)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSettingsIntelligence_IsNotSI_returnFalse() {
|
||||
ShadowBinder.setCallingUid(USER_ID);
|
||||
when(mPackageManager.getPackagesForUid(USER_ID)).thenReturn(new String[]{PACKAGE_NAME});
|
||||
|
||||
assertThat(Utils.isSettingsIntelligence(mContext)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canCurrentUserDream_isMainUser_returnTrue() {
|
||||
Context mockContext = mock(Context.class);
|
||||
UserManager mockUserManager = mock(UserManager.class);
|
||||
|
||||
when(mockContext.getSystemService(UserManager.class)).thenReturn(mockUserManager);
|
||||
|
||||
// mock MainUser
|
||||
UserHandle mainUser = new UserHandle(10);
|
||||
when(mockUserManager.getMainUser()).thenReturn(mainUser);
|
||||
when(mockUserManager.isUserForeground()).thenReturn(true);
|
||||
|
||||
when(mockContext.createContextAsUser(mainUser, 0)).thenReturn(mockContext);
|
||||
|
||||
assertThat(Utils.canCurrentUserDream(mockContext)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canCurrentUserDream_nullMainUser_returnFalse() {
|
||||
Context mockContext = mock(Context.class);
|
||||
UserManager mockUserManager = mock(UserManager.class);
|
||||
|
||||
when(mockContext.getSystemService(UserManager.class)).thenReturn(mockUserManager);
|
||||
when(mockUserManager.getMainUser()).thenReturn(null);
|
||||
|
||||
assertThat(Utils.canCurrentUserDream(mockContext)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canCurrentUserDream_notMainUser_returnFalse() {
|
||||
Context mockContext = mock(Context.class);
|
||||
UserManager mockUserManager = mock(UserManager.class);
|
||||
|
||||
when(mockContext.getSystemService(UserManager.class)).thenReturn(mockUserManager);
|
||||
when(mockUserManager.isUserForeground()).thenReturn(false);
|
||||
|
||||
assertThat(Utils.canCurrentUserDream(mockContext)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkUserOwnsFrpCredential_userOwnsFrpCredential_returnUserId() {
|
||||
ShadowLockPatternUtils.setUserOwnsFrpCredential(true);
|
||||
|
||||
assertThat(Utils.checkUserOwnsFrpCredential(mContext, 123)).isEqualTo(123);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkUserOwnsFrpCredential_userNotOwnsFrpCredential_returnUserId() {
|
||||
ShadowLockPatternUtils.setUserOwnsFrpCredential(false);
|
||||
|
||||
assertThrows(
|
||||
SecurityException.class,
|
||||
() -> Utils.checkUserOwnsFrpCredential(mContext, 123));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConfirmCredentialStringForUser_Pin_shouldReturnCorrectString() {
|
||||
setUpForConfirmCredentialString(false /* isEffectiveUserManagedProfile */);
|
||||
|
||||
when(mContext.getString(R.string.lockpassword_confirm_your_pin_generic))
|
||||
.thenReturn("PIN");
|
||||
|
||||
String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext,
|
||||
USER_ID, LockPatternUtils.CREDENTIAL_TYPE_PIN);
|
||||
|
||||
assertThat(confirmCredentialString).isEqualTo("PIN");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConfirmCredentialStringForUser_Pattern_shouldReturnCorrectString() {
|
||||
setUpForConfirmCredentialString(false /* isEffectiveUserManagedProfile */);
|
||||
|
||||
when(mContext.getString(R.string.lockpassword_confirm_your_pattern_generic))
|
||||
.thenReturn("PATTERN");
|
||||
|
||||
String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext,
|
||||
USER_ID, LockPatternUtils.CREDENTIAL_TYPE_PATTERN);
|
||||
|
||||
assertThat(confirmCredentialString).isEqualTo("PATTERN");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConfirmCredentialStringForUser_Password_shouldReturnCorrectString() {
|
||||
setUpForConfirmCredentialString(false /* isEffectiveUserManagedProfile */);
|
||||
|
||||
when(mContext.getString(R.string.lockpassword_confirm_your_password_generic))
|
||||
.thenReturn("PASSWORD");
|
||||
|
||||
String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext,
|
||||
USER_ID, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD);
|
||||
|
||||
assertThat(confirmCredentialString).isEqualTo("PASSWORD");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConfirmCredentialStringForUser_workPin_shouldReturnNull() {
|
||||
setUpForConfirmCredentialString(true /* isEffectiveUserManagedProfile */);
|
||||
|
||||
String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext,
|
||||
USER_ID, LockPatternUtils.CREDENTIAL_TYPE_PIN);
|
||||
|
||||
assertNull(confirmCredentialString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConfirmCredentialStringForUser_workPattern_shouldReturnNull() {
|
||||
setUpForConfirmCredentialString(true /* isEffectiveUserManagedProfile */);
|
||||
|
||||
String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext,
|
||||
USER_ID, LockPatternUtils.CREDENTIAL_TYPE_PATTERN);
|
||||
|
||||
assertNull(confirmCredentialString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConfirmCredentialStringForUser_workPassword_shouldReturnNull() {
|
||||
setUpForConfirmCredentialString(true /* isEffectiveUserManagedProfile */);
|
||||
|
||||
String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext,
|
||||
USER_ID, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD);
|
||||
|
||||
assertNull(confirmCredentialString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConfirmCredentialStringForUser_credentialTypeNone_shouldReturnNull() {
|
||||
setUpForConfirmCredentialString(false /* isEffectiveUserManagedProfile */);
|
||||
|
||||
String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext,
|
||||
USER_ID, LockPatternUtils.CREDENTIAL_TYPE_NONE);
|
||||
|
||||
assertNull(confirmCredentialString);
|
||||
}
|
||||
|
||||
private void setUpForConfirmCredentialString(boolean isEffectiveUserManagedProfile) {
|
||||
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mMockUserManager);
|
||||
when(mMockUserManager.getCredentialOwnerProfile(USER_ID)).thenReturn(USER_ID);
|
||||
when(mMockUserManager.isManagedProfile(USER_ID)).thenReturn(isEffectiveUserManagedProfile);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.accessibility;
|
||||
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.icu.text.MessageFormat;
|
||||
import android.text.Html;
|
||||
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link AccessibilityButtonFooterPreferenceController}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AccessibilityButtonFooterPreferenceControllerTest {
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
@Spy
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
@Spy
|
||||
private final Resources mResources = mContext.getResources();
|
||||
@Mock
|
||||
private PreferenceScreen mScreen;
|
||||
private AccessibilityButtonFooterPreferenceController mController;
|
||||
private AccessibilityFooterPreference mPreference;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mController = new AccessibilityButtonFooterPreferenceController(mContext, "test_key");
|
||||
mPreference = new AccessibilityFooterPreference(mContext);
|
||||
mPreference.setKey("test_key");
|
||||
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_navigationGestureEnabled_setCorrectTitle() {
|
||||
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
|
||||
.thenReturn(NAV_BAR_MODE_GESTURAL);
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
assertThat(mPreference.getTitle().toString()).isEqualTo(
|
||||
Html.fromHtml(
|
||||
MessageFormat.format(mContext.getString(
|
||||
R.string.accessibility_button_gesture_description), 1, 2, 3),
|
||||
Html.FROM_HTML_MODE_COMPACT).toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_navigationGestureDisabled_setCorrectTitle() {
|
||||
when(mResources.getInteger(
|
||||
com.android.internal.R.integer.config_navBarInteractionMode)).thenReturn(
|
||||
NAV_BAR_MODE_2BUTTON);
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
assertThat(mPreference.getTitle().toString()).isEqualTo(
|
||||
Html.fromHtml(
|
||||
MessageFormat.format(
|
||||
mContext.getString(
|
||||
R.string.accessibility_button_description), 1, 2, 3),
|
||||
Html.FROM_HTML_MODE_COMPACT).toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.accessibility;
|
||||
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.XmlTestUtils;
|
||||
import com.android.settings.testutils.shadow.ShadowFragment;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** Tests for {@link AccessibilityButtonFragment}. */
|
||||
@Config(shadows = ShadowFragment.class)
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AccessibilityButtonFragmentTest {
|
||||
|
||||
@Rule
|
||||
public MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||
@Spy
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
@Spy
|
||||
private Resources mResources = spy(mContext.getResources());
|
||||
private AccessibilityButtonFragment mFragment;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mFragment = spy(new TestAccessibilityButtonFragment(mContext));
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
when(mFragment.getResources()).thenReturn(mResources);
|
||||
when(mFragment.getActivity()).thenReturn(Robolectric.setupActivity(FragmentActivity.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMetricsCategory_returnsCorrectCategory() {
|
||||
assertThat(mFragment.getMetricsCategory()).isEqualTo(
|
||||
SettingsEnums.ACCESSIBILITY_BUTTON_SETTINGS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLogTag_returnsCorrectTag() {
|
||||
assertThat(mFragment.getLogTag()).isEqualTo("AccessibilityButtonFragment");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreate_navigationGestureEnabled_setCorrectTitle() {
|
||||
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
|
||||
.thenReturn(NAV_BAR_MODE_GESTURAL);
|
||||
|
||||
mFragment.onAttach(mContext);
|
||||
mFragment.onCreate(Bundle.EMPTY);
|
||||
|
||||
assertThat(mFragment.getActivity().getTitle().toString()).isEqualTo(
|
||||
mContext.getString(R.string.accessibility_button_gesture_title));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreate_navigationGestureDisabled_setCorrectTitle() {
|
||||
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
|
||||
.thenReturn(NAV_BAR_MODE_2BUTTON);
|
||||
|
||||
mFragment.onAttach(mContext);
|
||||
mFragment.onCreate(Bundle.EMPTY);
|
||||
|
||||
assertThat(mFragment.getActivity().getTitle().toString()).isEqualTo(
|
||||
mContext.getString(R.string.accessibility_button_title));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getNonIndexableKeys_existInXmlLayout() {
|
||||
final List<String> niks = AccessibilityButtonFragment.SEARCH_INDEX_DATA_PROVIDER
|
||||
.getNonIndexableKeys(mContext);
|
||||
final List<String> keys =
|
||||
XmlTestUtils.getKeysFromPreferenceXml(mContext,
|
||||
R.xml.accessibility_button_settings);
|
||||
|
||||
assertThat(keys).containsAtLeastElementsIn(niks);
|
||||
}
|
||||
|
||||
private static class TestAccessibilityButtonFragment extends AccessibilityButtonFragment {
|
||||
|
||||
private final Context mContext;
|
||||
private final PreferenceManager mPreferenceManager;
|
||||
|
||||
TestAccessibilityButtonFragment(Context context) {
|
||||
super();
|
||||
mContext = context;
|
||||
mPreferenceManager = new PreferenceManager(context);
|
||||
mPreferenceManager.setPreferences(mPreferenceManager.createPreferenceScreen(context));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPreferenceScreenResId() {
|
||||
return R.xml.placeholder_prefs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreferenceScreen getPreferenceScreen() {
|
||||
return mPreferenceManager.getPreferenceScreen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreferenceManager getPreferenceManager() {
|
||||
return mPreferenceManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context getContext() {
|
||||
return mContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.accessibility;
|
||||
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_GESTURE;
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link AccessibilityButtonGesturePreferenceController}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AccessibilityButtonGesturePreferenceControllerTest {
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
|
||||
@Spy
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
@Spy
|
||||
private final Resources mResources = mContext.getResources();
|
||||
private final ContentResolver mContentResolver = mContext.getContentResolver();
|
||||
private final ListPreference mListPreference = new ListPreference(mContext);
|
||||
private AccessibilityButtonGesturePreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mController = new AccessibilityButtonGesturePreferenceController(mContext,
|
||||
"test_key");
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_navigationGestureEnabled_returnAvailable() {
|
||||
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
|
||||
.thenReturn(NAV_BAR_MODE_GESTURAL);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_navigationGestureDisabled_returnConditionallyUnavailable() {
|
||||
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
|
||||
.thenReturn(NAV_BAR_MODE_2BUTTON);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_a11yBtnModeGesture_navigationBarValue() {
|
||||
Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
|
||||
ACCESSIBILITY_BUTTON_MODE_GESTURE);
|
||||
|
||||
mController.updateState(mListPreference);
|
||||
|
||||
final String gestureValue = String.valueOf(ACCESSIBILITY_BUTTON_MODE_GESTURE);
|
||||
assertThat(mListPreference.getValue()).isEqualTo(gestureValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.accessibility;
|
||||
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR;
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link AccessibilityButtonLocationPreferenceController}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AccessibilityButtonLocationPreferenceControllerTest {
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
|
||||
@Spy
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
@Spy
|
||||
private final Resources mResources = mContext.getResources();
|
||||
private final ContentResolver mContentResolver = mContext.getContentResolver();
|
||||
private final ListPreference mListPreference = new ListPreference(mContext);
|
||||
private AccessibilityButtonLocationPreferenceController mController;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mController = new AccessibilityButtonLocationPreferenceController(mContext,
|
||||
"test_key");
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_navigationGestureEnabled_returnConditionallyUnavailable() {
|
||||
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
|
||||
.thenReturn(NAV_BAR_MODE_GESTURAL);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_navigationGestureDisabled_returnAvailable() {
|
||||
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
|
||||
.thenReturn(NAV_BAR_MODE_2BUTTON);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_a11yBtnModeNavigationBar_navigationBarValue() {
|
||||
Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
|
||||
ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR);
|
||||
|
||||
mController.updateState(mListPreference);
|
||||
|
||||
final String navigationBarValue = String.valueOf(ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR);
|
||||
assertThat(mListPreference.getValue()).isEqualTo(navigationBarValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.accessibility;
|
||||
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settingslib.search.SearchIndexableRaw;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** Tests for {@link AccessibilityButtonPreferenceController}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AccessibilityButtonPreferenceControllerTest {
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
@Spy
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
@Spy
|
||||
private final Resources mResources = mContext.getResources();
|
||||
@Mock
|
||||
private PreferenceScreen mScreen;
|
||||
private Preference mPreference;
|
||||
private AccessibilityButtonPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mController = new AccessibilityButtonPreferenceController(mContext, "test_key");
|
||||
mPreference = new Preference(mContext);
|
||||
mPreference.setKey("test_key");
|
||||
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_navigationGestureEnabled_setCorrectTitle() {
|
||||
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
|
||||
.thenReturn(NAV_BAR_MODE_GESTURAL);
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
assertThat(mPreference.getTitle()).isEqualTo(
|
||||
mContext.getText(R.string.accessibility_button_gesture_title));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_navigationGestureDisabled_setCorrectTitle() {
|
||||
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
|
||||
.thenReturn(NAV_BAR_MODE_2BUTTON);
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
assertThat(mPreference.getTitle()).isEqualTo(
|
||||
mContext.getText(R.string.accessibility_button_title));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateDynamicRawDataToIndex_navigationGestureEnabled_setCorrectIndex() {
|
||||
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
|
||||
.thenReturn(NAV_BAR_MODE_GESTURAL);
|
||||
List<SearchIndexableRaw> rawDataList = new ArrayList<>();
|
||||
|
||||
mController.updateDynamicRawDataToIndex(rawDataList);
|
||||
|
||||
assertThat(rawDataList).hasSize(1);
|
||||
SearchIndexableRaw raw = rawDataList.get(0);
|
||||
assertThat(raw.title).isEqualTo(
|
||||
mResources.getString(R.string.accessibility_button_gesture_title));
|
||||
assertThat(raw.screenTitle).isEqualTo(
|
||||
mResources.getString(R.string.accessibility_shortcuts_settings_title));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateDynamicRawDataToIndex_navigationGestureDisabled_setCorrectIndex() {
|
||||
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
|
||||
.thenReturn(NAV_BAR_MODE_2BUTTON);
|
||||
List<SearchIndexableRaw> rawDataList = new ArrayList<>();
|
||||
|
||||
mController.updateDynamicRawDataToIndex(rawDataList);
|
||||
|
||||
assertThat(rawDataList).hasSize(1);
|
||||
SearchIndexableRaw raw = rawDataList.get(0);
|
||||
assertThat(raw.title).isEqualTo(
|
||||
mResources.getString(R.string.accessibility_button_title));
|
||||
assertThat(raw.screenTitle).isEqualTo(
|
||||
mResources.getString(R.string.accessibility_shortcuts_settings_title));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.accessibility;
|
||||
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR;
|
||||
|
||||
import static com.android.settings.testutils.ImageTestUtils.drawableToBitmap;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settingslib.widget.IllustrationPreference;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link AccessibilityButtonPreviewPreferenceController}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AccessibilityButtonPreviewPreferenceControllerTest {
|
||||
|
||||
@Rule
|
||||
public MockitoRule mocks = MockitoJUnit.rule();
|
||||
|
||||
@Spy
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
@Mock
|
||||
private ContentResolver mContentResolver;
|
||||
private AccessibilityButtonPreviewPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
when(mContext.getContentResolver()).thenReturn(mContentResolver);
|
||||
mController = new AccessibilityButtonPreviewPreferenceController(mContext, "test_key");
|
||||
mController.mIllustrationPreference = new IllustrationPreference(mContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onChange_a11yBtnModeNavigationBar_getNavigationBarDrawable() {
|
||||
Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
|
||||
ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR);
|
||||
|
||||
mController.mContentObserver.onChange(false);
|
||||
|
||||
final Drawable navigationBarDrawable = mContext.getDrawable(
|
||||
R.drawable.a11y_button_navigation);
|
||||
assertThat(drawableToBitmap(mController.mIllustrationPreference.getImageDrawable()).sameAs(
|
||||
drawableToBitmap(navigationBarDrawable))).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onChange_updatePreviewPreferenceWithConfig_expectedPreviewDrawable() {
|
||||
Settings.Secure.putInt(mContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_BUTTON_MODE, ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU);
|
||||
Settings.Secure.putInt(mContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, /* small size */ 0);
|
||||
Settings.Secure.putFloat(mContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY, 0.1f);
|
||||
|
||||
mController.mContentObserver.onChange(false);
|
||||
|
||||
final Drawable smallFloatingMenuWithTenOpacityDrawable =
|
||||
AccessibilityLayerDrawable.createLayerDrawable(mContext,
|
||||
R.drawable.a11y_button_preview_small_floating_menu, 10);
|
||||
assertThat(
|
||||
mController.mIllustrationPreference.getImageDrawable().getConstantState())
|
||||
.isEqualTo(smallFloatingMenuWithTenOpacityDrawable.getConstantState());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onResume_registerSpecificContentObserver() {
|
||||
mController.onResume();
|
||||
|
||||
verify(mContentResolver).registerContentObserver(
|
||||
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_MODE), false,
|
||||
mController.mContentObserver);
|
||||
verify(mContentResolver).registerContentObserver(
|
||||
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE), false,
|
||||
mController.mContentObserver);
|
||||
verify(mContentResolver).registerContentObserver(
|
||||
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY),
|
||||
false,
|
||||
mController.mContentObserver);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPause_unregisterContentObserver() {
|
||||
mController.onPause();
|
||||
|
||||
verify(mContentResolver).unregisterContentObserver(mController.mContentObserver);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.XmlTestUtils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** Tests for {@link AccessibilityControlTimeoutPreferenceFragment}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AccessibilityControlTimeoutPreferenceFragmentTest {
|
||||
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
private AccessibilityControlTimeoutPreferenceFragment mFragment;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mFragment = new AccessibilityControlTimeoutPreferenceFragment();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMetricsCategory_returnsCorrectCategory() {
|
||||
assertThat(mFragment.getMetricsCategory()).isEqualTo(
|
||||
SettingsEnums.ACCESSIBILITY_TIMEOUT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getPreferenceScreenResId_returnsCorrectXml() {
|
||||
assertThat(mFragment.getPreferenceScreenResId()).isEqualTo(
|
||||
R.xml.accessibility_control_timeout_settings);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getHelpResource_returnsCorrectHelpResource() {
|
||||
assertThat(mFragment.getHelpResource()).isEqualTo(R.string.help_url_timeout);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLogTag_returnsCorrectTag() {
|
||||
assertThat(mFragment.getLogTag()).isEqualTo(
|
||||
"AccessibilityControlTimeoutPreferenceFragment");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getNonIndexableKeys_existInXmlLayout() {
|
||||
final List<String> niks =
|
||||
AccessibilityControlTimeoutPreferenceFragment.SEARCH_INDEX_DATA_PROVIDER
|
||||
.getNonIndexableKeys(mContext);
|
||||
final List<String> keys =
|
||||
XmlTestUtils.getKeysFromPreferenceXml(mContext,
|
||||
R.xml.accessibility_control_timeout_settings);
|
||||
|
||||
assertThat(keys).containsAtLeastElementsIn(niks);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.accessibility;
|
||||
|
||||
import static com.android.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_BUTTON_COMPONENT_NAME;
|
||||
import static com.android.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME;
|
||||
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||
import android.app.Activity;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
|
||||
import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
import org.robolectric.shadows.ShadowAccessibilityManager;
|
||||
import org.robolectric.shadows.androidx.fragment.FragmentController;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** Tests for {@link AccessibilityDetailsSettingsFragment}. */
|
||||
@Config(shadows = {
|
||||
ShadowDevicePolicyManager.class,
|
||||
ShadowRestrictedLockUtilsInternal.class
|
||||
})
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AccessibilityDetailsSettingsFragmentTest {
|
||||
private static final String PACKAGE_NAME = "com.foo.bar";
|
||||
private static final String CLASS_NAME = PACKAGE_NAME + ".fake_a11y_service";
|
||||
private static final String COMPONENT_NAME = PACKAGE_NAME + "/" + CLASS_NAME;
|
||||
|
||||
private Context mContext;
|
||||
|
||||
private FragmentController<AccessibilityDetailsSettingsFragment> mFragmentController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = ApplicationProvider.getApplicationContext();
|
||||
ShadowAccessibilityManager shadowAccessibilityManager = Shadow.extract(
|
||||
AccessibilityManager.getInstance(mContext));
|
||||
shadowAccessibilityManager.setInstalledAccessibilityServiceList(getMockServiceList());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreate_afterSuccessfullyLaunch_shouldBeFinished() {
|
||||
final Intent intent = new Intent();
|
||||
intent.putExtra(Intent.EXTRA_COMPONENT_NAME, COMPONENT_NAME);
|
||||
|
||||
AccessibilityDetailsSettingsFragment fragment = startFragment(intent);
|
||||
|
||||
assertThat(fragment.getActivity().isFinishing()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreate_hasValidExtraComponentName_launchExpectedFragment() {
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(Intent.EXTRA_COMPONENT_NAME, COMPONENT_NAME);
|
||||
|
||||
AccessibilityDetailsSettingsFragment fragment = startFragment(intent);
|
||||
|
||||
assertStartActivityWithExpectedFragment(fragment.getActivity(),
|
||||
ToggleAccessibilityServicePreferenceFragment.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreate_hasInvalidExtraComponentName_launchAccessibilitySettings() {
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(Intent.EXTRA_COMPONENT_NAME, PACKAGE_NAME + "/.service");
|
||||
|
||||
AccessibilityDetailsSettingsFragment fragment = startFragment(intent);
|
||||
|
||||
assertStartActivityWithExpectedFragment(fragment.getActivity(),
|
||||
AccessibilitySettings.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreate_hasNoExtraComponentName_launchAccessibilitySettings() {
|
||||
AccessibilityDetailsSettingsFragment fragment = startFragment(/* intent= */ null);
|
||||
|
||||
assertStartActivityWithExpectedFragment(fragment.getActivity(),
|
||||
AccessibilitySettings.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreate_extraComponentNameIsDisallowed_launchAccessibilitySettings() {
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(Intent.EXTRA_COMPONENT_NAME, COMPONENT_NAME);
|
||||
DevicePolicyManager dpm = mContext.getSystemService(
|
||||
DevicePolicyManager.class);
|
||||
((ShadowDevicePolicyManager) Shadows.shadowOf(dpm)).setPermittedAccessibilityServices(
|
||||
ImmutableList.of());
|
||||
|
||||
AccessibilityDetailsSettingsFragment fragment = startFragment(intent);
|
||||
|
||||
assertStartActivityWithExpectedFragment(fragment.getActivity(),
|
||||
AccessibilitySettings.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreate_magnificationComponentName_launchMagnificationFragment() {
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(Intent.EXTRA_COMPONENT_NAME,
|
||||
MAGNIFICATION_COMPONENT_NAME.flattenToString());
|
||||
|
||||
AccessibilityDetailsSettingsFragment fragment = startFragment(intent);
|
||||
|
||||
assertStartActivityWithExpectedFragment(fragment.getActivity(),
|
||||
ToggleScreenMagnificationPreferenceFragment.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreate_accessibilityButton_launchAccessibilityButtonFragment() {
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(Intent.EXTRA_COMPONENT_NAME,
|
||||
ACCESSIBILITY_BUTTON_COMPONENT_NAME.flattenToString());
|
||||
|
||||
AccessibilityDetailsSettingsFragment fragment = startFragment(intent);
|
||||
|
||||
assertStartActivityWithExpectedFragment(fragment.getActivity(),
|
||||
AccessibilityButtonFragment.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreate_hearingAidsComponentName_launchAccessibilityHearingAidsFragment() {
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(Intent.EXTRA_COMPONENT_NAME,
|
||||
ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString());
|
||||
|
||||
AccessibilityDetailsSettingsFragment fragment = startFragment(intent);
|
||||
|
||||
assertStartActivityWithExpectedFragment(fragment.getActivity(),
|
||||
AccessibilityHearingAidsFragment.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMetricsCategory_returnsCorrectCategory() {
|
||||
|
||||
AccessibilityDetailsSettingsFragment fragment = startFragment(/* intent= */ null);
|
||||
|
||||
assertThat(fragment.getMetricsCategory()).isEqualTo(
|
||||
SettingsEnums.ACCESSIBILITY_DETAILS_SETTINGS);
|
||||
}
|
||||
|
||||
private AccessibilityDetailsSettingsFragment startFragment(Intent intent) {
|
||||
mFragmentController = FragmentController.of(
|
||||
new AccessibilityDetailsSettingsFragment(), intent)
|
||||
.create()
|
||||
.visible();
|
||||
|
||||
return mFragmentController.get();
|
||||
}
|
||||
|
||||
private AccessibilityServiceInfo getMockAccessibilityServiceInfo() {
|
||||
final ApplicationInfo applicationInfo = new ApplicationInfo();
|
||||
final ServiceInfo serviceInfo = new ServiceInfo();
|
||||
applicationInfo.packageName = PACKAGE_NAME;
|
||||
serviceInfo.packageName = PACKAGE_NAME;
|
||||
serviceInfo.name = CLASS_NAME;
|
||||
serviceInfo.applicationInfo = applicationInfo;
|
||||
|
||||
final ResolveInfo resolveInfo = new ResolveInfo();
|
||||
resolveInfo.serviceInfo = serviceInfo;
|
||||
|
||||
try {
|
||||
final AccessibilityServiceInfo info = new AccessibilityServiceInfo(resolveInfo,
|
||||
mContext);
|
||||
ComponentName componentName = ComponentName.unflattenFromString(COMPONENT_NAME);
|
||||
info.setComponentName(componentName);
|
||||
return info;
|
||||
} catch (XmlPullParserException | IOException e) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<AccessibilityServiceInfo> getMockServiceList() {
|
||||
final List<AccessibilityServiceInfo> infoList = new ArrayList<>();
|
||||
infoList.add(getMockAccessibilityServiceInfo());
|
||||
return infoList;
|
||||
}
|
||||
|
||||
private void assertStartActivityWithExpectedFragment(Activity activity, String fragmentName) {
|
||||
Intent intent = Shadows.shadowOf(activity).getNextStartedActivity();
|
||||
assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT)).isEqualTo(
|
||||
fragmentName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link AccessibilityDialogUtils} */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AccessibilityDialogUtilsTest {
|
||||
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext.setTheme(androidx.appcompat.R.style.Theme_AppCompat);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateShortcutInDialog_correctDialogType_success() {
|
||||
final AlertDialog dialog = AccessibilityDialogUtils.showEditShortcutDialog(
|
||||
mContext, AccessibilityDialogUtils.DialogType.EDIT_SHORTCUT_GENERIC, "Title",
|
||||
null);
|
||||
|
||||
assertThat(
|
||||
AccessibilityDialogUtils.updateShortcutInDialog(mContext, dialog)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateShortcutInDialog_useNotSupportedDialog_fail() {
|
||||
final AlertDialog dialog = new AlertDialog.Builder(mContext).setTitle("Title").show();
|
||||
|
||||
assertThat(AccessibilityDialogUtils.updateShortcutInDialog(mContext,
|
||||
dialog)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void showDialog_createCustomDialog_isShowing() {
|
||||
final Dialog dialog = AccessibilityDialogUtils.createCustomDialog(mContext,
|
||||
"Title", /* customView= */ null, "positiveButton", /* positiveListener= */ null,
|
||||
"negativeButton", /* negativeListener= */ null);
|
||||
dialog.show();
|
||||
|
||||
assertThat(dialog.isShowing()).isTrue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/**
|
||||
* Tests for {@link AccessibilityFooterPreferenceController}.
|
||||
*/
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AccessibilityFooterPreferenceControllerTest {
|
||||
|
||||
private static final String TEST_KEY = "test_pref_key";
|
||||
private static final String TEST_TITLE = "test_title";
|
||||
private static final String TEST_INTRODUCTION_TITLE = "test_introduction_title";
|
||||
private static final String TEST_CONTENT_DESCRIPTION = "test_content_description";
|
||||
private static final int TEST_HELP_ID = 12345;
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
|
||||
@Spy
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
@Mock
|
||||
private PreferenceScreen mScreen;
|
||||
private AccessibilityFooterPreferenceController mController;
|
||||
private AccessibilityFooterPreference mPreference;
|
||||
private PreferenceViewHolder mPreferenceViewHolder;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mController = new AccessibilityFooterPreferenceController(mContext, TEST_KEY);
|
||||
mPreference = new AccessibilityFooterPreference(mContext);
|
||||
mPreference.setKey(TEST_KEY);
|
||||
mPreference.setTitle(TEST_TITLE);
|
||||
|
||||
final LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||
final View view = inflater.inflate(
|
||||
com.android.settingslib.widget.preference.footer.R.layout.preference_footer, null);
|
||||
mPreferenceViewHolder = PreferenceViewHolder.createInstanceForTests(view);
|
||||
mPreference.onBindViewHolder(mPreferenceViewHolder);
|
||||
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setIntroductionTitle_setCorrectIntroductionTitle() {
|
||||
mController.setIntroductionTitle(TEST_INTRODUCTION_TITLE);
|
||||
|
||||
assertThat(mController.getIntroductionTitle()).isEqualTo(TEST_INTRODUCTION_TITLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindViewHolder_setIntroductionTitle_setCorrectIntroductionTitle() {
|
||||
mController.setIntroductionTitle(TEST_INTRODUCTION_TITLE);
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
mPreference.onBindViewHolder(mPreferenceViewHolder);
|
||||
|
||||
final TextView summaryView = (TextView) mPreferenceViewHolder
|
||||
.findViewById(android.R.id.title);
|
||||
assertThat(summaryView.getContentDescription().toString())
|
||||
.contains(TEST_INTRODUCTION_TITLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setupHelpLink_setCorrectHelpLinkAndLearnMoreText() {
|
||||
mController.setupHelpLink(TEST_HELP_ID, TEST_CONTENT_DESCRIPTION);
|
||||
|
||||
assertThat(mController.getHelpResource()).isEqualTo(TEST_HELP_ID);
|
||||
assertThat(mController.getLearnMoreText())
|
||||
.isEqualTo(TEST_CONTENT_DESCRIPTION);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindViewHolder_setHelpResource_emptyString_notVisible() {
|
||||
mController.setupHelpLink(R.string.help_url_timeout, TEST_CONTENT_DESCRIPTION);
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
mPreference.onBindViewHolder(mPreferenceViewHolder);
|
||||
|
||||
final TextView learnMoreView = (TextView) mPreferenceViewHolder
|
||||
.findViewById(com.android.settingslib.widget.preference.footer.R.id.settingslib_learn_more);
|
||||
assertThat(learnMoreView.getContentDescription()).isNull();
|
||||
assertThat(learnMoreView.getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(mPreference.isLinkEnabled()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindViewHolder_setHelpResource_expectSummaryViewIsNonFocusable() {
|
||||
mController.setupHelpLink(R.string.help_url_timeout, TEST_CONTENT_DESCRIPTION);
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
mPreference.onBindViewHolder(mPreferenceViewHolder);
|
||||
|
||||
final TextView summaryView = (TextView) mPreferenceViewHolder
|
||||
.findViewById(android.R.id.title);
|
||||
assertThat(summaryView.isFocusable()).isFalse();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.method.MovementMethod;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
/** Tests for {@link AccessibilityFooterPreference} */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public final class AccessibilityFooterPreferenceTest {
|
||||
|
||||
private AccessibilityFooterPreference mAccessibilityFooterPreference;
|
||||
private PreferenceViewHolder mPreferenceViewHolder;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
final Context context = RuntimeEnvironment.application;
|
||||
mAccessibilityFooterPreference = new AccessibilityFooterPreference(context);
|
||||
|
||||
final LayoutInflater inflater = LayoutInflater.from(context);
|
||||
final View view =
|
||||
inflater.inflate(com.android.settingslib.widget.preference.footer.R.layout.preference_footer, null);
|
||||
mPreferenceViewHolder = PreferenceViewHolder.createInstanceForTests(view);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindViewHolder_LinkDisabledByDefault_notReturnLinkMovement() {
|
||||
mAccessibilityFooterPreference.onBindViewHolder(mPreferenceViewHolder);
|
||||
|
||||
final TextView summaryView = (TextView) mPreferenceViewHolder.findViewById(
|
||||
android.R.id.title);
|
||||
assertThat(summaryView.getMovementMethod()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindViewHolder_setLinkEnabled_returnLinkMovement() {
|
||||
mAccessibilityFooterPreference.setLinkEnabled(true);
|
||||
|
||||
mAccessibilityFooterPreference.onBindViewHolder(mPreferenceViewHolder);
|
||||
|
||||
final TextView summaryView = (TextView) mPreferenceViewHolder.findViewById(
|
||||
android.R.id.title);
|
||||
assertThat(summaryView.getMovementMethod()).isInstanceOf(MovementMethod.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindViewHolder_setLinkEnabled_expectSummaryViewIsNonFocusable() {
|
||||
mAccessibilityFooterPreference.setLinkEnabled(true);
|
||||
|
||||
mAccessibilityFooterPreference.onBindViewHolder(mPreferenceViewHolder);
|
||||
|
||||
final TextView summaryView = (TextView) mPreferenceViewHolder.findViewById(
|
||||
android.R.id.title);
|
||||
assertThat(summaryView.isFocusable()).isFalse();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.accessibility;
|
||||
|
||||
import static com.android.settings.accessibility.AccessibilityGestureNavigationTutorial.createAccessibilityTutorialDialog;
|
||||
import static com.android.settings.accessibility.AccessibilityGestureNavigationTutorial.createAccessibilityTutorialDialogForSetupWizard;
|
||||
import static com.android.settings.accessibility.AccessibilityGestureNavigationTutorial.createShortcutTutorialPages;
|
||||
import static com.android.settings.accessibility.AccessibilityGestureNavigationTutorial.showGestureNavigationTutorialDialog;
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.platform.test.annotations.RequiresFlagsEnabled;
|
||||
import android.platform.test.flag.junit.CheckFlagsRule;
|
||||
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.server.accessibility.Flags;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.SubSettings;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.LooperMode;
|
||||
|
||||
/** Tests for {@link AccessibilityGestureNavigationTutorial}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@LooperMode(LooperMode.Mode.LEGACY)
|
||||
public final class AccessibilityGestureNavigationTutorialTest {
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||
@Rule
|
||||
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
|
||||
@Mock
|
||||
private DialogInterface.OnClickListener mOnClickListener;
|
||||
@Mock
|
||||
private DialogInterface.OnDismissListener mOnDismissListener;
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
private int mShortcutTypes;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext.setTheme(androidx.appcompat.R.style.Theme_AppCompat);
|
||||
mShortcutTypes = /* initial */ 0;
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void createTutorialPages_shortcutListIsEmpty_throwsException() {
|
||||
createAccessibilityTutorialDialog(mContext, mShortcutTypes);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createTutorialPages_turnOnTripleTapShortcut_hasOnePage() {
|
||||
mShortcutTypes |= UserShortcutType.TRIPLETAP;
|
||||
|
||||
final AlertDialog alertDialog =
|
||||
createAccessibilityTutorialDialog(mContext, mShortcutTypes);
|
||||
|
||||
assertThat(createShortcutTutorialPages(mContext,
|
||||
mShortcutTypes)).hasSize(/* expectedSize= */ 1);
|
||||
assertThat(alertDialog).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
|
||||
public void createTutorialPages_turnOnTwoFingerTripleTapShortcut_hasOnePage() {
|
||||
mShortcutTypes |= UserShortcutType.TWOFINGERTRIPLETAP;
|
||||
|
||||
final AlertDialog alertDialog =
|
||||
createAccessibilityTutorialDialog(mContext, mShortcutTypes);
|
||||
|
||||
assertThat(createShortcutTutorialPages(mContext,
|
||||
mShortcutTypes)).hasSize(/* expectedSize= */ 1);
|
||||
assertThat(alertDialog).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createTutorialPages_turnOnSoftwareShortcut_hasOnePage() {
|
||||
mShortcutTypes |= UserShortcutType.SOFTWARE;
|
||||
|
||||
final AlertDialog alertDialog =
|
||||
createAccessibilityTutorialDialog(mContext, mShortcutTypes);
|
||||
|
||||
assertThat(createShortcutTutorialPages(mContext,
|
||||
mShortcutTypes)).hasSize(/* expectedSize= */ 1);
|
||||
assertThat(alertDialog).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createTutorialPages_turnOnSoftwareAndHardwareShortcuts_hasTwoPages() {
|
||||
mShortcutTypes |= UserShortcutType.SOFTWARE;
|
||||
mShortcutTypes |= UserShortcutType.HARDWARE;
|
||||
|
||||
final AlertDialog alertDialog =
|
||||
createAccessibilityTutorialDialog(mContext, mShortcutTypes);
|
||||
|
||||
assertThat(createShortcutTutorialPages(mContext,
|
||||
mShortcutTypes)).hasSize(/* expectedSize= */ 2);
|
||||
assertThat(alertDialog).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createTutorialPages_turnOnSoftwareShortcut_linkButtonVisible() {
|
||||
mShortcutTypes |= UserShortcutType.SOFTWARE;
|
||||
|
||||
final AlertDialog alertDialog =
|
||||
createAccessibilityTutorialDialog(mContext, mShortcutTypes);
|
||||
alertDialog.show();
|
||||
|
||||
assertThat(alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).getVisibility())
|
||||
.isEqualTo(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createTutorialPages_turnOnSoftwareAndHardwareShortcut_linkButtonVisible() {
|
||||
mShortcutTypes |= UserShortcutType.SOFTWARE;
|
||||
mShortcutTypes |= UserShortcutType.HARDWARE;
|
||||
|
||||
final AlertDialog alertDialog =
|
||||
createAccessibilityTutorialDialog(mContext, mShortcutTypes);
|
||||
alertDialog.show();
|
||||
|
||||
assertThat(alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).getVisibility())
|
||||
.isEqualTo(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createTutorialPages_turnOnHardwareShortcut_linkButtonGone() {
|
||||
mShortcutTypes |= UserShortcutType.HARDWARE;
|
||||
|
||||
final AlertDialog alertDialog =
|
||||
createAccessibilityTutorialDialog(mContext, mShortcutTypes);
|
||||
alertDialog.show();
|
||||
|
||||
assertThat(alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).getVisibility())
|
||||
.isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createTutorialPages_turnOnSoftwareShortcut_showFromSuW_linkButtonGone() {
|
||||
mShortcutTypes |= UserShortcutType.SOFTWARE;
|
||||
|
||||
final AlertDialog alertDialog =
|
||||
createAccessibilityTutorialDialogForSetupWizard(mContext, mShortcutTypes);
|
||||
alertDialog.show();
|
||||
|
||||
assertThat(alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).getVisibility())
|
||||
.isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void performClickOnPositiveButton_turnOnSoftwareShortcut_dismiss() {
|
||||
mShortcutTypes |= UserShortcutType.SOFTWARE;
|
||||
final AlertDialog alertDialog =
|
||||
createAccessibilityTutorialDialog(mContext, mShortcutTypes);
|
||||
alertDialog.show();
|
||||
|
||||
alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick();
|
||||
|
||||
assertThat(alertDialog.isShowing()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void performClickOnPositiveButton_turnOnSoftwareShortcut_callOnClickListener() {
|
||||
mShortcutTypes |= UserShortcutType.SOFTWARE;
|
||||
final AlertDialog alertDialog =
|
||||
createAccessibilityTutorialDialog(mContext, mShortcutTypes, mOnClickListener);
|
||||
alertDialog.show();
|
||||
|
||||
alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick();
|
||||
|
||||
verify(mOnClickListener).onClick(alertDialog, DialogInterface.BUTTON_POSITIVE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void performClickOnNegativeButton_turnOnSoftwareShortcut_directToSettingsPage() {
|
||||
mShortcutTypes |= UserShortcutType.SOFTWARE;
|
||||
Activity activity = Robolectric.buildActivity(Activity.class).create().get();
|
||||
final AlertDialog alertDialog = createAccessibilityTutorialDialog(activity, mShortcutTypes);
|
||||
alertDialog.show();
|
||||
|
||||
alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).performClick();
|
||||
|
||||
final Intent intent = shadowOf(activity).peekNextStartedActivity();
|
||||
assertThat(intent.getComponent().getClassName()).isEqualTo(SubSettings.class.getName());
|
||||
assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
|
||||
.isEqualTo(AccessibilityButtonFragment.class.getName());
|
||||
assertThat(intent.getIntExtra(MetricsFeatureProvider.EXTRA_SOURCE_METRICS_CATEGORY, -1))
|
||||
.isEqualTo(SettingsEnums.SWITCH_SHORTCUT_DIALOG_ACCESSIBILITY_BUTTON_SETTINGS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void performClickOnPositiveButton_turnOnGestureShortcut_callOnDismissListener() {
|
||||
final AlertDialog alertDialog =
|
||||
showGestureNavigationTutorialDialog(mContext, mOnDismissListener);
|
||||
|
||||
alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick();
|
||||
|
||||
assertThat(alertDialog.isShowing()).isFalse();
|
||||
verify(mOnDismissListener).onDismiss(alertDialog);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,320 @@
|
||||
/*
|
||||
* Copyright 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.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
import android.app.Application;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothHapClient;
|
||||
import android.bluetooth.BluetoothHearingAid;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.bluetooth.Utils;
|
||||
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
|
||||
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
|
||||
import com.android.settingslib.bluetooth.BluetoothEventManager;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
|
||||
import com.android.settingslib.bluetooth.HapClientProfile;
|
||||
import com.android.settingslib.bluetooth.HearingAidInfo;
|
||||
import com.android.settingslib.bluetooth.HearingAidProfile;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/** Tests for {@link AccessibilityHearingAidPreferenceController}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {ShadowBluetoothAdapter.class, ShadowBluetoothUtils.class})
|
||||
public class AccessibilityHearingAidPreferenceControllerTest {
|
||||
@Rule
|
||||
public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
|
||||
private static final String TEST_DEVICE_ADDRESS = "00:A1:A1:A1:A1:A1";
|
||||
private static final String TEST_DEVICE_ADDRESS_2 = "00:A2:A2:A2:A2:A2";
|
||||
private static final String TEST_DEVICE_NAME = "TEST_HEARING_AID_BT_DEVICE_NAME";
|
||||
private static final String HEARING_AID_PREFERENCE = "hearing_aid_preference";
|
||||
|
||||
private BluetoothAdapter mBluetoothAdapter;
|
||||
private ShadowBluetoothAdapter mShadowBluetoothAdapter;
|
||||
private BluetoothDevice mBluetoothDevice;
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
private Preference mHearingAidPreference;
|
||||
private AccessibilityHearingAidPreferenceController mPreferenceController;
|
||||
private ShadowApplication mShadowApplication;
|
||||
|
||||
@Mock
|
||||
private CachedBluetoothDevice mCachedBluetoothDevice;
|
||||
@Mock
|
||||
private CachedBluetoothDevice mCachedSubBluetoothDevice;
|
||||
@Mock
|
||||
private CachedBluetoothDeviceManager mCachedDeviceManager;
|
||||
@Mock
|
||||
private LocalBluetoothManager mLocalBluetoothManager;
|
||||
@Mock
|
||||
private BluetoothEventManager mEventManager;
|
||||
@Mock
|
||||
private LocalBluetoothProfileManager mLocalBluetoothProfileManager;
|
||||
@Mock
|
||||
private HearingAidProfile mHearingAidProfile;
|
||||
@Mock
|
||||
private HapClientProfile mHapClientProfile;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mShadowApplication = shadowOf((Application) ApplicationProvider.getApplicationContext());
|
||||
setupEnvironment();
|
||||
|
||||
mHearingAidPreference = new Preference(mContext);
|
||||
mHearingAidPreference.setKey(HEARING_AID_PREFERENCE);
|
||||
mPreferenceController = new AccessibilityHearingAidPreferenceController(mContext,
|
||||
HEARING_AID_PREFERENCE);
|
||||
mPreferenceController.setPreference(mHearingAidPreference);
|
||||
mHearingAidPreference.setSummary("");
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
ShadowBluetoothUtils.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_connectedAshaHearingAidRightSide_connectedRightSideSummary() {
|
||||
when(mCachedBluetoothDevice.getDeviceSide()).thenReturn(
|
||||
HearingAidInfo.DeviceSide.SIDE_RIGHT);
|
||||
when(mHearingAidProfile.getConnectedDevices()).thenReturn(generateHearingAidDeviceList());
|
||||
|
||||
mPreferenceController.onStart();
|
||||
Intent intent = new Intent(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
|
||||
intent.putExtra(BluetoothHearingAid.EXTRA_STATE, BluetoothHearingAid.STATE_CONNECTED);
|
||||
sendIntent(intent);
|
||||
|
||||
assertThat(mHearingAidPreference.getSummary().toString().contentEquals(
|
||||
"TEST_HEARING_AID_BT_DEVICE_NAME, right only")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_connectedAshaHearingAidBothSide_connectedBothSideSummary() {
|
||||
when(mCachedBluetoothDevice.getDeviceSide()).thenReturn(
|
||||
HearingAidInfo.DeviceSide.SIDE_LEFT);
|
||||
when(mCachedSubBluetoothDevice.isConnected()).thenReturn(true);
|
||||
when(mCachedBluetoothDevice.getSubDevice()).thenReturn(mCachedSubBluetoothDevice);
|
||||
when(mHearingAidProfile.getConnectedDevices()).thenReturn(generateHearingAidDeviceList());
|
||||
|
||||
mPreferenceController.onStart();
|
||||
Intent intent = new Intent(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
|
||||
intent.putExtra(BluetoothHearingAid.EXTRA_STATE, BluetoothHearingAid.STATE_CONNECTED);
|
||||
sendIntent(intent);
|
||||
|
||||
assertThat(mHearingAidPreference.getSummary().toString().contentEquals(
|
||||
"TEST_HEARING_AID_BT_DEVICE_NAME, left and right")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_connectedLeAudioHearingAidLeftSide_connectedLeftSideSummary() {
|
||||
when(mCachedBluetoothDevice.getDeviceSide()).thenReturn(
|
||||
HearingAidInfo.DeviceSide.SIDE_LEFT);
|
||||
when(mCachedBluetoothDevice.getMemberDevice()).thenReturn(new HashSet<>());
|
||||
when(mHapClientProfile.getConnectedDevices()).thenReturn(generateHearingAidDeviceList());
|
||||
|
||||
mPreferenceController.onStart();
|
||||
Intent intent = new Intent(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED);
|
||||
intent.putExtra(BluetoothHearingAid.EXTRA_STATE, BluetoothHapClient.STATE_CONNECTED);
|
||||
sendIntent(intent);
|
||||
|
||||
assertThat(mHearingAidPreference.getSummary().toString().contentEquals(
|
||||
"TEST_HEARING_AID_BT_DEVICE_NAME, left only")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_connectedLeAudioHearingAidRightSide_connectedRightSideSummary() {
|
||||
when(mCachedBluetoothDevice.getDeviceSide()).thenReturn(
|
||||
HearingAidInfo.DeviceSide.SIDE_RIGHT);
|
||||
when(mCachedBluetoothDevice.getMemberDevice()).thenReturn(new HashSet<>());
|
||||
when(mHapClientProfile.getConnectedDevices()).thenReturn(generateHearingAidDeviceList());
|
||||
|
||||
mPreferenceController.onStart();
|
||||
Intent intent = new Intent(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED);
|
||||
intent.putExtra(BluetoothHearingAid.EXTRA_STATE, BluetoothHapClient.STATE_CONNECTED);
|
||||
sendIntent(intent);
|
||||
|
||||
assertThat(mHearingAidPreference.getSummary().toString().contentEquals(
|
||||
"TEST_HEARING_AID_BT_DEVICE_NAME, right only")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_connectedLeAudioHearingAidLeftAndRightSide_connectedSummary() {
|
||||
when(mCachedBluetoothDevice.getDeviceSide()).thenReturn(
|
||||
HearingAidInfo.DeviceSide.SIDE_LEFT_AND_RIGHT);
|
||||
when(mCachedBluetoothDevice.getMemberDevice()).thenReturn(new HashSet<>());
|
||||
when(mHapClientProfile.getConnectedDevices()).thenReturn(generateHearingAidDeviceList());
|
||||
|
||||
mPreferenceController.onStart();
|
||||
Intent intent = new Intent(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED);
|
||||
intent.putExtra(BluetoothHearingAid.EXTRA_STATE, BluetoothHapClient.STATE_CONNECTED);
|
||||
sendIntent(intent);
|
||||
|
||||
assertThat(mHearingAidPreference.getSummary().toString().contentEquals(
|
||||
"TEST_HEARING_AID_BT_DEVICE_NAME, left and right")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_connectedLeAudioHearingAidBothSide_connectedBothSideSummary() {
|
||||
when(mCachedBluetoothDevice.getMemberDevice()).thenReturn(generateMemberDevices());
|
||||
when(mCachedSubBluetoothDevice.isConnected()).thenReturn(true);
|
||||
when(mHapClientProfile.getConnectedDevices()).thenReturn(generateHearingAidDeviceList());
|
||||
|
||||
mPreferenceController.onStart();
|
||||
Intent intent = new Intent(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED);
|
||||
intent.putExtra(BluetoothHearingAid.EXTRA_STATE, BluetoothHapClient.STATE_CONNECTED);
|
||||
sendIntent(intent);
|
||||
|
||||
assertThat(mHearingAidPreference.getSummary().toString()).isEqualTo(
|
||||
"TEST_HEARING_AID_BT_DEVICE_NAME, left and right");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_connectedMultipleHearingAids_connectedMultipleDevicesSummary() {
|
||||
when(mCachedBluetoothDevice.getDeviceSide()).thenReturn(
|
||||
HearingAidInfo.DeviceSide.SIDE_LEFT);
|
||||
when(mHearingAidProfile.getConnectedDevices()).thenReturn(
|
||||
generateMultipleHearingAidDeviceList());
|
||||
|
||||
mPreferenceController.onStart();
|
||||
Intent intent = new Intent(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
|
||||
intent.putExtra(BluetoothHearingAid.EXTRA_STATE, BluetoothHearingAid.STATE_CONNECTED);
|
||||
sendIntent(intent);
|
||||
|
||||
assertThat(mHearingAidPreference.getSummary().toString().contentEquals(
|
||||
"TEST_HEARING_AID_BT_DEVICE_NAME +1 more")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_bluetoothOff_disconnectedSummary() {
|
||||
mPreferenceController.onStart();
|
||||
Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
|
||||
intent.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_OFF);
|
||||
sendIntent(intent);
|
||||
|
||||
assertThat(mHearingAidPreference.getSummary()).isEqualTo(
|
||||
mContext.getText(R.string.accessibility_hearingaid_not_connected_summary));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onServiceConnected_onHearingAidProfileConnected_updateSummary() {
|
||||
when(mCachedBluetoothDevice.getDeviceSide()).thenReturn(
|
||||
HearingAidInfo.DeviceSide.SIDE_LEFT);
|
||||
when(mHearingAidProfile.getConnectedDevices()).thenReturn(generateHearingAidDeviceList());
|
||||
|
||||
mPreferenceController.onStart();
|
||||
mPreferenceController.onServiceConnected();
|
||||
|
||||
assertThat(mHearingAidPreference.getSummary().toString()).isEqualTo(
|
||||
"TEST_HEARING_AID_BT_DEVICE_NAME, left only");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onServiceConnected_onHapClientProfileConnected_updateSummary() {
|
||||
when(mCachedBluetoothDevice.getDeviceSide()).thenReturn(
|
||||
HearingAidInfo.DeviceSide.SIDE_RIGHT);
|
||||
when(mHapClientProfile.getConnectedDevices()).thenReturn(generateHearingAidDeviceList());
|
||||
|
||||
mPreferenceController.onStart();
|
||||
mPreferenceController.onServiceConnected();
|
||||
|
||||
assertThat(mHearingAidPreference.getSummary().toString()).isEqualTo(
|
||||
"TEST_HEARING_AID_BT_DEVICE_NAME, right only");
|
||||
}
|
||||
|
||||
private void setupEnvironment() {
|
||||
ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
|
||||
mLocalBluetoothManager = Utils.getLocalBtManager(mContext);
|
||||
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
mShadowBluetoothAdapter = Shadow.extract(mBluetoothAdapter);
|
||||
mShadowBluetoothAdapter.addSupportedProfiles(BluetoothProfile.HEARING_AID);
|
||||
mShadowBluetoothAdapter.addSupportedProfiles(BluetoothProfile.HAP_CLIENT);
|
||||
mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS);
|
||||
mBluetoothAdapter.enable();
|
||||
|
||||
doReturn(mEventManager).when(mLocalBluetoothManager).getEventManager();
|
||||
when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager);
|
||||
when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
|
||||
when(mLocalBluetoothProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile);
|
||||
when(mLocalBluetoothProfileManager.getHapClientProfile()).thenReturn(mHapClientProfile);
|
||||
when(mHearingAidProfile.isProfileReady()).thenReturn(true);
|
||||
when(mHapClientProfile.isProfileReady()).thenReturn(true);
|
||||
when(mCachedDeviceManager.findDevice(mBluetoothDevice)).thenReturn(mCachedBluetoothDevice);
|
||||
when(mCachedBluetoothDevice.getAddress()).thenReturn(TEST_DEVICE_ADDRESS);
|
||||
when(mCachedBluetoothDevice.getName()).thenReturn(TEST_DEVICE_NAME);
|
||||
}
|
||||
|
||||
private void sendIntent(Intent intent) {
|
||||
for (BroadcastReceiver receiver : mShadowApplication.getReceiversForIntent(intent)) {
|
||||
receiver.onReceive(mContext, intent);
|
||||
}
|
||||
}
|
||||
|
||||
private List<BluetoothDevice> generateHearingAidDeviceList() {
|
||||
final List<BluetoothDevice> deviceList = new ArrayList<>(1);
|
||||
deviceList.add(mBluetoothDevice);
|
||||
return deviceList;
|
||||
}
|
||||
|
||||
private List<BluetoothDevice> generateMultipleHearingAidDeviceList() {
|
||||
// Generates different Bluetooth devices for testing multiple devices
|
||||
final List<BluetoothDevice> deviceList = new ArrayList<>(2);
|
||||
deviceList.add(mBluetoothDevice);
|
||||
deviceList.add(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_2));
|
||||
return deviceList;
|
||||
}
|
||||
|
||||
private Set<CachedBluetoothDevice> generateMemberDevices() {
|
||||
final Set<CachedBluetoothDevice> memberDevices = new HashSet<>();
|
||||
memberDevices.add(mCachedSubBluetoothDevice);
|
||||
return memberDevices;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.XmlTestUtils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** Tests for {@link AccessibilityHearingAidsFragment}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AccessibilityHearingAidsFragmentTest {
|
||||
|
||||
@Rule
|
||||
public MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||
@Spy
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
private TelephonyManager mTelephonyManager;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mTelephonyManager = spy(mContext.getSystemService(TelephonyManager.class));
|
||||
when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
|
||||
doReturn(true).when(mTelephonyManager).isHearingAidCompatibilitySupported();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getNonIndexableKeys_existInXmlLayout() {
|
||||
final List<String> niks = AccessibilityHearingAidsFragment.SEARCH_INDEX_DATA_PROVIDER
|
||||
.getNonIndexableKeys(mContext);
|
||||
final List<String> keys =
|
||||
XmlTestUtils.getKeysFromPreferenceXml(mContext, R.xml.accessibility_hearing_aids);
|
||||
|
||||
assertThat(keys).containsAtLeastElementsIn(niks);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.ImageTestUtils;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link AccessibilityLayerDrawable}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AccessibilityLayerDrawableTest {
|
||||
|
||||
private static final int TEST_RES_ID =
|
||||
com.android.internal.R.drawable.ic_accessibility_magnification;
|
||||
private static final int TEST_RES_ID_2 =
|
||||
com.android.internal.R.drawable.ic_accessibility_color_inversion;
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
@Test
|
||||
public void createLayerDrawable_configCorrect() {
|
||||
final Drawable expected1stDrawable = mContext.getDrawable(
|
||||
R.drawable.a11y_button_preview_base);
|
||||
final Drawable expected2ndDrawable = mContext.getDrawable(TEST_RES_ID);
|
||||
|
||||
final AccessibilityLayerDrawable actualDrawable =
|
||||
AccessibilityLayerDrawable.createLayerDrawable(mContext, TEST_RES_ID,
|
||||
/* opacity= */ 27);
|
||||
|
||||
final Drawable actual1stDrawable = actualDrawable.getDrawable(0);
|
||||
final Drawable actual2ndDrawable = actualDrawable.getDrawable(1);
|
||||
assertThat(ImageTestUtils.drawableToBitmap(actual1stDrawable).sameAs(
|
||||
ImageTestUtils.drawableToBitmap(expected1stDrawable))).isTrue();
|
||||
assertThat(ImageTestUtils.drawableToBitmap(actual2ndDrawable).sameAs(
|
||||
ImageTestUtils.drawableToBitmap(expected2ndDrawable))).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateLayerDrawable_expectedFloatingMenuLayerDrawableState() {
|
||||
final AccessibilityLayerDrawable originalDrawable =
|
||||
AccessibilityLayerDrawable.createLayerDrawable(mContext, TEST_RES_ID, /* opacity= */
|
||||
72);
|
||||
|
||||
originalDrawable.updateLayerDrawable(mContext, TEST_RES_ID_2, /* opacity= */ 27);
|
||||
|
||||
assertThat(originalDrawable.getConstantState()).isEqualTo(
|
||||
new AccessibilityLayerDrawable.AccessibilityLayerDrawableState(mContext,
|
||||
TEST_RES_ID_2, /* opacity= */ 27));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link AccessibilityQuickSettingUtils}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public final class AccessibilityQuickSettingUtilsTest {
|
||||
private static final String DUMMY_PACKAGE_NAME = "com.mock.example";
|
||||
private static final String DUMMY_CLASS_NAME = DUMMY_PACKAGE_NAME + ".mock_a11y_service";
|
||||
private static final String DUMMY_CLASS_NAME2 = DUMMY_PACKAGE_NAME + ".mock_a11y_service2";
|
||||
private static final ComponentName DUMMY_COMPONENT_NAME = new ComponentName(DUMMY_PACKAGE_NAME,
|
||||
DUMMY_CLASS_NAME);
|
||||
private static final ComponentName DUMMY_COMPONENT_NAME2 = new ComponentName(DUMMY_PACKAGE_NAME,
|
||||
DUMMY_CLASS_NAME2);
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
@Test
|
||||
public void optInValueToSharedPreferences_optInValue_haveMatchString() {
|
||||
AccessibilityQuickSettingUtils.optInValueToSharedPreferences(mContext,
|
||||
DUMMY_COMPONENT_NAME);
|
||||
|
||||
assertThat(AccessibilityQuickSettingUtils.hasValueInSharedPreferences(mContext,
|
||||
DUMMY_COMPONENT_NAME)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void optInValueToSharedPreferences_optInTwoValues_haveMatchString() {
|
||||
AccessibilityQuickSettingUtils.optInValueToSharedPreferences(mContext,
|
||||
DUMMY_COMPONENT_NAME);
|
||||
AccessibilityQuickSettingUtils.optInValueToSharedPreferences(mContext,
|
||||
DUMMY_COMPONENT_NAME2);
|
||||
|
||||
assertThat(AccessibilityQuickSettingUtils.hasValueInSharedPreferences(mContext,
|
||||
DUMMY_COMPONENT_NAME)).isTrue();
|
||||
assertThat(AccessibilityQuickSettingUtils.hasValueInSharedPreferences(mContext,
|
||||
DUMMY_COMPONENT_NAME2)).isTrue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.accessibility;
|
||||
|
||||
import static com.android.settings.accessibility.ToggleFeaturePreferenceFragment.KEY_SAVED_QS_TOOLTIP_RESHOW;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.PopupWindow;
|
||||
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.testutils.shadow.ShadowFragment;
|
||||
import com.android.settingslib.PrimarySwitchPreference;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.annotation.LooperMode;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
|
||||
/**
|
||||
* Tests for {@link AccessibilityQuickSettingsPrimarySwitchPreferenceController}.
|
||||
*/
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@LooperMode(LooperMode.Mode.LEGACY)
|
||||
public class AccessibilityQuickSettingsPrimarySwitchPreferenceControllerTest {
|
||||
|
||||
private static final String PLACEHOLDER_PACKAGE_NAME = "com.placeholder.example";
|
||||
private static final String PLACEHOLDER_TILE_CLASS_NAME =
|
||||
PLACEHOLDER_PACKAGE_NAME + "tile.placeholder";
|
||||
private static final ComponentName PLACEHOLDER_TILE_COMPONENT_NAME = new ComponentName(
|
||||
PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_TILE_CLASS_NAME);
|
||||
private static final CharSequence PLACEHOLDER_TILE_CONTENT =
|
||||
PLACEHOLDER_TILE_CLASS_NAME + ".tile.content";
|
||||
private static final String TEST_KEY = "test_pref_key";
|
||||
private static final String TEST_TITLE = "test_title";
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
|
||||
@Spy
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
private TestAccessibilityQuickSettingsPrimarySwitchPreferenceController mController;
|
||||
private PrimarySwitchPreference mPreference;
|
||||
private TestFragment mFragment;
|
||||
private PreferenceScreen mScreen;
|
||||
private PreferenceViewHolder mHolder;
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private PreferenceManager mPreferenceManager;
|
||||
|
||||
private static PopupWindow getLatestPopupWindow() {
|
||||
final ShadowApplication shadowApplication =
|
||||
Shadow.extract(ApplicationProvider.getApplicationContext());
|
||||
return shadowApplication.getLatestPopupWindow();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext.setTheme(androidx.appcompat.R.style.Theme_AppCompat);
|
||||
mFragment = spy(new TestFragment());
|
||||
when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
|
||||
when(mFragment.getPreferenceManager().getContext()).thenReturn(mContext);
|
||||
when(mFragment.getContext()).thenReturn(mContext);
|
||||
mScreen = spy(new PreferenceScreen(mContext, /* attrs= */ null));
|
||||
when(mScreen.getPreferenceManager()).thenReturn(mPreferenceManager);
|
||||
doReturn(mScreen).when(mFragment).getPreferenceScreen();
|
||||
|
||||
mPreference = new PrimarySwitchPreference(mContext);
|
||||
mPreference.setKey(TEST_KEY);
|
||||
mPreference.setTitle(TEST_TITLE);
|
||||
LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||
mHolder = PreferenceViewHolder.createInstanceForTests(inflater.inflate(
|
||||
com.android.settingslib.widget.preference.twotarget.R.layout.preference_two_target, null));
|
||||
LinearLayout mWidgetView = mHolder.itemView.findViewById(android.R.id.widget_frame);
|
||||
inflater.inflate(R.layout.preference_widget_primary_switch, mWidgetView, true);
|
||||
mPreference.onBindViewHolder(mHolder);
|
||||
|
||||
mController = new TestAccessibilityQuickSettingsPrimarySwitchPreferenceController(mContext,
|
||||
TEST_KEY);
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setChecked_showTooltipView() {
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
mController.setChecked(true);
|
||||
|
||||
assertThat(getLatestPopupWindow().isShowing()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setChecked_notCallDisplayPreference_notShowTooltipView() {
|
||||
// Simulates the slice highlight menu that does not call {@link #displayPreference} before
|
||||
// {@link #setChecked} called.
|
||||
mController.setChecked(true);
|
||||
|
||||
assertThat(getLatestPopupWindow()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setChecked_tooltipViewShown_notShowTooltipView() {
|
||||
mController.displayPreference(mScreen);
|
||||
mController.setChecked(true);
|
||||
getLatestPopupWindow().dismiss();
|
||||
mController.setChecked(false);
|
||||
|
||||
mController.setChecked(true);
|
||||
|
||||
assertThat(getLatestPopupWindow().isShowing()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = ShadowFragment.class)
|
||||
public void restoreValueFromSavedInstanceState_showTooltipView() {
|
||||
final Bundle savedInstanceState = new Bundle();
|
||||
savedInstanceState.putBoolean(KEY_SAVED_QS_TOOLTIP_RESHOW, /* value= */ true);
|
||||
mController.onCreate(savedInstanceState);
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
assertThat(getLatestPopupWindow().isShowing()).isTrue();
|
||||
}
|
||||
|
||||
public static class TestAccessibilityQuickSettingsPrimarySwitchPreferenceController
|
||||
extends AccessibilityQuickSettingsPrimarySwitchPreferenceController {
|
||||
|
||||
public TestAccessibilityQuickSettingsPrimarySwitchPreferenceController(Context context,
|
||||
String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
ComponentName getTileComponentName() {
|
||||
return PLACEHOLDER_TILE_COMPONENT_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
CharSequence getTileTooltipContent() {
|
||||
return PLACEHOLDER_TILE_CONTENT;
|
||||
}
|
||||
}
|
||||
|
||||
private static class TestFragment extends SettingsPreferenceFragment {
|
||||
|
||||
@Override
|
||||
protected boolean shouldSkipForInitialSUW() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.widget.PopupWindow;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
import org.robolectric.shadows.ShadowLooper;
|
||||
|
||||
/** Tests for {@link AccessibilityQuickSettingsTooltipWindow}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AccessibilityQuickSettingsTooltipWindowTest {
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||
|
||||
@Mock
|
||||
private PopupWindow.OnDismissListener mMockOnDismissListener;
|
||||
|
||||
private static final String TEST_PACKAGE_NAME = "com.test.package";
|
||||
private static final int TEST_RES_ID = 1234;
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
private AccessibilityQuickSettingsTooltipWindow mTooltipView;
|
||||
private View mView;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mTooltipView = new AccessibilityQuickSettingsTooltipWindow(mContext);
|
||||
mView = new View(mContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initTooltipView_atMostAvailableTextWidth() {
|
||||
final String quickSettingsTooltipsContent = mContext.getString(
|
||||
R.string.accessibility_service_qs_tooltip_content, TEST_PACKAGE_NAME);
|
||||
mTooltipView.setup(quickSettingsTooltipsContent, TEST_RES_ID);
|
||||
|
||||
final int getMaxWidth = mTooltipView.getAvailableWindowWidth();
|
||||
assertThat(mTooltipView.getWidth()).isAtMost(getMaxWidth);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void showTooltipView_success() {
|
||||
mTooltipView.setup(TEST_PACKAGE_NAME, TEST_RES_ID);
|
||||
assertThat(getLatestPopupWindow()).isNull();
|
||||
|
||||
mTooltipView.showAtTopCenter(mView);
|
||||
|
||||
assertThat(getLatestPopupWindow()).isSameInstanceAs(mTooltipView);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accessibilityClickActionOnTooltipViewShown_shouldInvokeCallbackAndNotShowing() {
|
||||
mTooltipView.setup(TEST_PACKAGE_NAME, TEST_RES_ID);
|
||||
mTooltipView.setOnDismissListener(mMockOnDismissListener);
|
||||
mTooltipView.showAtTopCenter(mView);
|
||||
|
||||
final boolean isActionPerformed =
|
||||
mTooltipView.getContentView().performAccessibilityAction(
|
||||
AccessibilityNodeInfo.ACTION_CLICK,
|
||||
/* arguments= */ null);
|
||||
|
||||
assertThat(isActionPerformed).isTrue();
|
||||
verify(mMockOnDismissListener).onDismiss();
|
||||
assertThat(getLatestPopupWindow().isShowing()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dismiss_tooltipViewShown_shouldInvokeCallbackAndNotShowing() {
|
||||
mTooltipView.setup(TEST_PACKAGE_NAME, TEST_RES_ID);
|
||||
mTooltipView.setOnDismissListener(mMockOnDismissListener);
|
||||
mTooltipView.showAtTopCenter(mView);
|
||||
|
||||
mTooltipView.dismiss();
|
||||
|
||||
verify(mMockOnDismissListener).onDismiss();
|
||||
assertThat(getLatestPopupWindow().isShowing()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void waitAutoCloseDelayTime_tooltipViewShown_shouldInvokeCallbackAndNotShowing() {
|
||||
mTooltipView.setup(TEST_PACKAGE_NAME, TEST_RES_ID, /* closeDelayTimeMillis= */ 1);
|
||||
mTooltipView.setOnDismissListener(mMockOnDismissListener);
|
||||
mTooltipView.showAtTopCenter(mView);
|
||||
|
||||
ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
|
||||
|
||||
verify(mMockOnDismissListener).onDismiss();
|
||||
assertThat(getLatestPopupWindow().isShowing()).isFalse();
|
||||
}
|
||||
|
||||
private static PopupWindow getLatestPopupWindow() {
|
||||
final ShadowApplication shadowApplication = shadowOf(
|
||||
(Application) ApplicationProvider.getApplicationContext());
|
||||
return shadowApplication.getLatestPopupWindow();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.database.ContentObserver;
|
||||
import android.os.Handler;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
import org.robolectric.shadows.ShadowContentResolver;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/** Test for {@link AccessibilitySettingsContentObserver}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AccessibilitySettingsContentObserverTest {
|
||||
|
||||
private static final String SPECIFIC_KEY_A_1 = "SPECIFIC_KEY_A_1";
|
||||
private static final String SPECIFIC_KEY_A_2 = "SPECIFIC_KEY_A_2";
|
||||
private static final String SPECIFIC_KEY_B_1 = "SPECIFIC_KEY_B_1";
|
||||
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
private final AccessibilitySettingsContentObserver mObserver =
|
||||
new AccessibilitySettingsContentObserver(new Handler());
|
||||
private final AccessibilitySettingsContentObserver.ContentObserverCallback mObserverCallbackA =
|
||||
spy(new TestableContentObserverCallback());
|
||||
private final AccessibilitySettingsContentObserver.ContentObserverCallback mObserverCallbackB =
|
||||
spy(new TestableContentObserverCallback());
|
||||
private final ContentResolver mContentResolver = mContext.getContentResolver();
|
||||
|
||||
@Test
|
||||
public void register_shouldRegisterContentObserverForDefaultKeys() {
|
||||
mObserver.register(mContentResolver);
|
||||
|
||||
ShadowContentResolver shadowContentResolver = Shadow.extract(mContentResolver);
|
||||
assertObserverToUri(shadowContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_ENABLED, mObserver);
|
||||
assertObserverToUri(shadowContentResolver,
|
||||
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, mObserver);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unregister_shouldUnregisterContentObserver() {
|
||||
mObserver.register(mContentResolver);
|
||||
|
||||
mObserver.unregister(mContentResolver);
|
||||
|
||||
ShadowContentResolver shadowContentResolver = Shadow.extract(mContentResolver);
|
||||
assertNotObserverToUri(shadowContentResolver, Settings.Secure.ACCESSIBILITY_ENABLED);
|
||||
assertNotObserverToUri(shadowContentResolver,
|
||||
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void register_addSpecificKeys_shouldRegisterContentObserverForSpecificAndDefaultKeys() {
|
||||
mObserver.registerKeysToObserverCallback(List.of(SPECIFIC_KEY_A_1), mObserverCallbackA);
|
||||
|
||||
mObserver.register(mContentResolver);
|
||||
|
||||
ShadowContentResolver shadowContentResolver = Shadow.extract(mContentResolver);
|
||||
assertObserverToUri(shadowContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_ENABLED, mObserver);
|
||||
assertObserverToUri(shadowContentResolver,
|
||||
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, mObserver);
|
||||
assertObserverToUri(shadowContentResolver, SPECIFIC_KEY_A_1, mObserver);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onChange_shouldTriggerCallbackOnDefaultKey() {
|
||||
mObserver.registerObserverCallback(mObserverCallbackA);
|
||||
mObserver.register(mContentResolver);
|
||||
|
||||
mObserver.onChange(/* selfChange= */ false,
|
||||
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_ENABLED));
|
||||
|
||||
verify(mObserverCallbackA).onChange(Settings.Secure.ACCESSIBILITY_ENABLED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onChange_registerSpecificKeys_shouldTriggerSpecificCallback() {
|
||||
mObserver.registerKeysToObserverCallback(
|
||||
List.of(SPECIFIC_KEY_A_1, SPECIFIC_KEY_A_2), mObserverCallbackA);
|
||||
mObserver.register(mContentResolver);
|
||||
|
||||
mObserver.onChange(/* selfChange= */ false,
|
||||
Settings.Secure.getUriFor(SPECIFIC_KEY_A_2));
|
||||
|
||||
verify(mObserverCallbackA).onChange(SPECIFIC_KEY_A_2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onChange_registerSpecificKeys_withoutTriggerOtherCallback() {
|
||||
mObserver.registerKeysToObserverCallback(
|
||||
List.of(SPECIFIC_KEY_A_1, SPECIFIC_KEY_A_2), mObserverCallbackA);
|
||||
mObserver.registerKeysToObserverCallback(
|
||||
List.of(SPECIFIC_KEY_B_1), mObserverCallbackB);
|
||||
mObserver.register(mContentResolver);
|
||||
|
||||
mObserver.onChange(/* selfChange= */ false,
|
||||
Settings.Secure.getUriFor(SPECIFIC_KEY_B_1));
|
||||
|
||||
verify(mObserverCallbackA, never()).onChange(SPECIFIC_KEY_A_1);
|
||||
verify(mObserverCallbackA, never()).onChange(SPECIFIC_KEY_A_2);
|
||||
verify(mObserverCallbackA, never()).onChange(SPECIFIC_KEY_B_1);
|
||||
verify(mObserverCallbackB).onChange(SPECIFIC_KEY_B_1);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
mObserver.unregister(mContentResolver);
|
||||
}
|
||||
|
||||
private void assertNotObserverToUri(ShadowContentResolver resolver, String key) {
|
||||
assertThat(resolver.getContentObservers(Settings.Secure.getUriFor(key))).isEmpty();
|
||||
}
|
||||
|
||||
private void assertObserverToUri(ShadowContentResolver resolver,
|
||||
String key, ContentObserver observer) {
|
||||
Collection<ContentObserver> observers =
|
||||
resolver.getContentObservers(Settings.Secure.getUriFor(key));
|
||||
assertThat(observers).contains(observer);
|
||||
}
|
||||
|
||||
private static class TestableContentObserverCallback implements
|
||||
AccessibilitySettingsContentObserver.ContentObserverCallback {
|
||||
@Override
|
||||
public void onChange(String key) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.accessibility;
|
||||
|
||||
import static com.android.settings.accessibility.AccessibilitySettingsForSetupWizard.SCREEN_READER_PACKAGE_NAME;
|
||||
import static com.android.settings.accessibility.AccessibilitySettingsForSetupWizard.SCREEN_READER_SERVICE_NAME;
|
||||
import static com.android.settings.accessibility.AccessibilitySettingsForSetupWizard.SELECT_TO_SPEAK_PACKAGE_NAME;
|
||||
import static com.android.settings.accessibility.AccessibilitySettingsForSetupWizard.SELECT_TO_SPEAK_SERVICE_NAME;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
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.accessibilityservice.AccessibilityServiceInfo;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settingslib.RestrictedPreference;
|
||||
|
||||
import com.google.android.setupcompat.template.FooterBarMixin;
|
||||
import com.google.android.setupdesign.GlifPreferenceLayout;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Tests for {@link AccessibilitySettingsForSetupWizard}.
|
||||
*/
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {
|
||||
com.android.settings.testutils.shadow.ShadowFragment.class,
|
||||
})
|
||||
public class AccessibilitySettingsForSetupWizardTest {
|
||||
|
||||
private static final ComponentName TEST_SCREEN_READER_COMPONENT_NAME = new ComponentName(
|
||||
SCREEN_READER_PACKAGE_NAME, SCREEN_READER_SERVICE_NAME);
|
||||
private static final ComponentName TEST_SELECT_TO_SPEAK_COMPONENT_NAME = new ComponentName(
|
||||
SELECT_TO_SPEAK_PACKAGE_NAME, SELECT_TO_SPEAK_SERVICE_NAME);
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
private final List<AccessibilityServiceInfo> mAccessibilityServices = new ArrayList<>();
|
||||
@Rule
|
||||
public MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||
@Mock
|
||||
private AccessibilityManager mAccessibilityManager;
|
||||
@Mock
|
||||
private FragmentActivity mActivity;
|
||||
@Mock
|
||||
private GlifPreferenceLayout mGlifLayoutView;
|
||||
@Mock
|
||||
private FooterBarMixin mFooterBarMixin;
|
||||
private AccessibilitySettingsForSetupWizard mFragment;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mFragment = spy(new TestAccessibilitySettingsForSetupWizard(mContext));
|
||||
doReturn(mAccessibilityManager).when(mActivity).getSystemService(
|
||||
AccessibilityManager.class);
|
||||
when(mAccessibilityManager.getInstalledAccessibilityServiceList()).thenReturn(
|
||||
mAccessibilityServices);
|
||||
doReturn(mActivity).when(mFragment).getActivity();
|
||||
doReturn(mock(LifecycleOwner.class)).when(mFragment).getViewLifecycleOwner();
|
||||
doReturn(mFooterBarMixin).when(mGlifLayoutView).getMixin(FooterBarMixin.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onViewCreated_verifyAction() {
|
||||
mFragment.onViewCreated(mGlifLayoutView, null);
|
||||
|
||||
verify(mGlifLayoutView).setHeaderText(
|
||||
mContext.getString(R.string.vision_settings_title));
|
||||
verify(mGlifLayoutView).setDescriptionText(
|
||||
mContext.getString(R.string.vision_settings_description));
|
||||
verify(mFooterBarMixin).setPrimaryButton(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onResume_accessibilityServiceListInstalled_returnExpectedValue() {
|
||||
addEnabledServiceInfo(TEST_SCREEN_READER_COMPONENT_NAME, true);
|
||||
addEnabledServiceInfo(TEST_SELECT_TO_SPEAK_COMPONENT_NAME, true);
|
||||
mFragment.onAttach(mContext);
|
||||
mFragment.onViewCreated(mGlifLayoutView, null);
|
||||
|
||||
mFragment.onResume();
|
||||
|
||||
assertRestrictedPreferenceMatch(mFragment.mScreenReaderPreference,
|
||||
TEST_SCREEN_READER_COMPONENT_NAME.getPackageName(),
|
||||
TEST_SCREEN_READER_COMPONENT_NAME.flattenToString());
|
||||
assertRestrictedPreferenceMatch(mFragment.mSelectToSpeakPreference,
|
||||
TEST_SELECT_TO_SPEAK_COMPONENT_NAME.getPackageName(),
|
||||
TEST_SELECT_TO_SPEAK_COMPONENT_NAME.flattenToString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onResume_accessibilityServiceListNotInstalled_returnNull() {
|
||||
mFragment.onAttach(mContext);
|
||||
mFragment.onViewCreated(mGlifLayoutView, null);
|
||||
|
||||
mFragment.onResume();
|
||||
|
||||
assertThat(mFragment.mScreenReaderPreference.getKey()).isNull();
|
||||
assertThat(mFragment.mSelectToSpeakPreference.getKey()).isNull();
|
||||
}
|
||||
|
||||
private void addEnabledServiceInfo(ComponentName componentName, boolean isAccessibilityTool) {
|
||||
final AccessibilityServiceInfo a11yServiceInfo = mock(AccessibilityServiceInfo.class);
|
||||
when(a11yServiceInfo.getComponentName()).thenReturn(componentName);
|
||||
when(a11yServiceInfo.isAccessibilityTool()).thenReturn(isAccessibilityTool);
|
||||
final ResolveInfo resolveInfo = mock(ResolveInfo.class);
|
||||
when(a11yServiceInfo.getResolveInfo()).thenReturn(resolveInfo);
|
||||
resolveInfo.serviceInfo = mock(ServiceInfo.class);
|
||||
resolveInfo.serviceInfo.packageName = componentName.getPackageName();
|
||||
resolveInfo.serviceInfo.name = componentName.getClassName();
|
||||
when(resolveInfo.loadLabel(mActivity.getPackageManager())).thenReturn(
|
||||
componentName.getPackageName());
|
||||
mAccessibilityServices.add(a11yServiceInfo);
|
||||
}
|
||||
|
||||
private void assertRestrictedPreferenceMatch(RestrictedPreference preference, String title,
|
||||
String key) {
|
||||
assertThat(preference.getTitle().toString()).isEqualTo(title);
|
||||
assertThat(preference.getKey()).isEqualTo(key);
|
||||
assertThat(preference.getExtras().getString(AccessibilitySettings.EXTRA_TITLE))
|
||||
.isEqualTo(title);
|
||||
assertThat(preference.getExtras().getString(AccessibilitySettings.EXTRA_PREFERENCE_KEY))
|
||||
.isEqualTo(key);
|
||||
}
|
||||
|
||||
private static class TestAccessibilitySettingsForSetupWizard
|
||||
extends AccessibilitySettingsForSetupWizard {
|
||||
|
||||
private final Context mContext;
|
||||
private final PreferenceManager mPreferenceManager;
|
||||
|
||||
TestAccessibilitySettingsForSetupWizard(Context context) {
|
||||
super();
|
||||
mContext = context;
|
||||
mPreferenceManager = new PreferenceManager(context);
|
||||
mPreferenceManager.setPreferences(mPreferenceManager.createPreferenceScreen(context));
|
||||
mDisplayMagnificationPreference = new Preference(context);
|
||||
mScreenReaderPreference = new RestrictedPreference(context);
|
||||
mSelectToSpeakPreference = new RestrictedPreference(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPreferenceScreenResId() {
|
||||
return R.xml.placeholder_prefs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreferenceScreen getPreferenceScreen() {
|
||||
return mPreferenceManager.getPreferenceScreen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreferenceManager getPreferenceManager() {
|
||||
return mPreferenceManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context getContext() {
|
||||
return mContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,494 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
|
||||
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||
import android.accessibilityservice.AccessibilityShortcutInfo;
|
||||
import android.app.Application;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.database.ContentObserver;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.internal.accessibility.util.AccessibilityUtils;
|
||||
import com.android.internal.content.PackageMonitor;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.testutils.XmlTestUtils;
|
||||
import com.android.settings.testutils.shadow.ShadowApplicationPackageManager;
|
||||
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
|
||||
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
|
||||
import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal;
|
||||
import com.android.settings.testutils.shadow.ShadowUserManager;
|
||||
import com.android.settingslib.RestrictedPreference;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.search.SearchIndexableRaw;
|
||||
import com.android.settingslib.testutils.shadow.ShadowColorDisplayManager;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.android.controller.ActivityController;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
import org.robolectric.shadows.ShadowAccessibilityManager;
|
||||
import org.robolectric.shadows.ShadowContentResolver;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/** Test for {@link AccessibilitySettings}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {
|
||||
ShadowBluetoothAdapter.class,
|
||||
ShadowUserManager.class,
|
||||
ShadowColorDisplayManager.class,
|
||||
ShadowApplicationPackageManager.class,
|
||||
ShadowRestrictedLockUtilsInternal.class,
|
||||
})
|
||||
public class AccessibilitySettingsTest {
|
||||
private static final String PACKAGE_NAME = "com.android.test";
|
||||
private static final String CLASS_NAME = PACKAGE_NAME + ".test_a11y_service";
|
||||
private static final ComponentName COMPONENT_NAME = new ComponentName(PACKAGE_NAME, CLASS_NAME);
|
||||
private static final String EMPTY_STRING = "";
|
||||
private static final String DEFAULT_SUMMARY = "default summary";
|
||||
private static final String DEFAULT_DESCRIPTION = "default description";
|
||||
private static final String DEFAULT_LABEL = "default label";
|
||||
private static final Boolean SERVICE_ENABLED = true;
|
||||
private static final Boolean SERVICE_DISABLED = false;
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mocks = MockitoJUnit.rule();
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
@Spy
|
||||
private final AccessibilityServiceInfo mServiceInfo = getMockAccessibilityServiceInfo(
|
||||
PACKAGE_NAME, CLASS_NAME);
|
||||
@Mock
|
||||
private AccessibilityShortcutInfo mShortcutInfo;
|
||||
private ShadowAccessibilityManager mShadowAccessibilityManager;
|
||||
@Mock
|
||||
private LocalBluetoothManager mLocalBluetoothManager;
|
||||
private ActivityController<SettingsActivity> mActivityController;
|
||||
private AccessibilitySettings mFragment;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
mShadowAccessibilityManager = Shadow.extract(AccessibilityManager.getInstance(mContext));
|
||||
mShadowAccessibilityManager.setInstalledAccessibilityServiceList(new ArrayList<>());
|
||||
mContext.setTheme(androidx.appcompat.R.style.Theme_AppCompat);
|
||||
ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
|
||||
setMockAccessibilityShortcutInfo(mShortcutInfo);
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT,
|
||||
AccessibilitySettings.class.getName());
|
||||
|
||||
mActivityController = ActivityController.of(new SettingsActivity(), intent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getNonIndexableKeys_existInXmlLayout() {
|
||||
final List<String> niks = AccessibilitySettings.SEARCH_INDEX_DATA_PROVIDER
|
||||
.getNonIndexableKeys(mContext);
|
||||
final List<String> keys =
|
||||
XmlTestUtils.getKeysFromPreferenceXml(mContext, R.xml.accessibility_settings);
|
||||
|
||||
assertThat(keys).containsAtLeastElementsIn(niks);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRawDataToIndex_isNull() {
|
||||
final List<SearchIndexableRaw> indexableRawList =
|
||||
AccessibilitySettings.SEARCH_INDEX_DATA_PROVIDER
|
||||
.getRawDataToIndex(mContext, true);
|
||||
|
||||
assertThat(indexableRawList).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceSummary_serviceCrash_showsStopped() {
|
||||
mServiceInfo.crashed = true;
|
||||
|
||||
final CharSequence summary = AccessibilitySettings.getServiceSummary(mContext,
|
||||
mServiceInfo, SERVICE_ENABLED);
|
||||
|
||||
assertThat(summary).isEqualTo(
|
||||
mContext.getString(R.string.accessibility_summary_state_stopped));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceSummary_invisibleToggle_shortcutEnabled_showsOnSummary() {
|
||||
setInvisibleToggleFragmentType(mServiceInfo);
|
||||
doReturn(DEFAULT_SUMMARY).when(mServiceInfo).loadSummary(any());
|
||||
setShortcutEnabled(mServiceInfo.getComponentName(), true);
|
||||
|
||||
final CharSequence summary = AccessibilitySettings.getServiceSummary(mContext,
|
||||
mServiceInfo, SERVICE_ENABLED);
|
||||
|
||||
assertThat(summary).isEqualTo(
|
||||
mContext.getString(R.string.preference_summary_default_combination,
|
||||
mContext.getString(R.string.accessibility_summary_shortcut_enabled),
|
||||
DEFAULT_SUMMARY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceSummary_invisibleToggle_shortcutDisabled_showsOffSummary() {
|
||||
setInvisibleToggleFragmentType(mServiceInfo);
|
||||
setShortcutEnabled(mServiceInfo.getComponentName(), false);
|
||||
doReturn(DEFAULT_SUMMARY).when(mServiceInfo).loadSummary(any());
|
||||
|
||||
final CharSequence summary = AccessibilitySettings.getServiceSummary(mContext,
|
||||
mServiceInfo, SERVICE_ENABLED);
|
||||
|
||||
assertThat(summary).isEqualTo(
|
||||
mContext.getString(R.string.preference_summary_default_combination,
|
||||
mContext.getString(R.string.generic_accessibility_feature_shortcut_off),
|
||||
DEFAULT_SUMMARY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceSummary_enableServiceShortcutOn_showsServiceEnabledShortcutOn() {
|
||||
doReturn(EMPTY_STRING).when(mServiceInfo).loadSummary(any());
|
||||
setShortcutEnabled(mServiceInfo.getComponentName(), true);
|
||||
|
||||
String summary = AccessibilitySettings.getServiceSummary(mContext,
|
||||
mServiceInfo, SERVICE_ENABLED).toString();
|
||||
|
||||
assertThat(summary).isEqualTo(
|
||||
mContext.getString(R.string.generic_accessibility_service_on));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceSummary_enableServiceShortcutOff_showsServiceEnabledShortcutOff() {
|
||||
doReturn(EMPTY_STRING).when(mServiceInfo).loadSummary(any());
|
||||
setShortcutEnabled(mServiceInfo.getComponentName(), false);
|
||||
|
||||
String summary = AccessibilitySettings.getServiceSummary(
|
||||
mContext, mServiceInfo, SERVICE_ENABLED).toString();
|
||||
|
||||
assertThat(summary).isEqualTo(
|
||||
mContext.getString(R.string.generic_accessibility_service_on));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceSummary_disableServiceShortcutOff_showsDisabledShortcutOff() {
|
||||
doReturn(EMPTY_STRING).when(mServiceInfo).loadSummary(any());
|
||||
setShortcutEnabled(mServiceInfo.getComponentName(), false);
|
||||
|
||||
String summary = AccessibilitySettings.getServiceSummary(mContext,
|
||||
mServiceInfo, SERVICE_DISABLED).toString();
|
||||
|
||||
assertThat(summary).isEqualTo(
|
||||
mContext.getString(R.string.generic_accessibility_service_off));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceSummary_disableServiceShortcutOn_showsDisabledShortcutOn() {
|
||||
doReturn(EMPTY_STRING).when(mServiceInfo).loadSummary(any());
|
||||
setShortcutEnabled(mServiceInfo.getComponentName(), true);
|
||||
|
||||
String summary = AccessibilitySettings.getServiceSummary(mContext,
|
||||
mServiceInfo, SERVICE_DISABLED).toString();
|
||||
|
||||
assertThat(summary).isEqualTo(
|
||||
mContext.getString(R.string.generic_accessibility_service_off));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceSummary_enableServiceShortcutOffAndHasSummary_showsEnabledSummary() {
|
||||
setShortcutEnabled(mServiceInfo.getComponentName(), false);
|
||||
doReturn(DEFAULT_SUMMARY).when(mServiceInfo).loadSummary(any());
|
||||
|
||||
String summary = AccessibilitySettings.getServiceSummary(mContext,
|
||||
mServiceInfo, SERVICE_ENABLED).toString();
|
||||
|
||||
assertThat(summary).isEqualTo(
|
||||
mContext.getString(R.string.preference_summary_default_combination,
|
||||
mContext.getString(R.string.generic_accessibility_service_on),
|
||||
DEFAULT_SUMMARY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceSummary_enableServiceShortcutOnAndHasSummary_showsEnabledSummary() {
|
||||
doReturn(DEFAULT_SUMMARY).when(mServiceInfo).loadSummary(any());
|
||||
setShortcutEnabled(mServiceInfo.getComponentName(), true);
|
||||
|
||||
String summary = AccessibilitySettings.getServiceSummary(mContext,
|
||||
mServiceInfo, SERVICE_ENABLED).toString();
|
||||
|
||||
assertThat(summary).isEqualTo(
|
||||
mContext.getString(R.string.preference_summary_default_combination,
|
||||
mContext.getString(R.string.generic_accessibility_service_on),
|
||||
DEFAULT_SUMMARY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceSummary_disableServiceShortcutOnAndHasSummary_showsDisabledSummary() {
|
||||
doReturn(DEFAULT_SUMMARY).when(mServiceInfo).loadSummary(any());
|
||||
setShortcutEnabled(mServiceInfo.getComponentName(), true);
|
||||
|
||||
String summary = AccessibilitySettings.getServiceSummary(mContext,
|
||||
mServiceInfo, SERVICE_DISABLED).toString();
|
||||
|
||||
assertThat(summary).isEqualTo(
|
||||
mContext.getString(R.string.preference_summary_default_combination,
|
||||
mContext.getString(R.string.generic_accessibility_service_off),
|
||||
DEFAULT_SUMMARY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceSummary_disableServiceShortcutOffAndHasSummary_showsDisabledSummary() {
|
||||
setShortcutEnabled(mServiceInfo.getComponentName(), false);
|
||||
doReturn(DEFAULT_SUMMARY).when(mServiceInfo).loadSummary(any());
|
||||
|
||||
String summary = AccessibilitySettings.getServiceSummary(mContext,
|
||||
mServiceInfo, SERVICE_DISABLED).toString();
|
||||
|
||||
assertThat(summary).isEqualTo(
|
||||
mContext.getString(R.string.preference_summary_default_combination,
|
||||
mContext.getString(R.string.generic_accessibility_service_off),
|
||||
DEFAULT_SUMMARY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceDescription_serviceCrash_showsStopped() {
|
||||
mServiceInfo.crashed = true;
|
||||
|
||||
String description = AccessibilitySettings.getServiceDescription(mContext,
|
||||
mServiceInfo, SERVICE_ENABLED).toString();
|
||||
|
||||
assertThat(description).isEqualTo(
|
||||
mContext.getString(R.string.accessibility_description_state_stopped));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceDescription_haveDescription_showsDescription() {
|
||||
doReturn(DEFAULT_DESCRIPTION).when(mServiceInfo).loadDescription(any());
|
||||
|
||||
String description = AccessibilitySettings.getServiceDescription(mContext,
|
||||
mServiceInfo, SERVICE_ENABLED).toString();
|
||||
|
||||
assertThat(description).isEqualTo(DEFAULT_DESCRIPTION);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreate_haveRegisterToSpecificUrisAndActions() {
|
||||
setupFragment();
|
||||
|
||||
ShadowContentResolver shadowContentResolver = shadowOf(mContext.getContentResolver());
|
||||
Collection<ContentObserver> a11yButtonTargetsObservers =
|
||||
shadowContentResolver.getContentObservers(
|
||||
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS));
|
||||
Collection<ContentObserver> a11yShortcutTargetServiceObservers =
|
||||
shadowContentResolver.getContentObservers(Settings.Secure.getUriFor(
|
||||
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE));
|
||||
List<BroadcastReceiver> broadcastReceivers =
|
||||
shadowOf((Application) ApplicationProvider.getApplicationContext())
|
||||
.getRegisteredReceivers()
|
||||
.stream().map(wrapper -> wrapper.broadcastReceiver).toList();
|
||||
assertThat(
|
||||
a11yButtonTargetsObservers.stream()
|
||||
.anyMatch(contentObserver ->
|
||||
contentObserver instanceof AccessibilitySettingsContentObserver))
|
||||
.isTrue();
|
||||
assertThat(
|
||||
a11yShortcutTargetServiceObservers.stream()
|
||||
.anyMatch(contentObserver ->
|
||||
contentObserver instanceof AccessibilitySettingsContentObserver))
|
||||
.isTrue();
|
||||
assertThat(broadcastReceivers.stream().anyMatch(
|
||||
broadcastReceiver -> broadcastReceiver instanceof PackageMonitor)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDestroy_unregisterObserverAndReceiver() {
|
||||
setupFragment();
|
||||
|
||||
mActivityController.pause().stop().destroy();
|
||||
|
||||
ShadowContentResolver shadowContentResolver = shadowOf(mContext.getContentResolver());
|
||||
Collection<ContentObserver> a11yButtonTargetsObservers =
|
||||
shadowContentResolver.getContentObservers(
|
||||
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS));
|
||||
Collection<ContentObserver> a11yShortcutTargetServiceObservers =
|
||||
shadowContentResolver.getContentObservers(Settings.Secure.getUriFor(
|
||||
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE));
|
||||
List<BroadcastReceiver> broadcastReceivers =
|
||||
shadowOf((Application) ApplicationProvider.getApplicationContext())
|
||||
.getRegisteredReceivers()
|
||||
.stream().map(wrapper -> wrapper.broadcastReceiver).toList();
|
||||
assertThat(
|
||||
a11yButtonTargetsObservers.stream()
|
||||
.anyMatch(contentObserver ->
|
||||
contentObserver instanceof AccessibilitySettingsContentObserver))
|
||||
.isFalse();
|
||||
assertThat(
|
||||
a11yShortcutTargetServiceObservers.stream()
|
||||
.anyMatch(contentObserver ->
|
||||
contentObserver instanceof AccessibilitySettingsContentObserver))
|
||||
.isFalse();
|
||||
assertThat(broadcastReceivers.stream().anyMatch(
|
||||
broadcastReceiver -> broadcastReceiver instanceof PackageMonitor)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onContentChanged_updatePreferenceInForeground_preferenceUpdated() {
|
||||
setupFragment();
|
||||
mShadowAccessibilityManager.setInstalledAccessibilityServiceList(
|
||||
singletonList(mServiceInfo));
|
||||
|
||||
mFragment.onContentChanged();
|
||||
|
||||
RestrictedPreference preference = mFragment.getPreferenceScreen().findPreference(
|
||||
COMPONENT_NAME.flattenToString());
|
||||
|
||||
assertThat(preference).isNotNull();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onContentChanged_updatePreferenceInBackground_preferenceUpdated() {
|
||||
setupFragment();
|
||||
mFragment.onPause();
|
||||
mFragment.onStop();
|
||||
|
||||
mShadowAccessibilityManager.setInstalledAccessibilityServiceList(
|
||||
singletonList(mServiceInfo));
|
||||
|
||||
mFragment.onContentChanged();
|
||||
mFragment.onStart();
|
||||
|
||||
RestrictedPreference preference = mFragment.getPreferenceScreen().findPreference(
|
||||
COMPONENT_NAME.flattenToString());
|
||||
|
||||
assertThat(preference).isNotNull();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAccessibilityMenuInSystem_IncludedInInteractionControl() {
|
||||
mShadowAccessibilityManager.setInstalledAccessibilityServiceList(
|
||||
List.of(getMockAccessibilityServiceInfo(
|
||||
AccessibilityUtils.ACCESSIBILITY_MENU_IN_SYSTEM)));
|
||||
setupFragment();
|
||||
|
||||
final RestrictedPreference pref = mFragment.getPreferenceScreen().findPreference(
|
||||
AccessibilityUtils.ACCESSIBILITY_MENU_IN_SYSTEM.flattenToString());
|
||||
final String prefCategory = mFragment.mServicePreferenceToPreferenceCategoryMap.get(
|
||||
pref).getKey();
|
||||
assertThat(prefCategory).isEqualTo(AccessibilitySettings.CATEGORY_INTERACTION_CONTROL);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAccessibilityMenuInSystem_NoPrefWhenNotInstalled() {
|
||||
mShadowAccessibilityManager.setInstalledAccessibilityServiceList(List.of());
|
||||
setupFragment();
|
||||
|
||||
final RestrictedPreference pref = mFragment.getPreferenceScreen().findPreference(
|
||||
AccessibilityUtils.ACCESSIBILITY_MENU_IN_SYSTEM.flattenToString());
|
||||
assertThat(pref).isNull();
|
||||
}
|
||||
|
||||
private AccessibilityServiceInfo getMockAccessibilityServiceInfo(String packageName,
|
||||
String className) {
|
||||
return getMockAccessibilityServiceInfo(new ComponentName(packageName, className));
|
||||
}
|
||||
|
||||
private AccessibilityServiceInfo getMockAccessibilityServiceInfo(ComponentName componentName) {
|
||||
final ApplicationInfo applicationInfo = new ApplicationInfo();
|
||||
final ServiceInfo serviceInfo = new ServiceInfo();
|
||||
applicationInfo.packageName = componentName.getPackageName();
|
||||
serviceInfo.packageName = componentName.getPackageName();
|
||||
serviceInfo.name = componentName.getClassName();
|
||||
serviceInfo.applicationInfo = applicationInfo;
|
||||
|
||||
final ResolveInfo resolveInfo = new ResolveInfo();
|
||||
resolveInfo.serviceInfo = serviceInfo;
|
||||
try {
|
||||
final AccessibilityServiceInfo info = new AccessibilityServiceInfo(resolveInfo,
|
||||
mContext);
|
||||
info.setComponentName(componentName);
|
||||
return info;
|
||||
} catch (XmlPullParserException | IOException e) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void setMockAccessibilityShortcutInfo(AccessibilityShortcutInfo mockInfo) {
|
||||
final ActivityInfo activityInfo = Mockito.mock(ActivityInfo.class);
|
||||
activityInfo.applicationInfo = new ApplicationInfo();
|
||||
when(mockInfo.getActivityInfo()).thenReturn(activityInfo);
|
||||
when(activityInfo.loadLabel(any())).thenReturn(DEFAULT_LABEL);
|
||||
when(mockInfo.loadSummary(any())).thenReturn(DEFAULT_SUMMARY);
|
||||
when(mockInfo.loadDescription(any())).thenReturn(DEFAULT_DESCRIPTION);
|
||||
when(mockInfo.getComponentName()).thenReturn(COMPONENT_NAME);
|
||||
}
|
||||
|
||||
private void setInvisibleToggleFragmentType(AccessibilityServiceInfo info) {
|
||||
info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.R;
|
||||
info.flags |= AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
|
||||
}
|
||||
|
||||
private void setupFragment() {
|
||||
mActivityController.create().start().resume();
|
||||
Fragment fragment = mActivityController.get().getSupportFragmentManager().findFragmentById(
|
||||
R.id.main_content);
|
||||
|
||||
assertThat(fragment).isNotNull();
|
||||
assertThat(fragment).isInstanceOf(AccessibilitySettings.class);
|
||||
|
||||
mFragment = (AccessibilitySettings) fragment;
|
||||
}
|
||||
|
||||
private void setShortcutEnabled(ComponentName componentName, boolean enabled) {
|
||||
Settings.Secure.putString(mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
|
||||
enabled ? componentName.flattenToString() : "");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.accessibility;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.google.android.setupdesign.GlifPreferenceLayout;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link AccessibilitySetupWizardUtils} */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AccessibilitySetupWizardUtilsTest {
|
||||
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
@Test
|
||||
public void setupGlifPreferenceLayout_assignValueToVariable() {
|
||||
final String title = "title";
|
||||
final String description = "description";
|
||||
final Drawable icon = mock(Drawable.class);
|
||||
GlifPreferenceLayout layout = mock(GlifPreferenceLayout.class);
|
||||
|
||||
AccessibilitySetupWizardUtils.updateGlifPreferenceLayout(mContext, layout, title,
|
||||
description, icon);
|
||||
|
||||
verify(layout).setHeaderText(title);
|
||||
verify(layout).setDescriptionText(description);
|
||||
verify(layout).setIcon(icon);
|
||||
verify(layout).setHeaderText(title);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setupGlifPreferenceLayout_descriptionIsNull_doesNotCallSetDescriptionText() {
|
||||
GlifPreferenceLayout layout = mock(GlifPreferenceLayout.class);
|
||||
|
||||
AccessibilitySetupWizardUtils.updateGlifPreferenceLayout(mContext, layout, "title",
|
||||
/* description= */ null, /* icon= */ null);
|
||||
|
||||
verify(layout, times(0)).setDescriptionText(any());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,332 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.accessibility;
|
||||
|
||||
import static com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment.KEY_SAVED_QS_TOOLTIP_RESHOW;
|
||||
import static com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment.KEY_SAVED_USER_SHORTCUT_TYPE;
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
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.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.PopupWindow;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.testutils.shadow.ShadowFragment;
|
||||
|
||||
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.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
|
||||
/** Tests for {@link AccessibilityShortcutPreferenceFragment} */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {
|
||||
com.android.settings.testutils.shadow.ShadowFragment.class,
|
||||
})
|
||||
public class AccessibilityShortcutPreferenceFragmentTest {
|
||||
|
||||
private static final String PLACEHOLDER_PACKAGE_NAME = "com.placeholder.example";
|
||||
private static final String PLACEHOLDER_CLASS_NAME = PLACEHOLDER_PACKAGE_NAME + ".placeholder";
|
||||
private static final String PLACEHOLDER_TILE_CLASS_NAME =
|
||||
PLACEHOLDER_PACKAGE_NAME + "tile.placeholder";
|
||||
private static final ComponentName PLACEHOLDER_COMPONENT_NAME = new ComponentName(
|
||||
PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_CLASS_NAME);
|
||||
private static final ComponentName PLACEHOLDER_TILE_COMPONENT_NAME = new ComponentName(
|
||||
PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_TILE_CLASS_NAME);
|
||||
private static final String PLACEHOLDER_TILE_TOOLTIP_CONTENT =
|
||||
PLACEHOLDER_PACKAGE_NAME + "tooltip_content";
|
||||
private static final String PLACEHOLDER_DIALOG_TITLE = "title";
|
||||
|
||||
private static final String SOFTWARE_SHORTCUT_KEY =
|
||||
Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
|
||||
private static final String HARDWARE_SHORTCUT_KEY =
|
||||
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
|
||||
|
||||
private TestAccessibilityShortcutPreferenceFragment mFragment;
|
||||
private PreferenceScreen mScreen;
|
||||
private Context mContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private PreferenceManager mPreferenceManager;
|
||||
|
||||
@Before
|
||||
public void setUpTestFragment() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mFragment = spy(new TestAccessibilityShortcutPreferenceFragment(null));
|
||||
when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
|
||||
when(mFragment.getPreferenceManager().getContext()).thenReturn(mContext);
|
||||
when(mFragment.getContext()).thenReturn(mContext);
|
||||
when(mFragment.getActivity()).thenReturn(Robolectric.setupActivity(FragmentActivity.class));
|
||||
mScreen = spy(new PreferenceScreen(mContext, null));
|
||||
when(mScreen.getPreferenceManager()).thenReturn(mPreferenceManager);
|
||||
doReturn(mScreen).when(mFragment).getPreferenceScreen();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateShortcutPreferenceData_assignDefaultValueToVariable() {
|
||||
mFragment.updateShortcutPreferenceData();
|
||||
|
||||
final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
|
||||
mFragment.getComponentName().flattenToString());
|
||||
// Compare to default UserShortcutType
|
||||
assertThat(expectedType).isEqualTo(UserShortcutType.SOFTWARE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateShortcutPreferenceData_hasValueInSettings_assignToVariable() {
|
||||
putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, PLACEHOLDER_COMPONENT_NAME.flattenToString());
|
||||
putStringIntoSettings(HARDWARE_SHORTCUT_KEY, PLACEHOLDER_COMPONENT_NAME.flattenToString());
|
||||
|
||||
mFragment.updateShortcutPreferenceData();
|
||||
|
||||
final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
|
||||
mFragment.getComponentName().flattenToString());
|
||||
assertThat(expectedType).isEqualTo(UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateShortcutPreferenceData_hasValueInSharedPreference_assignToVariable() {
|
||||
final PreferredShortcut hardwareShortcut = new PreferredShortcut(
|
||||
PLACEHOLDER_COMPONENT_NAME.flattenToString(), UserShortcutType.HARDWARE);
|
||||
|
||||
putUserShortcutTypeIntoSharedPreference(mContext, hardwareShortcut);
|
||||
mFragment.updateShortcutPreferenceData();
|
||||
|
||||
final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
|
||||
mFragment.getComponentName().flattenToString());
|
||||
assertThat(expectedType).isEqualTo(UserShortcutType.HARDWARE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setupEditShortcutDialog_shortcutPreferenceOff_checkboxIsEmptyValue() {
|
||||
mContext.setTheme(androidx.appcompat.R.style.Theme_AppCompat);
|
||||
final AlertDialog dialog = AccessibilityDialogUtils.showEditShortcutDialog(
|
||||
mContext, AccessibilityDialogUtils.DialogType.EDIT_SHORTCUT_GENERIC,
|
||||
PLACEHOLDER_DIALOG_TITLE,
|
||||
this::callEmptyOnClicked);
|
||||
final ShortcutPreference shortcutPreference = new ShortcutPreference(mContext, /* attrs= */
|
||||
null);
|
||||
mFragment.mShortcutPreference = shortcutPreference;
|
||||
|
||||
mFragment.mShortcutPreference.setChecked(false);
|
||||
mFragment.setupEditShortcutDialog(dialog);
|
||||
|
||||
final int checkboxValue = mFragment.getShortcutTypeCheckBoxValue();
|
||||
assertThat(checkboxValue).isEqualTo(UserShortcutType.EMPTY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setupEditShortcutDialog_shortcutPreferenceOn_checkboxIsSavedValue() {
|
||||
mContext.setTheme(androidx.appcompat.R.style.Theme_AppCompat);
|
||||
final AlertDialog dialog = AccessibilityDialogUtils.showEditShortcutDialog(
|
||||
mContext, AccessibilityDialogUtils.DialogType.EDIT_SHORTCUT_GENERIC,
|
||||
PLACEHOLDER_DIALOG_TITLE,
|
||||
this::callEmptyOnClicked);
|
||||
final ShortcutPreference shortcutPreference = new ShortcutPreference(mContext, /* attrs= */
|
||||
null);
|
||||
final PreferredShortcut hardwareShortcut = new PreferredShortcut(
|
||||
PLACEHOLDER_COMPONENT_NAME.flattenToString(), UserShortcutType.HARDWARE);
|
||||
mFragment.mShortcutPreference = shortcutPreference;
|
||||
|
||||
PreferredShortcuts.saveUserShortcutType(mContext, hardwareShortcut);
|
||||
mFragment.mShortcutPreference.setChecked(true);
|
||||
mFragment.setupEditShortcutDialog(dialog);
|
||||
|
||||
final int checkboxValue = mFragment.getShortcutTypeCheckBoxValue();
|
||||
assertThat(checkboxValue).isEqualTo(UserShortcutType.HARDWARE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = ShadowFragment.class)
|
||||
public void restoreValueFromSavedInstanceState_assignShortcutTypeToVariable() {
|
||||
mContext.setTheme(androidx.appcompat.R.style.Theme_AppCompat);
|
||||
final AlertDialog dialog = AccessibilityDialogUtils.showEditShortcutDialog(
|
||||
mContext, AccessibilityDialogUtils.DialogType.EDIT_SHORTCUT_GENERIC,
|
||||
PLACEHOLDER_DIALOG_TITLE,
|
||||
this::callEmptyOnClicked);
|
||||
final Bundle savedInstanceState = new Bundle();
|
||||
final ShortcutPreference shortcutPreference = new ShortcutPreference(mContext, /* attrs= */
|
||||
null);
|
||||
mFragment.mShortcutPreference = shortcutPreference;
|
||||
|
||||
savedInstanceState.putInt(KEY_SAVED_USER_SHORTCUT_TYPE,
|
||||
UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE);
|
||||
mFragment.onAttach(mContext);
|
||||
mFragment.onCreate(savedInstanceState);
|
||||
mFragment.setupEditShortcutDialog(dialog);
|
||||
final int value = mFragment.getShortcutTypeCheckBoxValue();
|
||||
mFragment.saveNonEmptyUserShortcutType(value);
|
||||
|
||||
final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
|
||||
mFragment.getComponentName().flattenToString());
|
||||
assertThat(expectedType).isEqualTo(UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = ShadowFragment.class)
|
||||
public void restoreValueFromSavedInstanceState_showTooltipView() {
|
||||
mContext.setTheme(androidx.appcompat.R.style.Theme_AppCompat);
|
||||
mFragment.showQuickSettingsTooltipIfNeeded(QuickSettingsTooltipType.GUIDE_TO_EDIT);
|
||||
assertThat(getLatestPopupWindow().isShowing()).isTrue();
|
||||
|
||||
final Bundle savedInstanceState = new Bundle();
|
||||
savedInstanceState.putBoolean(KEY_SAVED_QS_TOOLTIP_RESHOW, /* value= */ true);
|
||||
mFragment.onAttach(mContext);
|
||||
mFragment.onCreate(savedInstanceState);
|
||||
mFragment.onCreateView(LayoutInflater.from(mContext), mock(ViewGroup.class), Bundle.EMPTY);
|
||||
mFragment.onViewCreated(mFragment.getView(), savedInstanceState);
|
||||
|
||||
assertThat(getLatestPopupWindow().isShowing()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = ShadowFragment.class)
|
||||
public void showGeneralCategory_shouldInitCategory() {
|
||||
final Bundle savedInstanceState = new Bundle();
|
||||
when(mFragment.showGeneralCategory()).thenReturn(true);
|
||||
mFragment.onAttach(mContext);
|
||||
mFragment.onCreate(savedInstanceState);
|
||||
|
||||
verify(mFragment).initGeneralCategory();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void showGeneralCategory_shouldSetDefaultDescription() {
|
||||
assertThat(mFragment.getGeneralCategoryDescription(null)).isNotNull();
|
||||
}
|
||||
|
||||
private void callEmptyOnClicked(DialogInterface dialog, int which) {}
|
||||
|
||||
private void putStringIntoSettings(String key, String componentName) {
|
||||
Settings.Secure.putString(mContext.getContentResolver(), key, componentName);
|
||||
}
|
||||
|
||||
private void putUserShortcutTypeIntoSharedPreference(Context context,
|
||||
PreferredShortcut shortcut) {
|
||||
PreferredShortcuts.saveUserShortcutType(context, shortcut);
|
||||
}
|
||||
|
||||
private static PopupWindow getLatestPopupWindow() {
|
||||
final ShadowApplication shadowApplication =
|
||||
Shadow.extract(ApplicationProvider.getApplicationContext());
|
||||
return shadowApplication.getLatestPopupWindow();
|
||||
}
|
||||
|
||||
public static class TestAccessibilityShortcutPreferenceFragment
|
||||
extends AccessibilityShortcutPreferenceFragment {
|
||||
|
||||
public TestAccessibilityShortcutPreferenceFragment(String restrictionKey) {
|
||||
super(restrictionKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
return mock(View.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ComponentName getComponentName() {
|
||||
return PLACEHOLDER_COMPONENT_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CharSequence getLabelName() {
|
||||
return PLACEHOLDER_PACKAGE_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ComponentName getTileComponentName() {
|
||||
return PLACEHOLDER_TILE_COMPONENT_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CharSequence getTileTooltipContent(@QuickSettingsTooltipType int type) {
|
||||
return PLACEHOLDER_TILE_TOOLTIP_CONTENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUserShortcutTypes() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CharSequence getGeneralCategoryDescription(@Nullable CharSequence title) {
|
||||
return super.getGeneralCategoryDescription(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean showGeneralCategory() {
|
||||
// For showGeneralCategory_shouldInitCategory()
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceScreenResId() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getLogTag() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView() {
|
||||
return mock(View.class);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* 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.accessibility;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.provider.Settings;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
|
||||
import com.android.settingslib.accessibility.AccessibilityUtils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
import org.robolectric.shadows.ShadowAccessibilityManager;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AccessibilitySlicePreferenceControllerTest {
|
||||
|
||||
private final String PACKAGE_NAME = "com.android.settings.fake";
|
||||
private final String CLASS_NAME = "com.android.settings.fake.classname";
|
||||
private final String SERVICE_NAME = PACKAGE_NAME + "/" + CLASS_NAME;
|
||||
|
||||
private Context mContext;
|
||||
|
||||
private AccessibilitySlicePreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = RuntimeEnvironment.application;
|
||||
|
||||
final ContentResolver contentResolver = mContext.getContentResolver();
|
||||
Settings.Secure.putInt(contentResolver, Settings.Secure.ACCESSIBILITY_ENABLED, 1 /* on */);
|
||||
Settings.Secure.putString(contentResolver, Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
|
||||
SERVICE_NAME);
|
||||
|
||||
// Register the fake a11y Service
|
||||
ShadowAccessibilityManager shadowAccessibilityManager = Shadow.extract(
|
||||
RuntimeEnvironment.application.getSystemService(AccessibilityManager.class));
|
||||
shadowAccessibilityManager.setInstalledAccessibilityServiceList(getFakeServiceList());
|
||||
|
||||
mController = new AccessibilitySlicePreferenceController(mContext, SERVICE_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailability_availableService_returnsAvailable() {
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailability_unknownService_returnsUnsupported() {
|
||||
AccessibilitySlicePreferenceController controller =
|
||||
new AccessibilitySlicePreferenceController(mContext, "fake_service/name");
|
||||
|
||||
assertThat(controller.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setChecked_availableService_serviceIsEnabled() {
|
||||
mController.setChecked(true);
|
||||
|
||||
assertThat(mController.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setNotChecked_availableService_serviceIsDisabled() {
|
||||
mController.setChecked(false);
|
||||
|
||||
assertThat(mController.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isChecked_serviceEnabled_returnsTrue() {
|
||||
AccessibilityUtils.setAccessibilityServiceState(mContext,
|
||||
ComponentName.unflattenFromString(mController.getPreferenceKey()), true);
|
||||
|
||||
assertThat(mController.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isChecked_serviceNotEnabled_returnsFalse() {
|
||||
AccessibilitySlicePreferenceController controller =
|
||||
new AccessibilitySlicePreferenceController(mContext, "fake_service/name");
|
||||
|
||||
assertThat(controller.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void illegalServiceName_exceptionThrown() {
|
||||
new AccessibilitySlicePreferenceController(mContext, "not_split_by_slash");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSliceable_returnTrue() {
|
||||
assertThat(mController.isSliceable()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isPublicSlice_returnTrue() {
|
||||
assertThat(mController.isPublicSlice()).isTrue();
|
||||
}
|
||||
|
||||
private List<AccessibilityServiceInfo> getFakeServiceList() {
|
||||
final List<AccessibilityServiceInfo> infoList = new ArrayList<>();
|
||||
|
||||
final ServiceInfo serviceInfo = new ServiceInfo();
|
||||
serviceInfo.packageName = PACKAGE_NAME;
|
||||
serviceInfo.name = CLASS_NAME;
|
||||
|
||||
final ResolveInfo resolveInfo = new ResolveInfo();
|
||||
resolveInfo.serviceInfo = serviceInfo;
|
||||
|
||||
try {
|
||||
final AccessibilityServiceInfo info = new AccessibilityServiceInfo(resolveInfo,
|
||||
mContext);
|
||||
ComponentName componentName = new ComponentName(PACKAGE_NAME, CLASS_NAME);
|
||||
info.setComponentName(componentName);
|
||||
infoList.add(info);
|
||||
} catch (XmlPullParserException | IOException e) {
|
||||
|
||||
}
|
||||
|
||||
return infoList;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* 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.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settingslib.widget.SelectorWithWidgetPreference;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link AccessibilityTimeoutController}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AccessibilityTimeoutControllerTest {
|
||||
|
||||
private static final String PREF_KEY = "accessibility_control_timeout_30secs";
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||
@Mock
|
||||
private SelectorWithWidgetPreference mMockPref;
|
||||
@Mock
|
||||
private PreferenceScreen mScreen;
|
||||
@Mock
|
||||
private AccessibilitySettingsContentObserver mAccessibilitySettingsContentObserver;
|
||||
private Context mContext = ApplicationProvider.getApplicationContext();
|
||||
private ContentResolver mContentResolver;
|
||||
private AccessibilityTimeoutController mController;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
mContentResolver = mContext.getContentResolver();
|
||||
mController = new AccessibilityTimeoutController(mContext, PREF_KEY,
|
||||
mAccessibilitySettingsContentObserver);
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mMockPref);
|
||||
when(mMockPref.getKey()).thenReturn(PREF_KEY);
|
||||
final String prefTitle =
|
||||
mContext.getResources().getString(R.string.accessibility_timeout_30secs);
|
||||
when(mMockPref.getTitle()).thenReturn(prefTitle);
|
||||
mController.displayPreference(mScreen);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_shouldReturnAvailable() {
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_notChecked() {
|
||||
Settings.Secure.putString(mContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS, "0");
|
||||
|
||||
mController.updateState(mMockPref);
|
||||
|
||||
// the first checked state is set to false by control
|
||||
verify(mMockPref).setChecked(false);
|
||||
verify(mMockPref).setChecked(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_checked() {
|
||||
Settings.Secure.putString(mContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS, "30000");
|
||||
|
||||
mController.updateState(mMockPref);
|
||||
|
||||
// the first checked state is set to false by control
|
||||
verify(mMockPref).setChecked(false);
|
||||
verify(mMockPref).setChecked(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onRadioButtonClick() {
|
||||
mController.onRadioButtonClicked(mMockPref);
|
||||
|
||||
String accessibilityUiTimeoutValue = Settings.Secure.getString(mContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS);
|
||||
|
||||
assertThat(accessibilityUiTimeoutValue).isEqualTo("30000");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStart_registerSpecificContentObserverForSpecificKeys() {
|
||||
mController.onStart();
|
||||
|
||||
verify(mAccessibilitySettingsContentObserver).register(mContentResolver);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStop_unregisterContentObserver() {
|
||||
mController.onStop();
|
||||
|
||||
verify(mAccessibilitySettingsContentObserver).unregister(mContentResolver);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link AccessibilityTimeoutPreferenceController}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AccessibilityTimeoutPreferenceControllerTest {
|
||||
|
||||
private Context mContext = ApplicationProvider.getApplicationContext();
|
||||
private AccessibilityTimeoutPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mController = new AccessibilityTimeoutPreferenceController(mContext, "control_timeout");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_shouldReturnAvailable() {
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_byDefault_shouldReturnDefaultSummary() {
|
||||
final String[] timeoutSummaries = mContext.getResources().getStringArray(
|
||||
R.array.accessibility_timeout_summaries);
|
||||
Settings.Secure.putString(mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS, "0");
|
||||
|
||||
assertThat(mController.getSummary().toString()).isEqualTo(timeoutSummaries[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_invalidTimeout_shouldReturnDefaultSummary() {
|
||||
final String[] timeoutSummaries = mContext.getResources().getStringArray(
|
||||
R.array.accessibility_timeout_summaries);
|
||||
Settings.Secure.putString(mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS, "invalid_timeout");
|
||||
|
||||
assertThat(mController.getSummary().toString()).isEqualTo(timeoutSummaries[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_validTimeout_shouldReturnValidSummary() {
|
||||
final String[] timeoutSummaries = mContext.getResources().getStringArray(
|
||||
R.array.accessibility_timeout_summaries);
|
||||
Settings.Secure.putString(mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS, "60000");
|
||||
|
||||
assertThat(mController.getSummary().toString()).isEqualTo(timeoutSummaries[3]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link AccessibilityTimeoutUtils}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public final class AccessibilityTimeoutUtilsTest {
|
||||
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
@Test
|
||||
public void getSecureAccessibilityTimeoutValue_byDefault_shouldReturnDefaultValue() {
|
||||
Settings.Secure.putString(mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS, "0");
|
||||
|
||||
final int timeOutValue = AccessibilityTimeoutUtils.getSecureAccessibilityTimeoutValue(
|
||||
mContext.getContentResolver());
|
||||
assertThat(timeOutValue).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSecureAccessibilityTimeoutValue_invalidTimeout_shouldReturnDefaultValue() {
|
||||
Settings.Secure.putString(mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS, "invalid_timeout");
|
||||
|
||||
final int timeOutValue = AccessibilityTimeoutUtils.getSecureAccessibilityTimeoutValue(
|
||||
mContext.getContentResolver());
|
||||
assertThat(timeOutValue).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSecureAccessibilityTimeoutValue_validTimeout_shouldReturnValidValue() {
|
||||
Settings.Secure.putString(mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS, "60000");
|
||||
|
||||
final int timeOutValue = AccessibilityTimeoutUtils.getSecureAccessibilityTimeoutValue(
|
||||
mContext.getContentResolver());
|
||||
assertThat(timeOutValue).isEqualTo(60000);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public final class AccessibilityUtilTest {
|
||||
private static final String SECURE_TEST_KEY = "secure_test_key";
|
||||
private static final String MOCK_PACKAGE_NAME = "com.mock.example";
|
||||
private static final String MOCK_CLASS_NAME = MOCK_PACKAGE_NAME + ".mock_a11y_service";
|
||||
private static final String MOCK_CLASS_NAME2 = MOCK_PACKAGE_NAME + ".mock_a11y_service2";
|
||||
private static final ComponentName MOCK_COMPONENT_NAME = new ComponentName(MOCK_PACKAGE_NAME,
|
||||
MOCK_CLASS_NAME);
|
||||
private static final ComponentName MOCK_COMPONENT_NAME2 = new ComponentName(MOCK_PACKAGE_NAME,
|
||||
MOCK_CLASS_NAME2);
|
||||
private static final String SOFTWARE_SHORTCUT_KEY =
|
||||
Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
|
||||
private static final String HARDWARE_SHORTCUT_KEY =
|
||||
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
|
||||
|
||||
private static final String PLACEHOLDER_SETTING_FEATURE = "placeholderSettingFeature";
|
||||
|
||||
private Context mContext;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = ApplicationProvider.getApplicationContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void capitalize_shouldReturnCapitalizedString() {
|
||||
assertThat(AccessibilityUtil.capitalize(null)).isNull();
|
||||
assertThat(AccessibilityUtil.capitalize("")).isEmpty();
|
||||
assertThat(AccessibilityUtil.capitalize("Hans")).isEqualTo("Hans");
|
||||
assertThat(AccessibilityUtil.capitalize("hans")).isEqualTo("Hans");
|
||||
assertThat(AccessibilityUtil.capitalize(",hans")).isEqualTo(",hans");
|
||||
assertThat(AccessibilityUtil.capitalize("Hans, Hans")).isEqualTo("Hans, hans");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_hasValueAndEqualsToOne_shouldReturnOnString() {
|
||||
setSettingsFeatureEnabled(SECURE_TEST_KEY, true);
|
||||
|
||||
final CharSequence result = AccessibilityUtil.getSummary(mContext, SECURE_TEST_KEY,
|
||||
R.string.switch_on_text, R.string.switch_off_text);
|
||||
|
||||
assertThat(result)
|
||||
.isEqualTo(mContext.getText(R.string.switch_on_text));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_hasValueAndEqualsToZero_shouldReturnOffString() {
|
||||
setSettingsFeatureEnabled(SECURE_TEST_KEY, false);
|
||||
|
||||
final CharSequence result = AccessibilityUtil.getSummary(mContext, SECURE_TEST_KEY,
|
||||
R.string.switch_on_text, R.string.switch_off_text);
|
||||
|
||||
assertThat(result)
|
||||
.isEqualTo(mContext.getText(R.string.switch_off_text));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_noValue_shouldReturnOffString() {
|
||||
final CharSequence result = AccessibilityUtil.getSummary(mContext, SECURE_TEST_KEY,
|
||||
R.string.switch_on_text, R.string.switch_off_text);
|
||||
|
||||
assertThat(result)
|
||||
.isEqualTo(mContext.getText(R.string.switch_off_text));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAccessibilityServiceFragmentType_targetSdkQ_volumeShortcutType() {
|
||||
final AccessibilityServiceInfo info = getMockAccessibilityServiceInfo();
|
||||
|
||||
info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.Q;
|
||||
info.flags |= AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
|
||||
|
||||
assertThat(AccessibilityUtil.getAccessibilityServiceFragmentType(info)).isEqualTo(
|
||||
AccessibilityUtil.AccessibilityServiceFragmentType.VOLUME_SHORTCUT_TOGGLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAccessibilityServiceFragmentType_targetSdkR_HaveA11yButton_invisibleType() {
|
||||
final AccessibilityServiceInfo info = getMockAccessibilityServiceInfo();
|
||||
|
||||
info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.R;
|
||||
info.flags |= AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
|
||||
|
||||
assertThat(AccessibilityUtil.getAccessibilityServiceFragmentType(info)).isEqualTo(
|
||||
AccessibilityUtil.AccessibilityServiceFragmentType.INVISIBLE_TOGGLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAccessibilityServiceFragmentType_targetSdkR_NoA11yButton_toggleType() {
|
||||
final AccessibilityServiceInfo info = getMockAccessibilityServiceInfo();
|
||||
|
||||
info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.R;
|
||||
info.flags |= ~AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
|
||||
|
||||
assertThat(AccessibilityUtil.getAccessibilityServiceFragmentType(info)).isEqualTo(
|
||||
AccessibilityUtil.AccessibilityServiceFragmentType.TOGGLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasValueInSettings_putValue_hasValue() {
|
||||
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString());
|
||||
|
||||
assertThat(AccessibilityUtil.hasValueInSettings(mContext, UserShortcutType.SOFTWARE,
|
||||
MOCK_COMPONENT_NAME)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getUserShortcutTypeFromSettings_putOneValue_hasValue() {
|
||||
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString());
|
||||
|
||||
final int shortcutType = AccessibilityUtil.getUserShortcutTypesFromSettings(mContext,
|
||||
MOCK_COMPONENT_NAME);
|
||||
|
||||
assertThat(
|
||||
(shortcutType & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getUserShortcutTypeFromSettings_putTwoValues_hasValue() {
|
||||
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString());
|
||||
setShortcut(UserShortcutType.HARDWARE, MOCK_COMPONENT_NAME.flattenToString());
|
||||
|
||||
final int shortcutType = AccessibilityUtil.getUserShortcutTypesFromSettings(mContext,
|
||||
MOCK_COMPONENT_NAME);
|
||||
|
||||
assertThat(
|
||||
(shortcutType & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE).isTrue();
|
||||
assertThat(
|
||||
(shortcutType & UserShortcutType.HARDWARE) == UserShortcutType.HARDWARE).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void optInAllValuesToSettings_optInValue_haveMatchString() {
|
||||
clearShortcuts();
|
||||
int shortcutTypes = UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE;
|
||||
|
||||
AccessibilityUtil.optInAllValuesToSettings(mContext, shortcutTypes, MOCK_COMPONENT_NAME);
|
||||
|
||||
assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEqualTo(
|
||||
MOCK_COMPONENT_NAME.flattenToString());
|
||||
assertThat(getStringFromSettings(HARDWARE_SHORTCUT_KEY)).isEqualTo(
|
||||
MOCK_COMPONENT_NAME.flattenToString());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void optInValueToSettings_optInValue_haveMatchString() {
|
||||
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString());
|
||||
|
||||
AccessibilityUtil.optInValueToSettings(mContext, UserShortcutType.SOFTWARE,
|
||||
MOCK_COMPONENT_NAME2);
|
||||
|
||||
assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEqualTo(
|
||||
MOCK_COMPONENT_NAME.flattenToString() + ":"
|
||||
+ MOCK_COMPONENT_NAME2.flattenToString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void optInValueToSettings_optInTwoValues_haveMatchString() {
|
||||
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString());
|
||||
|
||||
AccessibilityUtil.optInValueToSettings(mContext, UserShortcutType.SOFTWARE,
|
||||
MOCK_COMPONENT_NAME2);
|
||||
AccessibilityUtil.optInValueToSettings(mContext, UserShortcutType.SOFTWARE,
|
||||
MOCK_COMPONENT_NAME2);
|
||||
|
||||
assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEqualTo(
|
||||
MOCK_COMPONENT_NAME.flattenToString() + ":"
|
||||
+ MOCK_COMPONENT_NAME2.flattenToString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void optOutAllValuesToSettings_optOutValue_emptyString() {
|
||||
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString());
|
||||
setShortcut(UserShortcutType.HARDWARE, MOCK_COMPONENT_NAME.flattenToString());
|
||||
int shortcutTypes =
|
||||
UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE | UserShortcutType.TRIPLETAP;
|
||||
|
||||
AccessibilityUtil.optOutAllValuesFromSettings(mContext, shortcutTypes,
|
||||
MOCK_COMPONENT_NAME);
|
||||
|
||||
assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEmpty();
|
||||
assertThat(getStringFromSettings(HARDWARE_SHORTCUT_KEY)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void optOutValueFromSettings_optOutValue_emptyString() {
|
||||
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString());
|
||||
|
||||
AccessibilityUtil.optOutValueFromSettings(mContext, UserShortcutType.SOFTWARE,
|
||||
MOCK_COMPONENT_NAME);
|
||||
|
||||
assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void optOutValueFromSettings_optOutValue_haveMatchString() {
|
||||
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString(),
|
||||
MOCK_COMPONENT_NAME2.flattenToString());
|
||||
|
||||
AccessibilityUtil.optOutValueFromSettings(mContext, UserShortcutType.SOFTWARE,
|
||||
MOCK_COMPONENT_NAME2);
|
||||
|
||||
assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEqualTo(
|
||||
MOCK_COMPONENT_NAME.flattenToString());
|
||||
}
|
||||
|
||||
private AccessibilityServiceInfo getMockAccessibilityServiceInfo() {
|
||||
final ApplicationInfo applicationInfo = new ApplicationInfo();
|
||||
final ServiceInfo serviceInfo = new ServiceInfo();
|
||||
applicationInfo.packageName = MOCK_PACKAGE_NAME;
|
||||
serviceInfo.packageName = MOCK_PACKAGE_NAME;
|
||||
serviceInfo.name = MOCK_CLASS_NAME;
|
||||
serviceInfo.applicationInfo = applicationInfo;
|
||||
|
||||
final ResolveInfo resolveInfo = new ResolveInfo();
|
||||
resolveInfo.serviceInfo = serviceInfo;
|
||||
|
||||
try {
|
||||
final AccessibilityServiceInfo info = new AccessibilityServiceInfo(resolveInfo,
|
||||
mContext);
|
||||
info.setComponentName(MOCK_COMPONENT_NAME);
|
||||
return info;
|
||||
} catch (XmlPullParserException | IOException e) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getStringFromSettings(String key) {
|
||||
return Settings.Secure.getString(mContext.getContentResolver(), key);
|
||||
}
|
||||
|
||||
private void setSettingsFeatureEnabled(String settingsKey, boolean enabled) {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||
settingsKey,
|
||||
enabled ? AccessibilityUtil.State.ON : AccessibilityUtil.State.OFF);
|
||||
}
|
||||
|
||||
private void setShortcut(@UserShortcutType int shortcutType, String... componentNames) {
|
||||
StringJoiner shortcutComponents = new StringJoiner(":");
|
||||
for (String componentName : componentNames) {
|
||||
shortcutComponents.add(componentName);
|
||||
}
|
||||
Settings.Secure.putString(mContext.getContentResolver(),
|
||||
shortcutType == UserShortcutType.SOFTWARE ? SOFTWARE_SHORTCUT_KEY
|
||||
: HARDWARE_SHORTCUT_KEY, shortcutComponents.toString());
|
||||
}
|
||||
|
||||
private void clearShortcuts() {
|
||||
Settings.Secure.putString(mContext.getContentResolver(), SOFTWARE_SHORTCUT_KEY, "");
|
||||
Settings.Secure.putString(mContext.getContentResolver(), HARDWARE_SHORTCUT_KEY, "");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.AudioManager;
|
||||
import android.os.VibrationAttributes;
|
||||
import android.os.Vibrator;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.testutils.shadow.ShadowInteractionJankMonitor;
|
||||
import com.android.settings.widget.SeekBarPreference;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {ShadowInteractionJankMonitor.class})
|
||||
public class AlarmVibrationIntensityPreferenceControllerTest {
|
||||
|
||||
private static final String PREFERENCE_KEY = "preference_key";
|
||||
|
||||
@Mock private PreferenceScreen mScreen;
|
||||
@Mock private AudioManager mAudioManager;
|
||||
|
||||
private Lifecycle mLifecycle;
|
||||
private Context mContext;
|
||||
private Vibrator mVibrator;
|
||||
private AlarmVibrationIntensityPreferenceController mController;
|
||||
private SeekBarPreference mPreference;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mLifecycle = new Lifecycle(() -> mLifecycle);
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
when(mContext.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager);
|
||||
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
|
||||
mVibrator = mContext.getSystemService(Vibrator.class);
|
||||
mController = new AlarmVibrationIntensityPreferenceController(mContext, PREFERENCE_KEY,
|
||||
Vibrator.VIBRATION_INTENSITY_HIGH);
|
||||
mLifecycle.addObserver(mController);
|
||||
mPreference = new SeekBarPreference(mContext);
|
||||
mPreference.setSummary("Test summary");
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
|
||||
mController.displayPreference(mScreen);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyConstants() {
|
||||
assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
|
||||
assertThat(mController.getAvailabilityStatus())
|
||||
.isEqualTo(BasePreferenceController.AVAILABLE);
|
||||
assertThat(mController.getMin()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
|
||||
assertThat(mController.getMax()).isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void missingSetting_shouldReturnDefault() {
|
||||
Settings.System.putString(mContext.getContentResolver(),
|
||||
Settings.System.ALARM_VIBRATION_INTENSITY, /* value= */ null);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.getProgress()).isEqualTo(
|
||||
mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_ALARM));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_ringerModeUpdates_shouldNotAffectSettings() {
|
||||
updateSetting(Settings.System.ALARM_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
|
||||
|
||||
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
|
||||
mController.updateState(mPreference);
|
||||
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
|
||||
assertThat(mPreference.isEnabled()).isTrue();
|
||||
|
||||
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
|
||||
mController.updateState(mPreference);
|
||||
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
|
||||
assertThat(mPreference.isEnabled()).isTrue();
|
||||
|
||||
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
|
||||
mController.updateState(mPreference);
|
||||
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
|
||||
assertThat(mPreference.isEnabled()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_shouldDisplayIntensityInSliderPosition() {
|
||||
updateSetting(Settings.System.ALARM_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
|
||||
mController.updateState(mPreference);
|
||||
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
|
||||
|
||||
updateSetting(Settings.System.ALARM_VIBRATION_INTENSITY,
|
||||
Vibrator.VIBRATION_INTENSITY_MEDIUM);
|
||||
mController.updateState(mPreference);
|
||||
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_MEDIUM);
|
||||
|
||||
updateSetting(Settings.System.ALARM_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
|
||||
mController.updateState(mPreference);
|
||||
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
|
||||
|
||||
updateSetting(Settings.System.ALARM_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
|
||||
mController.updateState(mPreference);
|
||||
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void setProgress_updatesIntensitySetting() throws Exception {
|
||||
mController.setSliderPosition(Vibrator.VIBRATION_INTENSITY_OFF);
|
||||
assertThat(readSetting(Settings.System.ALARM_VIBRATION_INTENSITY))
|
||||
.isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
|
||||
|
||||
mController.setSliderPosition(Vibrator.VIBRATION_INTENSITY_LOW);
|
||||
assertThat(readSetting(Settings.System.ALARM_VIBRATION_INTENSITY))
|
||||
.isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
|
||||
|
||||
mController.setSliderPosition(Vibrator.VIBRATION_INTENSITY_MEDIUM);
|
||||
assertThat(readSetting(Settings.System.ALARM_VIBRATION_INTENSITY))
|
||||
.isEqualTo(Vibrator.VIBRATION_INTENSITY_MEDIUM);
|
||||
|
||||
mController.setSliderPosition(Vibrator.VIBRATION_INTENSITY_HIGH);
|
||||
assertThat(readSetting(Settings.System.ALARM_VIBRATION_INTENSITY))
|
||||
.isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
|
||||
}
|
||||
|
||||
private void updateSetting(String key, int value) {
|
||||
Settings.System.putInt(mContext.getContentResolver(), key, value);
|
||||
}
|
||||
|
||||
private int readSetting(String settingKey) throws Settings.SettingNotFoundException {
|
||||
return Settings.System.getInt(mContext.getContentResolver(), settingKey);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.AudioManager;
|
||||
import android.os.VibrationAttributes;
|
||||
import android.os.Vibrator;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.preference.SwitchPreference;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AlarmVibrationTogglePreferenceControllerTest {
|
||||
|
||||
private static final String PREFERENCE_KEY = "preference_key";
|
||||
|
||||
@Mock private PreferenceScreen mScreen;
|
||||
@Mock AudioManager mAudioManager;
|
||||
|
||||
private Lifecycle mLifecycle;
|
||||
private Context mContext;
|
||||
private Vibrator mVibrator;
|
||||
private AlarmVibrationTogglePreferenceController mController;
|
||||
private SwitchPreference mPreference;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mLifecycle = new Lifecycle(() -> mLifecycle);
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
when(mContext.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager);
|
||||
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
|
||||
mVibrator = mContext.getSystemService(Vibrator.class);
|
||||
mController = new AlarmVibrationTogglePreferenceController(mContext, PREFERENCE_KEY);
|
||||
mLifecycle.addObserver(mController);
|
||||
mPreference = new SwitchPreference(mContext);
|
||||
mPreference.setSummary("Test summary");
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
|
||||
mController.displayPreference(mScreen);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyConstants() {
|
||||
assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
|
||||
assertThat(mController.getAvailabilityStatus())
|
||||
.isEqualTo(BasePreferenceController.AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void missingSetting_shouldReturnDefault() {
|
||||
Settings.System.putString(mContext.getContentResolver(),
|
||||
Settings.System.ALARM_VIBRATION_INTENSITY, /* value= */ null);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_ringerModeUpdates_shouldNotAffectSettings() {
|
||||
updateSetting(Settings.System.ALARM_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
|
||||
|
||||
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
|
||||
mController.updateState(mPreference);
|
||||
assertThat(mPreference.isChecked()).isTrue();
|
||||
assertThat(mPreference.isEnabled()).isTrue();
|
||||
|
||||
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
|
||||
mController.updateState(mPreference);
|
||||
assertThat(mPreference.isChecked()).isTrue();
|
||||
assertThat(mPreference.isEnabled()).isTrue();
|
||||
|
||||
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
|
||||
mController.updateState(mPreference);
|
||||
assertThat(mPreference.isChecked()).isTrue();
|
||||
assertThat(mPreference.isEnabled()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_shouldDisplayOnOffState() {
|
||||
updateSetting(Settings.System.ALARM_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
|
||||
mController.updateState(mPreference);
|
||||
assertThat(mPreference.isChecked()).isTrue();
|
||||
|
||||
updateSetting(Settings.System.ALARM_VIBRATION_INTENSITY,
|
||||
Vibrator.VIBRATION_INTENSITY_MEDIUM);
|
||||
mController.updateState(mPreference);
|
||||
assertThat(mPreference.isChecked()).isTrue();
|
||||
|
||||
updateSetting(Settings.System.ALARM_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
|
||||
mController.updateState(mPreference);
|
||||
assertThat(mPreference.isChecked()).isTrue();
|
||||
|
||||
updateSetting(Settings.System.ALARM_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
|
||||
mController.updateState(mPreference);
|
||||
assertThat(mPreference.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setChecked_updatesIntensityAndDependentSettings() throws Exception {
|
||||
updateSetting(Settings.System.ALARM_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
|
||||
mController.updateState(mPreference);
|
||||
assertThat(mPreference.isChecked()).isFalse();
|
||||
|
||||
mController.setChecked(true);
|
||||
assertThat(readSetting(Settings.System.ALARM_VIBRATION_INTENSITY)).isEqualTo(
|
||||
mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_ALARM));
|
||||
|
||||
mController.setChecked(false);
|
||||
assertThat(readSetting(Settings.System.ALARM_VIBRATION_INTENSITY))
|
||||
.isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
|
||||
}
|
||||
|
||||
private void updateSetting(String key, int value) {
|
||||
Settings.System.putInt(mContext.getContentResolver(), key, value);
|
||||
}
|
||||
|
||||
private int readSetting(String settingKey) throws Settings.SettingNotFoundException {
|
||||
return Settings.System.getInt(mContext.getContentResolver(), settingKey);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link ArrowPreference} */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class ArrowPreferenceTest {
|
||||
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
private ArrowPreference mPreference;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mPreference = new ArrowPreference(mContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void construct_withArrow() {
|
||||
assertThat(mPreference.getWidgetLayoutResource()).isEqualTo(
|
||||
R.layout.preference_widget_arrow);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.XmlTestUtils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** Tests for {@link AudioAdjustmentFragment}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AudioAdjustmentFragmentTest {
|
||||
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
private AudioAdjustmentFragment mFragment;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mFragment = new AudioAdjustmentFragment();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMetricsCategory_returnsCorrectCategory() {
|
||||
assertThat(mFragment.getMetricsCategory()).isEqualTo(
|
||||
SettingsEnums.ACCESSIBILITY_AUDIO_ADJUSTMENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getPreferenceScreenResId_returnsCorrectXml() {
|
||||
assertThat(mFragment.getPreferenceScreenResId()).isEqualTo(
|
||||
R.xml.accessibility_audio_adjustment);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLogTag_returnsCorrectTag() {
|
||||
assertThat(mFragment.getLogTag()).isEqualTo("AudioAdjustmentFragment");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getNonIndexableKeys_existInXmlLayout() {
|
||||
final List<String> niks = AudioAdjustmentFragment.SEARCH_INDEX_DATA_PROVIDER
|
||||
.getNonIndexableKeys(mContext);
|
||||
final List<String> keys =
|
||||
XmlTestUtils.getKeysFromPreferenceXml(mContext,
|
||||
R.xml.accessibility_audio_adjustment);
|
||||
|
||||
assertThat(keys).containsAtLeastElementsIn(niks);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.accessibility;
|
||||
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.preference.SwitchPreference;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AudioDescriptionPreferenceControllerTest {
|
||||
|
||||
private static final String KEY_AUDIO_DESCRIPTION =
|
||||
Settings.Secure.ENABLED_ACCESSIBILITY_AUDIO_DESCRIPTION_BY_DEFAULT;
|
||||
private static final int UNKNOWN = -1;
|
||||
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
private final SwitchPreference mSwitchPreference = spy(new SwitchPreference(mContext));
|
||||
private final AudioDescriptionPreferenceController mController =
|
||||
new AudioDescriptionPreferenceController(mContext,
|
||||
AudioDescriptionPreferenceController.PREF_KEY);
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
final PreferenceManager preferenceManager = new PreferenceManager(mContext);
|
||||
final PreferenceScreen screen = preferenceManager.createPreferenceScreen(mContext);
|
||||
mSwitchPreference.setKey(AudioDescriptionPreferenceController.PREF_KEY);
|
||||
screen.addPreference(mSwitchPreference);
|
||||
mController.displayPreference(screen);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_byDefault_shouldReturnAvailable() {
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isChecked_disableAudioDescription_onResumeShouldReturnFalse() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), KEY_AUDIO_DESCRIPTION, OFF);
|
||||
|
||||
mController.updateState(mSwitchPreference);
|
||||
|
||||
assertThat(mController.isChecked()).isFalse();
|
||||
assertThat(mSwitchPreference.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isChecked_enableAudioDescription_onResumeShouldReturnTrue() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), KEY_AUDIO_DESCRIPTION, ON);
|
||||
|
||||
mController.updateState(mSwitchPreference);
|
||||
|
||||
assertThat(mController.isChecked()).isTrue();
|
||||
assertThat(mSwitchPreference.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void performClick_enableAudioDescription_shouldReturnTrue() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), KEY_AUDIO_DESCRIPTION, OFF);
|
||||
|
||||
mController.updateState(mSwitchPreference);
|
||||
|
||||
mSwitchPreference.performClick();
|
||||
|
||||
verify(mSwitchPreference).setChecked(true);
|
||||
assertThat(mController.isChecked()).isTrue();
|
||||
assertThat(mSwitchPreference.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void performClick_disableAudioDescription_shouldReturnFalse() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), KEY_AUDIO_DESCRIPTION, ON);
|
||||
|
||||
mController.updateState(mSwitchPreference);
|
||||
|
||||
mSwitchPreference.performClick();
|
||||
|
||||
verify(mSwitchPreference).setChecked(false);
|
||||
assertThat(mController.isChecked()).isFalse();
|
||||
assertThat(mSwitchPreference.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setChecked_setFalse_shouldDisableAudioDescription() {
|
||||
mController.setChecked(false);
|
||||
|
||||
assertThat(Settings.Secure.getInt(
|
||||
mContext.getContentResolver(), KEY_AUDIO_DESCRIPTION, UNKNOWN)).isEqualTo(OFF);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setChecked_setTrue_shouldEnableAudioDescription() {
|
||||
mController.setChecked(true);
|
||||
|
||||
assertThat(Settings.Secure.getInt(
|
||||
mContext.getContentResolver(), KEY_AUDIO_DESCRIPTION, UNKNOWN)).isEqualTo(ON);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.accessibility;
|
||||
|
||||
import static android.view.accessibility.AccessibilityManager.AUTOCLICK_DELAY_DEFAULT;
|
||||
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link AutoclickPreferenceController}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AutoclickPreferenceControllerTest {
|
||||
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
private AutoclickPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mController = new AutoclickPreferenceController(mContext, "auto_click");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_shouldReturnAvailableUnsearchable() {
|
||||
assertThat(mController.getAvailabilityStatus())
|
||||
.isEqualTo(BasePreferenceController.AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_disabledAutoclick_shouldReturnOffSummary() {
|
||||
setAutoClickEnabled(false);
|
||||
|
||||
assertThat(mController.getSummary().toString())
|
||||
.isEqualTo(mContext.getText(R.string.autoclick_disabled));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_enabledAutoclick_shouldReturnOnSummary() {
|
||||
setAutoClickEnabled(true);
|
||||
setAutoClickDelayed(AUTOCLICK_DELAY_DEFAULT);
|
||||
|
||||
|
||||
assertThat(mController.getSummary().toString())
|
||||
.isEqualTo(AutoclickUtils.getAutoclickDelaySummary(
|
||||
mContext,
|
||||
R.string.accessibilty_autoclick_preference_subtitle_medium_delay,
|
||||
AUTOCLICK_DELAY_DEFAULT).toString());
|
||||
}
|
||||
|
||||
private void setAutoClickEnabled(boolean enabled) {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED, enabled ? ON : OFF);
|
||||
}
|
||||
|
||||
private void setAutoClickDelayed(int delayedInMs) {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_AUTOCLICK_DELAY, delayedInMs);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.accessibility;
|
||||
|
||||
import static com.android.settings.accessibility.AutoclickUtils.MAX_AUTOCLICK_DELAY_MS;
|
||||
import static com.android.settings.accessibility.AutoclickUtils.MIN_AUTOCLICK_DELAY_MS;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link AutoclickUtils}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public final class AutoclickUtilsTest {
|
||||
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
@Test
|
||||
public void getAutoclickDelaySummary_minDelay_shouldReturnOnSummary() {
|
||||
final CharSequence summary = AutoclickUtils.getAutoclickDelaySummary(
|
||||
mContext, R.string.accessibilty_autoclick_delay_unit_second,
|
||||
MIN_AUTOCLICK_DELAY_MS);
|
||||
assertThat(summary.toString()).isEqualTo("0.2 seconds");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAutoclickDelaySummary_maxDelay_shouldReturnOnSummary() {
|
||||
final CharSequence summary = AutoclickUtils.getAutoclickDelaySummary(
|
||||
mContext, R.string.accessibilty_autoclick_delay_unit_second,
|
||||
MAX_AUTOCLICK_DELAY_MS);
|
||||
assertThat(summary.toString()).isEqualTo("1 second");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.bluetooth.Utils;
|
||||
import com.android.settings.connecteddevice.DevicePreferenceCallback;
|
||||
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** Tests for {@link AvailableHearingDeviceUpdater}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {ShadowBluetoothUtils.class})
|
||||
public class AvailableHearingDeviceUpdaterTest {
|
||||
@Rule
|
||||
public MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
@Mock
|
||||
private DevicePreferenceCallback mDevicePreferenceCallback;
|
||||
@Mock
|
||||
private CachedBluetoothDeviceManager mCachedDeviceManager;
|
||||
@Mock
|
||||
private LocalBluetoothManager mLocalBluetoothManager;
|
||||
@Mock
|
||||
private CachedBluetoothDevice mCachedBluetoothDevice;
|
||||
@Mock
|
||||
private BluetoothDevice mBluetoothDevice;
|
||||
private AvailableHearingDeviceUpdater mUpdater;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
|
||||
mLocalBluetoothManager = Utils.getLocalBtManager(mContext);
|
||||
when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager);
|
||||
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
|
||||
mUpdater = new AvailableHearingDeviceUpdater(mContext,
|
||||
mDevicePreferenceCallback, /* metricsCategory= */ 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isFilterMatch_connectedHearingDevice_returnTrue() {
|
||||
CachedBluetoothDevice connectedHearingDevice = mCachedBluetoothDevice;
|
||||
when(connectedHearingDevice.isHearingAidDevice()).thenReturn(true);
|
||||
when(mBluetoothDevice.isConnected()).thenReturn(true);
|
||||
when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
|
||||
when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(
|
||||
new ArrayList<>(List.of(connectedHearingDevice)));
|
||||
|
||||
assertThat(mUpdater.isFilterMatched(connectedHearingDevice)).isEqualTo(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isFilterMatch_nonConnectedHearingDevice_returnFalse() {
|
||||
CachedBluetoothDevice nonConnectedHearingDevice = mCachedBluetoothDevice;
|
||||
when(nonConnectedHearingDevice.isHearingAidDevice()).thenReturn(true);
|
||||
when(mBluetoothDevice.isConnected()).thenReturn(false);
|
||||
when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
|
||||
when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(
|
||||
new ArrayList<>(List.of(nonConnectedHearingDevice)));
|
||||
|
||||
assertThat(mUpdater.isFilterMatched(nonConnectedHearingDevice)).isEqualTo(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isFilterMatch_connectedBondingHearingDevice_returnFalse() {
|
||||
CachedBluetoothDevice connectedBondingHearingDevice = mCachedBluetoothDevice;
|
||||
when(connectedBondingHearingDevice.isHearingAidDevice()).thenReturn(true);
|
||||
when(mBluetoothDevice.isConnected()).thenReturn(true);
|
||||
when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDING);
|
||||
when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(
|
||||
new ArrayList<>(List.of(connectedBondingHearingDevice)));
|
||||
|
||||
assertThat(mUpdater.isFilterMatched(connectedBondingHearingDevice)).isEqualTo(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isFilterMatch_hearingDeviceNotInCachedDevicesList_returnFalse() {
|
||||
CachedBluetoothDevice notInCachedDevicesListDevice = mCachedBluetoothDevice;
|
||||
when(notInCachedDevicesListDevice.isHearingAidDevice()).thenReturn(true);
|
||||
when(mBluetoothDevice.isConnected()).thenReturn(true);
|
||||
when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
|
||||
when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(new ArrayList<>());
|
||||
|
||||
assertThat(mUpdater.isFilterMatched(notInCachedDevicesListDevice)).isEqualTo(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.accessibility;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link BackgroundPreference} */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class BackgroundPreferenceTest {
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
private View mRootView = new View(mContext);
|
||||
@Spy
|
||||
private PreferenceViewHolder mViewHolder = PreferenceViewHolder.createInstanceForTests(
|
||||
mRootView);
|
||||
@Spy
|
||||
private LinearLayout mLinearLayout = new LinearLayout(mContext);
|
||||
private BackgroundPreference mPreference;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mPreference = new BackgroundPreference(mContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setBackground_success() {
|
||||
doReturn(mLinearLayout).when(mViewHolder).findViewById(R.id.background);
|
||||
|
||||
mPreference.setBackground(android.R.drawable.screen_background_dark);
|
||||
mPreference.onBindViewHolder(mViewHolder);
|
||||
|
||||
verify(mLinearLayout).setBackground(any());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.testutils.shadow.ShadowInteractionJankMonitor;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {ShadowInteractionJankMonitor.class})
|
||||
public class BalanceSeekBarPreferenceTest {
|
||||
private static final int BALANCE_CENTER_VALUE = 100;
|
||||
private static final int BALANCE_MAX_VALUE = 200;
|
||||
|
||||
private Context mContext;
|
||||
private AttributeSet mAttrs;
|
||||
private PreferenceViewHolder mHolder;
|
||||
private BalanceSeekBar mSeekBar;
|
||||
private BalanceSeekBarPreference mSeekBarPreference;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mSeekBarPreference = new BalanceSeekBarPreference(mContext, mAttrs);
|
||||
LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||
final View view =
|
||||
inflater.inflate(mSeekBarPreference.getLayoutResource(),
|
||||
new LinearLayout(mContext), false);
|
||||
mHolder = PreferenceViewHolder.createInstanceForTests(view);
|
||||
mSeekBar = (BalanceSeekBar) view.findViewById(com.android.internal.R.id.seekbar);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void seekBarPreferenceOnBindViewHolder_shouldInitSeekBarValue() {
|
||||
mSeekBarPreference.onBindViewHolder(mHolder);
|
||||
|
||||
assertThat(mSeekBar.getMax()).isEqualTo(BALANCE_MAX_VALUE);
|
||||
assertThat(mSeekBar.getProgress()).isEqualTo(BALANCE_CENTER_VALUE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.accessibility;
|
||||
|
||||
import static android.view.HapticFeedbackConstants.CLOCK_TICK;
|
||||
import static android.view.HapticFeedbackConstants.CONTEXT_CLICK;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.SeekBar;
|
||||
|
||||
import com.android.settings.testutils.shadow.ShadowSystemSettings;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {
|
||||
ShadowSystemSettings.class,
|
||||
})
|
||||
public class BalanceSeekBarTest {
|
||||
// Fix the maximum process value to 200 for testing the BalanceSeekBar.
|
||||
// It affects the SeekBar value of center(100) and snapThreshold(200 * SNAP_TO_PERCENTAGE).
|
||||
private static final int MAX_PROGRESS_VALUE = 200;
|
||||
|
||||
private Context mContext;
|
||||
private AttributeSet mAttrs;
|
||||
private BalanceSeekBar mSeekBar;
|
||||
private BalanceSeekBar.OnSeekBarChangeListener mProxySeekBarListener;
|
||||
private SeekBar.OnSeekBarChangeListener mockSeekBarChangeListener;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mSeekBar = new BalanceSeekBar(mContext, mAttrs);
|
||||
mProxySeekBarListener = shadowOf(mSeekBar).getOnSeekBarChangeListener();
|
||||
mockSeekBarChangeListener = mock(SeekBar.OnSeekBarChangeListener.class);
|
||||
mSeekBar.setOnSeekBarChangeListener(mockSeekBarChangeListener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStartTrackingTouch_shouldInvokeMethod() {
|
||||
mProxySeekBarListener.onStartTrackingTouch(mSeekBar);
|
||||
|
||||
verify(mockSeekBarChangeListener, times(1)).onStartTrackingTouch(mSeekBar);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStopTrackingTouch_shouldInvokeMethod() {
|
||||
mProxySeekBarListener.onStopTrackingTouch(mSeekBar);
|
||||
|
||||
verify(mockSeekBarChangeListener, times(1)).onStopTrackingTouch(mSeekBar);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onProgressChanged_shouldInvokeMethod() {
|
||||
// Assign the test value of SeekBar progress
|
||||
mProxySeekBarListener.onProgressChanged(mSeekBar, MAX_PROGRESS_VALUE, true);
|
||||
|
||||
verify(mockSeekBarChangeListener, times(1)).onProgressChanged(eq(mSeekBar),
|
||||
eq(MAX_PROGRESS_VALUE), eq(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onProgressChanged_minimumValue_clockTickFeedbackPerformed() {
|
||||
mSeekBar.performHapticFeedback(CONTEXT_CLICK);
|
||||
mProxySeekBarListener.onProgressChanged(mSeekBar, 0, true);
|
||||
|
||||
assertThat(shadowOf(mSeekBar).lastHapticFeedbackPerformed()).isEqualTo(CLOCK_TICK);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onProgressChanged_centerValue_clockTickFeedbackPerformed() {
|
||||
mSeekBar.performHapticFeedback(CONTEXT_CLICK);
|
||||
mProxySeekBarListener.onProgressChanged(mSeekBar, MAX_PROGRESS_VALUE / 2, true);
|
||||
|
||||
assertThat(shadowOf(mSeekBar).lastHapticFeedbackPerformed()).isEqualTo(CLOCK_TICK);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onProgressChanged_maximumValue_clockTickFeedbackPerformed() {
|
||||
mSeekBar.setMax(MAX_PROGRESS_VALUE);
|
||||
mSeekBar.performHapticFeedback(CONTEXT_CLICK);
|
||||
mProxySeekBarListener.onProgressChanged(mSeekBar, MAX_PROGRESS_VALUE, true);
|
||||
|
||||
assertThat(shadowOf(mSeekBar).lastHapticFeedbackPerformed()).isEqualTo(CLOCK_TICK);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setMaxTest_shouldSetValue() {
|
||||
mSeekBar.setMax(MAX_PROGRESS_VALUE);
|
||||
|
||||
assertThat(getBalanceSeekBarCenter(mSeekBar)).isEqualTo(MAX_PROGRESS_VALUE / 2);
|
||||
assertThat(getBalanceSeekBarSnapThreshold(mSeekBar)).isEqualTo(
|
||||
MAX_PROGRESS_VALUE * BalanceSeekBar.SNAP_TO_PERCENTAGE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setProgressTest_shouldSnapToCenter() {
|
||||
// Assign the test value of SeekBar progress within the threshold (94-106 in this case).
|
||||
final int progressWithinThreshold = 102;
|
||||
mSeekBar.setMax(MAX_PROGRESS_VALUE);
|
||||
mSeekBar.setProgress(progressWithinThreshold + 10); //set progress which is over threshold.
|
||||
mProxySeekBarListener.onProgressChanged(mSeekBar, progressWithinThreshold, true);
|
||||
|
||||
assertThat(mSeekBar.getProgress()).isEqualTo(getBalanceSeekBarCenter(mSeekBar));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setProgressTest_shouldMaintainInputValue() {
|
||||
// Assign the test value of SeekBar progress without the threshold.
|
||||
final int progressWithoutThreshold = 107;
|
||||
mSeekBar.setMax(MAX_PROGRESS_VALUE);
|
||||
mSeekBar.setProgress(progressWithoutThreshold);
|
||||
mProxySeekBarListener.onProgressChanged(mSeekBar, progressWithoutThreshold, true);
|
||||
|
||||
assertThat(mSeekBar.getProgress()).isEqualTo(progressWithoutThreshold);
|
||||
}
|
||||
|
||||
// method to get the center from BalanceSeekBar for testing setMax().
|
||||
private int getBalanceSeekBarCenter(BalanceSeekBar seekBar) {
|
||||
return seekBar.getMax() / 2;
|
||||
}
|
||||
|
||||
// method to get the snapThreshold from BalanceSeekBar for testing setMax().
|
||||
private float getBalanceSeekBarSnapThreshold(BalanceSeekBar seekBar) {
|
||||
return seekBar.getMax() * BalanceSeekBar.SNAP_TO_PERCENTAGE;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user