Merge "Split page title and toggle title due to the request from L10N team" into main
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 4b38062..2b2a1b8 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -2686,6 +2686,7 @@
<activity android:name=".biometrics.face.FaceEnrollIntroduction"
android:exported="true"
+ android:theme="@style/GlifV4Theme.DayNight"
android:screenOrientation="nosensor">
<intent-filter>
<action android:name="android.settings.FACE_ENROLL"/>
@@ -2696,18 +2697,22 @@
<activity android:name=".biometrics.face.FaceEnrollIntroductionInternal"
android:exported="false"
android:screenOrientation="nosensor"
+ android:theme="@style/GlifV4Theme.DayNight"
android:taskAffinity="com.android.settings.root" />
<activity android:name=".biometrics.face.FaceEnrollEducation"
android:exported="false"
+ android:theme="@style/GlifV4Theme.DayNight"
android:screenOrientation="nosensor"/>
<activity android:name=".biometrics.face.FaceEnrollEnrolling"
android:exported="false"
+ android:theme="@style/GlifV4Theme.DayNight"
android:screenOrientation="portrait"/>
<activity android:name=".biometrics.face.FaceEnrollFinish"
android:exported="false"
+ android:theme="@style/GlifV4Theme.DayNight"
android:screenOrientation="portrait"/>
<activity android:name=".biometrics.BiometricHandoffActivity"
@@ -5179,9 +5184,11 @@
<activity
android:name="com.android.settings.network.WepNetworkDialogActivity"
+ android:configChanges="orientation|keyboard|keyboardHidden|screenSize|screenLayout|smallestScreenSize"
+ android:excludeFromRecents="true"
android:exported="true"
- android:theme="@style/Theme.SpaLib.Dialog"
- android:permission="android.permission.NETWORK_SETTINGS">
+ android:permission="android.permission.NETWORK_SETTINGS"
+ android:theme="@style/Theme.SpaLib.Dialog">
</activity>
<!-- This is the longest AndroidManifest.xml ever. -->
diff --git a/res/drawable/ic_android_vd_theme_24.xml b/res/drawable/ic_android_vd_theme_24.xml
new file mode 100644
index 0000000..6581209
--- /dev/null
+++ b/res/drawable/ic_android_vd_theme_24.xml
@@ -0,0 +1,26 @@
+<!--
+ ~ 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.
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="960"
+ android:viewportHeight="960"
+ android:tint="?android:attr/colorControlNormal">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M40,720Q49,613 105.5,523Q162,433 256,380L182,252Q176,243 179,233Q182,223 192,218Q200,213 210,216Q220,219 226,228L300,356Q386,320 480,320Q574,320 660,356L734,228Q740,219 750,216Q760,213 768,218Q778,223 781,233Q784,243 778,252L704,380Q798,433 854.5,523Q911,613 920,720L40,720ZM280,610Q301,610 315.5,595.5Q330,581 330,560Q330,539 315.5,524.5Q301,510 280,510Q259,510 244.5,524.5Q230,539 230,560Q230,581 244.5,595.5Q259,610 280,610ZM680,610Q701,610 715.5,595.5Q730,581 730,560Q730,539 715.5,524.5Q701,510 680,510Q659,510 644.5,524.5Q630,539 630,560Q630,581 644.5,595.5Q659,610 680,610Z"/>
+</vector>
+
diff --git a/res/drawable/ic_database_vd_theme_24.xml b/res/drawable/ic_database_vd_theme_24.xml
new file mode 100644
index 0000000..713a65e
--- /dev/null
+++ b/res/drawable/ic_database_vd_theme_24.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ 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.
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="960"
+ android:viewportHeight="960"
+ android:tint="?android:attr/colorControlNormal">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M480,440Q630,440 735,393Q840,346 840,280Q840,214 735,167Q630,120 480,120Q330,120 225,167Q120,214 120,280Q120,346 225,393Q330,440 480,440ZM480,540Q521,540 582.5,531.5Q644,523 701,504Q758,485 799,454.5Q840,424 840,380L840,480Q840,524 799,554.5Q758,585 701,604Q644,623 582.5,631.5Q521,640 480,640Q439,640 377.5,631.5Q316,623 259,604Q202,585 161,554.5Q120,524 120,480L120,380Q120,424 161,454.5Q202,485 259,504Q316,523 377.5,531.5Q439,540 480,540ZM480,740Q521,740 582.5,731.5Q644,723 701,704Q758,685 799,654.5Q840,624 840,580L840,680Q840,724 799,754.5Q758,785 701,804Q644,823 582.5,831.5Q521,840 480,840Q439,840 377.5,831.5Q316,823 259,804Q202,785 161,754.5Q120,724 120,680L120,580Q120,624 161,654.5Q202,685 259,704Q316,723 377.5,731.5Q439,740 480,740Z"/>
+</vector>
diff --git a/res/layout/private_space_pre_finish_delay.xml b/res/layout/private_space_pre_finish_delay.xml
new file mode 100644
index 0000000..3b620bf
--- /dev/null
+++ b/res/layout/private_space_pre_finish_delay.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+
+<com.google.android.setupdesign.GlifLoadingLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/private_space_pre_finish"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:icon="@drawable/ic_private_space_icon"
+ app:sudUsePartnerHeavyTheme="true"
+ app:sudIllustrationType="default"
+ app:sucHeaderText="@string/private_space_pre_finish_title">
+</com.google.android.setupdesign.GlifLoadingLayout>
\ No newline at end of file
diff --git a/res/navigation/privatespace_main_context_nav.xml b/res/navigation/privatespace_main_context_nav.xml
index 80cd399..b027d87 100644
--- a/res/navigation/privatespace_main_context_nav.xml
+++ b/res/navigation/privatespace_main_context_nav.xml
@@ -46,6 +46,13 @@
android:id="@+id/action_retry_profile_creation"
app:destination="@id/ps_auto_advance_fragment"/>
</fragment>
+ <fragment android:id="@+id/ps_pre_finish_delay_fragment"
+ android:name="com.android.settings.privatespace.SetupPreFinishDelayFragment"
+ android:label="fragment_ps_pre_finish">
+ <action
+ android:id="@+id/action_success_fragment"
+ app:destination="@id/ps_profile_success_fragment"/>
+ </fragment>
<fragment android:id="@+id/ps_profile_success_fragment"
android:name="com.android.settings.privatespace.SetupSuccessFragment"
android:label="fragment_ps_success"/>
@@ -64,7 +71,7 @@
android:label="fragment_ps_lock">
<action
android:id="@+id/action_lock_success_fragment"
- app:destination="@id/ps_profile_success_fragment"/>
+ app:destination="@id/ps_pre_finish_delay_fragment"/>
</fragment>
<fragment android:id="@+id/ps_account_intro_fragment"
android:name="com.android.settings.privatespace.PrivateSpaceGaiaEducationFragment"
@@ -76,6 +83,6 @@
android:id="@+id/action_advance_login_error"
app:destination="@id/ps_account_error_fragment"/>
</fragment>
- <action android:id="@+id/action_success_fragment"
- app:destination="@id/ps_profile_success_fragment"/>
+ <action android:id="@+id/action_pre_finish_delay_fragment"
+ app:destination="@id/ps_pre_finish_delay_fragment"/>
</navigation>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 00f6ebc..5f7b0b6 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1352,6 +1352,8 @@
<string name="private_space_use_screenlock_label">Use screen lock</string>
<!-- Label for private space lock setup button to choose a new lock. [CHAR LIMIT=50] -->
<string name="private_space_set_lock_label">Choose new lock</string>
+ <!-- Title for private space setup pre completion screen to add a delay. [CHAR LIMIT=30] -->
+ <string name="private_space_pre_finish_title">Just a sec\u2026</string>
<!-- Title for private space setup success screen. [CHAR LIMIT=30] -->
<string name="private_space_success_title">All set!</string>
<!-- Summary for the private space setup success screen. [CHAR LIMIT=NONE] -->
@@ -1378,12 +1380,6 @@
<string name="private_space_choose_your_password_header">Set a password for your private space</string>
<!-- Header for private space choose your pattern screen [CHAR LIMIT=40] -->
<string name="private_space_choose_your_pattern_header">Set a pattern for your private space</string>
- <!-- Header for private space apps and notifications section [CHAR LIMIT=40] -->
- <string name="private_space_apps_and_notifications_header">Apps and notifications</string>
- <!-- Title for private space sensitive notifications toggle [CHAR LIMIT=80] -->
- <string name="private_space_notifications_title">Sensitive notifications on lock screen</string>
- <!-- Summary description for private space sensitive notifications toggle [CHAR LIMIT=200] -->
- <string name="private_space_sensitive_notifications_description">Show sensitive content when private space is unlocked</string>
<!-- Title for private space GAIA education screen [CHAR LIMIT=90] -->
<string name="private_space_gaia_education_title">Create a Google Account to help keep your data private</string>
<!-- Description for private space GAIA education screen [CHAR LIMIT=120] -->
@@ -4419,8 +4415,10 @@
<!-- Title text for 'Tap to click'. [CHAR LIMIT=35] -->
<string name="trackpad_tap_to_click">Tap to click</string>
- <!-- TODO(b/321978150): mark as translatable once we have finalized text from UX. -->
- <string name="trackpad_tap_dragging" translatable="false">Tap dragging</string>
+ <!-- Title text for 'Tap dragging', a touchpad setting which allows dragging of UI elements by tapping the touchpad with a single finger and then moving it. [CHAR LIMIT=35] -->
+ <string name="trackpad_tap_dragging_title">Tap dragging</string>
+ <!-- Summary text for 'Tap dragging', a touchpad setting which allows dragging of UI elements by tapping the touchpad with a single finger and then moving it. [CHAR LIMIT=60] -->
+ <string name="trackpad_tap_dragging_summary">Tap and drag your finger on the touchpad to move objects</string>
<!-- Title text for 'Touchpad gestures' [CHAR LIMIT=35] -->
<string name="trackpad_touchpad_gesture_title">Touchpad gestures</string>
<!-- Summary text for 'Touchpad gestures' [CHAR LIMIT=60] -->
@@ -9838,13 +9836,6 @@
<!-- Label for showing apps that can manage external storage[CHAR LIMIT=45] -->
<string name="filter_manage_external_storage">Can access all files</string>
- <!-- Voice Activation apps settings title [CHAR LIMIT=40] -->
- <string name="voice_activation_apps_title">Voice activation apps</string>
- <!-- Label for a setting which controls whether an app can be voice activated [CHAR LIMIT=NONE] -->
- <string name="permit_voice_activation_apps">Allow voice activation</string>
- <!-- Description for a setting which controls whether an app can be voice activated [CHAR LIMIT=NONE] -->
- <string name ="allow_voice_activation_apps_description">Voice activation turns-on approved apps, hands-free, using voice command. Built-in adaptive sensing ensures data stays private only to you.\n\n<a href="">More about protected adaptive sensing</a></string>
-
<!-- Manage full screen intent permission title [CHAR LIMIT=40] -->
<string name="full_screen_intent_title">Full screen notifications</string>
@@ -10144,6 +10135,9 @@
<!-- Format for a summary describing the amount of data before the user is warned or limited [CHAR LIMIT=NONE] -->
<string name="cell_data_warning_and_limit"><xliff:g name="amount" example="1 GB">^1</xliff:g> data warning / <xliff:g name="amount" example="2 GB">^2</xliff:g> data limit</string>
+ <!-- A summary shown on data usage screens to indicate inaccuracy of data tracking [CHAR LIMIT=NONE] -->
+ <string name="operator_warning">Carrier data accounting may differ from device accounting</string>
+
<!-- A summary shown on data usage screens to indicate data tracking excluded from carrier networks [CHAR LIMIT=NONE] -->
<string name="non_carrier_data_usage_warning">Excludes data used by carrier networks</string>
@@ -11088,8 +11082,8 @@
]]>
</string>
- <!-- Title for setting tile leading to saved autofill passwords, passkeys, autofill, and account settings [CHAR LIMIT=40]-->
- <string name="account_dashboard_title_with_passkeys">Passwords, passkeys & autofill</string>
+ <!-- Title for setting tile leading to saved autofill passwords, passkeys, and account settings [CHAR LIMIT=40]-->
+ <string name="account_dashboard_title_with_passkeys">Passwords, passkeys & accounts</string>
<!-- Message of the warning dialog for disabling the credential provider (new strings for 24Q3). [CHAR_LIMIT=NONE] -->
<string name="credman_confirmation_message_new_ui">
diff --git a/res/xml/data_usage_list.xml b/res/xml/data_usage_list.xml
index 62456ed..292d729 100644
--- a/res/xml/data_usage_list.xml
+++ b/res/xml/data_usage_list.xml
@@ -27,8 +27,7 @@
/>
<Preference
- android:key="non_carrier_data_usage_warning"
- android:summary="@string/non_carrier_data_usage_warning"
+ android:key="warning"
android:selectable="false" />
</PreferenceCategory>
diff --git a/res/xml/private_space_settings.xml b/res/xml/private_space_settings.xml
index f979599..b1233b9 100644
--- a/res/xml/private_space_settings.xml
+++ b/res/xml/private_space_settings.xml
@@ -60,17 +60,6 @@
</PreferenceCategory>
<PreferenceCategory
- android:title="@string/private_space_apps_and_notifications_header">
-
- <com.android.settingslib.RestrictedSwitchPreference
- android:key="private_space_sensitive_notifications"
- android:title="@string/private_space_notifications_title"
- android:summary="@string/private_space_sensitive_notifications_description"
- settings:controller="com.android.settings.privatespace.HidePrivateSpaceSensitiveNotificationsController" />
-
- </PreferenceCategory>
-
- <PreferenceCategory
android:title="@string/private_space_category_system">
<Preference
diff --git a/res/xml/special_access.xml b/res/xml/special_access.xml
index 572345c..4caf7ac 100644
--- a/res/xml/special_access.xml
+++ b/res/xml/special_access.xml
@@ -117,11 +117,6 @@
settings:controller="com.android.settings.spa.app.specialaccess.UseFullScreenIntentPreferenceController" />
<Preference
- android:key="voice_activation_apps"
- android:title="@string/voice_activation_apps_title"
- settings:controller="com.android.settings.spa.app.specialaccess.VoiceActivationAppsPreferenceController" />
-
- <Preference
android:key="picture_in_picture"
android:title="@string/picture_in_picture_title"
android:order="-1100"
diff --git a/res/xml/storage_category_fragment.xml b/res/xml/storage_category_fragment.xml
index 2c95889..58bd891 100644
--- a/res/xml/storage_category_fragment.xml
+++ b/res/xml/storage_category_fragment.xml
@@ -62,18 +62,30 @@
android:icon="@drawable/ic_folder_vd_theme_24"
android:order="106"/>
<com.android.settings.deviceinfo.StorageItemPreference
- android:key="pref_system"
- android:title="@string/storage_system"
- android:icon="@drawable/ic_system_update"
- android:order="107"/>
- <com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_trash"
android:title="@string/storage_trash"
android:icon="@drawable/ic_trash_can"
- android:order="108"/>
- <!-- Preference order 100~200 are 'ONLY' for storage category preferences above. -->
+ android:order="107"/>
+ <!-- Preference order 100~200 are 'ONLY' for storage category
+ preferences that are sorted by size. -->
+ <PreferenceCategory
+ android:key="storage_category_splitter"
+ android:title="@string/storage_system_label"
+ android:order="201"
+ settings:searchable="false">
+ <com.android.settings.deviceinfo.StorageItemPreference
+ android:key="pref_system"
+ android:title="@string/storage_os_name"
+ android:icon="@drawable/ic_android_vd_theme_24"
+ android:order="202"/>
+ <com.android.settings.deviceinfo.StorageItemPreference
+ android:key="temporary_files"
+ android:title="@string/storage_temporary_files"
+ android:icon="@drawable/ic_database_vd_theme_24"
+ android:order="203"/>
+ </PreferenceCategory>
<PreferenceCategory
android:key="pref_non_current_users"
android:title="@string/storage_other_users"
- android:order="201" />
+ android:order="204" />
</PreferenceScreen>
diff --git a/res/xml/storage_dashboard_fragment.xml b/res/xml/storage_dashboard_fragment.xml
index 7c0f3a6..fd866ad 100644
--- a/res/xml/storage_dashboard_fragment.xml
+++ b/res/xml/storage_dashboard_fragment.xml
@@ -81,18 +81,30 @@
android:icon="@drawable/ic_folder_vd_theme_24"
android:order="106"/>
<com.android.settings.deviceinfo.StorageItemPreference
- android:key="pref_system"
- android:title="@string/storage_system"
- android:icon="@drawable/ic_system_update"
- android:order="107"/>
- <com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_trash"
android:title="@string/storage_trash"
android:icon="@drawable/ic_trash_can"
- android:order="108"/>
- <!-- Preference order 100~200 are 'ONLY' for storage category preferences above. -->
+ android:order="107"/>
+ <!-- Preference order 100~200 are 'ONLY' for storage category
+ preferences that are sorted by size. -->
+ <PreferenceCategory
+ android:key="storage_category_splitter"
+ android:title="@string/storage_system_label"
+ android:order="201"
+ settings:searchable="false">
+ <com.android.settings.deviceinfo.StorageItemPreference
+ android:key="pref_system"
+ android:title="@string/storage_os_name"
+ android:icon="@drawable/ic_android_vd_theme_24"
+ android:order="202"/>
+ <com.android.settings.deviceinfo.StorageItemPreference
+ android:key="temporary_files"
+ android:title="@string/storage_temporary_files"
+ android:icon="@drawable/ic_database_vd_theme_24"
+ android:order="203"/>
+ </PreferenceCategory>
<PreferenceCategory
android:key="pref_non_current_users"
android:title="@string/storage_other_users"
- android:order="201" />
+ android:order="204" />
</PreferenceScreen>
diff --git a/res/xml/trackpad_settings.xml b/res/xml/trackpad_settings.xml
index 6601036..fcd43a5 100644
--- a/res/xml/trackpad_settings.xml
+++ b/res/xml/trackpad_settings.xml
@@ -48,10 +48,10 @@
android:order="30"
settings:keywords="@string/keywords_trackpad_bottom_right_tap"/>
- <!-- TODO(b/321978150): add a summary line once we have finalized text from UX. -->
<SwitchPreferenceCompat
android:key="trackpad_tap_dragging"
- android:title="@string/trackpad_tap_dragging"
+ android:title="@string/trackpad_tap_dragging_title"
+ android:summary="@string/trackpad_tap_dragging_summary"
settings:controller="com.android.settings.inputmethod.TrackpadTapDraggingPreferenceController"
android:order="35"/>
diff --git a/src/com/android/settings/SettingsActivityUtil.kt b/src/com/android/settings/SettingsActivityUtil.kt
index b1927f1..3cbd4b4 100644
--- a/src/com/android/settings/SettingsActivityUtil.kt
+++ b/src/com/android/settings/SettingsActivityUtil.kt
@@ -38,7 +38,6 @@
import com.android.settings.spa.app.specialaccess.ModifySystemSettingsAppListProvider
import com.android.settings.spa.app.specialaccess.NfcTagAppsSettingsProvider
import com.android.settings.spa.app.specialaccess.PictureInPictureListProvider
-import com.android.settings.spa.app.specialaccess.VoiceActivationAppsListProvider
import com.android.settings.spa.app.specialaccess.WifiControlAppListProvider
import com.android.settings.wifi.ChangeWifiStateDetails
@@ -67,8 +66,6 @@
WifiControlAppListProvider.getAppInfoRoutePrefix(),
NfcTagAppsSettingsProvider::class.qualifiedName to
NfcTagAppsSettingsProvider.getAppInfoRoutePrefix(),
- VoiceActivationAppsListProvider::class.qualifiedName to
- VoiceActivationAppsListProvider.getAppInfoRoutePrefix(),
BackupTasksAppsListProvider::class.qualifiedName to
BackupTasksAppsListProvider.getAppInfoRoutePrefix(),
)
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index d44d727..e067c73 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -54,8 +54,10 @@
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.VectorDrawable;
+import android.hardware.biometrics.SensorProperties;
import android.hardware.face.Face;
import android.hardware.face.FaceManager;
+import android.hardware.face.FaceSensorPropertiesInternal;
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintManager;
import android.net.ConnectivityManager;
@@ -928,6 +930,23 @@
}
/**
+ * Return true if face is supported as Class 2 biometrics and above on the device, false
+ * otherwise.
+ */
+ public static boolean isFaceNotConvenienceBiometric(@NonNull Context context) {
+ FaceManager faceManager = getFaceManagerOrNull(context);
+ if (faceManager != null) {
+ final List<FaceSensorPropertiesInternal> faceProperties =
+ faceManager.getSensorPropertiesInternal();
+ if (!faceProperties.isEmpty()) {
+ final FaceSensorPropertiesInternal props = faceProperties.get(0);
+ return props.sensorStrength != SensorProperties.STRENGTH_CONVENIENCE;
+ }
+ }
+ return false;
+ }
+
+ /**
* Launches an intent which may optionally have a user id defined.
* @param fragment Fragment to use to launch the activity.
* @param intent Intent to launch.
diff --git a/src/com/android/settings/applications/credentials/CredentialsPickerActivity.java b/src/com/android/settings/applications/credentials/CredentialsPickerActivity.java
index 479a184..44dbac0 100644
--- a/src/com/android/settings/applications/credentials/CredentialsPickerActivity.java
+++ b/src/com/android/settings/applications/credentials/CredentialsPickerActivity.java
@@ -54,7 +54,12 @@
@Override
protected void onCreate(Bundle savedInstanceState) {
- injectFragmentIntoIntent(this, getIntent());
+ final String packageName = getCallingPackage();
+ final Intent intent = getIntent();
+
+ intent.putExtra(DefaultCombinedPicker.EXTRA_PACKAGE_NAME, packageName);
+ injectFragmentIntoIntent(this, intent);
+
super.onCreate(savedInstanceState);
}
diff --git a/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java b/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java
index 1b9a70f..5ebe9c7 100644
--- a/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java
+++ b/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java
@@ -229,13 +229,15 @@
}
// Show secondary button once scroll is completed.
- if (!scrollNeeded) {
- if (!enrollmentCompleted) {
- getSecondaryFooterButton().setVisibility(View.VISIBLE);
- }
- mHasScrolledToBottom = true;
- }
+ getSecondaryFooterButton().setVisibility(
+ !scrollNeeded && !enrollmentCompleted ? View.VISIBLE : View.INVISIBLE);
+ mHasScrolledToBottom = !scrollNeeded;
});
+
+ final boolean isScrollNeeded = requireScrollMixin.isScrollingRequired();
+ final boolean enrollmentCompleted = checkMaxEnrolled() != 0;
+ getSecondaryFooterButton().setVisibility(
+ !isScrollNeeded && !enrollmentCompleted ? View.VISIBLE : View.INVISIBLE);
}
@Override
diff --git a/src/com/android/settings/biometrics/face/FaceSettings.java b/src/com/android/settings/biometrics/face/FaceSettings.java
index 197aca0..3398c20 100644
--- a/src/com/android/settings/biometrics/face/FaceSettings.java
+++ b/src/com/android/settings/biometrics/face/FaceSettings.java
@@ -201,8 +201,9 @@
}
mRemoveController.setUserId(mUserId);
- // Don't show keyguard controller for work profile settings.
- if (mUserManager.isManagedProfile(mUserId)) {
+ // Don't show keyguard controller for work and private profile settings.
+ if (mUserManager.isManagedProfile(mUserId)
+ || mUserManager.getUserInfo(mUserId).isPrivateProfile()) {
removePreference(FaceSettingsKeyguardPreferenceController.KEY);
removePreference(mLockscreenController.getPreferenceKey());
}
diff --git a/src/com/android/settings/datausage/DataUsageList.kt b/src/com/android/settings/datausage/DataUsageList.kt
index 3083fb7..1995097 100644
--- a/src/com/android/settings/datausage/DataUsageList.kt
+++ b/src/com/android/settings/datausage/DataUsageList.kt
@@ -34,6 +34,7 @@
import com.android.settings.datausage.lib.BillingCycleRepository
import com.android.settings.datausage.lib.NetworkUsageData
import com.android.settings.network.MobileNetworkRepository
+import com.android.settings.network.SubscriptionUtil
import com.android.settings.network.mobileDataEnabledFlow
import com.android.settingslib.mobile.dataservice.SubscriptionInfoEntity
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
@@ -95,6 +96,18 @@
}
chartDataUsagePreferenceController = use(ChartDataUsagePreferenceController::class.java)
.apply { init(template) }
+
+ updateWarning()
+ }
+
+ private fun updateWarning() {
+ val template = template ?: return
+ val warningPreference = findPreference<Preference>(KEY_WARNING)!!
+ if (template.matchRule != NetworkTemplate.MATCH_WIFI) {
+ warningPreference.setSummary(R.string.operator_warning)
+ } else if (SubscriptionUtil.isSimHardwareVisible(context)) {
+ warningPreference.setSummary(R.string.non_carrier_data_usage_warning)
+ }
}
override fun onViewCreated(v: View, savedInstanceState: Bundle?) {
@@ -188,5 +201,8 @@
private const val TAG = "DataUsageList"
private const val KEY_USAGE_AMOUNT = "usage_amount"
+
+ @VisibleForTesting
+ const val KEY_WARNING = "warning"
}
}
diff --git a/src/com/android/settings/development/AdbQrcodeScannerFragment.java b/src/com/android/settings/development/AdbQrcodeScannerFragment.java
index ca44747..1d38454 100644
--- a/src/com/android/settings/development/AdbQrcodeScannerFragment.java
+++ b/src/com/android/settings/development/AdbQrcodeScannerFragment.java
@@ -16,6 +16,7 @@
package com.android.settings.development;
+import android.annotation.Nullable;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -26,6 +27,7 @@
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
+import android.net.wifi.WifiConfiguration;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
@@ -47,7 +49,6 @@
import com.android.settings.SetupWizardUtils;
import com.android.settings.wifi.dpp.AdbQrCode;
import com.android.settings.wifi.dpp.WifiDppQrCodeBaseFragment;
-import com.android.settings.wifi.dpp.WifiNetworkConfig;
import com.android.settingslib.qrcode.QrCamera;
import com.android.settingslib.qrcode.QrDecorateView;
@@ -81,7 +82,8 @@
/** QR code data scanned by camera */
private AdbQrCode mAdbQrCode;
- private WifiNetworkConfig mAdbConfig;
+ @Nullable
+ private WifiConfiguration mAdbConfig;
private IAdbManager mAdbManager;
@@ -287,13 +289,16 @@
AdbQrCode.triggerVibrationForQrCodeRecognition(getContext());
mVerifyingTextView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
try {
- mAdbManager.enablePairingByQrCode(mAdbConfig.getSsid(),
- mAdbConfig.getPreSharedKey());
+ if (mAdbConfig != null) {
+ mAdbManager.enablePairingByQrCode(mAdbConfig.SSID,
+ mAdbConfig.preSharedKey);
+ return;
+ }
} catch (RemoteException e) {
- Log.e(TAG, "Unable to enable QR code pairing");
- getActivity().setResult(Activity.RESULT_CANCELED);
- getActivity().finish();
+ Log.e(TAG, "Unable to enable QR code pairing" + e);
}
+ getActivity().setResult(Activity.RESULT_CANCELED);
+ getActivity().finish();
}
@Override
diff --git a/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java b/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java
index 54935ec..4906cf2 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java
@@ -30,8 +30,10 @@
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Environment;
import android.os.UserHandle;
import android.os.UserManager;
+import android.os.storage.StorageManager;
import android.provider.MediaStore;
import android.provider.MediaStore.Files.FileColumns;
import android.provider.MediaStore.MediaColumns;
@@ -94,6 +96,7 @@
media /* queryArgs */);
result.audioSize = getFilesSize(info.id, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
media /* queryArgs */);
+ result.systemSize = getSystemSize();
final Bundle documentsAndOtherQueryArgs = new Bundle();
documentsAndOtherQueryArgs.putString(ContentResolver.QUERY_ARG_SQL_SELECTION,
@@ -140,6 +143,16 @@
}
}
+ private long getSystemSize() {
+ try {
+ return mStatsManager.getTotalBytes(StorageManager.UUID_DEFAULT)
+ - Environment.getDataDirectory().getTotalSpace();
+ } catch (IOException e) {
+ Log.e(TAG, "Exception in calculating System category size", e);
+ return 0;
+ }
+ }
+
private StorageResult getAppsAndGamesSize(int userId) {
Log.d(TAG, "Loading apps");
final List<ApplicationInfo> applicationInfos =
@@ -225,6 +238,7 @@
public long videosSize;
public long documentsAndOtherSize;
public long trashSize;
+ public long systemSize;
public long cacheSize;
public long duplicateCodeSize;
diff --git a/src/com/android/settings/deviceinfo/storage/StorageCacheHelper.java b/src/com/android/settings/deviceinfo/storage/StorageCacheHelper.java
index e6da454..50690cb 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageCacheHelper.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageCacheHelper.java
@@ -35,6 +35,7 @@
private static final String DOCUMENTS_AND_OTHER_SIZE_KEY = "documents_and_other_size_key";
private static final String TRASH_SIZE_KEY = "trash_size_key";
private static final String SYSTEM_SIZE_KEY = "system_size_key";
+ private static final String TEMPORARY_FILES_SIZE_KEY = "temporary_files_size_key";
private static final String USED_SIZE_KEY = "used_size_key";
private final SharedPreferences mSharedPreferences;
@@ -66,6 +67,7 @@
.putLong(DOCUMENTS_AND_OTHER_SIZE_KEY, data.documentsAndOtherSize)
.putLong(TRASH_SIZE_KEY, data.trashSize)
.putLong(SYSTEM_SIZE_KEY, data.systemSize)
+ .putLong(TEMPORARY_FILES_SIZE_KEY, data.temporaryFilesSize)
.apply();
}
@@ -109,6 +111,7 @@
result.documentsAndOtherSize = mSharedPreferences.getLong(DOCUMENTS_AND_OTHER_SIZE_KEY, 0);
result.trashSize = mSharedPreferences.getLong(TRASH_SIZE_KEY, 0);
result.systemSize = mSharedPreferences.getLong(SYSTEM_SIZE_KEY, 0);
+ result.temporaryFilesSize = mSharedPreferences.getLong(TEMPORARY_FILES_SIZE_KEY, 0);
return result;
}
@@ -126,5 +129,6 @@
public long documentsAndOtherSize;
public long trashSize;
public long systemSize;
+ public long temporaryFilesSize;
}
}
diff --git a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
index fd42417..62422ca 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
@@ -27,6 +27,7 @@
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
@@ -40,6 +41,7 @@
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.Fragment;
import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
@@ -52,6 +54,7 @@
import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
import com.android.settings.deviceinfo.StorageItemPreference;
import com.android.settings.deviceinfo.storage.StorageUtils.SystemInfoFragment;
+import com.android.settings.deviceinfo.storage.StorageUtils.TemporaryFilesInfoFragment;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -74,6 +77,7 @@
private static final String TAG = "StorageItemPreference";
private static final String SYSTEM_FRAGMENT_TAG = "SystemInfo";
+ private static final String TEMPORARY_FILES_FRAGMENT_TAG = "TemporaryFilesInfo";
@VisibleForTesting
static final String PUBLIC_STORAGE_KEY = "pref_public_storage";
@@ -92,6 +96,10 @@
@VisibleForTesting
static final String SYSTEM_KEY = "pref_system";
@VisibleForTesting
+ static final String TEMPORARY_FILES_KEY = "temporary_files";
+ @VisibleForTesting
+ static final String CATEGORY_SPLITTER = "storage_category_splitter";
+ @VisibleForTesting
static final String TRASH_KEY = "pref_trash";
@VisibleForTesting
@@ -133,9 +141,13 @@
@VisibleForTesting
@Nullable StorageItemPreference mDocumentsAndOtherPreference;
@VisibleForTesting
+ @Nullable StorageItemPreference mTrashPreference;
+ @VisibleForTesting
@Nullable StorageItemPreference mSystemPreference;
@VisibleForTesting
- @Nullable StorageItemPreference mTrashPreference;
+ @Nullable StorageItemPreference mTemporaryFilesPreference;
+ @VisibleForTesting
+ @Nullable PreferenceCategory mCategorySplitterPreferenceCategory;
private final int mProfileType;
@@ -220,6 +232,13 @@
dialog.setTargetFragment(mFragment, 0);
dialog.show(mFragment.getFragmentManager(), SYSTEM_FRAGMENT_TAG);
return true;
+ case TEMPORARY_FILES_KEY:
+ final TemporaryFilesInfoFragment temporaryFilesDialog =
+ new TemporaryFilesInfoFragment();
+ temporaryFilesDialog.setTargetFragment(mFragment, 0);
+ temporaryFilesDialog.show(mFragment.getFragmentManager(),
+ TEMPORARY_FILES_FRAGMENT_TAG);
+ return true;
case TRASH_KEY:
launchTrashIntent();
return true;
@@ -285,6 +304,8 @@
mAppsPreference.setVisible(visible);
mGamesPreference.setVisible(visible);
mSystemPreference.setVisible(visible);
+ mTemporaryFilesPreference.setVisible(visible);
+ mCategorySplitterPreferenceCategory.setVisible(visible);
mTrashPreference.setVisible(visible);
// If we don't have a shared volume for our internal storage (or the shared volume isn't
@@ -315,7 +336,6 @@
mPrivateStorageItemPreferences.add(mAppsPreference);
mPrivateStorageItemPreferences.add(mGamesPreference);
mPrivateStorageItemPreferences.add(mDocumentsAndOtherPreference);
- mPrivateStorageItemPreferences.add(mSystemPreference);
mPrivateStorageItemPreferences.add(mTrashPreference);
}
mScreen.removePreference(mImagesPreference);
@@ -324,7 +344,6 @@
mScreen.removePreference(mAppsPreference);
mScreen.removePreference(mGamesPreference);
mScreen.removePreference(mDocumentsAndOtherPreference);
- mScreen.removePreference(mSystemPreference);
mScreen.removePreference(mTrashPreference);
// Sort display order by size.
@@ -361,6 +380,7 @@
tintPreference(mGamesPreference);
tintPreference(mDocumentsAndOtherPreference);
tintPreference(mSystemPreference);
+ tintPreference(mTemporaryFilesPreference);
tintPreference(mTrashPreference);
}
@@ -389,7 +409,9 @@
mAppsPreference = screen.findPreference(APPS_KEY);
mGamesPreference = screen.findPreference(GAMES_KEY);
mDocumentsAndOtherPreference = screen.findPreference(DOCUMENTS_AND_OTHER_KEY);
+ mCategorySplitterPreferenceCategory = screen.findPreference(CATEGORY_SPLITTER);
mSystemPreference = screen.findPreference(SYSTEM_KEY);
+ mTemporaryFilesPreference = screen.findPreference(TEMPORARY_FILES_KEY);
mTrashPreference = screen.findPreference(TRASH_KEY);
}
@@ -417,6 +439,12 @@
mTrashPreference.setStorageSize(storageCache.trashSize, mTotalSize, animate);
if (mSystemPreference != null) {
mSystemPreference.setStorageSize(storageCache.systemSize, mTotalSize, animate);
+ mSystemPreference.setTitle(mContext.getString(R.string.storage_os_name,
+ Build.VERSION.RELEASE));
+ }
+ if (mTemporaryFilesPreference != null) {
+ mTemporaryFilesPreference.setStorageSize(storageCache.temporaryFilesSize, mTotalSize,
+ animate);
}
// Cache the size info
if (result != null) {
@@ -445,6 +473,7 @@
storageCache.gamesSize = data.gamesSize;
storageCache.documentsAndOtherSize = data.documentsAndOtherSize;
storageCache.trashSize = data.trashSize;
+ storageCache.systemSize = data.systemSize;
// Everything else that hasn't already been attributed is tracked as
// belonging to system.
long attributedSize = 0;
@@ -460,7 +489,9 @@
+ otherData.allAppsExceptGamesSize;
attributedSize -= otherData.duplicateCodeSize;
}
- storageCache.systemSize = Math.max(DataUnit.GIBIBYTES.toBytes(1),
+ // System size is equal for each user and should be added only once
+ attributedSize += data.systemSize;
+ storageCache.temporaryFilesSize = Math.max(DataUnit.GIBIBYTES.toBytes(1),
mUsedBytes - attributedSize);
return storageCache;
}
diff --git a/src/com/android/settings/deviceinfo/storage/StorageUtils.java b/src/com/android/settings/deviceinfo/storage/StorageUtils.java
index 4b6a2c4..5c4a4b4 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageUtils.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageUtils.java
@@ -23,7 +23,6 @@
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
-import android.os.Build;
import android.os.Bundle;
import android.os.storage.DiskInfo;
import android.os.storage.StorageManager;
@@ -34,6 +33,7 @@
import android.util.Log;
import android.widget.Toast;
+import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
@@ -206,7 +206,7 @@
/** Shows information about system storage. */
public static class SystemInfoFragment extends InstrumentedDialogFragment {
/** Shows the fragment. */
- public static void show(Fragment parent) {
+ public static void show(@NonNull Fragment parent) {
if (!parent.isAdded()) return;
final SystemInfoFragment dialog = new SystemInfoFragment();
@@ -222,8 +222,33 @@
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
- .setMessage(getContext().getString(R.string.storage_detail_dialog_system,
- Build.VERSION.RELEASE_OR_PREVIEW_DISPLAY))
+ .setMessage(getContext().getString(R.string.storage_os_detail_dialog_system))
+ .setPositiveButton(android.R.string.ok, null)
+ .create();
+ }
+ }
+
+ /** Shows information about temporary system files. */
+ public static class TemporaryFilesInfoFragment extends InstrumentedDialogFragment {
+ /** Shows the fragment. */
+ public static void show(@NonNull Fragment parent) {
+ if (!parent.isAdded()) return;
+
+ final TemporaryFilesInfoFragment dialog = new TemporaryFilesInfoFragment();
+ dialog.setTargetFragment(parent, 0);
+ dialog.show(parent.getFragmentManager(), "temporaryFilesInfo");
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return SettingsEnums.DIALOG_TEMPORARY_FILES_INFO;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ return new AlertDialog.Builder(getActivity())
+ .setMessage(getContext().getString(
+ R.string.storage_other_files_detail_dialog_system))
.setPositiveButton(android.R.string.ok, null)
.create();
}
diff --git a/src/com/android/settings/network/WepNetworkDialogActivity.kt b/src/com/android/settings/network/WepNetworkDialogActivity.kt
index fef93ef..d6fa795 100644
--- a/src/com/android/settings/network/WepNetworkDialogActivity.kt
+++ b/src/com/android/settings/network/WepNetworkDialogActivity.kt
@@ -27,18 +27,21 @@
import com.android.settings.R
import com.android.settings.core.SubSettingLauncher
import com.android.settings.wifi.ConfigureWifiSettings
-import com.android.settingslib.spa.SpaBaseDialogActivity
+import com.android.settingslib.spa.SpaDialogWindowTypeActivity
import com.android.settingslib.spa.widget.dialog.AlertDialogButton
-import com.android.settingslib.spa.widget.dialog.SettingsAlertDialogWithIcon
+import com.android.settingslib.spa.widget.dialog.SettingsAlertDialogContent
import com.android.settingslib.wifi.WifiUtils.Companion.SSID
-class WepNetworkDialogActivity : SpaBaseDialogActivity() {
+class WepNetworkDialogActivity : SpaDialogWindowTypeActivity() {
+
+ // TODO: Set different window type when called from Quick Settings.
+ override val dialogWindowType = null
+
@Composable
override fun Content() {
val context = LocalContext.current
val wifiManager = context.getSystemService(WifiManager::class.java)
- SettingsAlertDialogWithIcon(
- onDismissRequest = { finish() },
+ SettingsAlertDialogContent(
confirmButton = AlertDialogButton(
getString(R.string.wifi_settings_ssid_block_button_close)
) { finish() },
@@ -67,4 +70,4 @@
)
})
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/settings/network/telephony/EuiccRacConnectivityDialogActivity.java b/src/com/android/settings/network/telephony/EuiccRacConnectivityDialogActivity.java
index d439d4f..aaf98f1 100644
--- a/src/com/android/settings/network/telephony/EuiccRacConnectivityDialogActivity.java
+++ b/src/com/android/settings/network/telephony/EuiccRacConnectivityDialogActivity.java
@@ -16,6 +16,7 @@
package com.android.settings.network.telephony;
+import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
@@ -28,20 +29,21 @@
import com.android.settings.R;
import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
/** This dialog activity advise the user to have connectivity if the eSIM uses a RAC. */
public class EuiccRacConnectivityDialogActivity extends FragmentActivity
implements WarningDialogFragment.OnConfirmListener {
private static final String TAG = "EuiccRacConnectivityDialogActivity";
- // Dialog tags
- private static final int DIALOG_TAG_ERASE_ANYWAY_CONFIRMATION = 1;
private static final String ARG_SUB_ID = "sub_id";
private static final String ARG_RESET_MOBILE_NETWORK_ID = "reset_mobile_netword_id";
private int mSubId;
@Nullable
private Intent mResetMobileNetworkIntent;
+ private MetricsFeatureProvider mMetricsFeatureProvider;
/**
* Returns an intent of EuiccRacConnectivityDialogActivity for Settings: erase eSIM.
@@ -80,6 +82,7 @@
mSubId = intent.getIntExtra(ARG_SUB_ID, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
mResetMobileNetworkIntent =
intent.getParcelableExtra(ARG_RESET_MOBILE_NETWORK_ID, Intent.class);
+ mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
if (savedInstanceState == null) {
showConnectivityWarningDialog();
@@ -88,20 +91,26 @@
@Override
public void onConfirm(int tag, boolean confirmed) {
+ if (tag == SettingsEnums.ACTION_SETTINGS_ESIM_RAC_CONNECTIVITY_WARNING
+ || tag == SettingsEnums.ACTION_RESET_MOBILE_NETWORK_RAC_CONNECTIVITY_WARNING) {
+ mMetricsFeatureProvider.action(this, tag, confirmed ? 1 : 0);
+ }
+
if (!confirmed) {
finish();
return;
}
+ finish();
switch (tag) {
- case DIALOG_TAG_ERASE_ANYWAY_CONFIRMATION:
- finish();
+ case SettingsEnums.ACTION_SETTINGS_ESIM_RAC_CONNECTIVITY_WARNING:
+ Log.i(TAG, "Show dialogue activity that handles deleting eSIM profile");
+ startActivity(DeleteEuiccSubscriptionDialogActivity.getIntent(this, mSubId));
+ break;
+ case SettingsEnums.ACTION_RESET_MOBILE_NETWORK_RAC_CONNECTIVITY_WARNING:
if (mResetMobileNetworkIntent != null) {
Log.i(TAG, "Show fragment activity that handles mobile network settings reset");
new SubSettingLauncher(this).launchWithIntent(mResetMobileNetworkIntent);
- } else {
- Log.i(TAG, "Show dialogue activity that handles deleting eSIM profiles");
- startActivity(DeleteEuiccSubscriptionDialogActivity.getIntent(this, mSubId));
}
break;
default:
@@ -115,10 +124,19 @@
WarningDialogFragment.show(
this,
WarningDialogFragment.OnConfirmListener.class,
- DIALOG_TAG_ERASE_ANYWAY_CONFIRMATION,
+ getMetricsTag(),
getString(R.string.wifi_warning_dialog_title),
getString(R.string.wifi_warning_dialog_text),
getString(R.string.wifi_warning_continue_button),
getString(R.string.wifi_warning_return_button));
}
+
+ /* Get the metrics tag depending on the intent. */
+ private int getMetricsTag() {
+ if (mResetMobileNetworkIntent != null) {
+ return SettingsEnums.ACTION_RESET_MOBILE_NETWORK_RAC_CONNECTIVITY_WARNING;
+ } else {
+ return SettingsEnums.ACTION_SETTINGS_ESIM_RAC_CONNECTIVITY_WARNING;
+ }
+ }
}
diff --git a/src/com/android/settings/privatespace/AutoAdvanceSetupFragment.java b/src/com/android/settings/privatespace/AutoAdvanceSetupFragment.java
index 7d551ee..14627ec 100644
--- a/src/com/android/settings/privatespace/AutoAdvanceSetupFragment.java
+++ b/src/com/android/settings/privatespace/AutoAdvanceSetupFragment.java
@@ -60,7 +60,7 @@
private static final int ANIMATION_DURATION_MILLIS = 500;
private static final int HEADER_TEXT_MAX_LINES = 4;
private GlifLayout mRootView;
- private Handler mHandler;
+ private static final Handler sHandler = new Handler(Looper.getMainLooper());
private int mScreenTitleIndex;
private static final List<Pair<Integer, Integer>> HEADER_ILLUSTRATION_PAIRS =
ImmutableList.of(
@@ -78,7 +78,7 @@
if (getActivity() != null) {
if (++mScreenTitleIndex < HEADER_ILLUSTRATION_PAIRS.size()) {
startFadeOutAnimation();
- mHandler.postDelayed(mUpdateScreenResources, DELAY_BETWEEN_SCREENS);
+ sHandler.postDelayed(mUpdateScreenResources, DELAY_BETWEEN_SCREENS);
} else if (PrivateSpaceMaintainer.getInstance(getActivity())
.doesPrivateSpaceExist()) {
mMetricsFeatureProvider.action(
@@ -133,8 +133,6 @@
mRootView.getHeaderTextView().setBreakStrategy(BREAK_STRATEGY_SIMPLE);
mRootView.getHeaderTextView().setAccessibilityLiveRegion(ACCESSIBILITY_LIVE_REGION_POLITE);
updateHeaderAndIllustration();
- mHandler = new Handler(Looper.getMainLooper());
- mHandler.postDelayed(mUpdateScreenResources, DELAY_BETWEEN_SCREENS);
OnBackPressedCallback callback =
new OnBackPressedCallback(true /* enabled by default */) {
@Override
@@ -155,13 +153,17 @@
@Override
public void onDestroy() {
- if (mHandler != null) {
- mHandler.removeCallbacks(mUpdateScreenResources);
- }
+ sHandler.removeCallbacks(mUpdateScreenResources);
super.onDestroy();
}
@Override
+ public void onResume() {
+ sHandler.postDelayed(mUpdateScreenResources, DELAY_BETWEEN_SCREENS);
+ super.onResume();
+ }
+
+ @Override
public int getMetricsCategory() {
return SettingsEnums.PRIVATE_SPACE_SETUP_SPACE_CREATION;
}
diff --git a/src/com/android/settings/privatespace/HidePrivateSpaceSensitiveNotificationsController.java b/src/com/android/settings/privatespace/HidePrivateSpaceSensitiveNotificationsController.java
deleted file mode 100644
index 6cb54a1..0000000
--- a/src/com/android/settings/privatespace/HidePrivateSpaceSensitiveNotificationsController.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * 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.privatespace;
-
-import static android.provider.Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS;
-
-import android.content.Context;
-import android.os.UserHandle;
-import android.provider.Settings;
-
-import androidx.annotation.NonNull;
-
-import com.android.settings.core.TogglePreferenceController;
-
-import java.util.Objects;
-
-/**
- * A controller object for sensitive notifications in Private Space settings page.
- */
-public class HidePrivateSpaceSensitiveNotificationsController extends TogglePreferenceController {
- private final PrivateSpaceMaintainer mPrivateSpaceMaintainer;
- private final UserHandle mPrivateProfileId;
- public static final int ENABLED = 1;
- public static final int DISABLED = 0;
- private static final int DEVICE_SENSITIVE_NOTIFICATIONS_DEFAULT = ENABLED;
- private static final int DEVICE_LOCK_SCREEN_NOTIFICATIONS_DEFAULT = ENABLED;
- private static final int PRIVATE_SPACE_SENSITIVE_NOTIFICATIONS_DEFAULT = DISABLED;
-
- public HidePrivateSpaceSensitiveNotificationsController(@NonNull Context context,
- @NonNull String preferenceKey) {
- super(context, preferenceKey);
- mPrivateSpaceMaintainer = PrivateSpaceMaintainer.getInstance(context);
- mPrivateProfileId = Objects.requireNonNull(
- mPrivateSpaceMaintainer.getPrivateProfileHandle());
- }
-
- @Override
- public int getAvailabilityStatus() {
- if (!android.os.Flags.allowPrivateProfile()
- || !android.multiuser.Flags.enablePsSensitiveNotificationsToggle()
- || !android.multiuser.Flags.enablePrivateSpaceFeatures()
- || !mPrivateSpaceMaintainer.doesPrivateSpaceExist()) {
- return UNSUPPORTED_ON_DEVICE;
- }
- if (!getLockscreenNotificationsEnabled(mContext)
- || !getLockscreenSensitiveNotificationsEnabledOnDevice(mContext)) {
- return DISABLED_DEPENDENT_SETTING;
- }
- return AVAILABLE;
- }
-
- @Override
- public boolean isChecked() {
- return Settings.Secure.getIntForUser(mContext.getContentResolver(),
- LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
- PRIVATE_SPACE_SENSITIVE_NOTIFICATIONS_DEFAULT, mPrivateProfileId.getIdentifier())
- != DISABLED;
- }
-
- @Override
- public boolean setChecked(boolean isChecked) {
- Settings.Secure.putIntForUser(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
- isChecked ? ENABLED : DISABLED, mPrivateProfileId.getIdentifier());
- return true;
- }
-
- @Override
- public int getSliceHighlightMenuRes() {
- return 0;
- }
-
- /**
- * If notifications are disabled on the device, the toggle for private space sensitive
- * notifications should be unavailable.
- */
- private static boolean getLockscreenNotificationsEnabled(Context context) {
- return Settings.Secure.getInt(context.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
- DEVICE_LOCK_SCREEN_NOTIFICATIONS_DEFAULT) != DISABLED;
- }
-
- /**
- * If sensitive notifications are hidden on the device, they should be hidden for private space
- * also.
- */
- private static boolean getLockscreenSensitiveNotificationsEnabledOnDevice(Context context) {
- return Settings.Secure.getInt(context.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
- DEVICE_SENSITIVE_NOTIFICATIONS_DEFAULT) != DISABLED;
- }
-}
diff --git a/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java b/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java
index a0c4cbe..2ca22d1 100644
--- a/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java
+++ b/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java
@@ -23,20 +23,21 @@
import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
import android.app.ActivityManager;
-import android.app.IActivityManager;
import android.app.KeyguardManager;
+import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.pm.UserInfo;
import android.os.Flags;
-import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.util.ArraySet;
import android.util.Log;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
@@ -54,9 +55,12 @@
private final Context mContext;
private final UserManager mUserManager;
+ private final ActivityManager mActivityManager;
@GuardedBy("this")
private UserHandle mUserHandle;
private final KeyguardManager mKeyguardManager;
+ /** This variable should be accessed via {@link #getBroadcastReceiver()} only. */
+ @Nullable private ProfileAvailabilityBroadcastReceiver mProfileAvailabilityBroadcastReceiver;
/** This is the default value for the hide private space entry point settings. */
public static final int HIDE_PRIVATE_SPACE_ENTRY_POINT_DISABLED_VAL = 0;
@@ -65,6 +69,8 @@
@Settings.Secure.PrivateSpaceAutoLockOption
public static final int PRIVATE_SPACE_AUTO_LOCK_DEFAULT_VAL =
PRIVATE_SPACE_AUTO_LOCK_AFTER_DEVICE_RESTART;
+ /** Default value for the hide private space sensitive notifications on lockscreen. */
+ public static final int HIDE_PRIVATE_SPACE_SENSITIVE_NOTIFICATIONS_DISABLED_VAL = 0;
public enum ErrorDeletingPrivateSpace {
DELETE_PS_ERROR_NONE,
@@ -104,12 +110,13 @@
return false;
}
- IActivityManager am = ActivityManager.getService();
+ registerBroadcastReceiver();
+
try {
//TODO(b/313926659): To check and handle failure of startProfile
- am.startProfile(mUserHandle.getIdentifier());
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to start private profile");
+ mActivityManager.startProfile(mUserHandle);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Unexpected that " + mUserHandle.getIdentifier() + " is not a profile");
return false;
}
@@ -134,6 +141,7 @@
Log.i(TAG, "Deleting Private space with id: " + mUserHandle.getIdentifier());
if (mUserManager.removeUser(mUserHandle)) {
Log.i(TAG, "Private space deleted");
+ unregisterBroadcastReceiver();
mUserHandle = null;
return ErrorDeletingPrivateSpace.DELETE_PS_ERROR_NONE;
@@ -160,6 +168,7 @@
for (UserInfo user : users) {
if (user.isPrivateProfile()) {
mUserHandle = user.getUserHandle();
+ registerBroadcastReceiver();
return true;
}
}
@@ -213,6 +222,7 @@
mContext = context.getApplicationContext();
mUserManager = mContext.getSystemService(UserManager.class);
mKeyguardManager = mContext.getSystemService(KeyguardManager.class);
+ mActivityManager = mContext.getSystemService(ActivityManager.class);
}
@@ -287,6 +297,14 @@
}
}
+ /**
+ * Returns true if private profile can be added to the device or if private space already
+ * exists, false otherwise.
+ */
+ public boolean isPrivateSpaceEntryPointEnabled() {
+ return mUserManager.canAddPrivateProfile() || doesPrivateSpaceExist();
+ }
+
/** Returns true if private space exists and is running, otherwise returns false */
@VisibleForTesting
synchronized boolean isPrivateProfileRunning() {
@@ -308,7 +326,7 @@
private void setPrivateSpaceSensitiveNotificationsDefaultValue() {
Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
- HidePrivateSpaceSensitiveNotificationsController.DISABLED,
+ HIDE_PRIVATE_SPACE_SENSITIVE_NOTIFICATIONS_DISABLED_VAL,
mUserHandle.getIdentifier());
}
@@ -328,4 +346,91 @@
&& android.multiuser.Flags.supportAutolockForPrivateSpace()
&& android.multiuser.Flags.enablePrivateSpaceFeatures();
}
+
+ /** {@link BroadcastReceiver} which handles the private profile's availability related
+ * broadcasts.
+ */
+ private final class ProfileAvailabilityBroadcastReceiver extends BroadcastReceiver {
+ void register() {
+ Log.d(TAG, "Registering the receiver");
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_PROFILE_UNAVAILABLE);
+ mContext.registerReceiver(/* receiver= */ this, filter, Context.RECEIVER_NOT_EXPORTED);
+ }
+
+ void unregister() {
+ Log.d(TAG, "Unregistering the receiver");
+ mContext.unregisterReceiver(/* receiver= */ this);
+ }
+
+ @Override
+ public void onReceive(@NonNull Context context, @NonNull Intent intent) {
+ UserHandle userHandle = intent.getParcelableExtra(Intent.EXTRA_USER, UserHandle.class);
+ if (!userHandle.equals(getPrivateProfileHandle())) {
+ Log.d(TAG, "Ignoring intent for non-private profile with user id "
+ + userHandle.getIdentifier());
+ return;
+ }
+
+ Log.i(TAG, "Removing all Settings tasks.");
+ removeSettingsAllTasks();
+ }
+ }
+
+ private synchronized void registerBroadcastReceiver() {
+ if (!android.os.Flags.allowPrivateProfile()
+ || !android.multiuser.Flags.enablePrivateSpaceFeatures()) {
+ return;
+ }
+ var broadcastReceiver = getBroadcastReceiver();
+ if (broadcastReceiver == null) {
+ return;
+ }
+ broadcastReceiver.register();
+ }
+
+ private synchronized void unregisterBroadcastReceiver() {
+ if (!android.os.Flags.allowPrivateProfile()
+ || !android.multiuser.Flags.enablePrivateSpaceFeatures()) {
+ return;
+ }
+ if (mProfileAvailabilityBroadcastReceiver == null) {
+ Log.w(TAG, "Requested to unregister when there is no receiver.");
+ return;
+ }
+ mProfileAvailabilityBroadcastReceiver.unregister();
+ mProfileAvailabilityBroadcastReceiver = null;
+ }
+
+ /** Always use this getter to access {@link #mProfileAvailabilityBroadcastReceiver}. */
+ @VisibleForTesting
+ @Nullable synchronized ProfileAvailabilityBroadcastReceiver getBroadcastReceiver() {
+ if (!android.os.Flags.allowPrivateProfile()
+ || !android.multiuser.Flags.enablePrivateSpaceFeatures()) {
+ return null;
+ }
+ if (!doesPrivateSpaceExist()) {
+ Log.e(TAG, "Cannot return a broadcast receiver when private space doesn't exist");
+ return null;
+ }
+ if (mProfileAvailabilityBroadcastReceiver == null) {
+ mProfileAvailabilityBroadcastReceiver = new ProfileAvailabilityBroadcastReceiver();
+ }
+ return mProfileAvailabilityBroadcastReceiver;
+ }
+
+ /** This is purely for testing purpose only, and should not be used elsewhere. */
+ @VisibleForTesting
+ synchronized void resetBroadcastReceiver() {
+ mProfileAvailabilityBroadcastReceiver = null;
+ }
+
+ private void removeSettingsAllTasks() {
+ List<ActivityManager.AppTask> appTasks = mActivityManager.getAppTasks();
+ for (var appTask : appTasks) {
+ if (!appTask.getTaskInfo().isVisible()) {
+ appTask.finishAndRemoveTask();
+ }
+ }
+ }
}
diff --git a/src/com/android/settings/privatespace/PrivateSpaceSafetySource.java b/src/com/android/settings/privatespace/PrivateSpaceSafetySource.java
index 3272f12..9a01853 100644
--- a/src/com/android/settings/privatespace/PrivateSpaceSafetySource.java
+++ b/src/com/android/settings/privatespace/PrivateSpaceSafetySource.java
@@ -52,9 +52,7 @@
// Do not add the entry point when
// -Private Profile is not present and
// -Private Profile cannot be added.
- if (!privateSpaceMaintainer.doesPrivateSpaceExist()
- && userManager != null
- && !userManager.canAddPrivateProfile()) {
+ if (!privateSpaceMaintainer.isPrivateSpaceEntryPointEnabled()) {
Log.i(TAG, "Private Space not allowed for user " + context.getUser());
return;
}
diff --git a/src/com/android/settings/privatespace/PrivateSpaceSetLockFragment.java b/src/com/android/settings/privatespace/PrivateSpaceSetLockFragment.java
index 399c2c8..11f4bcb 100644
--- a/src/com/android/settings/privatespace/PrivateSpaceSetLockFragment.java
+++ b/src/com/android/settings/privatespace/PrivateSpaceSetLockFragment.java
@@ -97,7 +97,7 @@
getContext(), SettingsEnums.ACTION_PRIVATE_SPACE_SETUP_USE_SCREEN_LOCK);
// Simply Use default screen lock. No need to handle
NavHostFragment.findNavController(PrivateSpaceSetLockFragment.this)
- .navigate(R.id.action_lock_success_fragment);
+ .navigate(R.id.action_pre_finish_delay_fragment);
};
}
diff --git a/src/com/android/settings/privatespace/PrivateSpaceSetupActivity.java b/src/com/android/settings/privatespace/PrivateSpaceSetupActivity.java
index ec7132a..4cbcac7 100644
--- a/src/com/android/settings/privatespace/PrivateSpaceSetupActivity.java
+++ b/src/com/android/settings/privatespace/PrivateSpaceSetupActivity.java
@@ -60,7 +60,7 @@
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if (requestCode == SET_LOCK_ACTION && resultCode == RESULT_OK) {
- mNavHostFragment.getNavController().navigate(R.id.action_success_fragment);
+ mNavHostFragment.getNavController().navigate(R.id.action_pre_finish_delay_fragment);
} else if (requestCode == ACCOUNT_LOGIN_ACTION) {
if (resultCode == RESULT_OK) {
mMetricsFeatureProvider.action(
diff --git a/src/com/android/settings/privatespace/SetupPreFinishDelayFragment.java b/src/com/android/settings/privatespace/SetupPreFinishDelayFragment.java
new file mode 100644
index 0000000..aee8512
--- /dev/null
+++ b/src/com/android/settings/privatespace/SetupPreFinishDelayFragment.java
@@ -0,0 +1,136 @@
+/*
+ * 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.privatespace;
+
+import static android.content.Intent.ACTION_PROFILE_INACCESSIBLE;
+import static android.content.Intent.ACTION_PROFILE_UNAVAILABLE;
+
+import android.app.settings.SettingsEnums;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.activity.OnBackPressedCallback;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.navigation.fragment.NavHostFragment;
+
+import com.android.settings.R;
+import com.android.settings.core.InstrumentedFragment;
+
+import com.google.android.setupdesign.GlifLayout;
+
+public class SetupPreFinishDelayFragment extends InstrumentedFragment {
+ private static final String TAG = "SetupPreFinishDelayFrag";
+ private static final Handler sHandler = new Handler(Looper.getMainLooper());
+ private static final int MAX_DELAY_BEFORE_SETUP_FINISH = 5000;
+ private boolean mActionProfileUnavailable;
+ private boolean mActionProfileInaccessible;
+
+ protected final BroadcastReceiver mBroadcastReceiver =
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent == null) {
+ return;
+ }
+ String action = intent.getAction();
+ Log.i(TAG, "Received broadcast: " + action);
+ if (ACTION_PROFILE_UNAVAILABLE.equals(action)) {
+ mActionProfileUnavailable = true;
+ } else if (ACTION_PROFILE_INACCESSIBLE.equals(action)) {
+ mActionProfileInaccessible = true;
+ }
+ if (mActionProfileUnavailable && mActionProfileInaccessible) {
+ showSetupSuccessScreen();
+ }
+ }
+ };
+
+ private Runnable mRunnable =
+ () -> {
+ showSetupSuccessScreen();
+ };
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ if (android.os.Flags.allowPrivateProfile()
+ && android.multiuser.Flags.enablePrivateSpaceFeatures()) {
+ super.onCreate(savedInstanceState);
+ }
+ }
+
+ @NonNull
+ @Override
+ public View onCreateView(
+ @NonNull LayoutInflater inflater,
+ @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
+ GlifLayout rootView =
+ (GlifLayout)
+ inflater.inflate(R.layout.private_space_pre_finish_delay, container, false);
+ OnBackPressedCallback callback =
+ new OnBackPressedCallback(true /* enabled by default */) {
+ @Override
+ public void handleOnBackPressed() {
+ // Handle the back button event. We intentionally don't want to allow back
+ // button to work in this screen during the setup flow.
+ }
+ };
+ requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);
+ if (savedInstanceState == null) {
+ // TODO(b/307729746): Add a test to verify PS is locked after setup completion.
+ PrivateSpaceMaintainer.getInstance(getActivity()).lockPrivateSpace();
+ }
+ return rootView;
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ getActivity().unregisterReceiver(mBroadcastReceiver);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ final IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(ACTION_PROFILE_UNAVAILABLE);
+ intentFilter.addAction(ACTION_PROFILE_INACCESSIBLE);
+ getActivity().registerReceiver(mBroadcastReceiver, intentFilter);
+ sHandler.postDelayed(mRunnable, MAX_DELAY_BEFORE_SETUP_FINISH);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return SettingsEnums.PRIVATE_SPACE_SETUP_PRE_FINISH;
+ }
+
+ private void showSetupSuccessScreen() {
+ sHandler.removeCallbacks(mRunnable);
+ NavHostFragment.findNavController(SetupPreFinishDelayFragment.this)
+ .navigate(R.id.action_success_fragment);
+ }
+}
diff --git a/src/com/android/settings/privatespace/SetupSuccessFragment.java b/src/com/android/settings/privatespace/SetupSuccessFragment.java
index c0a2cd4..90be48e 100644
--- a/src/com/android/settings/privatespace/SetupSuccessFragment.java
+++ b/src/com/android/settings/privatespace/SetupSuccessFragment.java
@@ -87,8 +87,6 @@
if (activity != null) {
mMetricsFeatureProvider.action(
getContext(), SettingsEnums.ACTION_PRIVATE_SPACE_SETUP_DONE);
- //TODO(b/307729746): Add a test to verify PS is locked after setup completion.
- PrivateSpaceMaintainer.getInstance(activity).lockPrivateSpace();
Intent allAppsIntent = new Intent(Intent.ACTION_ALL_APPS);
ResolveInfo resolveInfo =
activity.getPackageManager()
diff --git a/src/com/android/settings/privatespace/delete/ResetOptionsDeletePrivateSpaceController.java b/src/com/android/settings/privatespace/delete/ResetOptionsDeletePrivateSpaceController.java
index 274bb2b..6e1f0df 100644
--- a/src/com/android/settings/privatespace/delete/ResetOptionsDeletePrivateSpaceController.java
+++ b/src/com/android/settings/privatespace/delete/ResetOptionsDeletePrivateSpaceController.java
@@ -59,10 +59,9 @@
@Override
public int getAvailabilityStatus() {
- // TODO(b/330396315) : use canAddPrivateProfile() to check if private space is supported
- // on the device
return android.multiuser.Flags.enablePrivateSpaceFeatures()
&& android.multiuser.Flags.deletePrivateSpaceFromReset()
+ && isPrivateSpaceEntryPointEnabled()
? AVAILABLE
: UNSUPPORTED_ON_DEVICE;
}
@@ -107,6 +106,11 @@
return mHostFragment.getFragmentManager();
}
+ @VisibleForTesting
+ boolean isPrivateSpaceEntryPointEnabled() {
+ return PrivateSpaceMaintainer.getInstance(mContext).isPrivateSpaceEntryPointEnabled();
+ }
+
/* Dialog shown when deleting private space from Reset Options. */
public static class DeletePrivateSpaceDialogFragment extends InstrumentedDialogFragment {
private static final String TAG = "PrivateSpaceResetFrag";
diff --git a/src/com/android/settings/privatespace/onelock/PrivateSpaceFacePreferenceController.java b/src/com/android/settings/privatespace/onelock/PrivateSpaceFacePreferenceController.java
index 583a093..6ccaacb 100644
--- a/src/com/android/settings/privatespace/onelock/PrivateSpaceFacePreferenceController.java
+++ b/src/com/android/settings/privatespace/onelock/PrivateSpaceFacePreferenceController.java
@@ -64,8 +64,8 @@
@Override
public int getAvailabilityStatus() {
return android.os.Flags.allowPrivateProfile()
- && android.multiuser.Flags.enableBiometricsToUnlockPrivateSpace()
- && android.multiuser.Flags.enablePrivateSpaceFeatures()
+ && android.multiuser.Flags.enableBiometricsToUnlockPrivateSpace()
+ && android.multiuser.Flags.enablePrivateSpaceFeatures()
? AVAILABLE
: UNSUPPORTED_ON_DEVICE;
}
@@ -87,7 +87,8 @@
public void displayPreference(@NonNull PreferenceScreen screen) {
super.displayPreference(screen);
Preference preference = screen.findPreference(getPreferenceKey());
- if (!Utils.isMultipleBiometricsSupported(mContext)) {
+ if (!Utils.isMultipleBiometricsSupported(mContext)
+ && Utils.isFaceNotConvenienceBiometric(mContext)) {
preference.setTitle(R.string.private_space_face_title);
}
}
diff --git a/src/com/android/settings/privatespace/onelock/PrivateSpaceFingerprintPreferenceController.java b/src/com/android/settings/privatespace/onelock/PrivateSpaceFingerprintPreferenceController.java
index f88c9fa..dd6518a 100644
--- a/src/com/android/settings/privatespace/onelock/PrivateSpaceFingerprintPreferenceController.java
+++ b/src/com/android/settings/privatespace/onelock/PrivateSpaceFingerprintPreferenceController.java
@@ -66,8 +66,8 @@
@Override
public int getAvailabilityStatus() {
return android.os.Flags.allowPrivateProfile()
- && android.multiuser.Flags.enableBiometricsToUnlockPrivateSpace()
- && android.multiuser.Flags.enablePrivateSpaceFeatures()
+ && android.multiuser.Flags.enableBiometricsToUnlockPrivateSpace()
+ && android.multiuser.Flags.enablePrivateSpaceFeatures()
? AVAILABLE
: UNSUPPORTED_ON_DEVICE;
}
@@ -89,7 +89,8 @@
public void displayPreference(@NonNull PreferenceScreen screen) {
super.displayPreference(screen);
Preference preference = screen.findPreference(getPreferenceKey());
- if (!Utils.isMultipleBiometricsSupported(mContext)) {
+ if (!Utils.isMultipleBiometricsSupported(mContext)
+ || !Utils.isFaceNotConvenienceBiometric(mContext)) {
preference.setTitle(R.string.private_space_fingerprint_title);
}
}
diff --git a/src/com/android/settings/privatespace/onelock/UseOneLockSettingsFragment.java b/src/com/android/settings/privatespace/onelock/UseOneLockSettingsFragment.java
index ce017e3..bf5748e 100644
--- a/src/com/android/settings/privatespace/onelock/UseOneLockSettingsFragment.java
+++ b/src/com/android/settings/privatespace/onelock/UseOneLockSettingsFragment.java
@@ -73,13 +73,14 @@
final List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(new UseOneLockControllerSwitch(context, this));
controllers.add(new PrivateSpaceLockController(context, this));
- if (Utils.isMultipleBiometricsSupported(context)) {
+ boolean isFaceAuthAllowed = Utils.isFaceNotConvenienceBiometric(context);
+ if (Utils.isMultipleBiometricsSupported(context) && isFaceAuthAllowed) {
controllers.add(new FaceFingerprintUnlockController(context, getSettingsLifecycle()));
} else if (Utils.hasFingerprintHardware(context)) {
controllers.add(
new PrivateSpaceFingerprintPreferenceController(
context, "private_space_biometrics", getSettingsLifecycle()));
- } else if (Utils.hasFaceHardware(context)) {
+ } else if (Utils.hasFaceHardware(context) && isFaceAuthAllowed) {
controllers.add(
new PrivateSpaceFacePreferenceController(
context, "private_space_biometrics", getSettingsLifecycle()));
diff --git a/src/com/android/settings/spa/SettingsSpaEnvironment.kt b/src/com/android/settings/spa/SettingsSpaEnvironment.kt
index f701323..b844d44 100644
--- a/src/com/android/settings/spa/SettingsSpaEnvironment.kt
+++ b/src/com/android/settings/spa/SettingsSpaEnvironment.kt
@@ -41,7 +41,6 @@
import com.android.settings.spa.app.specialaccess.SpecialAppAccessPageProvider
import com.android.settings.spa.app.specialaccess.TurnScreenOnAppsAppListProvider
import com.android.settings.spa.app.specialaccess.UseFullScreenIntentAppListProvider
-import com.android.settings.spa.app.specialaccess.VoiceActivationAppsListProvider
import com.android.settings.spa.app.specialaccess.WifiControlAppListProvider
import com.android.settings.spa.app.storage.StorageAppListPageProvider
import com.android.settings.spa.core.instrumentation.SpaLogProvider
@@ -76,7 +75,6 @@
PictureInPictureListProvider,
InstallUnknownAppsListProvider,
AlarmsAndRemindersAppListProvider,
- VoiceActivationAppsListProvider,
WifiControlAppListProvider,
NfcTagAppsSettingsProvider,
LongBackgroundTasksAppListProvider,
diff --git a/src/com/android/settings/spa/app/appinfo/AppInfoSettings.kt b/src/com/android/settings/spa/app/appinfo/AppInfoSettings.kt
index c12915c..2fd8fc5 100644
--- a/src/com/android/settings/spa/app/appinfo/AppInfoSettings.kt
+++ b/src/com/android/settings/spa/app/appinfo/AppInfoSettings.kt
@@ -43,7 +43,6 @@
import com.android.settings.spa.app.specialaccess.InstallUnknownAppsListProvider
import com.android.settings.spa.app.specialaccess.ModifySystemSettingsAppListProvider
import com.android.settings.spa.app.specialaccess.PictureInPictureListProvider
-import com.android.settings.spa.app.specialaccess.VoiceActivationAppsListProvider
import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.compose.navigator
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
@@ -167,9 +166,6 @@
InstallUnknownAppsListProvider.InfoPageEntryItem(app)
InteractAcrossProfilesDetailsPreference(app)
AlarmsAndRemindersAppListProvider.InfoPageEntryItem(app)
- if (Flags.enableVoiceActivationAppsInSettings()) {
- VoiceActivationAppsListProvider.InfoPageEntryItem(app)
- }
if (Flags.enablePerformBackupTasksInSettings()) {
BackupTasksAppsListProvider.InfoPageEntryItem(app)
}
diff --git a/src/com/android/settings/spa/app/specialaccess/SpecialAppAccess.kt b/src/com/android/settings/spa/app/specialaccess/SpecialAppAccess.kt
index 4f79173..aabc9f8 100644
--- a/src/com/android/settings/spa/app/specialaccess/SpecialAppAccess.kt
+++ b/src/com/android/settings/spa/app/specialaccess/SpecialAppAccess.kt
@@ -67,7 +67,6 @@
PictureInPictureListProvider,
InstallUnknownAppsListProvider,
AlarmsAndRemindersAppListProvider,
- VoiceActivationAppsListProvider,
WifiControlAppListProvider,
LongBackgroundTasksAppListProvider,
TurnScreenOnAppsAppListProvider,
diff --git a/src/com/android/settings/spa/app/specialaccess/VoiceActivationApps.kt b/src/com/android/settings/spa/app/specialaccess/VoiceActivationApps.kt
deleted file mode 100644
index 1225806..0000000
--- a/src/com/android/settings/spa/app/specialaccess/VoiceActivationApps.kt
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.spa.app.specialaccess
-
-import android.Manifest
-import android.app.AppOpsManager
-import android.app.settings.SettingsEnums
-import android.content.Context
-import com.android.settings.R
-import com.android.settings.overlay.FeatureFactory
-import com.android.settingslib.spaprivileged.model.app.PackageManagers.hasGrantPermission
-import com.android.settingslib.spaprivileged.template.app.AppOpPermissionListModel
-import com.android.settingslib.spaprivileged.template.app.AppOpPermissionRecord
-import com.android.settingslib.spaprivileged.template.app.TogglePermissionAppListProvider
-
-/**
- * This class builds an App List under voice activation apps and the individual page which
- * allows the user to toggle voice activation related permissions on / off for the apps displayed
- * in the list.
- */
-object VoiceActivationAppsListProvider : TogglePermissionAppListProvider {
- override val permissionType = "VoiceActivationApps"
- override fun createModel(context: Context) = VoiceActivationAppsListModel(context)
-}
-
-class VoiceActivationAppsListModel(context: Context) : AppOpPermissionListModel(context) {
- override val pageTitleResId = R.string.voice_activation_apps_title
- override val switchTitleResId = R.string.permit_voice_activation_apps
- override val footerResId = R.string.allow_voice_activation_apps_description
- override val appOp = AppOpsManager.OP_RECEIVE_SANDBOX_TRIGGER_AUDIO
- override val permission = Manifest.permission.RECEIVE_SANDBOX_TRIGGER_AUDIO
- override val setModeByUid = true
-
- override fun setAllowed(record: AppOpPermissionRecord, newAllowed: Boolean) {
- super.setAllowed(record, newAllowed)
- logPermissionChange(newAllowed)
- }
-
- override fun isChangeable(record: AppOpPermissionRecord): Boolean =
- super.isChangeable(record) && record.app.hasGrantPermission(permission)
-
- private fun logPermissionChange(newAllowed: Boolean) {
- val category = when {
- newAllowed -> SettingsEnums.APP_SPECIAL_PERMISSION_RECEIVE_SANDBOX_TRIGGER_AUDIO_ALLOW
- else -> SettingsEnums.APP_SPECIAL_PERMISSION_RECEIVE_SANDBOX_TRIGGER_AUDIO_DENY
- }
- /**
- * Leave the package string empty as we should not log the package names for the collected
- * metrics.
- */
- FeatureFactory.featureFactory.metricsFeatureProvider.action(context, category, "")
- }
-}
\ No newline at end of file
diff --git a/src/com/android/settings/spa/app/specialaccess/VoiceActivationAppsPreferenceController.kt b/src/com/android/settings/spa/app/specialaccess/VoiceActivationAppsPreferenceController.kt
deleted file mode 100644
index 27d4b4b..0000000
--- a/src/com/android/settings/spa/app/specialaccess/VoiceActivationAppsPreferenceController.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.spa.app.specialaccess
-
-import android.content.Context
-import androidx.preference.Preference
-import com.android.settings.core.BasePreferenceController
-import com.android.settings.flags.Flags
-import com.android.settings.spa.SpaActivity.Companion.startSpaActivity
-
-class VoiceActivationAppsPreferenceController(context: Context, preferenceKey: String) :
- BasePreferenceController(context, preferenceKey) {
- override fun getAvailabilityStatus() =
- if (Flags.enableVoiceActivationAppsInSettings()) AVAILABLE
- else CONDITIONALLY_UNAVAILABLE
-
- override fun handlePreferenceTreeClick(preference: Preference): Boolean {
- if (preference.key == mPreferenceKey) {
- mContext.startSpaActivity(VoiceActivationAppsListProvider.getAppListRoute())
- return true
- }
- return false
- }
-}
\ No newline at end of file
diff --git a/src/com/android/settings/wallpaper/WallpaperSuggestionActivity.java b/src/com/android/settings/wallpaper/WallpaperSuggestionActivity.java
index 675e10f..14ef483 100644
--- a/src/com/android/settings/wallpaper/WallpaperSuggestionActivity.java
+++ b/src/com/android/settings/wallpaper/WallpaperSuggestionActivity.java
@@ -17,7 +17,6 @@
package com.android.settings.wallpaper;
import android.app.WallpaperManager;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -81,10 +80,9 @@
SearchIndexableRaw data = new SearchIndexableRaw(context);
data.title = controller.getTitle();
data.screenTitle = data.title;
- ComponentName component = controller.getComponentName();
- data.intentTargetPackage = component.getPackageName();
- data.intentTargetClass = component.getClassName();
- data.intentAction = controller.getComponentActionName();
+ data.intentTargetPackage = context.getPackageName();
+ data.intentTargetClass = WallpaperSuggestionActivity.class.getName();
+ data.intentAction = Intent.ACTION_MAIN;
data.key = SUPPORT_SEARCH_INDEX_KEY;
data.keywords = controller.getKeywords();
result.add(data);
diff --git a/src/com/android/settings/wifi/AddNetworkFragment.java b/src/com/android/settings/wifi/AddNetworkFragment.java
index 9fd8626..f5bf5ee 100644
--- a/src/com/android/settings/wifi/AddNetworkFragment.java
+++ b/src/com/android/settings/wifi/AddNetworkFragment.java
@@ -16,12 +16,17 @@
package com.android.settings.wifi;
+import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG;
+
import android.app.Activity;
import android.app.settings.SettingsEnums;
+import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Bundle;
+import android.os.UserManager;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -43,6 +48,7 @@
*/
public class AddNetworkFragment extends InstrumentedFragment implements WifiConfigUiBase2,
View.OnClickListener {
+ private static final String TAG = "AddNetworkFragment";
public static final String WIFI_CONFIG_KEY = "wifi_config_key";
@VisibleForTesting
@@ -62,6 +68,10 @@
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ if (!isAddWifiConfigAllowed(getContext())) {
+ getActivity().finish();
+ return;
+ }
}
@Override
@@ -237,4 +247,14 @@
activity.setResult(Activity.RESULT_CANCELED);
activity.finish();
}
+
+ @VisibleForTesting
+ static boolean isAddWifiConfigAllowed(Context context) {
+ UserManager userManager = context.getSystemService(UserManager.class);
+ if (userManager != null && userManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)) {
+ Log.e(TAG, "The user is not allowed to add Wi-Fi configuration.");
+ return false;
+ }
+ return true;
+ }
}
diff --git a/src/com/android/settings/wifi/dpp/AdbQrCode.java b/src/com/android/settings/wifi/dpp/AdbQrCode.java
index 6557787..2d830b2 100644
--- a/src/com/android/settings/wifi/dpp/AdbQrCode.java
+++ b/src/com/android/settings/wifi/dpp/AdbQrCode.java
@@ -16,8 +16,12 @@
package com.android.settings.wifi.dpp;
import android.content.Context;
+import android.net.wifi.UriParserResults;
+import android.net.wifi.WifiConfiguration;
import android.text.TextUtils;
+import androidx.annotation.NonNull;
+
/**
* Extension of WifiQrCode to support ADB QR code format.
* It will be based on the ZXing format:
@@ -27,31 +31,31 @@
public class AdbQrCode extends WifiQrCode {
static final String SECURITY_ADB = "ADB";
- private WifiNetworkConfig mAdbConfig;
+ private WifiConfiguration mAdbConfig;
public AdbQrCode(String qrCode) throws IllegalArgumentException {
super(qrCode);
// Only accept the zxing format.
- if (!WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG.equals(getScheme())) {
+ if (getScheme() != UriParserResults.URI_SCHEME_ZXING_WIFI_NETWORK_CONFIG) {
throw new IllegalArgumentException("DPP format not supported for ADB QR code");
}
+ mAdbConfig = getWifiConfiguration();
- mAdbConfig = getWifiNetworkConfig();
- if (!SECURITY_ADB.equals(mAdbConfig.getSecurity())) {
- throw new IllegalArgumentException("Invalid security type");
+ if (mAdbConfig == null) {
+ throw new IllegalArgumentException("Null config when parsing ADB QR code");
}
-
- if (TextUtils.isEmpty(mAdbConfig.getSsid())) {
+ if (TextUtils.isEmpty(mAdbConfig.SSID)) {
throw new IllegalArgumentException("Empty service name");
}
- if (TextUtils.isEmpty(mAdbConfig.getPreSharedKey())) {
+ if (TextUtils.isEmpty(mAdbConfig.preSharedKey)) {
throw new IllegalArgumentException("Empty password");
}
}
- public WifiNetworkConfig getAdbNetworkConfig() {
+ @NonNull
+ public WifiConfiguration getAdbNetworkConfig() {
return mAdbConfig;
}
diff --git a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
index e6f0b31..a7527d7 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
@@ -16,6 +16,8 @@
package com.android.settings.wifi.dpp;
+import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG;
+
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.Intent;
@@ -99,6 +101,10 @@
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ if (!isAddWifiConfigAllowed(getApplicationContext())) {
+ finish();
+ return;
+ }
if (savedInstanceState != null) {
String qrCode = savedInstanceState.getString(KEY_QR_CODE);
@@ -119,6 +125,10 @@
@Override
protected void handleIntent(Intent intent) {
+ if (!isAddWifiConfigAllowed(getApplicationContext())) {
+ finish();
+ return;
+ }
if (isGuestUser(getApplicationContext())) {
Log.e(TAG, "Guest user is not allowed to configure Wi-Fi!");
EventLog.writeEvent(0x534e4554, "224772890", -1 /* UID */, "User is a guest");
@@ -402,4 +412,14 @@
if (userManager == null) return false;
return userManager.isGuestUser();
}
+
+ @VisibleForTesting
+ static boolean isAddWifiConfigAllowed(Context context) {
+ UserManager userManager = context.getSystemService(UserManager.class);
+ if (userManager != null && userManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)) {
+ Log.e(TAG, "The user is not allowed to add Wi-Fi configuration.");
+ return false;
+ }
+ return true;
+ }
}
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
index 479c81d..34948dc 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
@@ -26,6 +26,7 @@
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.net.wifi.EasyConnectStatusCallback;
+import android.net.wifi.UriParserResults;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Bundle;
@@ -183,32 +184,29 @@
// one for open network and one for enhanced open network.
final WifiManager wifiManager =
context.getSystemService(WifiManager.class);
- final WifiNetworkConfig qrCodeWifiNetworkConfig =
- (WifiNetworkConfig)msg.obj;
- final List<WifiConfiguration> qrCodeWifiConfigurations =
- qrCodeWifiNetworkConfig.getWifiConfigurations();
+ final WifiConfiguration qrCodeWifiConfiguration = (WifiConfiguration) msg.obj;
// Adds all Wi-Fi networks in QR code to the set of configured networks and
// connects to it if it's reachable.
boolean hasHiddenOrReachableWifiNetwork = false;
- for (WifiConfiguration qrCodeWifiConfiguration : qrCodeWifiConfigurations) {
- final int id = wifiManager.addNetwork(qrCodeWifiConfiguration);
- if (id == -1) {
- continue;
- }
+ final int id = wifiManager.addNetwork(qrCodeWifiConfiguration);
+ if (id == -1) {
+ return;
+ }
- if (!canConnectWifi(qrCodeWifiConfiguration.SSID)) return;
+ if (!canConnectWifi(qrCodeWifiConfiguration.SSID)) {
+ return;
+ }
- wifiManager.enableNetwork(id, /* attemptConnect */ false);
- // WifiTracker only contains a hidden SSID Wi-Fi network if it's saved.
- // We can't check if a hidden SSID Wi-Fi network is reachable in advance.
- if (qrCodeWifiConfiguration.hiddenSSID ||
- isReachableWifiNetwork(qrCodeWifiConfiguration)) {
- hasHiddenOrReachableWifiNetwork = true;
- mEnrolleeWifiConfiguration = qrCodeWifiConfiguration;
- wifiManager.connect(id,
- /* listener */ WifiDppQrCodeScannerFragment.this);
- }
+ wifiManager.enableNetwork(id, /* attemptConnect */ false);
+ // WifiTracker only contains a hidden SSID Wi-Fi network if it's saved.
+ // We can't check if a hidden SSID Wi-Fi network is reachable in advance.
+ if (qrCodeWifiConfiguration.hiddenSSID
+ || isReachableWifiNetwork(qrCodeWifiConfiguration)) {
+ hasHiddenOrReachableWifiNetwork = true;
+ mEnrolleeWifiConfiguration = qrCodeWifiConfiguration;
+ wifiManager.connect(id,
+ /* listener */ WifiDppQrCodeScannerFragment.this);
}
if (!hasHiddenOrReachableWifiNetwork) {
@@ -530,8 +528,9 @@
}
// It's impossible to provision other device with ZXing Wi-Fi Network config format
- final String scheme = mWifiQrCode.getScheme();
- if (mIsConfiguratorMode && WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG.equals(scheme)) {
+ if (mIsConfiguratorMode
+ && mWifiQrCode.getScheme()
+ == UriParserResults.URI_SCHEME_ZXING_WIFI_NETWORK_CONFIG) {
showErrorMessage(R.string.wifi_dpp_qr_code_is_not_valid_format);
return false;
}
@@ -545,11 +544,11 @@
@Override
public void handleSuccessfulResult(String qrCode) {
switch (mWifiQrCode.getScheme()) {
- case WifiQrCode.SCHEME_DPP:
+ case UriParserResults.URI_SCHEME_DPP:
handleWifiDpp();
break;
- case WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG:
+ case UriParserResults.URI_SCHEME_ZXING_WIFI_NETWORK_CONFIG:
handleZxingWifiFormat();
break;
@@ -567,7 +566,7 @@
private void handleZxingWifiFormat() {
Message message = mHandler.obtainMessage(MESSAGE_SCAN_ZXING_WIFI_FORMAT_SUCCESS);
- message.obj = new WifiQrCode(mWifiQrCode.getQrCode()).getWifiNetworkConfig();
+ message.obj = new WifiQrCode(mWifiQrCode.getQrCode()).getWifiConfiguration();
mHandler.sendMessageDelayed(message, SHOW_SUCCESS_SQUARE_INTERVAL);
}
diff --git a/src/com/android/settings/wifi/dpp/WifiQrCode.java b/src/com/android/settings/wifi/dpp/WifiQrCode.java
index 70ac96c..9b93480 100644
--- a/src/com/android/settings/wifi/dpp/WifiQrCode.java
+++ b/src/com/android/settings/wifi/dpp/WifiQrCode.java
@@ -16,14 +16,12 @@
package com.android.settings.wifi.dpp;
+import android.annotation.NonNull;
+import android.net.wifi.UriParserResults;
import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiUriParser;
import android.text.TextUtils;
-
-import androidx.annotation.VisibleForTesting;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.regex.Pattern;
+import android.util.Log;
/**
* Supports to parse 2 types of QR code
@@ -70,19 +68,8 @@
static final String SECURITY_SAE = "SAE";
private String mQrCode;
-
- /**
- * SCHEME_DPP for standard Wi-Fi device provision protocol; SCHEME_ZXING_WIFI_NETWORK_CONFIG
- * for ZXing reader library' Wi-Fi Network config format
- */
- private String mScheme;
-
- // Data from parsed Wi-Fi DPP QR code
- private String mPublicKey;
- private String mInformation;
-
- // Data from parsed ZXing reader library's Wi-Fi Network config format
- private WifiNetworkConfig mWifiNetworkConfig;
+ @NonNull
+ private UriParserResults mUriParserResults;
public WifiQrCode(String qrCode) throws IllegalArgumentException {
if (TextUtils.isEmpty(qrCode)) {
@@ -90,111 +77,14 @@
}
mQrCode = qrCode;
-
- if (qrCode.startsWith(PREFIX_DPP)) {
- mScheme = SCHEME_DPP;
- parseWifiDppQrCode(qrCode);
- } else if (qrCode.startsWith(PREFIX_ZXING_WIFI_NETWORK_CONFIG)) {
- mScheme = SCHEME_ZXING_WIFI_NETWORK_CONFIG;
- parseZxingWifiQrCode(qrCode);
- } else {
+ try {
+ mUriParserResults = WifiUriParser.parseUri(mQrCode);
+ Log.i("WifiQrCode", "mUriParserResults = " + mUriParserResults);
+ } catch (IllegalArgumentException ie) {
throw new IllegalArgumentException("Invalid scheme");
}
}
- /** Parses Wi-Fi DPP QR code string */
- private void parseWifiDppQrCode(String qrCode) throws IllegalArgumentException {
- List<String> keyValueList = getKeyValueList(qrCode, PREFIX_DPP, DELIMITER_QR_CODE);
-
- String publicKey = getValueOrNull(keyValueList, PREFIX_DPP_PUBLIC_KEY);
- if (TextUtils.isEmpty(publicKey)) {
- throw new IllegalArgumentException("Invalid format");
- }
- mPublicKey = publicKey;
-
- mInformation = getValueOrNull(keyValueList, PREFIX_DPP_INFORMATION);
- }
-
- /** Parses ZXing reader library's Wi-Fi Network config format */
- private void parseZxingWifiQrCode(String qrCode) throws IllegalArgumentException {
- List<String> keyValueList = getKeyValueList(qrCode, PREFIX_ZXING_WIFI_NETWORK_CONFIG,
- DELIMITER_QR_CODE);
-
- String security = getValueOrNull(keyValueList, PREFIX_ZXING_SECURITY);
- String ssid = getValueOrNull(keyValueList, PREFIX_ZXING_SSID);
- String password = getValueOrNull(keyValueList, PREFIX_ZXING_PASSWORD);
- String hiddenSsidString = getValueOrNull(keyValueList, PREFIX_ZXING_HIDDEN_SSID);
-
- boolean hiddenSsid = "true".equalsIgnoreCase(hiddenSsidString);
-
- //"\", ";", "," and ":" are escaped with a backslash "\", should remove at first
- security = removeBackSlash(security);
- ssid = removeBackSlash(ssid);
- password = removeBackSlash(password);
-
- mWifiNetworkConfig = WifiNetworkConfig.getValidConfigOrNull(security, ssid, password,
- hiddenSsid, WifiConfiguration.INVALID_NETWORK_ID, /* isHotspot */ false);
-
- if (mWifiNetworkConfig == null) {
- throw new IllegalArgumentException("Invalid format");
- }
- }
-
- /**
- * Splits key/value pairs from qrCode
- *
- * @param qrCode the QR code raw string
- * @param prefixQrCode the string before all key/value pairs in qrCode
- * @param delimiter the string to split key/value pairs, can't contain a backslash
- * @return a list contains string of key/value (e.g. K:key1)
- */
- private List<String> getKeyValueList(String qrCode, String prefixQrCode,
- String delimiter) {
- String keyValueString = qrCode.substring(prefixQrCode.length());
-
- // Should not treat \delimiter as a delimiter
- String regex = "(?<!\\\\)" + Pattern.quote(delimiter);
-
- return Arrays.asList(keyValueString.split(regex));
- }
-
- private String getValueOrNull(List<String> keyValueList, String prefix) {
- for (String keyValue : keyValueList) {
- String strippedKeyValue = keyValue.stripLeading();
- if (strippedKeyValue.startsWith(prefix)) {
- return strippedKeyValue.substring(prefix.length());
- }
- }
-
- return null;
- }
-
- @VisibleForTesting
- String removeBackSlash(String input) {
- if (input == null) {
- return null;
- }
-
- StringBuilder sb = new StringBuilder();
- boolean backSlash = false;
- for (char ch : input.toCharArray()) {
- if (ch != '\\') {
- sb.append(ch);
- backSlash = false;
- } else {
- if (backSlash) {
- sb.append(ch);
- backSlash = false;
- continue;
- }
-
- backSlash = true;
- }
- }
-
- return sb.toString();
- }
-
String getQrCode() {
return mQrCode;
}
@@ -205,28 +95,23 @@
* SCHEME_DPP for standard Wi-Fi device provision protocol; SCHEME_ZXING_WIFI_NETWORK_CONFIG
* for ZXing reader library' Wi-Fi Network config format
*/
- public String getScheme() {
- return mScheme;
+ public int getScheme() {
+ return mUriParserResults.getUriScheme();
}
/** Available when {@code getScheme()} returns SCHEME_DPP */
- @VisibleForTesting
String getPublicKey() {
- return mPublicKey;
+ return mUriParserResults.getPublicKey();
}
/** May be available when {@code getScheme()} returns SCHEME_DPP */
public String getInformation() {
- return mInformation;
+ return mUriParserResults.getInformation();
}
/** Available when {@code getScheme()} returns SCHEME_ZXING_WIFI_NETWORK_CONFIG */
- WifiNetworkConfig getWifiNetworkConfig() {
- if (mWifiNetworkConfig == null) {
- return null;
- }
-
- return new WifiNetworkConfig(mWifiNetworkConfig);
+ WifiConfiguration getWifiConfiguration() {
+ return mUriParserResults.getWifiConfiguration();
}
static WifiQrCode getValidWifiDppQrCodeOrNull(String qrCode) {
diff --git a/tests/robotests/src/com/android/settings/UtilsTest.java b/tests/robotests/src/com/android/settings/UtilsTest.java
index 0c555da..0c57b01 100644
--- a/tests/robotests/src/com/android/settings/UtilsTest.java
+++ b/tests/robotests/src/com/android/settings/UtilsTest.java
@@ -16,6 +16,10 @@
package com.android.settings;
+import static android.hardware.biometrics.SensorProperties.STRENGTH_CONVENIENCE;
+import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG;
+import static android.hardware.biometrics.SensorProperties.STRENGTH_WEAK;
+
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertNull;
@@ -43,6 +47,9 @@
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.VectorDrawable;
+import android.hardware.face.FaceManager;
+import android.hardware.face.FaceSensorProperties;
+import android.hardware.face.FaceSensorPropertiesInternal;
import android.net.ConnectivityManager;
import android.net.LinkAddress;
import android.net.LinkProperties;
@@ -433,6 +440,69 @@
assertNull(confirmCredentialString);
}
+ @Test
+ public void isFaceNotConvenienceBiometric_faceStrengthStrong_shouldReturnTrue() {
+ FaceManager mockFaceManager = mock(FaceManager.class);
+ when(mContext.getSystemService(Context.FACE_SERVICE)).thenReturn(mockFaceManager);
+ doReturn(true).when(mPackageManager).hasSystemFeature(anyString());
+ List<FaceSensorPropertiesInternal> props = List.of(new FaceSensorPropertiesInternal(
+ 0 /* id */,
+ STRENGTH_STRONG,
+ 1 /* maxTemplatesAllowed */,
+ new ArrayList<>() /* componentInfo */,
+ FaceSensorProperties.TYPE_UNKNOWN,
+ true /* supportsFaceDetection */,
+ true /* supportsSelfIllumination */,
+ false /* resetLockoutRequiresChallenge */));
+ doReturn(props).when(mockFaceManager).getSensorPropertiesInternal();
+
+ assertThat(Utils.isFaceNotConvenienceBiometric(mContext)).isTrue();
+ }
+
+ @Test
+ public void isFaceNotConvenienceBiometric_faceStrengthWeak_shouldReturnTrue() {
+ FaceManager mockFaceManager = mock(FaceManager.class);
+ when(mContext.getSystemService(Context.FACE_SERVICE)).thenReturn(mockFaceManager);
+ doReturn(true).when(mPackageManager).hasSystemFeature(anyString());
+ List<FaceSensorPropertiesInternal> props = List.of(new FaceSensorPropertiesInternal(
+ 0 /* id */,
+ STRENGTH_WEAK,
+ 1 /* maxTemplatesAllowed */,
+ new ArrayList<>() /* componentInfo */,
+ FaceSensorProperties.TYPE_UNKNOWN,
+ true /* supportsFaceDetection */,
+ true /* supportsSelfIllumination */,
+ false /* resetLockoutRequiresChallenge */));
+ doReturn(props).when(mockFaceManager).getSensorPropertiesInternal();
+
+ assertThat(Utils.isFaceNotConvenienceBiometric(mContext)).isTrue();
+ }
+
+ @Test
+ public void isFaceNotConvenienceBiometric_faceStrengthConvenience_shouldReturnFalse() {
+ FaceManager mockFaceManager = mock(FaceManager.class);
+ when(mContext.getSystemService(Context.FACE_SERVICE)).thenReturn(mockFaceManager);
+ doReturn(true).when(mPackageManager).hasSystemFeature(anyString());
+ List<FaceSensorPropertiesInternal> props = List.of(new FaceSensorPropertiesInternal(
+ 0 /* id */,
+ STRENGTH_CONVENIENCE,
+ 1 /* maxTemplatesAllowed */,
+ new ArrayList<>() /* componentInfo */,
+ FaceSensorProperties.TYPE_UNKNOWN,
+ true /* supportsFaceDetection */,
+ true /* supportsSelfIllumination */,
+ false /* resetLockoutRequiresChallenge */));
+ doReturn(props).when(mockFaceManager).getSensorPropertiesInternal();
+
+ assertThat(Utils.isFaceNotConvenienceBiometric(mContext)).isFalse();
+ }
+
+ @Test
+ public void isFaceNotConvenienceBiometric_faceManagerNull_shouldReturnFalse() {
+ when(mContext.getSystemService(Context.FACE_SERVICE)).thenReturn(null);
+ assertThat(Utils.isFaceNotConvenienceBiometric(mContext)).isFalse();
+ }
+
private void setUpForConfirmCredentialString(boolean isEffectiveUserManagedProfile) {
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mMockUserManager);
when(mMockUserManager.getCredentialOwnerProfile(USER_ID)).thenReturn(USER_ID);
diff --git a/tests/robotests/src/com/android/settings/biometrics/face/FaceEnrollIntroductionTest.java b/tests/robotests/src/com/android/settings/biometrics/face/FaceEnrollIntroductionTest.java
index a56c34c..81a7269 100644
--- a/tests/robotests/src/com/android/settings/biometrics/face/FaceEnrollIntroductionTest.java
+++ b/tests/robotests/src/com/android/settings/biometrics/face/FaceEnrollIntroductionTest.java
@@ -78,6 +78,7 @@
import com.google.android.setupcompat.template.FooterButton;
import com.google.android.setupcompat.util.WizardManagerHelper;
import com.google.android.setupdesign.GlifLayout;
+import com.google.android.setupdesign.template.RequireScrollMixin;
import com.google.android.setupdesign.view.BottomScrollView;
import org.junit.After;
@@ -138,6 +139,11 @@
}
@Override
+ protected void onResume() {
+ super.onResume();
+ }
+
+ @Override
public void recreate() {
mRecreateCount++;
// Do nothing
@@ -424,11 +430,39 @@
}
@Test
- public void testFaceEnrollIntroduction_notShowFooterSecondaryButton() {
+ public void testFaceEnrollIntroduction_footerSecondaryButtonWhenCanEnroll() {
setupActivity();
FooterBarMixin footer = getGlifLayout(mActivity).getMixin(FooterBarMixin.class);
FooterButton footerButton = footer.getSecondaryButton();
+ final RequireScrollMixin requireScrollMixin = getGlifLayout(mActivity).getMixin(
+ RequireScrollMixin.class);
+ assertThat(footerButton.getVisibility()).isEqualTo(
+ requireScrollMixin.isScrollingRequired() ? View.INVISIBLE : View.VISIBLE);
+
+ requireScrollMixin.getOnRequireScrollStateChangedListener().onRequireScrollStateChanged(
+ false);
+ assertThat(footerButton.getVisibility()).isEqualTo(View.VISIBLE);
+ }
+
+ @Test
+ public void testFaceEnrollIntroduction_footerSecondaryButtonWhenMaxEnroll() {
+ setFaceManagerToHave(1 /* numEnrollments */);
+ final Intent intent = new Intent();
+ intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, new byte[0]);
+ mController = Robolectric.buildActivity(TestFaceEnrollIntroduction.class, intent);
+ mActivity = (TestFaceEnrollIntroduction) mController.get();
+
+ mController.create();
+
+ FooterBarMixin footer = getGlifLayout(mActivity).getMixin(FooterBarMixin.class);
+ FooterButton footerButton = footer.getSecondaryButton();
+ final RequireScrollMixin requireScrollMixin = getGlifLayout(mActivity).getMixin(
+ RequireScrollMixin.class);
+ assertThat(footerButton.getVisibility()).isEqualTo(View.INVISIBLE);
+
+ requireScrollMixin.getOnRequireScrollStateChangedListener().onRequireScrollStateChanged(
+ false);
assertThat(footerButton.getVisibility()).isEqualTo(View.INVISIBLE);
}
diff --git a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroductionTest.java b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroductionTest.java
index 6df8b8e..edd50a6 100644
--- a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroductionTest.java
+++ b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroductionTest.java
@@ -183,14 +183,6 @@
int result = mFingerprintEnrollIntroduction.checkMaxEnrolled();
assertThat(result).isEqualTo(0);
-
- final RequireScrollMixin requireScrollMixin =
- ((GlifLayout) mFingerprintEnrollIntroduction.findViewById(
- R.id.setup_wizard_layout)).getMixin(RequireScrollMixin.class);
- requireScrollMixin.getOnRequireScrollStateChangedListener().onRequireScrollStateChanged(
- false);
- Assert.assertEquals(View.VISIBLE,
- mFingerprintEnrollIntroduction.getSecondaryFooterButton().getVisibility());
}
@Test
@@ -206,14 +198,6 @@
int result = mFingerprintEnrollIntroduction.checkMaxEnrolled();
assertThat(result).isEqualTo(R.string.fingerprint_intro_error_max);
-
- final RequireScrollMixin requireScrollMixin =
- ((GlifLayout) mFingerprintEnrollIntroduction.findViewById(
- R.id.setup_wizard_layout)).getMixin(RequireScrollMixin.class);
- requireScrollMixin.getOnRequireScrollStateChangedListener().onRequireScrollStateChanged(
- false);
- Assert.assertEquals(View.INVISIBLE,
- mFingerprintEnrollIntroduction.getSecondaryFooterButton().getVisibility());
}
@Test
@@ -321,6 +305,57 @@
.isEqualTo(FingerprintEnrollOptions.ENROLL_REASON_SETTINGS);
}
+ @Test
+ public void intro_CheckNoThanksButtonWhenCanEnroll() {
+ // This code path should depend on suw_max_fingerprints_enrollable versus
+ // FingerprintManager.getSensorProperties...maxEnrollmentsPerUser()
+ Resources resources = mock(Resources.class);
+ when(resources.getInteger(anyInt())).thenReturn(5);
+ when(mContext.getResources()).thenReturn(resources);
+
+ setupFingerprintEnrollIntroWith(newFirstSuwIntent());
+ setFingerprintManagerToHave(0 /* numEnrollments */);
+
+ final RequireScrollMixin requireScrollMixin =
+ ((GlifLayout) mFingerprintEnrollIntroduction.findViewById(
+ R.id.setup_wizard_layout)).getMixin(RequireScrollMixin.class);
+
+ Assert.assertEquals(
+ requireScrollMixin.isScrollingRequired() ? View.INVISIBLE : View.VISIBLE,
+ mFingerprintEnrollIntroduction.getSecondaryFooterButton().getVisibility());
+
+ requireScrollMixin.getOnRequireScrollStateChangedListener().onRequireScrollStateChanged(
+ false);
+ Assert.assertEquals(View.VISIBLE,
+ mFingerprintEnrollIntroduction.getSecondaryFooterButton().getVisibility());
+ }
+
+ @Test
+ public void intro_CheckNoThanksButtonWhenMaxEnroll() {
+ // This code path should depend on suw_max_fingerprints_enrollable versus
+ // FingerprintManager.getSensorProperties...maxEnrollmentsPerUser()
+ Resources resources = mock(Resources.class);
+ when(mContext.getResources()).thenReturn(resources);
+ when(resources.getInteger(anyInt())).thenReturn(1);
+
+ setupFingerprintEnrollIntroWith(newFirstSuwIntent());
+ setFingerprintManagerToHave(1 /* numEnrollments */);
+
+ final RequireScrollMixin requireScrollMixin =
+ ((GlifLayout) mFingerprintEnrollIntroduction.findViewById(
+ R.id.setup_wizard_layout)).getMixin(RequireScrollMixin.class);
+
+ mFingerprintEnrollIntroduction.onResume();
+ Assert.assertEquals(View.INVISIBLE,
+ mFingerprintEnrollIntroduction.getSecondaryFooterButton().getVisibility());
+
+ requireScrollMixin.getOnRequireScrollStateChangedListener().onRequireScrollStateChanged(
+ false);
+ Assert.assertEquals(View.INVISIBLE,
+ mFingerprintEnrollIntroduction.getSecondaryFooterButton().getVisibility());
+
+ }
+
private Intent newTokenOnlyIntent() {
return new Intent()
.putExtra(EXTRA_KEY_CHALLENGE_TOKEN, new byte[] { 1 });
@@ -365,6 +400,11 @@
public int mNewSensorId;
public long mNewChallenge;
+ @Override
+ protected void onResume() {
+ super.onResume();
+ }
+
@Nullable
public byte[] getTokenField() {
return mToken;
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageCacheHelperTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageCacheHelperTest.java
index 9e20e78..a26ea1d 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageCacheHelperTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageCacheHelperTest.java
@@ -41,6 +41,7 @@
private static final long FAKE_TOTAL_SIZE = 256000L;
private static final long FAKE_TOTAL_USED_SIZE = 50000L;
private static final long FAKE_USED_SIZE = 6500L;
+ private static final long FAKE_TEMPORARY_FILES_SIZE = 2500L;
private Context mContext;
private StorageCacheHelper mHelper;
@@ -70,6 +71,7 @@
StorageCacheHelper.StorageCache storageCache = mHelper.retrieveCachedSize();
assertThat(storageCache.imagesSize).isEqualTo(FAKE_IMAGES_SIZE);
+ assertThat(storageCache.temporaryFilesSize).isEqualTo(FAKE_TEMPORARY_FILES_SIZE);
assertThat(storageCache.totalSize).isEqualTo(0);
}
@@ -100,6 +102,7 @@
result.gamesSize = FAKE_GAMES_SIZE;
result.videosSize = FAKE_VIDEOS_SIZE;
result.allAppsExceptGamesSize = FAKE_APPS_SIZE;
+ result.temporaryFilesSize = FAKE_TEMPORARY_FILES_SIZE;
return result;
}
}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
index b61f5ab..2590f52 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
@@ -45,6 +45,7 @@
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
+import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
@@ -126,7 +127,10 @@
final StorageItemPreference documentsAndOther = spy(new StorageItemPreference(mContext));
documentsAndOther.setIcon(R.drawable.ic_folder_vd_theme_24);
final StorageItemPreference system = spy(new StorageItemPreference(mContext));
- system.setIcon(com.android.settingslib.R.drawable.ic_system_update);
+ system.setIcon(R.drawable.ic_android_vd_theme_24);
+ final StorageItemPreference temporaryFiles = spy(new StorageItemPreference(mContext));
+ temporaryFiles.setIcon(R.drawable.ic_database_vd_theme_24);
+ final PreferenceCategory categorySplitter = spy(new PreferenceCategory(mContext));
final StorageItemPreference trash = spy(new StorageItemPreference(mContext));
trash.setIcon(R.drawable.ic_trash_can);
@@ -147,6 +151,10 @@
.thenReturn(documentsAndOther);
when(screen.findPreference(eq(StorageItemPreferenceController.SYSTEM_KEY)))
.thenReturn(system);
+ when(screen.findPreference(eq(StorageItemPreferenceController.TEMPORARY_FILES_KEY)))
+ .thenReturn(temporaryFiles);
+ when(screen.findPreference(eq(StorageItemPreferenceController.CATEGORY_SPLITTER)))
+ .thenReturn(categorySplitter);
when(screen.findPreference(eq(StorageItemPreferenceController.TRASH_KEY)))
.thenReturn(trash);
@@ -219,6 +227,7 @@
assertThat(mController.mGamesPreference.isVisible()).isFalse();
assertThat(mController.mDocumentsAndOtherPreference.isVisible()).isFalse();
assertThat(mController.mSystemPreference.isVisible()).isFalse();
+ assertThat(mController.mTemporaryFilesPreference.isVisible()).isFalse();
assertThat(mController.mTrashPreference.isVisible()).isFalse();
}
@@ -330,6 +339,16 @@
}
@Test
+ public void testClickTemporaryFiles() {
+ mPreference.setKey(StorageItemPreferenceController.TEMPORARY_FILES_KEY);
+ assertThat(mController.handlePreferenceTreeClick(mPreference)).isTrue();
+
+ verify(mFragment.getFragmentManager().beginTransaction())
+ .add(nullable(StorageUtils.TemporaryFilesInfoFragment.class),
+ nullable(String.class));
+ }
+
+ @Test
@Config(shadows = ShadowUserManager.class)
public void testMeasurementCompletedUpdatesPreferences() {
mController.displayPreference(mPreferenceScreen);
@@ -343,6 +362,7 @@
result.documentsAndOtherSize = MEGABYTE_IN_BYTES * 50;
result.trashSize = KILOBYTE_IN_BYTES * 100;
result.allAppsExceptGamesSize = MEGABYTE_IN_BYTES * 90;
+ result.systemSize = MEGABYTE_IN_BYTES * 60;
final SparseArray<StorageAsyncLoader.StorageResult> results = new SparseArray<>();
results.put(0, result);
@@ -356,6 +376,8 @@
assertThat(mController.mDocumentsAndOtherPreference.getSummary().toString())
.isEqualTo("50 MB");
assertThat(mController.mTrashPreference.getSummary().toString()).isEqualTo("100 kB");
+ assertThat(mController.mSystemPreference.getSummary().toString())
+ .isEqualTo("60 MB");
}
@Test
@@ -373,6 +395,7 @@
verify(mController.mDocumentsAndOtherPreference, times(2))
.setIcon(nullable(Drawable.class));
verify(mController.mSystemPreference, times(2)).setIcon(nullable(Drawable.class));
+ verify(mController.mTemporaryFilesPreference, times(2)).setIcon(nullable(Drawable.class));
verify(mController.mTrashPreference, times(2)).setIcon(nullable(Drawable.class));
}
@@ -437,6 +460,7 @@
assertThat(mController.mGamesPreference.isVisible()).isFalse();
assertThat(mController.mDocumentsAndOtherPreference.isVisible()).isFalse();
assertThat(mController.mSystemPreference.isVisible()).isFalse();
+ assertThat(mController.mTemporaryFilesPreference.isVisible()).isFalse();
assertThat(mController.mTrashPreference.isVisible()).isFalse();
}
diff --git a/tests/robotests/src/com/android/settings/network/telephony/EuiccRacConnectivityDialogActivityTest.java b/tests/robotests/src/com/android/settings/network/telephony/EuiccRacConnectivityDialogActivityTest.java
new file mode 100644
index 0000000..29d8f79
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/telephony/EuiccRacConnectivityDialogActivityTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.network.telephony;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.app.settings.SettingsEnums;
+
+import com.android.settings.testutils.FakeFeatureFactory;
+
+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 EuiccRacConnectivityDialogActivityTest {
+ private static final boolean CONFIRMED = true;
+
+ private FakeFeatureFactory mFeatureFactory;
+ private EuiccRacConnectivityDialogActivity mActivity;
+
+ @Before
+ public void setUp() {
+ mFeatureFactory = FakeFeatureFactory.setupForTest();
+ mActivity = spy(Robolectric.buildActivity(EuiccRacConnectivityDialogActivity.class).get());
+ mActivity.onCreate(null);
+ }
+
+ @Test
+ public void dialogAction_continue_intentResetMobileNetwork_metricsLogged() {
+ mActivity.onConfirm(
+ SettingsEnums.ACTION_RESET_MOBILE_NETWORK_RAC_CONNECTIVITY_WARNING, CONFIRMED);
+
+ verify(mFeatureFactory.metricsFeatureProvider)
+ .action(
+ mActivity,
+ SettingsEnums.ACTION_RESET_MOBILE_NETWORK_RAC_CONNECTIVITY_WARNING,
+ getMetricsValue(CONFIRMED));
+ }
+
+ @Test
+ public void dialogAction_back_intentResetMobileNetwork_metricsLogged() {
+ mActivity.onConfirm(
+ SettingsEnums.ACTION_RESET_MOBILE_NETWORK_RAC_CONNECTIVITY_WARNING, !CONFIRMED);
+
+ verify(mFeatureFactory.metricsFeatureProvider)
+ .action(
+ mActivity,
+ SettingsEnums.ACTION_RESET_MOBILE_NETWORK_RAC_CONNECTIVITY_WARNING,
+ getMetricsValue(!CONFIRMED));
+ }
+
+ @Test
+ public void dialogAction_continue_intentSettingsEsimDelete_metricsLogged() {
+ mActivity.onConfirm(SettingsEnums.ACTION_SETTINGS_ESIM_RAC_CONNECTIVITY_WARNING, CONFIRMED);
+
+ verify(mFeatureFactory.metricsFeatureProvider)
+ .action(
+ mActivity,
+ SettingsEnums.ACTION_SETTINGS_ESIM_RAC_CONNECTIVITY_WARNING,
+ getMetricsValue(CONFIRMED));
+ }
+
+ @Test
+ public void dialogAction_back_intentSettingsEsimDelete_metricsLogged() {
+ mActivity.onConfirm(
+ SettingsEnums.ACTION_SETTINGS_ESIM_RAC_CONNECTIVITY_WARNING, !CONFIRMED);
+
+ verify(mFeatureFactory.metricsFeatureProvider)
+ .action(
+ mActivity,
+ SettingsEnums.ACTION_SETTINGS_ESIM_RAC_CONNECTIVITY_WARNING,
+ getMetricsValue(!CONFIRMED));
+ }
+
+ private int getMetricsValue(boolean confirmed) {
+ return confirmed ? 1 : 0;
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/privatespace/delete/ResetOptionsDeletePrivateSpaceControllerTest.java b/tests/robotests/src/com/android/settings/privatespace/delete/ResetOptionsDeletePrivateSpaceControllerTest.java
index ebff07a..a17859a 100644
--- a/tests/robotests/src/com/android/settings/privatespace/delete/ResetOptionsDeletePrivateSpaceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/privatespace/delete/ResetOptionsDeletePrivateSpaceControllerTest.java
@@ -103,11 +103,23 @@
}
@Test
- public void getAvailabilityStatus_flagsEnabled_returnsAvailable() {
+ public void getAvailabilityStatus_flagsEnabledCanAddProfile_returnsAvailable() {
mSetFlagsRule.enableFlags(android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
mSetFlagsRule.enableFlags(android.multiuser.Flags.FLAG_DELETE_PRIVATE_SPACE_FROM_RESET);
+ ResetOptionsDeletePrivateSpaceController spyController = spy(mController);
+ doReturn(true).when(spyController).isPrivateSpaceEntryPointEnabled();
- assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+ assertThat(spyController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+ }
+
+ @Test
+ public void getAvailabilityStatus_flagsEnabledCannotAddProfile_returnsUnsupported() {
+ mSetFlagsRule.enableFlags(android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
+ mSetFlagsRule.enableFlags(android.multiuser.Flags.FLAG_DELETE_PRIVATE_SPACE_FROM_RESET);
+ ResetOptionsDeletePrivateSpaceController spyController = spy(mController);
+ doReturn(false).when(spyController).isPrivateSpaceEntryPointEnabled();
+
+ assertThat(spyController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
diff --git a/tests/spa_unit/src/com/android/settings/datausage/DataUsageListTest.kt b/tests/spa_unit/src/com/android/settings/datausage/DataUsageListTest.kt
index 29ec0ee..7274eaa 100644
--- a/tests/spa_unit/src/com/android/settings/datausage/DataUsageListTest.kt
+++ b/tests/spa_unit/src/com/android/settings/datausage/DataUsageListTest.kt
@@ -26,8 +26,11 @@
import androidx.fragment.app.testing.launchFragment
import androidx.fragment.app.testing.withFragment
import androidx.lifecycle.Lifecycle
+import androidx.preference.Preference
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settings.R
+import com.android.settings.datausage.DataUsageList.Companion.KEY_WARNING
import com.android.settingslib.spaprivileged.framework.common.userManager
import com.google.common.truth.Truth.assertThat
import org.junit.Before
@@ -38,12 +41,14 @@
import org.mockito.kotlin.spy
import org.mockito.kotlin.stub
-private val mockUserManager: UserManager = mock<UserManager>()
+private val mockUserManager = mock<UserManager>()
-private val mockContext: Context = spy(ApplicationProvider.getApplicationContext()) {
+private val spyContext: Context = spy(ApplicationProvider.getApplicationContext()) {
on { userManager } doReturn mockUserManager
}
+private val spyResources = spy(spyContext.resources)
+
private var fakeIntent = Intent()
@RunWith(AndroidJUnit4::class)
@@ -51,6 +56,9 @@
@Before
fun setUp() {
+ spyContext.stub {
+ on { resources } doReturn spyResources
+ }
mockUserManager.stub {
on { isGuestUser } doReturn false
}
@@ -122,10 +130,60 @@
assertThat(activity!!.isFinishing).isFalse()
}
}
+
+ @Test
+ fun warning_wifiAndHasSim_displayNonCarrierWarning() {
+ val template = NetworkTemplate.Builder(NetworkTemplate.MATCH_WIFI).build()
+ spyResources.stub {
+ on { getBoolean(R.bool.config_show_sim_info) } doReturn true
+ }
+ fakeIntent = Intent().apply {
+ putExtra(Settings.EXTRA_NETWORK_TEMPLATE, template)
+ }
+
+ val scenario = launchFragment<TestDataUsageList>(initialState = Lifecycle.State.CREATED)
+
+ scenario.withFragment {
+ assertThat(findPreference<Preference>(KEY_WARNING)!!.summary)
+ .isEqualTo(context.getString(R.string.non_carrier_data_usage_warning))
+ }
+ }
+
+ @Test
+ fun warning_wifiAndNoSim_noWarning() {
+ val template = NetworkTemplate.Builder(NetworkTemplate.MATCH_WIFI).build()
+ spyResources.stub {
+ on { getBoolean(R.bool.config_show_sim_info) } doReturn false
+ }
+ fakeIntent = Intent().apply {
+ putExtra(Settings.EXTRA_NETWORK_TEMPLATE, template)
+ }
+
+ val scenario = launchFragment<TestDataUsageList>(initialState = Lifecycle.State.CREATED)
+
+ scenario.withFragment {
+ assertThat(findPreference<Preference>(KEY_WARNING)!!.summary).isNull()
+ }
+ }
+
+ @Test
+ fun warning_mobile_operatorWarning() {
+ val template = NetworkTemplate.Builder(NetworkTemplate.MATCH_MOBILE).build()
+ fakeIntent = Intent().apply {
+ putExtra(Settings.EXTRA_NETWORK_TEMPLATE, template)
+ }
+
+ val scenario = launchFragment<TestDataUsageList>(initialState = Lifecycle.State.CREATED)
+
+ scenario.withFragment {
+ assertThat(findPreference<Preference>(KEY_WARNING)!!.summary)
+ .isEqualTo(context.getString(R.string.operator_warning))
+ }
+ }
}
class TestDataUsageList : DataUsageList() {
- override fun getContext() = mockContext
+ override fun getContext() = spyContext
override fun getIntent() = fakeIntent
}
diff --git a/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/VoiceActivationAppsPreferenceControllerTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/VoiceActivationAppsPreferenceControllerTest.kt
deleted file mode 100644
index 2127497..0000000
--- a/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/VoiceActivationAppsPreferenceControllerTest.kt
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.android.settings.spa.app.specialaccess
-
-import android.content.Context
-import android.platform.test.annotations.RequiresFlagsDisabled
-import android.platform.test.annotations.RequiresFlagsEnabled
-import android.platform.test.flag.junit.CheckFlagsRule
-import android.platform.test.flag.junit.DeviceFlagsValueProvider
-import androidx.preference.Preference
-import androidx.test.core.app.ApplicationProvider
-import androidx.test.ext.junit.runners.AndroidJUnit4
-
-import com.android.settings.flags.Flags
-import com.google.common.truth.Truth.assertThat
-
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.kotlin.any
-import org.mockito.kotlin.doNothing
-import org.mockito.kotlin.spy
-import org.mockito.kotlin.whenever
-
-@RunWith(AndroidJUnit4::class)
-class VoiceActivationAppsPreferenceControllerTest {
-
- @get:Rule
- val checkFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
-
- private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
- doNothing().whenever(mock).startActivity(any())
- }
-
- private val matchedPreference = Preference(context).apply { key = preferenceKey }
-
- private val misMatchedPreference = Preference(context).apply { key = testPreferenceKey }
-
- private val controller = VoiceActivationAppsPreferenceController(context, preferenceKey)
-
- @Test
- @RequiresFlagsEnabled(Flags.FLAG_ENABLE_VOICE_ACTIVATION_APPS_IN_SETTINGS)
- fun getAvailabilityStatus_enableVoiceActivationApps_returnAvailable() {
- assertThat(controller.isAvailable).isTrue()
- }
-
- @Test
- @RequiresFlagsDisabled(Flags.FLAG_ENABLE_VOICE_ACTIVATION_APPS_IN_SETTINGS)
- fun getAvailableStatus_disableVoiceActivationApps_returnConditionallyUnavailable() {
- assertThat(controller.isAvailable).isFalse()
- }
-
- @Test
- fun handlePreferenceTreeClick_keyMatched_returnTrue() {
- assertThat(controller.handlePreferenceTreeClick(matchedPreference)).isTrue()
- }
-
- @Test
- fun handlePreferenceTreeClick_keyMisMatched_returnFalse() {
- assertThat(controller.handlePreferenceTreeClick(misMatchedPreference)).isFalse()
- }
-
- companion object {
- private const val preferenceKey: String = "voice_activation_apps"
- private const val testPreferenceKey: String = "test_key"
- }
-}
\ No newline at end of file
diff --git a/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/VoiceActivationAppsTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/VoiceActivationAppsTest.kt
deleted file mode 100644
index a2aa293..0000000
--- a/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/VoiceActivationAppsTest.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.android.settings.spa.app.specialaccess
-
-import android.Manifest
-import android.app.AppOpsManager
-import android.content.Context
-import androidx.test.core.app.ApplicationProvider
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import com.android.settings.R
-import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@RunWith(AndroidJUnit4::class)
-class VoiceActivationAppsTest {
- private val context: Context = ApplicationProvider.getApplicationContext()
-
- private val listModel = VoiceActivationAppsListModel(context)
-
- @Test
- fun modelResourceIdAndProperties() {
- assertThat(listModel.pageTitleResId).isEqualTo(R.string.voice_activation_apps_title)
- assertThat(listModel.switchTitleResId).isEqualTo(R.string.permit_voice_activation_apps)
- assertThat(listModel.footerResId).isEqualTo(R.string.allow_voice_activation_apps_description)
- assertThat(listModel.appOp).isEqualTo(AppOpsManager.OP_RECEIVE_SANDBOX_TRIGGER_AUDIO)
- assertThat(listModel.permission).isEqualTo(
- Manifest.permission.RECEIVE_SANDBOX_TRIGGER_AUDIO
- )
- assertThat(listModel.setModeByUid).isTrue()
- }
-}
\ No newline at end of file
diff --git a/tests/unit/src/com/android/settings/privatespace/HidePrivateSpaceSensitiveNotificationsControllerTest.java b/tests/unit/src/com/android/settings/privatespace/HidePrivateSpaceSensitiveNotificationsControllerTest.java
deleted file mode 100644
index 88503a5..0000000
--- a/tests/unit/src/com/android/settings/privatespace/HidePrivateSpaceSensitiveNotificationsControllerTest.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * 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.privatespace;
-
-import static com.android.settings.core.BasePreferenceController.AVAILABLE;
-import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
-import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assume.assumeTrue;
-import static org.mockito.Mockito.spy;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.platform.test.flag.junit.SetFlagsRule;
-import android.provider.Settings;
-
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-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;
-
-/**
- * Tests for HidePrivateSpaceSensitiveNotificationsController.
- * Run as {@code atest SettingsUnitTests:HidePrivateSpaceSensitiveNotificationsControllerTest}
- */
-@RunWith(AndroidJUnit4.class)
-public class HidePrivateSpaceSensitiveNotificationsControllerTest {
- @Rule
- public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
-
- private Context mContext;
- private HidePrivateSpaceSensitiveNotificationsController
- mHidePrivateSpaceSensitiveNotificationsController;
- @Mock
- private ContentResolver mContentResolver;
- private int mOriginalDeviceSensitiveNotifValue;
- private int mOriginalDeviceNotifValue;
- private int mOriginalPsSensitiveNotifValue;
- private int mPrivateProfileId;
-
- @Before
- public void setUp() {
- mContext = spy(ApplicationProvider.getApplicationContext());
- mContentResolver = mContext.getContentResolver();
- assumeTrue(PrivateSpaceMaintainer.getInstance(mContext).doesPrivateSpaceExist());
-
- mSetFlagsRule.enableFlags(
- android.multiuser.Flags.FLAG_ENABLE_PS_SENSITIVE_NOTIFICATIONS_TOGGLE);
- mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
- android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
-
- mPrivateProfileId = PrivateSpaceMaintainer.getInstance(
- mContext).getPrivateProfileHandle().getIdentifier();
-
- mOriginalDeviceSensitiveNotifValue = Settings.Secure.getInt(mContentResolver,
- Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1);
- mOriginalDeviceNotifValue = Settings.Secure.getInt(mContentResolver,
- Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1);
- mOriginalPsSensitiveNotifValue = Settings.Secure.getIntForUser(mContentResolver,
- Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mPrivateProfileId);
-
- final String preferenceKey = "private_space_sensitive_notifications";
- mHidePrivateSpaceSensitiveNotificationsController =
- new HidePrivateSpaceSensitiveNotificationsController(mContext, preferenceKey);
- }
-
- @After
- public void tearDown() {
- Settings.Secure.putInt(mContentResolver,
- Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
- mOriginalDeviceSensitiveNotifValue
- );
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, mOriginalDeviceNotifValue);
- Settings.Secure.putIntForUser(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
- mOriginalPsSensitiveNotifValue, mPrivateProfileId);
- }
-
- /**
- * Tests that the controller is unavailable if lockscreen sensitive notifications are disabled
- * on the device.
- */
- @Test
- public void getAvailabilityStatus_lockScreenPrivateNotificationsOff() {
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0);
- assertThat(mHidePrivateSpaceSensitiveNotificationsController.getAvailabilityStatus())
- .isEqualTo(DISABLED_DEPENDENT_SETTING);
- }
-
- /**
- * Tests that the controller is unavailable if lockscreen notifications are disabled on the
- * device.
- */
- @Test
- public void getAvailabilityStatus_lockScreenNotificationsOff() {
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0);
- assertThat(mHidePrivateSpaceSensitiveNotificationsController.getAvailabilityStatus())
- .isEqualTo(DISABLED_DEPENDENT_SETTING);
- }
-
- /**
- * Tests that the controller is available if lockscreen notifications and lockscreen private
- * notifications are enabled on the device.
- */
- @Test
- public void getAvailabilityStatus_returnAvailable() {
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1);
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1);
- assertThat(mHidePrivateSpaceSensitiveNotificationsController.getAvailabilityStatus())
- .isEqualTo(AVAILABLE);
- }
-
-
- /**
- * Tests that toggle is not available if the flag for this feature and MVP flag are disabled.
- */
- @Test
- public void getAvailabilityStatus_flagDisabled() {
- mSetFlagsRule.disableFlags(
- android.multiuser.Flags.FLAG_ENABLE_PS_SENSITIVE_NOTIFICATIONS_TOGGLE);
- mSetFlagsRule.disableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
- android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1);
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1);
- assertThat(mHidePrivateSpaceSensitiveNotificationsController.getAvailabilityStatus())
- .isEqualTo(UNSUPPORTED_ON_DEVICE);
- }
-
- @Test
- public void testSetChecked() {
- assertThat(mHidePrivateSpaceSensitiveNotificationsController.setChecked(true)).isTrue();
- assertThat(mHidePrivateSpaceSensitiveNotificationsController.isChecked()).isEqualTo(true);
- assertThat(mHidePrivateSpaceSensitiveNotificationsController.setChecked(false)).isTrue();
- assertThat(mHidePrivateSpaceSensitiveNotificationsController.isChecked()).isEqualTo(false);
- }
-}
diff --git a/tests/unit/src/com/android/settings/privatespace/PrivateSpaceMaintainerTest.java b/tests/unit/src/com/android/settings/privatespace/PrivateSpaceMaintainerTest.java
index 50f67d3..f75e76f 100644
--- a/tests/unit/src/com/android/settings/privatespace/PrivateSpaceMaintainerTest.java
+++ b/tests/unit/src/com/android/settings/privatespace/PrivateSpaceMaintainerTest.java
@@ -21,16 +21,23 @@
import static com.android.settings.privatespace.PrivateSpaceMaintainer.HIDE_PRIVATE_SPACE_ENTRY_POINT_DISABLED_VAL;
import static com.android.settings.privatespace.PrivateSpaceMaintainer.HIDE_PRIVATE_SPACE_ENTRY_POINT_ENABLED_VAL;
+import static com.android.settings.privatespace.PrivateSpaceMaintainer.HIDE_PRIVATE_SPACE_SENSITIVE_NOTIFICATIONS_DISABLED_VAL;
import static com.android.settings.privatespace.PrivateSpaceMaintainer.PRIVATE_SPACE_AUTO_LOCK_DEFAULT_VAL;
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
import android.app.ActivityManager;
import android.app.IActivityManager;
import android.content.ContentResolver;
import android.content.Context;
import android.os.Flags;
import android.os.RemoteException;
+import android.os.UserManager;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
@@ -72,6 +79,8 @@
/** Tests that {@link PrivateSpaceMaintainer#deletePrivateSpace()} deletes PS when PS exists. */
@Test
public void deletePrivateSpace_psExists_deletesPS() {
+ mSetFlagsRule.enableFlags(
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
PrivateSpaceMaintainer privateSpaceMaintainer =
PrivateSpaceMaintainer.getInstance(mContext);
privateSpaceMaintainer.createPrivateSpace();
@@ -88,8 +97,11 @@
*/
@Test
public void deletePrivateSpace_psDoesNotExist_returnsNoPSError() {
+ mSetFlagsRule.enableFlags(
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
PrivateSpaceMaintainer privateSpaceMaintainer =
PrivateSpaceMaintainer.getInstance(mContext);
+ privateSpaceMaintainer.deletePrivateSpace();
ErrorDeletingPrivateSpace errorDeletingPrivateSpace =
privateSpaceMaintainer.deletePrivateSpace();
assertThat(errorDeletingPrivateSpace)
@@ -100,6 +112,8 @@
/** Tests that {@link PrivateSpaceMaintainer#createPrivateSpace()} when PS exists creates PS. */
@Test
public void createPrivateSpace_psDoesNotExist_createsPS() {
+ mSetFlagsRule.enableFlags(
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
PrivateSpaceMaintainer privateSpaceMaintainer =
PrivateSpaceMaintainer.getInstance(mContext);
privateSpaceMaintainer.deletePrivateSpace();
@@ -113,6 +127,8 @@
*/
@Test
public void createPrivateSpace_psExists_returnsFalse() {
+ mSetFlagsRule.enableFlags(
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
PrivateSpaceMaintainer privateSpaceMaintainer =
PrivateSpaceMaintainer.getInstance(mContext);
privateSpaceMaintainer.deletePrivateSpace();
@@ -127,6 +143,8 @@
*/
@Test
public void createPrivateSpace_psDoesNotExist_resetsHidePSSettings() {
+ mSetFlagsRule.enableFlags(
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
PrivateSpaceMaintainer privateSpaceMaintainer =
PrivateSpaceMaintainer.getInstance(mContext);
Settings.Secure.putInt(
@@ -156,7 +174,7 @@
privateSpaceMaintainer.createPrivateSpace();
assertThat(privateSpaceMaintainer.doesPrivateSpaceExist()).isTrue();
assertThat(getPsSensitiveNotificationsValue(privateSpaceMaintainer))
- .isEqualTo(HidePrivateSpaceSensitiveNotificationsController.DISABLED);
+ .isEqualTo(HIDE_PRIVATE_SPACE_SENSITIVE_NOTIFICATIONS_DISABLED_VAL);
}
/**
@@ -165,6 +183,8 @@
*/
@Test
public void createPrivateSpace_psExists_doesNotResetHidePSSettings() {
+ mSetFlagsRule.enableFlags(
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
PrivateSpaceMaintainer privateSpaceMaintainer =
PrivateSpaceMaintainer.getInstance(mContext);
privateSpaceMaintainer.createPrivateSpace();
@@ -178,12 +198,38 @@
.isEqualTo(HIDE_PRIVATE_SPACE_ENTRY_POINT_ENABLED_VAL);
}
+ @Test
+ public void createPrivateSpace_psDoesNotExist_registersTheBroadcastReceiver() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_ALLOW_PRIVATE_PROFILE,
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
+ PrivateSpaceMaintainer privateSpaceMaintainer =
+ PrivateSpaceMaintainer.getInstance(mContext);
+ privateSpaceMaintainer.deletePrivateSpace();
+ privateSpaceMaintainer.createPrivateSpace();
+ // test that no exception is thrown, which would indicate that the receiver was registered.
+ mContext.unregisterReceiver(privateSpaceMaintainer.getBroadcastReceiver());
+ privateSpaceMaintainer.resetBroadcastReceiver();
+ }
+
+ @Test
+ public void deletePrivateSpace_psExists_unregistersTheBroadcastReceiver() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_ALLOW_PRIVATE_PROFILE,
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
+ PrivateSpaceMaintainer privateSpaceMaintainer =
+ PrivateSpaceMaintainer.getInstance(mContext);
+ privateSpaceMaintainer.createPrivateSpace();
+ privateSpaceMaintainer.deletePrivateSpace();
+ assertThat(privateSpaceMaintainer.getBroadcastReceiver()).isNull();
+ }
+
/**
* Tests that {@link PrivateSpaceMaintainer#lockPrivateSpace()} when PS exists and is running
* locks the private profile.
*/
@Test
public void lockPrivateSpace_psExistsAndPrivateProfileRunning_locksCreatedPrivateSpace() {
+ mSetFlagsRule.enableFlags(
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
PrivateSpaceMaintainer privateSpaceMaintainer =
PrivateSpaceMaintainer.getInstance(mContext);
privateSpaceMaintainer.createPrivateSpace();
@@ -200,6 +246,8 @@
*/
@Test
public void lockPrivateSpace_psExistsAndPrivateProfileNotRunning_returnsFalse() {
+ mSetFlagsRule.enableFlags(
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
PrivateSpaceMaintainer privateSpaceMaintainer =
PrivateSpaceMaintainer.getInstance(mContext);
privateSpaceMaintainer.createPrivateSpace();
@@ -220,6 +268,8 @@
*/
@Test
public void lockPrivateSpace_psDoesNotExist_returnsFalse() {
+ mSetFlagsRule.enableFlags(
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
PrivateSpaceMaintainer privateSpaceMaintainer =
PrivateSpaceMaintainer.getInstance(mContext);
assertThat(privateSpaceMaintainer.doesPrivateSpaceExist()).isFalse();
@@ -232,6 +282,8 @@
*/
@Test
public void createPrivateSpace_psDoesNotExist_setsUserSetupComplete() {
+ mSetFlagsRule.enableFlags(
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
PrivateSpaceMaintainer privateSpaceMaintainer =
PrivateSpaceMaintainer.getInstance(mContext);
privateSpaceMaintainer.createPrivateSpace();
@@ -244,6 +296,8 @@
*/
@Test
public void createPrivateSpace_pSExists_doesNotChangeUserSetupSetting() {
+ mSetFlagsRule.enableFlags(
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
PrivateSpaceMaintainer privateSpaceMaintainer =
PrivateSpaceMaintainer.getInstance(mContext);
privateSpaceMaintainer.createPrivateSpace();
@@ -300,6 +354,61 @@
.isEqualTo(privateSpaceAutLockValue);
}
+ @Test
+ public void isPrivateSpaceEntryPointEnabled_psExistCanAddProfileTrue_returnsTrue() {
+ mSetFlagsRule.enableFlags(
+ Flags.FLAG_ALLOW_PRIVATE_PROFILE,
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
+ assumeTrue(mContext.getSystemService(UserManager.class).canAddPrivateProfile());
+ PrivateSpaceMaintainer privateSpaceMaintainer =
+ PrivateSpaceMaintainer.getInstance(mContext);
+ privateSpaceMaintainer.createPrivateSpace();
+ assertThat(privateSpaceMaintainer.doesPrivateSpaceExist()).isTrue();
+
+ assertThat(privateSpaceMaintainer.isPrivateSpaceEntryPointEnabled()).isTrue();
+ }
+
+ @Test
+ public void isPrivateSpaceEntryPointEnabled_psNotExistsCanAddProfileTrue_returnsTrue() {
+ mSetFlagsRule.enableFlags(
+ Flags.FLAG_ALLOW_PRIVATE_PROFILE,
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
+ assumeTrue(mContext.getSystemService(UserManager.class).canAddPrivateProfile());
+ PrivateSpaceMaintainer privateSpaceMaintainer =
+ PrivateSpaceMaintainer.getInstance(mContext);
+ privateSpaceMaintainer.deletePrivateSpace();
+ assertThat(privateSpaceMaintainer.doesPrivateSpaceExist()).isFalse();
+
+ assertThat(privateSpaceMaintainer.isPrivateSpaceEntryPointEnabled()).isTrue();
+ }
+
+ @Test
+ public void isPrivateSpaceEntryPointEnabled_psExistsCanAddProfileFalse_returnsTrue() {
+ mSetFlagsRule.enableFlags(
+ Flags.FLAG_ALLOW_PRIVATE_PROFILE,
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
+ assumeFalse(mContext.getSystemService(UserManager.class).canAddPrivateProfile());
+ PrivateSpaceMaintainer privateSpaceMaintainer =
+ spy(PrivateSpaceMaintainer.getInstance(mContext));
+ when(privateSpaceMaintainer.doesPrivateSpaceExist()).thenReturn(true);
+
+ assertThat(privateSpaceMaintainer.isPrivateSpaceEntryPointEnabled()).isTrue();
+ }
+
+ @Test
+ public void isPrivateSpaceEntryPointEnabled_psNotExistsCanAddProfileFalse_returnsFalse() {
+ mSetFlagsRule.enableFlags(
+ Flags.FLAG_ALLOW_PRIVATE_PROFILE,
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
+ assumeFalse(mContext.getSystemService(UserManager.class).canAddPrivateProfile());
+ PrivateSpaceMaintainer privateSpaceMaintainer =
+ PrivateSpaceMaintainer.getInstance(mContext);
+ privateSpaceMaintainer.deletePrivateSpace();
+ assertThat(privateSpaceMaintainer.doesPrivateSpaceExist()).isFalse();
+
+ assertThat(privateSpaceMaintainer.isPrivateSpaceEntryPointEnabled()).isFalse();
+ }
+
private int getSecureUserSetupComplete() {
PrivateSpaceMaintainer privateSpaceMaintainer =
PrivateSpaceMaintainer.getInstance(mContext);
@@ -313,7 +422,7 @@
private int getPsSensitiveNotificationsValue(PrivateSpaceMaintainer privateSpaceMaintainer) {
return Settings.Secure.getIntForUser(mContentResolver,
LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
- HidePrivateSpaceSensitiveNotificationsController.ENABLED,
+ /* enabled */ 1,
privateSpaceMaintainer.getPrivateProfileHandle().getIdentifier());
}
}
diff --git a/tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java b/tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java
new file mode 100644
index 0000000..22d43c9
--- /dev/null
+++ b/tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.wifi;
+
+import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.UserManager;
+
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+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;
+
+@RunWith(AndroidJUnit4.class)
+@UiThreadTest
+public class AddNetworkFragmentTest {
+
+ @Rule
+ public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+ @Spy
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+ @Mock
+ private UserManager mUserManager;
+
+ private AddNetworkFragment mFragment;
+
+ @Before
+ public void setUp() {
+ when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
+
+ mFragment = new AddNetworkFragment();
+ }
+
+ @Test
+ public void isAddWifiConfigAllowed_hasNoUserRestriction_returnTrue() {
+ when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(false);
+
+ assertThat(mFragment.isAddWifiConfigAllowed(mContext)).isTrue();
+ }
+
+ @Test
+ public void isAddWifiConfigAllowed_hasUserRestriction_returnFalse() {
+ when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(true);
+
+ assertThat(mFragment.isAddWifiConfigAllowed(mContext)).isFalse();
+ }
+}
diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
new file mode 100644
index 0000000..4d723dc1
--- /dev/null
+++ b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.wifi.dpp;
+
+import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.UserManager;
+
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+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;
+
+@RunWith(AndroidJUnit4.class)
+@UiThreadTest
+public class WifiDppConfiguratorActivityTest {
+
+ @Rule
+ public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+ @Spy
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+ @Mock
+ private UserManager mUserManager;
+
+ private WifiDppConfiguratorActivity mActivity;
+
+ @Before
+ public void setUp() {
+ when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
+
+ mActivity = new WifiDppConfiguratorActivity();
+ }
+
+ @Test
+ public void isAddWifiConfigAllowed_hasNoUserRestriction_returnTrue() {
+ when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(false);
+
+ assertThat(mActivity.isAddWifiConfigAllowed(mContext)).isTrue();
+ }
+
+ @Test
+ public void isAddWifiConfigAllowed_hasUserRestriction_returnFalse() {
+ when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(true);
+
+ assertThat(mActivity.isAddWifiConfigAllowed(mContext)).isFalse();
+ }
+}
diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiQrCodeTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiQrCodeTest.java
deleted file mode 100644
index e3a8ca5..0000000
--- a/tests/unit/src/com/android/settings/wifi/dpp/WifiQrCodeTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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.wifi.dpp;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class WifiQrCodeTest {
- @Test
- public void testZxParsing_validCode() {
- WifiNetworkConfig config = new WifiQrCode("WIFI:S:testAbC;T:nopass").getWifiNetworkConfig();
- assertThat(config.getSsid()).isEqualTo("testAbC");
- assertThat(config.getSecurity()).isEqualTo("nopass");
-
- config = new WifiQrCode(
- "WIFI:S:reallyLONGone;T:WEP;P:somepasswo#%^**123rd").getWifiNetworkConfig();
- assertThat(config.getSsid()).isEqualTo("reallyLONGone");
- assertThat(config.getSecurity()).isEqualTo("WEP");
- assertThat(config.getPreSharedKey()).isEqualTo("somepasswo#%^**123rd");
-
- config = new WifiQrCode("WIFI:S:anotherone;T:WPA;P:3#=3j9asicla").getWifiNetworkConfig();
- assertThat(config.getSsid()).isEqualTo("anotherone");
- assertThat(config.getSecurity()).isEqualTo("WPA");
- assertThat(config.getPreSharedKey()).isEqualTo("3#=3j9asicla");
-
- config = new WifiQrCode("WIFI:S:xx;T:SAE;P:a").getWifiNetworkConfig();
- assertThat(config.getSsid()).isEqualTo("xx");
- assertThat(config.getSecurity()).isEqualTo("SAE");
- assertThat(config.getPreSharedKey()).isEqualTo("a");
- }
-
- @Test
- public void testZxParsing_invalidCodeButShouldWork() {
- WifiNetworkConfig config = new WifiQrCode(
- "WIFI:S:testAbC; T:nopass").getWifiNetworkConfig();
- assertThat(config.getSsid()).isEqualTo("testAbC");
- assertThat(config.getSecurity()).isEqualTo("nopass");
-
- config = new WifiQrCode(
- "WIFI:S:reallyLONGone;T:WEP; P:somepassword").getWifiNetworkConfig();
- assertThat(config.getSsid()).isEqualTo("reallyLONGone");
- assertThat(config.getSecurity()).isEqualTo("WEP");
- assertThat(config.getPreSharedKey()).isEqualTo("somepassword");
-
- config = new WifiQrCode("WIFI: S:anotherone;T:WPA;P:abcdefghihklmn").getWifiNetworkConfig();
- assertThat(config.getSsid()).isEqualTo("anotherone");
- assertThat(config.getSecurity()).isEqualTo("WPA");
- assertThat(config.getPreSharedKey()).isEqualTo("abcdefghihklmn");
-
- config = new WifiQrCode("WIFI: S:xx; T:SAE; P:a").getWifiNetworkConfig();
- assertThat(config.getSsid()).isEqualTo("xx");
- assertThat(config.getSecurity()).isEqualTo("SAE");
- assertThat(config.getPreSharedKey()).isEqualTo("a");
- }
-}