Snap for 12616459 from 9d1515e3ca to 25Q1-release

Change-Id: Id11744dba6165ba9da196e11833373c8c6f574f3
This commit is contained in:
Android Build Coastguard Worker
2024-11-07 00:25:22 +00:00
40 changed files with 1111 additions and 159 deletions

View File

@@ -1567,7 +1567,7 @@
<item>@*android:drawable/ic_zen_mode_icon_child</item> <item>@*android:drawable/ic_zen_mode_icon_child</item>
<item>@*android:drawable/ic_zen_mode_icon_animal_paw</item> <item>@*android:drawable/ic_zen_mode_icon_animal_paw</item>
<!-- Generic / abstract --> <!-- Generic / abstract -->
<item>@*android:drawable/ic_zen_mode_type_unknown</item> <!-- Star badge --> <item>@*android:drawable/ic_zen_mode_icon_star_badge</item>
<item>@*android:drawable/ic_zen_mode_type_managed</item> <!-- Two people / Supervisor --> <item>@*android:drawable/ic_zen_mode_type_managed</item> <!-- Two people / Supervisor -->
<item>@*android:drawable/ic_zen_mode_type_other</item> <!-- Star --> <item>@*android:drawable/ic_zen_mode_type_other</item> <!-- Star -->
<item>@*android:drawable/ic_zen_mode_icon_heart</item> <item>@*android:drawable/ic_zen_mode_icon_heart</item>

View File

@@ -9041,6 +9041,13 @@
<string name="notification_polite_work">Apply to work profiles</string> <string name="notification_polite_work">Apply to work profiles</string>
<string name="notification_polite_work_summary">Apply to work profile apps</string> <string name="notification_polite_work_summary">Apply to work profile apps</string>
<!-- Title for Bundled Notifications setting [CHAR LIMIT=45]-->
<string name="notification_bundle_title">Bundled notifications</string>
<string name="notification_bundle_on">On</string>
<string name="notification_bundle_off">Off</string>
<string name="notification_bundle_main_control_title">Use notification bundling</string>
<string name="notification_bundle_description">Notifications with similar themes will be silenced and grouped together for a quieter experience. Bundling will override an app\'s own notification settings.</string>
<!-- Title for managing VR (virtual reality) helper services. [CHAR LIMIT=50] --> <!-- Title for managing VR (virtual reality) helper services. [CHAR LIMIT=50] -->
<string name="vr_listeners_title">VR helper services</string> <string name="vr_listeners_title">VR helper services</string>
@@ -13781,9 +13788,12 @@
<string name="contacts_storage_no_account_set_summary">No default set</string> <string name="contacts_storage_no_account_set_summary">No default set</string>
<!-- Text for displaying when default account is set as local only [CHAR LIMIT=50] --> <!-- Text for displaying when default account is set as local only [CHAR LIMIT=50] -->
<string name="contacts_storage_local_account_summary">Device only</string> <string name="contacts_storage_local_account_summary">Device only</string>
<!-- Text for displaying eligible account preference title [CHAR LIMIT=50] -->
<string name="contacts_storage_account_title">Device and %1$s</string>
<!-- Text for add account selection message when no account has been added [CHAR LIMIT=100] --> <!-- Text for add account selection message when no account has been added [CHAR LIMIT=100] -->
<string name="contacts_storage_first_time_add_account_message">Add an account to get started</string> <string name="contacts_storage_first_time_add_account_message">Add an account to get started</string>
<!-- Text for account preference category title for contacts storage settings page [CHAR LIMIT=100] -->
<string name="contacts_storage_account_category_title">Where to save contacts</string>
<!-- Circle to Search (shared between all entrypoints) --> <!-- Circle to Search (shared between all entrypoints) -->
<!-- Name of Google's new feature to circle to search anything on your phone screen, <!-- Name of Google's new feature to circle to search anything on your phone screen,
without switching apps. Also used as the setting title. [CHAR LIMIT=60] --> without switching apps. Also used as the setting title. [CHAR LIMIT=60] -->

View File

@@ -20,7 +20,8 @@
android:title="@string/accessibility_hearingaid_title"> android:title="@string/accessibility_hearingaid_title">
<com.android.settingslib.widget.TopIntroPreference <com.android.settingslib.widget.TopIntroPreference
android:title="@string/accessibility_hearingaid_intro" /> android:title="@string/accessibility_hearingaid_intro"
settings:searchable="false" />
<PreferenceCategory <PreferenceCategory
android:key="available_hearing_devices" android:key="available_hearing_devices"

View File

@@ -0,0 +1,59 @@
<?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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:title="@string/notification_bundle_title">
<com.android.settingslib.widget.IllustrationPreference
android:key="illustration"
settings:searchable="false"
android:selectable="false"
app:lottie_cacheComposition="false"
settings:dynamicColor="true"/>
<com.android.settingslib.widget.TopIntroPreference
android:key="feature_description"
settings:searchable="false"
android:title="@string/notification_bundle_description"/>
<com.android.settingslib.widget.MainSwitchPreference
android:key="global_pref"
android:title="@string/notification_bundle_main_control_title"
settings:controller="com.android.settings.notification.BundleGlobalPreferenceController" />
<CheckBoxPreference
android:key="promotions"
android:title="@*android:string/promotional_notification_channel_label"
settings:controller="com.android.settings.notification.BundleTypePreferenceController"/>
<CheckBoxPreference
android:key="news"
android:title="@*android:string/news_notification_channel_label"
settings:controller="com.android.settings.notification.BundleTypePreferenceController"/>
<CheckBoxPreference
android:key="social"
android:title="@*android:string/social_notification_channel_label"
settings:controller="com.android.settings.notification.BundleTypePreferenceController"/>
<CheckBoxPreference
android:key="recs"
android:title="@*android:string/recs_notification_channel_label"
settings:controller="com.android.settings.notification.BundleTypePreferenceController"/>
</PreferenceScreen>

View File

@@ -43,6 +43,14 @@
android:targetPackage="com.android.settings" android:targetPackage="com.android.settings"
android:targetClass="com.android.settings.notification.history.NotificationHistoryActivity" /> android:targetClass="com.android.settings.notification.history.NotificationHistoryActivity" />
</Preference> </Preference>
<Preference
android:fragment="com.android.settings.notification.BundlePreferenceFragment"
android:key="bundle_notifications_preference"
android:persistent="false"
android:order="12"
android:title="@string/notification_bundle_title"
settings:controller="com.android.settings.notification.BundlePreferenceController" />
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory <PreferenceCategory

View File

@@ -22,6 +22,12 @@
<com.android.settingslib.widget.TopIntroPreference <com.android.settingslib.widget.TopIntroPreference
android:title="@string/contacts_storage_selection_message" /> android:title="@string/contacts_storage_selection_message" />
<PreferenceCategory
android:key="account_category"
android:persistent="false"
android:title="@string/contacts_storage_account_category_title">
</PreferenceCategory>
<com.android.settingslib.widget.SelectorWithWidgetPreference <com.android.settingslib.widget.SelectorWithWidgetPreference
android:key="device_only_account_preference" android:key="device_only_account_preference"
android:summary="@string/contacts_storage_device_only_preference_summary" android:summary="@string/contacts_storage_device_only_preference_summary"

View File

@@ -27,11 +27,6 @@
settings:controller="com.android.settings.dream.DreamMainSwitchPreferenceController" settings:controller="com.android.settings.dream.DreamMainSwitchPreferenceController"
settings:searchable="false"/> settings:searchable="false"/>
<Preference
android:key="when_to_start"
android:title="@string/screensaver_settings_when_to_dream"
android:fragment="com.android.settings.dream.WhenToDreamPicker"/>
<PreferenceCategory <PreferenceCategory
android:title="@string/dream_picker_category"> android:title="@string/dream_picker_category">
<com.android.settingslib.widget.LayoutPreference <com.android.settingslib.widget.LayoutPreference
@@ -40,6 +35,11 @@
android:layout="@layout/dream_picker_layout"/> android:layout="@layout/dream_picker_layout"/>
</PreferenceCategory> </PreferenceCategory>
<Preference
android:key="when_to_start"
android:title="@string/screensaver_settings_when_to_dream"
android:fragment="com.android.settings.dream.WhenToDreamPicker"/>
<SwitchPreferenceCompat <SwitchPreferenceCompat
android:key="dream_complications_toggle" android:key="dream_complications_toggle"
android:title="@string/dream_complications_toggle_title" android:title="@string/dream_complications_toggle_title"

View File

@@ -0,0 +1,44 @@
/*
* 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
import android.content.Context
import android.os.UserHandle
import androidx.annotation.CallSuper
import com.android.settingslib.RestrictedLockUtilsInternal
import com.android.settingslib.metadata.PreferenceRestrictionProvider
/** Mixin to support restriction. */
interface PreferenceRestrictionMixin : PreferenceRestrictionProvider {
val restrictionKey: String
val useAdminDisabledSummary: Boolean
get() = false
@CallSuper fun isEnabled(context: Context) = !context.hasBaseUserRestriction(restrictionKey)
override fun isRestricted(context: Context) =
RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
context,
restrictionKey,
UserHandle.myUserId(),
) != null
}
fun Context.hasBaseUserRestriction(restrictionKey: String) =
RestrictedLockUtilsInternal.hasBaseUserRestriction(this, restrictionKey, UserHandle.myUserId())

View File

@@ -33,6 +33,7 @@ import android.widget.CheckedTextView;
import android.widget.ListAdapter; import android.widget.ListAdapter;
import android.widget.ListView; import android.widget.ListView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AlertDialog.Builder; import androidx.appcompat.app.AlertDialog.Builder;
import androidx.preference.ListPreferenceDialogFragmentCompat; import androidx.preference.ListPreferenceDialogFragmentCompat;
@@ -40,11 +41,14 @@ import androidx.preference.PreferenceViewHolder;
import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedPreferenceHelper; import com.android.settingslib.RestrictedPreferenceHelper;
import com.android.settingslib.RestrictedPreferenceHelperProvider;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class RestrictedListPreference extends CustomListPreference { public class RestrictedListPreference extends CustomListPreference implements
RestrictedPreferenceHelperProvider {
private final RestrictedPreferenceHelper mHelper; private final RestrictedPreferenceHelper mHelper;
private final List<RestrictedItem> mRestrictedItems = new ArrayList<>(); private final List<RestrictedItem> mRestrictedItems = new ArrayList<>();
private boolean mRequiresActiveUnlockedProfile = false; private boolean mRequiresActiveUnlockedProfile = false;
@@ -61,6 +65,11 @@ public class RestrictedListPreference extends CustomListPreference {
mHelper = new RestrictedPreferenceHelper(context, this, attrs); mHelper = new RestrictedPreferenceHelper(context, this, attrs);
} }
@Override
public @NonNull RestrictedPreferenceHelper getRestrictedPreferenceHelper() {
return mHelper;
}
@Override @Override
public void onBindViewHolder(PreferenceViewHolder holder) { public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder); super.onBindViewHolder(holder);

View File

@@ -46,6 +46,7 @@ import com.android.settingslib.datastore.BackupRestoreStorageManager;
import com.android.settingslib.metadata.PreferenceScreenMetadata; import com.android.settingslib.metadata.PreferenceScreenMetadata;
import com.android.settingslib.metadata.PreferenceScreenRegistry; import com.android.settingslib.metadata.PreferenceScreenRegistry;
import com.android.settingslib.metadata.ProvidePreferenceScreenOptions; import com.android.settingslib.metadata.ProvidePreferenceScreenOptions;
import com.android.settingslib.preference.PreferenceBindingFactory;
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory; import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory;
import com.google.android.setupcompat.util.WizardManagerHelper; import com.google.android.setupcompat.util.WizardManagerHelper;
@@ -76,6 +77,7 @@ public class SettingsApplication extends Application {
if (Flags.catalyst()) { if (Flags.catalyst()) {
PreferenceScreenRegistry.INSTANCE.setPreferenceScreensSupplier( PreferenceScreenRegistry.INSTANCE.setPreferenceScreensSupplier(
this::getPreferenceScreens); this::getPreferenceScreens);
PreferenceBindingFactory.setDefaultFactory(new SettingsPreferenceBindingFactory());
} }
BackupRestoreStorageManager.getInstance(this) BackupRestoreStorageManager.getInstance(this)

View File

@@ -0,0 +1,49 @@
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings
import android.os.UserHandle
import androidx.preference.Preference
import com.android.settingslib.RestrictedPreferenceHelperProvider
import com.android.settingslib.metadata.PreferenceHierarchyNode
import com.android.settingslib.preference.DefaultPreferenceBindingFactory
import com.android.settingslib.preference.PreferenceBinding
/** Preference binding factory for settings app. */
class SettingsPreferenceBindingFactory : DefaultPreferenceBindingFactory() {
override fun bind(
preference: Preference,
node: PreferenceHierarchyNode,
preferenceBinding: PreferenceBinding?,
) {
super.bind(preference, node, preferenceBinding)
// handle restriction consistently
val metadata = node.metadata
if (metadata is PreferenceRestrictionMixin) {
if (preference is RestrictedPreferenceHelperProvider) {
preference.getRestrictedPreferenceHelper().apply {
val restrictionKey = metadata.restrictionKey
if (!preference.context.hasBaseUserRestriction(restrictionKey)) {
useAdminDisabledSummary(metadata.useAdminDisabledSummary)
checkRestrictionAndSetDisabled(restrictionKey, UserHandle.myUserId())
}
}
}
}
}
}

View File

@@ -61,6 +61,9 @@ public class ContactsStoragePreferenceController extends BasePreferenceControlle
@Override @Override
public CharSequence getSummary() { public CharSequence getSummary() {
if (mCurrentDefaultAccountAndState != null) { if (mCurrentDefaultAccountAndState != null) {
// Re-fetch account in controller to refresh the latest set default account.
mCurrentDefaultAccountAndState =
DefaultAccount.getDefaultAccountForNewContacts(mContext.getContentResolver());
int currentDefaultAccountState = mCurrentDefaultAccountAndState.getState(); int currentDefaultAccountState = mCurrentDefaultAccountAndState.getState();
Account currentDefaultAccount = mCurrentDefaultAccountAndState.getAccount(); Account currentDefaultAccount = mCurrentDefaultAccountAndState.getAccount();
if (currentDefaultAccountState if (currentDefaultAccountState

View File

@@ -25,6 +25,7 @@ import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
import android.os.UserHandle; import android.os.UserHandle;
import android.provider.ContactsContract.RawContacts.DefaultAccount.DefaultAccountAndState; import android.provider.ContactsContract.RawContacts.DefaultAccount.DefaultAccountAndState;
@@ -36,7 +37,7 @@ import androidx.annotation.Nullable;
import androidx.annotation.UiThread; import androidx.annotation.UiThread;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.Preference.OnPreferenceClickListener; import androidx.preference.Preference.OnPreferenceClickListener;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceGroup;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R; import com.android.settings.R;
@@ -63,6 +64,7 @@ public class ContactsStorageSettings extends DashboardFragment
private static final String TAG = "ContactsStorageSettings"; private static final String TAG = "ContactsStorageSettings";
private static final String PREF_KEY_ADD_ACCOUNT = "add_account"; private static final String PREF_KEY_ADD_ACCOUNT = "add_account";
private static final String PREF_KEY_DEVICE_ONLY = "device_only_account_preference"; private static final String PREF_KEY_DEVICE_ONLY = "device_only_account_preference";
private static final String PREF_KEY_ACCOUNT_CATEGORY = "account_category";
private final Map<String, DefaultAccountAndState> mAccountMap = new HashMap<>(); private final Map<String, DefaultAccountAndState> mAccountMap = new HashMap<>();
private AuthenticatorHelper mAuthenticatorHelper; private AuthenticatorHelper mAuthenticatorHelper;
@@ -71,6 +73,12 @@ public class ContactsStorageSettings extends DashboardFragment
super.onAttach(context); super.onAttach(context);
mAuthenticatorHelper = new AuthenticatorHelper(context, mAuthenticatorHelper = new AuthenticatorHelper(context,
new UserHandle(UserHandle.myUserId()), null); new UserHandle(UserHandle.myUserId()), null);
String[] accountTypes = getEligibleAccountTypes();
for (String accountType : accountTypes) {
// Preload the drawable for the account type to avoid the latency when rendering the
// account preference.
mAuthenticatorHelper.preloadDrawableForType(context, accountType);
}
} }
@UiThread @UiThread
@@ -130,23 +138,24 @@ public class ContactsStorageSettings extends DashboardFragment
// Clear all the accounts stored in the map and later on re-fetch the eligible accounts // Clear all the accounts stored in the map and later on re-fetch the eligible accounts
// when creating eligible account preferences. // when creating eligible account preferences.
mAccountMap.clear(); mAccountMap.clear();
final PreferenceScreen screen = getPreferenceScreen(); final PreferenceGroup preferenceGroup = findPreference(PREF_KEY_ACCOUNT_CATEGORY);
// If the default account is SIM, we should show in the page, otherwise don't show. // If the default account is SIM, we should show in the page, otherwise don't show.
SelectorWithWidgetPreference simAccountPreference = buildSimAccountPreference(); SelectorWithWidgetPreference simAccountPreference = buildSimAccountPreference();
if (simAccountPreference != null) { if (simAccountPreference != null) {
getPreferenceScreen().addPreference(simAccountPreference); preferenceGroup.addPreference(simAccountPreference);
} }
List<Account> accounts = DefaultAccount.getEligibleCloudAccounts(getContentResolver()); List<Account> accounts = DefaultAccount.getEligibleCloudAccounts(getContentResolver());
for (int i = 0; i < accounts.size(); i++) { for (int i = 0; i < accounts.size(); i++) {
screen.addPreference(buildCloudAccountPreference(accounts.get(i), /*order=*/i)); preferenceGroup.addPreference(
buildCloudAccountPreference(accounts.get(i), /*order=*/i));
} }
// If there's no eligible account types, the "Add Account" preference should // If there's no eligible account types, the "Add Account" preference should
// not be shown to the users. // not be shown to the users.
if (getEligibleAccountTypes().length > 0) { if (getEligibleAccountTypes().length > 0) {
screen.addPreference(buildAddAccountPreference(accounts.isEmpty())); getPreferenceScreen().addPreference(buildAddAccountPreference(accounts.isEmpty()));
} }
setupDeviceOnlyPreference(); setupDeviceOnlyPreference();
setDefaultAccountPreference(); setDefaultAccountPreference(preferenceGroup);
} }
private void setupDeviceOnlyPreference() { private void setupDeviceOnlyPreference() {
@@ -157,7 +166,7 @@ public class ContactsStorageSettings extends DashboardFragment
} }
} }
private void setDefaultAccountPreference() { private void setDefaultAccountPreference(PreferenceGroup preferenceGroup) {
DefaultAccountAndState currentDefaultAccountAndState = DefaultAccountAndState currentDefaultAccountAndState =
DefaultAccount.getDefaultAccountForNewContacts(getContentResolver()); DefaultAccount.getDefaultAccountForNewContacts(getContentResolver());
String preferenceKey = getAccountHashCode(currentDefaultAccountAndState); String preferenceKey = getAccountHashCode(currentDefaultAccountAndState);
@@ -170,20 +179,21 @@ public class ContactsStorageSettings extends DashboardFragment
preference = getPreferenceScreen().findPreference(preferenceKey); preference = getPreferenceScreen().findPreference(preferenceKey);
} else if (preferenceKey != null && currentDefaultAccount != null) { } else if (preferenceKey != null && currentDefaultAccount != null) {
preference = buildCloudAccountPreference(currentDefaultAccount, mAccountMap.size()); preference = buildCloudAccountPreference(currentDefaultAccount, mAccountMap.size());
getPreferenceScreen().addPreference(preference); preferenceGroup.addPreference(preference);
} }
if (preference != null) { if (preference != null) {
preference.setChecked(true); preference.setChecked(true);
} }
} }
//TODO: Add preference category on account preferences.
private SelectorWithWidgetPreference buildCloudAccountPreference(Account account, int order) { private SelectorWithWidgetPreference buildCloudAccountPreference(Account account, int order) {
SelectorWithWidgetPreference preference = new SelectorWithWidgetPreference( SelectorWithWidgetPreference preference = new SelectorWithWidgetPreference(
getPrefContext()); getPrefContext());
DefaultAccountAndState accountAndState = DefaultAccountAndState.ofCloud(account); DefaultAccountAndState accountAndState = DefaultAccountAndState.ofCloud(account);
String preferenceKey = getAccountHashCode(accountAndState); String preferenceKey = getAccountHashCode(accountAndState);
preference.setTitle(mAuthenticatorHelper.getLabelForType(getPrefContext(), account.type)); String accountPreferenceTitle = getString(R.string.contacts_storage_account_title,
mAuthenticatorHelper.getLabelForType(getPrefContext(), account.type));
preference.setTitle(accountPreferenceTitle);
preference.setIcon(mAuthenticatorHelper.getDrawableForType(getPrefContext(), account.type)); preference.setIcon(mAuthenticatorHelper.getDrawableForType(getPrefContext(), account.type));
preference.setSummary(account.name); preference.setSummary(account.name);
preference.setKey(preferenceKey); preference.setKey(preferenceKey);

View File

@@ -16,6 +16,7 @@
package com.android.settings.biometrics.fingerprint2.domain.interactor package com.android.settings.biometrics.fingerprint2.domain.interactor
import android.util.Log
import android.view.accessibility.AccessibilityEvent import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityEvent.TYPE_ANNOUNCEMENT import android.view.accessibility.AccessibilityEvent.TYPE_ANNOUNCEMENT
import android.view.accessibility.AccessibilityManager import android.view.accessibility.AccessibilityManager
@@ -30,13 +31,16 @@ import kotlinx.coroutines.flow.stateIn
interface AccessibilityInteractor { interface AccessibilityInteractor {
/** A flow that contains whether or not accessibility is enabled */ /** A flow that contains whether or not accessibility is enabled */
fun isEnabledFlow(scope: CoroutineScope): Flow<Boolean> fun isEnabledFlow(scope: CoroutineScope): Flow<Boolean>
val isEnabled: Boolean val isEnabled: Boolean
fun announce(clazz: Class<*>, announcement: CharSequence?) fun announce(clazz: Class<*>, announcement: CharSequence?)
fun interrupt()
} }
class AccessibilityInteractorImpl( class AccessibilityInteractorImpl(private val accessibilityManager: AccessibilityManager) :
private val accessibilityManager: AccessibilityManager, AccessibilityInteractor {
) : AccessibilityInteractor {
/** A flow that contains whether or not accessibility is enabled */ /** A flow that contains whether or not accessibility is enabled */
override fun isEnabledFlow(scope: CoroutineScope): Flow<Boolean> = override fun isEnabledFlow(scope: CoroutineScope): Flow<Boolean> =
callbackFlow { callbackFlow {
@@ -63,4 +67,17 @@ class AccessibilityInteractorImpl(
event.text.add(announcement) event.text.add(announcement)
accessibilityManager.sendAccessibilityEvent(event) accessibilityManager.sendAccessibilityEvent(event)
} }
/** Interrupts the current accessibility manager from announcing a phrase. */
override fun interrupt() {
try {
accessibilityManager.interrupt()
} catch (e: IllegalStateException) {
Log.e(TAG, "Error trying to interrupt when accessibility isn't enabled $e")
}
}
companion object {
const val TAG = "AccessibilityInteractor"
}
} }

View File

@@ -19,10 +19,13 @@ package com.android.settings.biometrics.fingerprint2.domain.interactor
import android.content.Context import android.content.Context
import android.view.OrientationEventListener import android.view.OrientationEventListener
import com.android.internal.R import com.android.internal.R
import com.android.settings.biometrics.fingerprint2.lib.model.Orientation
import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.transform import kotlinx.coroutines.flow.transform
/** Interactor which provides information about orientation */ /** Interactor which provides information about orientation */
@@ -45,6 +48,9 @@ interface OrientationInteractor {
* [R.bool.config_reverseDefaultConfigRotation] * [R.bool.config_reverseDefaultConfigRotation]
*/ */
fun getRotationFromDefault(rotation: Int): Int fun getRotationFromDefault(rotation: Int): Int
/** Indicates an orientation changed event has occurred */
val orientationChanged: Flow<Orientation>
} }
class OrientationInteractorImpl(private val context: Context) : OrientationInteractor { class OrientationInteractorImpl(private val context: Context) : OrientationInteractor {
@@ -60,7 +66,10 @@ class OrientationInteractorImpl(private val context: Context) : OrientationInter
awaitClose { orientationEventListener.disable() } awaitClose { orientationEventListener.disable() }
} }
override val rotation: Flow<Int> = orientation.transform { emit(context.display.rotation) } override val rotation: Flow<Int> =
orientation
.transform { emit(context.display.rotation) }
.onStart { emit(context.display.rotation) }
override val rotationFromDefault: Flow<Int> = rotation.map { getRotationFromDefault(it) } override val rotationFromDefault: Flow<Int> = rotation.map { getRotationFromDefault(it) }
@@ -73,4 +82,24 @@ class OrientationInteractorImpl(private val context: Context) : OrientationInter
rotation rotation
} }
} }
override val orientationChanged: Flow<Orientation> =
rotationFromDefault
.map {
when (it) {
1 -> {
Orientation.Portrait
}
2 -> {
Orientation.ReverseLandscape
}
3 -> {
Orientation.UpsideDownPortrait
}
else -> {
Orientation.Landscape
}
}
}
.distinctUntilChanged()
} }

View File

@@ -0,0 +1,32 @@
/*
* 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.biometrics.fingerprint2.lib.model
/** The orientation events correspond to androids internal orientation events. */
sealed class Orientation {
/** Indicates the device is in landscape orientation */
data object Landscape : Orientation()
/** Indicates the device is in reverse landscape orientation */
data object ReverseLandscape : Orientation()
/** Indicates the device is in portrait orientation */
data object Portrait : Orientation()
/** Indicates the device is in the upside down portrait orientation */
data object UpsideDownPortrait : Orientation()
}

View File

@@ -294,6 +294,7 @@ class DeviceDetailsFragmentFormatterImpl(
TwoTargetSwitchPreference( TwoTargetSwitchPreference(
switchPrefModel, switchPrefModel,
primaryOnClick = { triggerAction(model.action) }, primaryOnClick = { triggerAction(model.action) },
primaryEnabled = { !model.disabled }
) )
} else { } else {
SwitchPreference(switchPrefModel) SwitchPreference(switchPrefModel)

View File

@@ -30,6 +30,7 @@ import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
import com.android.settings.dashboard.DashboardFragment; import com.android.settings.dashboard.DashboardFragment;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.RestrictedPreferenceHelper; import com.android.settingslib.RestrictedPreferenceHelper;
import com.android.settingslib.RestrictedPreferenceHelperProvider;
import com.android.settingslib.applications.AppUtils; import com.android.settingslib.applications.AppUtils;
import com.android.settingslib.applications.ApplicationsState; import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.ApplicationsState.AppEntry; import com.android.settingslib.applications.ApplicationsState.AppEntry;
@@ -37,7 +38,7 @@ import com.android.settingslib.utils.ThreadUtils;
import com.android.settingslib.widget.AppSwitchPreference; import com.android.settingslib.widget.AppSwitchPreference;
public class UnrestrictedDataAccessPreference extends AppSwitchPreference implements public class UnrestrictedDataAccessPreference extends AppSwitchPreference implements
DataSaverBackend.Listener { DataSaverBackend.Listener, RestrictedPreferenceHelperProvider {
private static final String ECM_SETTING_IDENTIFIER = "android:unrestricted_data_access"; private static final String ECM_SETTING_IDENTIFIER = "android:unrestricted_data_access";
private final ApplicationsState mApplicationsState; private final ApplicationsState mApplicationsState;
@@ -78,6 +79,11 @@ public class UnrestrictedDataAccessPreference extends AppSwitchPreference implem
return entry.info.packageName + "|" + entry.info.uid; return entry.info.packageName + "|" + entry.info.uid;
} }
@Override
public @NonNull RestrictedPreferenceHelper getRestrictedPreferenceHelper() {
return mHelper;
}
@Override @Override
public void onAttached() { public void onAttached() {
super.onAttached(); super.onAttached();

View File

@@ -16,17 +16,15 @@
package com.android.settings.display package com.android.settings.display
import android.content.Context import android.content.Context
import android.os.Process
import android.os.UserHandle
import android.os.UserManager import android.os.UserManager
import android.provider.Settings import android.provider.Settings
import android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC import android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC
import android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL import android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL
import androidx.preference.Preference import androidx.preference.Preference
import com.android.settings.PreferenceRestrictionMixin
import com.android.settings.R import com.android.settings.R
import com.android.settings.flags.Flags import com.android.settings.flags.Flags
import com.android.settingslib.PrimarySwitchPreference import com.android.settingslib.PrimarySwitchPreference
import com.android.settingslib.RestrictedLockUtilsInternal
import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.datastore.KeyValueStore
import com.android.settingslib.datastore.KeyedObservableDelegate import com.android.settingslib.datastore.KeyedObservableDelegate
import com.android.settingslib.datastore.SettingsStore import com.android.settingslib.datastore.SettingsStore
@@ -35,7 +33,6 @@ import com.android.settingslib.metadata.BooleanValue
import com.android.settingslib.metadata.PersistentPreference import com.android.settingslib.metadata.PersistentPreference
import com.android.settingslib.metadata.PreferenceAvailabilityProvider import com.android.settingslib.metadata.PreferenceAvailabilityProvider
import com.android.settingslib.metadata.PreferenceMetadata import com.android.settingslib.metadata.PreferenceMetadata
import com.android.settingslib.metadata.PreferenceRestrictionProvider
import com.android.settingslib.metadata.ProvidePreferenceScreen import com.android.settingslib.metadata.ProvidePreferenceScreen
import com.android.settingslib.metadata.ReadWritePermit import com.android.settingslib.metadata.ReadWritePermit
import com.android.settingslib.metadata.preferenceHierarchy import com.android.settingslib.metadata.preferenceHierarchy
@@ -47,7 +44,7 @@ class AutoBrightnessScreen :
PreferenceScreenCreator, PreferenceScreenCreator,
PreferenceScreenBinding, PreferenceScreenBinding,
PreferenceAvailabilityProvider, PreferenceAvailabilityProvider,
PreferenceRestrictionProvider, PreferenceRestrictionMixin,
PersistentPreference<Boolean>, PersistentPreference<Boolean>,
BooleanValue { BooleanValue {
override val key: String override val key: String
@@ -75,23 +72,19 @@ class AutoBrightnessScreen :
com.android.internal.R.bool.config_automatic_brightness_available com.android.internal.R.bool.config_automatic_brightness_available
) )
override fun isEnabled(context: Context) = override fun isEnabled(context: Context) = super<PreferenceRestrictionMixin>.isEnabled(context)
!UserManager.get(context)
.hasBaseUserRestriction(UserManager.DISALLOW_CONFIG_BRIGHTNESS, Process.myUserHandle())
override fun isRestricted(context: Context) = override val restrictionKey: String
RestrictedLockUtilsInternal.checkIfRestrictionEnforced( get() = UserManager.DISALLOW_CONFIG_BRIGHTNESS
context,
UserManager.DISALLOW_CONFIG_BRIGHTNESS, override val useAdminDisabledSummary: Boolean
UserHandle.myUserId(), get() = true
) != null
override fun createWidget(context: Context) = PrimarySwitchPreference(context) override fun createWidget(context: Context) = PrimarySwitchPreference(context)
override fun bind(preference: Preference, metadata: PreferenceMetadata) { override fun bind(preference: Preference, metadata: PreferenceMetadata) {
super.bind(preference, metadata) super.bind(preference, metadata)
(preference as PrimarySwitchPreference).apply { (preference as PrimarySwitchPreference).apply {
useAdminDisabledSummary(true)
isSwitchEnabled = isEnabled isSwitchEnabled = isEnabled
// "true" is not the real default value (it is provided by AutoBrightnessDataStore) // "true" is not the real default value (it is provided by AutoBrightnessDataStore)
isChecked = preferenceDataStore!!.getBoolean(key, true) isChecked = preferenceDataStore!!.getBoolean(key, true)

View File

@@ -23,15 +23,13 @@ import android.content.Intent.EXTRA_BRIGHTNESS_DIALOG_IS_FULL_WIDTH
import android.hardware.display.BrightnessInfo import android.hardware.display.BrightnessInfo
import android.hardware.display.DisplayManager import android.hardware.display.DisplayManager
import android.hardware.display.DisplayManager.DisplayListener import android.hardware.display.DisplayManager.DisplayListener
import android.os.Process
import android.os.UserHandle
import android.os.UserManager import android.os.UserManager
import android.provider.Settings.System import android.provider.Settings.System
import androidx.preference.Preference import androidx.preference.Preference
import com.android.settings.PreferenceRestrictionMixin
import com.android.settings.R import com.android.settings.R
import com.android.settings.Utils import com.android.settings.Utils
import com.android.settings.core.SettingsBaseActivity import com.android.settings.core.SettingsBaseActivity
import com.android.settingslib.RestrictedLockUtilsInternal
import com.android.settingslib.RestrictedPreference import com.android.settingslib.RestrictedPreference
import com.android.settingslib.datastore.HandlerExecutor import com.android.settingslib.datastore.HandlerExecutor
import com.android.settingslib.datastore.KeyedObserver import com.android.settingslib.datastore.KeyedObserver
@@ -42,7 +40,6 @@ import com.android.settingslib.display.BrightnessUtils.convertLinearToGammaFloat
import com.android.settingslib.metadata.PreferenceLifecycleContext import com.android.settingslib.metadata.PreferenceLifecycleContext
import com.android.settingslib.metadata.PreferenceLifecycleProvider import com.android.settingslib.metadata.PreferenceLifecycleProvider
import com.android.settingslib.metadata.PreferenceMetadata import com.android.settingslib.metadata.PreferenceMetadata
import com.android.settingslib.metadata.PreferenceRestrictionProvider
import com.android.settingslib.metadata.PreferenceSummaryProvider import com.android.settingslib.metadata.PreferenceSummaryProvider
import com.android.settingslib.preference.PreferenceBinding import com.android.settingslib.preference.PreferenceBinding
import com.android.settingslib.transition.SettingsTransitionHelper import com.android.settingslib.transition.SettingsTransitionHelper
@@ -52,7 +49,7 @@ import java.text.NumberFormat
class BrightnessLevelRestrictedPreference : class BrightnessLevelRestrictedPreference :
PreferenceMetadata, PreferenceMetadata,
PreferenceBinding, PreferenceBinding,
PreferenceRestrictionProvider, PreferenceRestrictionMixin,
PreferenceSummaryProvider, PreferenceSummaryProvider,
PreferenceLifecycleProvider, PreferenceLifecycleProvider,
Preference.OnPreferenceClickListener { Preference.OnPreferenceClickListener {
@@ -69,35 +66,29 @@ class BrightnessLevelRestrictedPreference :
override val keywords: Int override val keywords: Int
get() = R.string.keywords_display_brightness_level get() = R.string.keywords_display_brightness_level
override fun getSummary(context: Context) = override fun getSummary(context: Context): CharSequence? =
NumberFormat.getPercentInstance().format(getCurrentBrightness(context)) NumberFormat.getPercentInstance().format(getCurrentBrightness(context))
override fun isEnabled(context: Context) = override fun isEnabled(context: Context) = super<PreferenceRestrictionMixin>.isEnabled(context)
!UserManager.get(context)
.hasBaseUserRestriction(UserManager.DISALLOW_CONFIG_BRIGHTNESS, Process.myUserHandle())
override fun isRestricted(context: Context) = override val restrictionKey: String
RestrictedLockUtilsInternal.checkIfRestrictionEnforced( get() = UserManager.DISALLOW_CONFIG_BRIGHTNESS
context,
UserManager.DISALLOW_CONFIG_BRIGHTNESS, override val useAdminDisabledSummary: Boolean
UserHandle.myUserId(), get() = true
) != null
override fun createWidget(context: Context) = RestrictedPreference(context) override fun createWidget(context: Context) = RestrictedPreference(context)
override fun bind(preference: Preference, metadata: PreferenceMetadata) { override fun bind(preference: Preference, metadata: PreferenceMetadata) {
super.bind(preference, metadata) super.bind(preference, metadata)
if (preference is RestrictedPreference) preference.useAdminDisabledSummary(true)
preference.onPreferenceClickListener = this preference.onPreferenceClickListener = this
} }
override fun onStart(context: PreferenceLifecycleContext) { override fun onStart(context: PreferenceLifecycleContext) {
val observer = val observer =
object : KeyedObserver<String> { KeyedObserver<String> { _, _ ->
override fun onKeyChanged(key: String, reason: Int) {
context.notifyPreferenceChange(this@BrightnessLevelRestrictedPreference) context.notifyPreferenceChange(this@BrightnessLevelRestrictedPreference)
} }
}
brightnessObserver = observer brightnessObserver = observer
SettingsSystemStore.get(context) SettingsSystemStore.get(context)
.addObserver(System.SCREEN_AUTO_BRIGHTNESS_ADJ, observer, HandlerExecutor.main) .addObserver(System.SCREEN_AUTO_BRIGHTNESS_ADJ, observer, HandlerExecutor.main)
@@ -113,9 +104,7 @@ class BrightnessLevelRestrictedPreference :
} }
} }
displayListener = listener displayListener = listener
context context.displayManager.registerDisplayListener(
.getSystemService(DisplayManager::class.java)
.registerDisplayListener(
listener, listener,
HandlerExecutor.main, HandlerExecutor.main,
DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS, DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS,
@@ -129,11 +118,14 @@ class BrightnessLevelRestrictedPreference :
} }
displayListener?.let { displayListener?.let {
context.getSystemService(DisplayManager::class.java).unregisterDisplayListener(it) context.displayManager.unregisterDisplayListener(it)
displayListener = null displayListener = null
} }
} }
private val Context.displayManager: DisplayManager
get() = getSystemService(DisplayManager::class.java)!!
override fun onPreferenceClick(preference: Preference): Boolean { override fun onPreferenceClick(preference: Preference): Boolean {
val context = preference.context val context = preference.context
val intent = val intent =

View File

@@ -0,0 +1,61 @@
/*
* 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.notification;
import android.app.Flags;
import android.content.Context;
import androidx.annotation.NonNull;
import com.android.settings.widget.SettingsMainSwitchPreferenceController;
public class BundleGlobalPreferenceController extends
SettingsMainSwitchPreferenceController {
NotificationBackend mBackend;
public BundleGlobalPreferenceController(@NonNull Context context,
@NonNull String preferenceKey) {
super(context, preferenceKey);
mBackend = new NotificationBackend();
}
@Override
public int getAvailabilityStatus() {
if (Flags.notificationClassificationUi() && mBackend.isNotificationBundlingSupported()) {
return AVAILABLE;
}
return CONDITIONALLY_UNAVAILABLE;
}
@Override
public boolean isChecked() {
return mBackend.isNotificationBundlingEnabled(mContext);
}
@Override
public boolean setChecked(boolean isChecked) {
mBackend.setNotificationBundlingEnabled(isChecked);
return true;
}
@Override
public int getSliceHighlightMenuRes() {
// not needed since it's not sliceable
return NO_RES;
}
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.notification;
import android.app.Flags;
import android.content.Context;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
/**
* Controller for the bundled notifications settings page.
*/
public class BundlePreferenceController extends BasePreferenceController {
NotificationBackend mBackend;
public BundlePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
mBackend = new NotificationBackend();
}
@Override
public int getAvailabilityStatus() {
return Flags.notificationClassificationUi() && mBackend.isNotificationBundlingSupported()
? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
}
@Override
public CharSequence getSummary() {
return mBackend.isNotificationBundlingEnabled(mContext)
? mContext.getString(R.string.notification_bundle_on)
: mContext.getString(R.string.notification_bundle_off);
}
}

View File

@@ -0,0 +1,60 @@
/*
* 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.notification;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.app.Flags;
import androidx.lifecycle.Lifecycle;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.search.SearchIndexable;
import org.jetbrains.annotations.NotNull;
/**
* Fragment for bundled notifications.
*/
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class BundlePreferenceFragment extends DashboardFragment {
@Override
public int getMetricsCategory() {
return SettingsEnums.BUNDLED_NOTIFICATIONS;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.bundle_notifications_settings;
}
@Override
protected String getLogTag() {
return "BundlePreferenceFragment";
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.bundle_notifications_settings) {
@Override
protected boolean isPageSearchEnabled(Context context) {
return Flags.notificationClassificationUi();
}
};
}

View File

@@ -0,0 +1,83 @@
/*
* 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.notification;
import android.app.Flags;
import android.content.Context;
import android.service.notification.Adjustment;
import androidx.annotation.NonNull;
import com.android.settings.widget.SettingsMainSwitchPreferenceController;
public class BundleTypePreferenceController extends
SettingsMainSwitchPreferenceController {
static final String PROMO_KEY = "promotions";
static final String NEWS_KEY = "news";
static final String SOCIAL_KEY = "social";
static final String RECS_KEY = "recs";
NotificationBackend mBackend;
int mType;
public BundleTypePreferenceController(@NonNull Context context,
@NonNull String preferenceKey) {
super(context, preferenceKey);
mBackend = new NotificationBackend();
mType = getBundleTypeForKey();
}
@Override
public int getAvailabilityStatus() {
if (Flags.notificationClassificationUi() && mBackend.isNotificationBundlingSupported()
&& mBackend.isNotificationBundlingEnabled(mContext)) {
return AVAILABLE;
}
return CONDITIONALLY_UNAVAILABLE;
}
@Override
public boolean isChecked() {
return mBackend.isBundleTypeApproved(mType);
}
@Override
public boolean setChecked(boolean isChecked) {
mBackend.setBundleTypeState(mType, isChecked);
return true;
}
@Override
public int getSliceHighlightMenuRes() {
// not needed since it's not sliceable
return NO_RES;
}
private @Adjustment.Types int getBundleTypeForKey() {
if (PROMO_KEY.equals(mPreferenceKey)) {
return Adjustment.TYPE_PROMOTION;
} else if (NEWS_KEY.equals(mPreferenceKey)) {
return Adjustment.TYPE_NEWS;
} else if (SOCIAL_KEY.equals(mPreferenceKey)) {
return Adjustment.TYPE_SOCIAL_MEDIA;
} else if (RECS_KEY.equals(mPreferenceKey)) {
return Adjustment.TYPE_CONTENT_RECOMMENDATION;
}
return Adjustment.TYPE_OTHER;
}
}

View File

@@ -20,18 +20,16 @@ import android.content.Context
import android.media.AudioManager import android.media.AudioManager
import android.media.AudioManager.STREAM_BLUETOOTH_SCO import android.media.AudioManager.STREAM_BLUETOOTH_SCO
import android.media.AudioManager.STREAM_VOICE_CALL import android.media.AudioManager.STREAM_VOICE_CALL
import android.os.UserHandle import android.os.UserManager
import android.os.UserManager.DISALLOW_ADJUST_VOLUME
import androidx.preference.Preference import androidx.preference.Preference
import com.android.settings.PreferenceRestrictionMixin
import com.android.settings.R import com.android.settings.R
import com.android.settingslib.RestrictedLockUtilsInternal
import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.datastore.KeyValueStore
import com.android.settingslib.datastore.NoOpKeyedObservable import com.android.settingslib.datastore.NoOpKeyedObservable
import com.android.settingslib.metadata.PersistentPreference import com.android.settingslib.metadata.PersistentPreference
import com.android.settingslib.metadata.PreferenceAvailabilityProvider import com.android.settingslib.metadata.PreferenceAvailabilityProvider
import com.android.settingslib.metadata.PreferenceIconProvider import com.android.settingslib.metadata.PreferenceIconProvider
import com.android.settingslib.metadata.PreferenceMetadata import com.android.settingslib.metadata.PreferenceMetadata
import com.android.settingslib.metadata.PreferenceRestrictionProvider
import com.android.settingslib.metadata.RangeValue import com.android.settingslib.metadata.RangeValue
import com.android.settingslib.metadata.ReadWritePermit import com.android.settingslib.metadata.ReadWritePermit
import com.android.settingslib.preference.PreferenceBinding import com.android.settingslib.preference.PreferenceBinding
@@ -44,7 +42,7 @@ open class CallVolumePreference :
RangeValue, RangeValue,
PreferenceAvailabilityProvider, PreferenceAvailabilityProvider,
PreferenceIconProvider, PreferenceIconProvider,
PreferenceRestrictionProvider { PreferenceRestrictionMixin {
override val key: String override val key: String
get() = KEY get() = KEY
@@ -55,18 +53,12 @@ open class CallVolumePreference :
override fun isAvailable(context: Context) = override fun isAvailable(context: Context) =
context.resources.getBoolean(R.bool.config_show_call_volume) && context.resources.getBoolean(R.bool.config_show_call_volume) &&
!createAudioHelper(context).isSingleVolume() !createAudioHelper(context).isSingleVolume
override fun isRestricted(context: Context) = override fun isEnabled(context: Context) = super<PreferenceRestrictionMixin>.isEnabled(context)
RestrictedLockUtilsInternal.hasBaseUserRestriction(
context, override val restrictionKey: String
DISALLOW_ADJUST_VOLUME, get() = UserManager.DISALLOW_ADJUST_VOLUME
UserHandle.myUserId()
) || RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
context,
DISALLOW_ADJUST_VOLUME,
UserHandle.myUserId()
) != null
override fun storage(context: Context): KeyValueStore { override fun storage(context: Context): KeyValueStore {
val helper = createAudioHelper(context) val helper = createAudioHelper(context)

View File

@@ -18,18 +18,16 @@ package com.android.settings.notification
import android.content.Context import android.content.Context
import android.media.AudioManager.STREAM_MUSIC import android.media.AudioManager.STREAM_MUSIC
import android.os.UserHandle
import android.os.UserManager import android.os.UserManager
import androidx.preference.Preference import androidx.preference.Preference
import com.android.settings.PreferenceRestrictionMixin
import com.android.settings.R import com.android.settings.R
import com.android.settingslib.RestrictedLockUtilsInternal
import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.datastore.KeyValueStore
import com.android.settingslib.datastore.NoOpKeyedObservable import com.android.settingslib.datastore.NoOpKeyedObservable
import com.android.settingslib.metadata.PersistentPreference import com.android.settingslib.metadata.PersistentPreference
import com.android.settingslib.metadata.PreferenceAvailabilityProvider import com.android.settingslib.metadata.PreferenceAvailabilityProvider
import com.android.settingslib.metadata.PreferenceIconProvider import com.android.settingslib.metadata.PreferenceIconProvider
import com.android.settingslib.metadata.PreferenceMetadata import com.android.settingslib.metadata.PreferenceMetadata
import com.android.settingslib.metadata.PreferenceRestrictionProvider
import com.android.settingslib.metadata.RangeValue import com.android.settingslib.metadata.RangeValue
import com.android.settingslib.metadata.ReadWritePermit import com.android.settingslib.metadata.ReadWritePermit
import com.android.settingslib.preference.PreferenceBinding import com.android.settingslib.preference.PreferenceBinding
@@ -42,7 +40,7 @@ open class MediaVolumePreference :
RangeValue, RangeValue,
PreferenceAvailabilityProvider, PreferenceAvailabilityProvider,
PreferenceIconProvider, PreferenceIconProvider,
PreferenceRestrictionProvider { PreferenceRestrictionMixin {
override val key: String override val key: String
get() = KEY get() = KEY
@@ -58,17 +56,10 @@ open class MediaVolumePreference :
override fun isAvailable(context: Context) = override fun isAvailable(context: Context) =
context.resources.getBoolean(R.bool.config_show_media_volume) context.resources.getBoolean(R.bool.config_show_media_volume)
override fun isRestricted(context: Context) = override fun isEnabled(context: Context) = super<PreferenceRestrictionMixin>.isEnabled(context)
RestrictedLockUtilsInternal.hasBaseUserRestriction(
context, override val restrictionKey: String
UserManager.DISALLOW_ADJUST_VOLUME, get() = UserManager.DISALLOW_ADJUST_VOLUME
UserHandle.myUserId(),
) ||
RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
context,
UserManager.DISALLOW_ADJUST_VOLUME,
UserHandle.myUserId(),
) != null
override fun storage(context: Context): KeyValueStore { override fun storage(context: Context): KeyValueStore {
val helper = createAudioHelper(context) val helper = createAudioHelper(context)
@@ -107,9 +98,9 @@ open class MediaVolumePreference :
open fun createAudioHelper(context: Context) = AudioHelper(context) open fun createAudioHelper(context: Context) = AudioHelper(context)
fun updateContentDescription(preference: VolumeSeekBarPreference) { private fun updateContentDescription(preference: VolumeSeekBarPreference) {
when { when {
preference.isMuted() -> preference.isMuted ->
preference.updateContentDescription( preference.updateContentDescription(
preference.context.getString( preference.context.getString(
R.string.volume_content_description_silent_mode, R.string.volume_content_description_silent_mode,

View File

@@ -46,6 +46,7 @@ import android.os.Build;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.ServiceManager; import android.os.ServiceManager;
import android.os.UserHandle; import android.os.UserHandle;
import android.service.notification.Adjustment;
import android.service.notification.ConversationChannelWrapper; import android.service.notification.ConversationChannelWrapper;
import android.service.notification.NotificationListenerFilter; import android.service.notification.NotificationListenerFilter;
import android.text.format.DateUtils; import android.text.format.DateUtils;
@@ -65,9 +66,11 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
public class NotificationBackend { public class NotificationBackend {
private static final String TAG = "NotificationBackend"; private static final String TAG = "NotificationBackend";
@@ -651,6 +654,59 @@ public class NotificationBackend {
return false; return false;
} }
public boolean isNotificationBundlingSupported() {
try {
return !sINM.getUnsupportedAdjustmentTypes().contains(Adjustment.KEY_TYPE);
} catch (Exception e) {
Log.w(TAG, "Error calling NoMan", e);
}
return false;
}
public boolean isNotificationBundlingEnabled(Context context) {
try {
return sINM.getAllowedAssistantAdjustments(context.getPackageName())
.contains(Adjustment.KEY_TYPE);
} catch (Exception e) {
Log.w(TAG, "Error calling NoMan", e);
}
return false;
}
public void setNotificationBundlingEnabled(boolean enabled) {
try {
if (enabled) {
sINM.allowAssistantAdjustment(Adjustment.KEY_TYPE);
} else {
sINM.disallowAssistantAdjustment(Adjustment.KEY_TYPE);
}
} catch (Exception e) {
Log.w(TAG, "Error calling NoMan", e);
}
}
public boolean isBundleTypeApproved(@Adjustment.Types int type) {
try {
int[] approved = sINM.getAllowedAdjustmentKeyTypes();
for (int approvedType : approved) {
if (type == approvedType) {
return true;
}
}
} catch (Exception e) {
Log.w(TAG, "Error calling NoMan", e);
}
return false;
}
public void setBundleTypeState(@Adjustment.Types int type, boolean enabled) {
try {
sINM.setAssistantAdjustmentKeyTypeState(type, enabled);
} catch (Exception e) {
Log.w(TAG, "Error calling NoMan", e);
}
}
@VisibleForTesting @VisibleForTesting
void setNm(INotificationManager inm) { void setNm(INotificationManager inm) {
sINM = inm; sINM = inm;

View File

@@ -24,21 +24,19 @@ import android.media.AudioManager.RINGER_MODE_SILENT
import android.media.AudioManager.RINGER_MODE_VIBRATE import android.media.AudioManager.RINGER_MODE_VIBRATE
import android.media.AudioManager.STREAM_RING import android.media.AudioManager.STREAM_RING
import android.os.ServiceManager import android.os.ServiceManager
import android.os.UserHandle import android.os.UserManager
import android.os.UserManager.DISALLOW_ADJUST_VOLUME
import android.os.Vibrator import android.os.Vibrator
import android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS import android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS
import android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_EFFECTS import android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_EFFECTS
import androidx.preference.Preference import androidx.preference.Preference
import com.android.settings.PreferenceRestrictionMixin
import com.android.settings.R import com.android.settings.R
import com.android.settingslib.RestrictedLockUtilsInternal
import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.datastore.KeyValueStore
import com.android.settingslib.datastore.NoOpKeyedObservable import com.android.settingslib.datastore.NoOpKeyedObservable
import com.android.settingslib.metadata.PersistentPreference import com.android.settingslib.metadata.PersistentPreference
import com.android.settingslib.metadata.PreferenceAvailabilityProvider import com.android.settingslib.metadata.PreferenceAvailabilityProvider
import com.android.settingslib.metadata.PreferenceIconProvider import com.android.settingslib.metadata.PreferenceIconProvider
import com.android.settingslib.metadata.PreferenceMetadata import com.android.settingslib.metadata.PreferenceMetadata
import com.android.settingslib.metadata.PreferenceRestrictionProvider
import com.android.settingslib.metadata.RangeValue import com.android.settingslib.metadata.RangeValue
import com.android.settingslib.metadata.ReadWritePermit import com.android.settingslib.metadata.ReadWritePermit
import com.android.settingslib.preference.PreferenceBinding import com.android.settingslib.preference.PreferenceBinding
@@ -51,7 +49,8 @@ open class SeparateRingVolumePreference :
RangeValue, RangeValue,
PreferenceAvailabilityProvider, PreferenceAvailabilityProvider,
PreferenceIconProvider, PreferenceIconProvider,
PreferenceRestrictionProvider { PreferenceRestrictionMixin {
override val key: String override val key: String
get() = KEY get() = KEY
@@ -64,21 +63,12 @@ open class SeparateRingVolumePreference :
else -> R.drawable.ic_ring_volume else -> R.drawable.ic_ring_volume
} }
override fun isAvailable(context: Context) = !createAudioHelper(context).isSingleVolume() override fun isAvailable(context: Context) = !createAudioHelper(context).isSingleVolume
override fun isEnabled(context: Context) = override fun isEnabled(context: Context) = super<PreferenceRestrictionMixin>.isEnabled(context)
!RestrictedLockUtilsInternal.hasBaseUserRestriction(
context,
DISALLOW_ADJUST_VOLUME,
UserHandle.myUserId(),
)
override fun isRestricted(context: Context) = override val restrictionKey: String
RestrictedLockUtilsInternal.checkIfRestrictionEnforced( get() = UserManager.DISALLOW_ADJUST_VOLUME
context,
DISALLOW_ADJUST_VOLUME,
UserHandle.myUserId(),
) != null
override fun storage(context: Context): KeyValueStore { override fun storage(context: Context): KeyValueStore {
val helper = createAudioHelper(context) val helper = createAudioHelper(context)
@@ -118,7 +108,7 @@ open class SeparateRingVolumePreference :
open fun createAudioHelper(context: Context) = AudioHelper(context) open fun createAudioHelper(context: Context) = AudioHelper(context)
fun updateContentDescription(preference: VolumeSeekBarPreference) { private fun updateContentDescription(preference: VolumeSeekBarPreference) {
val context = preference.context val context = preference.context
val ringerMode = getEffectiveRingerMode(context) val ringerMode = getEffectiveRingerMode(context)
when (ringerMode) { when (ringerMode) {
@@ -152,13 +142,13 @@ open class SeparateRingVolumePreference :
} }
} }
fun getSuppressionText(context: Context): String? { private fun getSuppressionText(context: Context): String? {
val suppressor = NotificationManager.from(context).getEffectsSuppressor() val suppressor = NotificationManager.from(context).getEffectsSuppressor()
val notificationManager = val notificationManager =
INotificationManager.Stub.asInterface( INotificationManager.Stub.asInterface(
ServiceManager.getService(Context.NOTIFICATION_SERVICE) ServiceManager.getService(Context.NOTIFICATION_SERVICE)
) )
val hints = notificationManager.getHintsFromListenerNoToken() val hints = notificationManager.hintsFromListenerNoToken
return when { return when {
hintsMatch(hints) -> SuppressorHelper.getSuppressionText(context, suppressor) hintsMatch(hints) -> SuppressorHelper.getSuppressionText(context, suppressor)
else -> null else -> null

View File

@@ -33,11 +33,13 @@ import androidx.preference.PreferenceViewHolder;
import com.android.settings.R; import com.android.settings.R;
import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedPreferenceHelper; import com.android.settingslib.RestrictedPreferenceHelper;
import com.android.settingslib.RestrictedPreferenceHelperProvider;
/** /**
* A tri-state preference allowing a user to specify what gets to bubble. * A tri-state preference allowing a user to specify what gets to bubble.
*/ */
public class BubblePreference extends Preference implements RadioGroup.OnCheckedChangeListener { public class BubblePreference extends Preference implements RadioGroup.OnCheckedChangeListener,
RestrictedPreferenceHelperProvider {
RestrictedPreferenceHelper mHelper; RestrictedPreferenceHelper mHelper;
private int mSelectedPreference; private int mSelectedPreference;
@@ -64,6 +66,11 @@ public class BubblePreference extends Preference implements RadioGroup.OnChecked
setLayoutResource(R.layout.bubble_preference); setLayoutResource(R.layout.bubble_preference);
} }
@Override
public @NonNull RestrictedPreferenceHelper getRestrictedPreferenceHelper() {
return mHelper;
}
public void setSelectedPreference(int preference) { public void setSelectedPreference(int preference) {
mSelectedPreference = preference; mSelectedPreference = preference;
notifyChanged(); notifyChanged();

View File

@@ -27,6 +27,7 @@ import androidx.preference.PreferenceViewHolder;
import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedPreferenceHelper; import com.android.settingslib.RestrictedPreferenceHelper;
import com.android.settingslib.RestrictedPreferenceHelperProvider;
import com.android.settingslib.widget.AppPreference; import com.android.settingslib.widget.AppPreference;
/** /**
@@ -34,7 +35,8 @@ import com.android.settingslib.widget.AppPreference;
* {@link com.android.settingslib.RestrictedPreferenceHelper}. * {@link com.android.settingslib.RestrictedPreferenceHelper}.
* Used to show policy transparency on {@link AppPreference}. * Used to show policy transparency on {@link AppPreference}.
*/ */
public class RestrictedAppPreference extends AppPreference { public class RestrictedAppPreference extends AppPreference implements
RestrictedPreferenceHelperProvider {
private RestrictedPreferenceHelper mHelper; private RestrictedPreferenceHelper mHelper;
private String userRestriction; private String userRestriction;
@@ -58,6 +60,11 @@ public class RestrictedAppPreference extends AppPreference {
this.userRestriction = userRestriction; this.userRestriction = userRestriction;
} }
@Override
public @NonNull RestrictedPreferenceHelper getRestrictedPreferenceHelper() {
return mHelper;
}
@Override @Override
public void onBindViewHolder(PreferenceViewHolder holder) { public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder); super.onBindViewHolder(holder);

View File

@@ -23,12 +23,14 @@ import android.util.AttributeSet;
import android.widget.CompoundButton; import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.CompoundButton.OnCheckedChangeListener;
import androidx.annotation.NonNull;
import androidx.preference.PreferenceViewHolder; import androidx.preference.PreferenceViewHolder;
import androidx.preference.TwoStatePreference; import androidx.preference.TwoStatePreference;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.widget.SettingsMainSwitchBar.OnBeforeCheckedChangeListener; import com.android.settings.widget.SettingsMainSwitchBar.OnBeforeCheckedChangeListener;
import com.android.settingslib.RestrictedPreferenceHelper; import com.android.settingslib.RestrictedPreferenceHelper;
import com.android.settingslib.RestrictedPreferenceHelperProvider;
import com.android.settingslib.core.instrumentation.SettingsJankMonitor; import com.android.settingslib.core.instrumentation.SettingsJankMonitor;
import java.util.ArrayList; import java.util.ArrayList;
@@ -40,7 +42,7 @@ import java.util.List;
* to enable or disable the preferences on the page. * to enable or disable the preferences on the page.
*/ */
public class SettingsMainSwitchPreference extends TwoStatePreference implements public class SettingsMainSwitchPreference extends TwoStatePreference implements
OnCheckedChangeListener { OnCheckedChangeListener, RestrictedPreferenceHelperProvider {
private final List<OnBeforeCheckedChangeListener> mBeforeCheckedChangeListeners = private final List<OnBeforeCheckedChangeListener> mBeforeCheckedChangeListeners =
new ArrayList<>(); new ArrayList<>();
@@ -71,6 +73,11 @@ public class SettingsMainSwitchPreference extends TwoStatePreference implements
init(context, attrs); init(context, attrs);
} }
@Override
public @NonNull RestrictedPreferenceHelper getRestrictedPreferenceHelper() {
return mRestrictedHelper;
}
@Override @Override
public void onBindViewHolder(PreferenceViewHolder holder) { public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder); super.onBindViewHolder(holder);

View File

@@ -66,7 +66,6 @@ import com.android.settingslib.development.DevelopmentSettingsEnabler;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@@ -263,7 +262,6 @@ public class MainClearTest {
assertThat(mMainClear.showWipeEuicc()).isTrue(); assertThat(mMainClear.showWipeEuicc()).isTrue();
} }
@Ignore("b/313566998")
@Test @Test
public void testShowWipeEuicc_developerMode_unprovisioned() { public void testShowWipeEuicc_developerMode_unprovisioned() {
prepareEuiccState( prepareEuiccState(

View File

@@ -51,6 +51,7 @@ import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow; import org.robolectric.shadow.api.Shadow;
import java.util.List; import java.util.List;
import java.util.Objects;
/** Tests for {@link AccessibilityHearingAidsFragment}. */ /** Tests for {@link AccessibilityHearingAidsFragment}. */
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
@@ -88,7 +89,9 @@ public class AccessibilityHearingAidsFragmentTest {
mShadowBluetoothAdapter.addSupportedProfiles(BluetoothProfile.HEARING_AID); mShadowBluetoothAdapter.addSupportedProfiles(BluetoothProfile.HEARING_AID);
final List<String> niks = AccessibilityHearingAidsFragment.SEARCH_INDEX_DATA_PROVIDER final List<String> niks = AccessibilityHearingAidsFragment.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(mContext); .getNonIndexableKeys(mContext).stream()
.filter(Objects::nonNull)
.toList();
final List<String> keys = final List<String> keys =
XmlTestUtils.getKeysFromPreferenceXml(mContext, R.xml.accessibility_hearing_aids); XmlTestUtils.getKeysFromPreferenceXml(mContext, R.xml.accessibility_hearing_aids);

View File

@@ -44,6 +44,7 @@ import android.provider.ContactsContract.RawContacts.DefaultAccount.DefaultAccou
import android.provider.SearchIndexableResource; import android.provider.SearchIndexableResource;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
@@ -73,7 +74,7 @@ import java.util.List;
@Config(shadows = ShadowAuthenticationHelper.class) @Config(shadows = ShadowAuthenticationHelper.class)
public class ContactsStorageSettingsTest { public class ContactsStorageSettingsTest {
private static final String PREF_KEY_DEVICE_ONLY = "device_only_account_preference"; private static final String PREF_KEY_DEVICE_ONLY = "device_only_account_preference";
private static final String PREF_KEY_ACCOUNT_CATEGORY = "account_category";
private static final String PREF_KEY_ADD_ACCOUNT = "add_account"; private static final String PREF_KEY_ADD_ACCOUNT = "add_account";
private static final Account TEST_ACCOUNT1 = new Account("test@gmail.com", "type1"); private static final Account TEST_ACCOUNT1 = new Account("test@gmail.com", "type1");
@@ -95,6 +96,7 @@ public class ContactsStorageSettingsTest {
private PreferenceManager mPreferenceManager; private PreferenceManager mPreferenceManager;
private TestContactsStorageSettings mContactsStorageSettings; private TestContactsStorageSettings mContactsStorageSettings;
private PreferenceScreen mScreen; private PreferenceScreen mScreen;
private PreferenceGroup accountCategory;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
@@ -103,8 +105,16 @@ public class ContactsStorageSettingsTest {
eq(ContactsContract.AUTHORITY_URI))).thenReturn(mContentProviderClient); eq(ContactsContract.AUTHORITY_URI))).thenReturn(mContentProviderClient);
mPreferenceManager = new PreferenceManager(mContext); mPreferenceManager = new PreferenceManager(mContext);
when(mContactsStorageSettings.getPreferenceManager()).thenReturn(mPreferenceManager); when(mContactsStorageSettings.getPreferenceManager()).thenReturn(mPreferenceManager);
mScreen = spy(new PreferenceScreen(mContext, /* attrs= */ null)); mScreen = spy(mPreferenceManager.inflateFromResource(mContext,
R.xml.contacts_storage_settings, mScreen));
when(mScreen.getPreferenceManager()).thenReturn(mPreferenceManager); when(mScreen.getPreferenceManager()).thenReturn(mPreferenceManager);
accountCategory = mScreen.findPreference(PREF_KEY_ACCOUNT_CATEGORY);
SelectorWithWidgetPreference deviceOnlyPreference = mScreen.findPreference(
PREF_KEY_DEVICE_ONLY);
when(mContactsStorageSettings.findPreference(eq(PREF_KEY_DEVICE_ONLY))).thenReturn(
deviceOnlyPreference);
when(mContactsStorageSettings.findPreference(eq(PREF_KEY_ACCOUNT_CATEGORY))).thenReturn(
accountCategory);
when(mContactsStorageSettings.getPreferenceScreen()).thenReturn(mScreen); when(mContactsStorageSettings.getPreferenceScreen()).thenReturn(mScreen);
mContactsStorageSettings.onAttach(mContext); mContactsStorageSettings.onAttach(mContext);
} }
@@ -134,17 +144,15 @@ public class ContactsStorageSettingsTest {
when(mContentProviderClient.call(eq(QUERY_ELIGIBLE_DEFAULT_ACCOUNTS_METHOD), any(), when(mContentProviderClient.call(eq(QUERY_ELIGIBLE_DEFAULT_ACCOUNTS_METHOD), any(),
any())).thenReturn(eligibleAccountBundle); any())).thenReturn(eligibleAccountBundle);
PreferenceScreen settingScreen = mPreferenceManager.inflateFromResource(mContext, SelectorWithWidgetPreference deviceOnlyPreference = mContactsStorageSettings.findPreference(
R.xml.contacts_storage_settings, mScreen);
SelectorWithWidgetPreference deviceOnlyPreference = settingScreen.findPreference(
PREF_KEY_DEVICE_ONLY); PREF_KEY_DEVICE_ONLY);
when(mContactsStorageSettings.findPreference(eq(PREF_KEY_DEVICE_ONLY))).thenReturn(
deviceOnlyPreference);
assertThat(deviceOnlyPreference.getTitle()).isEqualTo("Device only"); assertThat(deviceOnlyPreference.getTitle()).isEqualTo("Device only");
assertThat(deviceOnlyPreference.getSummary()).isEqualTo( assertThat(deviceOnlyPreference.getSummary()).isEqualTo(
"New contacts won't be synced with an account"); "New contacts won't be synced with an account");
assertThat(deviceOnlyPreference.getOrder()).isEqualTo(999); assertThat(deviceOnlyPreference.getOrder()).isEqualTo(999);
assertThat(mContactsStorageSettings.findPreference(
PREF_KEY_ACCOUNT_CATEGORY).getTitle()).isEqualTo("Where to save contacts");
mContactsStorageSettings.refreshUI(); mContactsStorageSettings.refreshUI();
mContactsStorageSettings.onRadioButtonClicked(deviceOnlyPreference); mContactsStorageSettings.onRadioButtonClicked(deviceOnlyPreference);
@@ -175,6 +183,8 @@ public class ContactsStorageSettingsTest {
mContactsStorageSettings.refreshUI(); mContactsStorageSettings.refreshUI();
assertThat(mContactsStorageSettings.findPreference(
PREF_KEY_ACCOUNT_CATEGORY).getTitle()).isEqualTo("Where to save contacts");
assertThat(mScreen.findPreference(PREF_KEY_ADD_ACCOUNT).getTitle()).isEqualTo( assertThat(mScreen.findPreference(PREF_KEY_ADD_ACCOUNT).getTitle()).isEqualTo(
"Add an account to get started"); "Add an account to get started");
assertThat(mScreen.findPreference(PREF_KEY_ADD_ACCOUNT).getOrder()).isEqualTo(998); assertThat(mScreen.findPreference(PREF_KEY_ADD_ACCOUNT).getOrder()).isEqualTo(998);
@@ -232,15 +242,15 @@ public class ContactsStorageSettingsTest {
mContactsStorageSettings.refreshUI(); mContactsStorageSettings.refreshUI();
SelectorWithWidgetPreference account1Preference = mScreen.findPreference( SelectorWithWidgetPreference account1Preference = accountCategory.findPreference(
String.valueOf(TEST_ACCOUNT1.hashCode())); String.valueOf(TEST_ACCOUNT1.hashCode()));
assertThat(account1Preference.getTitle()).isEqualTo("LABEL1"); assertThat(account1Preference.getTitle()).isEqualTo("Device and LABEL1");
assertThat(account1Preference.getSummary()).isEqualTo("test@gmail.com"); assertThat(account1Preference.getSummary()).isEqualTo("test@gmail.com");
assertThat(account1Preference.getIcon()).isNotNull(); assertThat(account1Preference.getIcon()).isNotNull();
SelectorWithWidgetPreference account2Preference = mScreen.findPreference( SelectorWithWidgetPreference account2Preference = accountCategory.findPreference(
String.valueOf(TEST_ACCOUNT2.hashCode())); String.valueOf(TEST_ACCOUNT2.hashCode()));
assertThat(account2Preference.getTitle()).isEqualTo("LABEL2"); assertThat(account2Preference.getTitle()).isEqualTo("Device and LABEL2");
assertThat(account2Preference.getSummary()).isEqualTo("test@samsung.com"); assertThat(account2Preference.getSummary()).isEqualTo("test@samsung.com");
assertThat(account2Preference.getIcon()).isNotNull(); assertThat(account2Preference.getIcon()).isNotNull();
@@ -286,21 +296,21 @@ public class ContactsStorageSettingsTest {
mContactsStorageSettings.refreshUI(); mContactsStorageSettings.refreshUI();
SelectorWithWidgetPreference account1Preference = mScreen.findPreference( SelectorWithWidgetPreference account1Preference = accountCategory.findPreference(
String.valueOf(TEST_ACCOUNT1.hashCode())); String.valueOf(TEST_ACCOUNT1.hashCode()));
assertThat(account1Preference.getTitle()).isEqualTo("LABEL1"); assertThat(account1Preference.getTitle()).isEqualTo("Device and LABEL1");
assertThat(account1Preference.getSummary()).isEqualTo("test@gmail.com"); assertThat(account1Preference.getSummary()).isEqualTo("test@gmail.com");
assertThat(account1Preference.getIcon()).isNotNull(); assertThat(account1Preference.getIcon()).isNotNull();
SelectorWithWidgetPreference account2Preference = mScreen.findPreference( SelectorWithWidgetPreference account2Preference = accountCategory.findPreference(
String.valueOf(TEST_ACCOUNT2.hashCode())); String.valueOf(TEST_ACCOUNT2.hashCode()));
assertThat(account2Preference.getTitle()).isEqualTo("LABEL2"); assertThat(account2Preference.getTitle()).isEqualTo("Device and LABEL2");
assertThat(account2Preference.getSummary()).isEqualTo("test@samsung.com"); assertThat(account2Preference.getSummary()).isEqualTo("test@samsung.com");
assertThat(account2Preference.getIcon()).isNotNull(); assertThat(account2Preference.getIcon()).isNotNull();
SelectorWithWidgetPreference account3Preference = mScreen.findPreference( SelectorWithWidgetPreference account3Preference = accountCategory.findPreference(
String.valueOf(TEST_ACCOUNT3.hashCode())); String.valueOf(TEST_ACCOUNT3.hashCode()));
assertThat(account3Preference.getTitle()).isEqualTo("LABEL3"); assertThat(account3Preference.getTitle()).isEqualTo("Device and LABEL3");
assertThat(account3Preference.getSummary()).isEqualTo("test@outlook.com"); assertThat(account3Preference.getSummary()).isEqualTo("test@outlook.com");
assertThat(account3Preference.getIcon()).isNotNull(); assertThat(account3Preference.getIcon()).isNotNull();
@@ -327,7 +337,7 @@ public class ContactsStorageSettingsTest {
mContactsStorageSettings.refreshUI(); mContactsStorageSettings.refreshUI();
SelectorWithWidgetPreference simPreference = mScreen.findPreference( SelectorWithWidgetPreference simPreference = accountCategory.findPreference(
String.valueOf(SIM_ACCOUNT.hashCode())); String.valueOf(SIM_ACCOUNT.hashCode()));
assertThat(simPreference.getTitle()).isEqualTo("SIM"); assertThat(simPreference.getTitle()).isEqualTo("SIM");
assertThat(simPreference.getSummary()).isEqualTo("SIM"); assertThat(simPreference.getSummary()).isEqualTo("SIM");

View File

@@ -25,7 +25,7 @@ import androidx.preference.PreferenceViewHolder
import androidx.test.core.app.ApplicationProvider import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settingslib.PrimarySwitchPreference import com.android.settingslib.PrimarySwitchPreference
import com.android.settingslib.preference.PreferenceDataStoreAdapter import com.android.settingslib.preference.createAndBindWidget
import com.android.settingslib.widget.SettingsThemeHelper.isExpressiveTheme import com.android.settingslib.widget.SettingsThemeHelper.isExpressiveTheme
import com.android.settingslib.widget.theme.R import com.android.settingslib.widget.theme.R
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
@@ -117,17 +117,14 @@ class AutoBrightnessScreenTest {
assertThat(preferenceScreenCreator.isAvailable(context)).isFalse() assertThat(preferenceScreenCreator.isAvailable(context)).isFalse()
} }
private fun getPrimarySwitchPreference(): PrimarySwitchPreference = private fun getPrimarySwitchPreference() =
preferenceScreenCreator.run { preferenceScreenCreator.createAndBindWidget<PrimarySwitchPreference>(context).also {
val preference = createWidget(context)
preference.preferenceDataStore = PreferenceDataStoreAdapter(storage(context))
bind(preference, this)
val holder = val holder =
PreferenceViewHolder.createInstanceForTests( PreferenceViewHolder.createInstanceForTests(
LayoutInflater.from(context).inflate(getResId(), /* root= */ null) LayoutInflater.from(context).inflate(getResId(), /* root= */ null)
) )
.apply { findViewById(androidx.preference.R.id.switchWidget) } .apply { findViewById(androidx.preference.R.id.switchWidget) }
preference.apply { onBindViewHolder(holder) } it.onBindViewHolder(holder)
} }
private fun setScreenBrightnessMode(value: Int) = private fun setScreenBrightnessMode(value: Int) =

View File

@@ -0,0 +1,101 @@
/*
* 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.notification;
import static android.service.notification.Adjustment.KEY_IMPORTANCE;
import static android.service.notification.Adjustment.KEY_TYPE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Flags;
import android.app.INotificationManager;
import android.content.Context;
import android.platform.test.flag.junit.SetFlagsRule;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
public class BundleGlobalPreferenceControllerTest {
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private static final String PREFERENCE_KEY = "preference_key";
private Context mContext;
BundleGlobalPreferenceController mController;
@Mock
INotificationManager mInm;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mSetFlagsRule.enableFlags(
android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION,
Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI);
mController = new BundleGlobalPreferenceController(mContext, PREFERENCE_KEY);
mController.mBackend.setNm(mInm);
}
@Test
public void isAvailable_flagEnabledNasSupports_shouldReturnTrue() {
assertThat(mController.isAvailable()).isTrue();
}
@Test
public void isAvailable_flagEnabledNasDoesNotSupport_shouldReturnFalse() throws Exception {
when(mInm.getUnsupportedAdjustmentTypes()).thenReturn(List.of(KEY_TYPE));
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void isAvailable_flagDisabledNasSupports_shouldReturnFalse() {
mSetFlagsRule.disableFlags(Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI);
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void isChecked() throws Exception {
when(mInm.getAllowedAssistantAdjustments(any())).thenReturn(List.of(KEY_TYPE));
assertThat(mController.isChecked()).isTrue();
when(mInm.getAllowedAssistantAdjustments(any())).thenReturn(List.of(KEY_IMPORTANCE));
assertThat(mController.isChecked()).isFalse();
}
@Test
public void setChecked() throws Exception {
mController.setChecked(false);
verify(mInm).disallowAssistantAdjustment(KEY_TYPE);
mController.setChecked(true);
verify(mInm).allowAssistantAdjustment(KEY_TYPE);
}
}

View File

@@ -0,0 +1,91 @@
/*
* 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.notification;
import static android.service.notification.Adjustment.KEY_IMPORTANCE;
import static android.service.notification.Adjustment.KEY_TYPE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import android.app.Flags;
import android.app.INotificationManager;
import android.content.Context;
import android.platform.test.flag.junit.SetFlagsRule;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
public class BundlePreferenceControllerTest {
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private static final String PREFERENCE_KEY = "preference_key";
private Context mContext;
BundlePreferenceController mController;
@Mock
INotificationManager mInm;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mSetFlagsRule.enableFlags(
android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION,
Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI);
mController = new BundlePreferenceController(mContext, PREFERENCE_KEY);
mController.mBackend.setNm(mInm);
}
@Test
public void isAvailable_flagEnabledNasSupports_shouldReturnTrue() {
assertThat(mController.isAvailable()).isTrue();
}
@Test
public void isAvailable_flagEnabledNasDoesNotSupport_shouldReturnFalse() throws Exception {
when(mInm.getUnsupportedAdjustmentTypes()).thenReturn(List.of(KEY_TYPE));
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void isAvailable_flagDisabledNasSupports_shouldReturnFalse() {
mSetFlagsRule.disableFlags(Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI);
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void getSummary() throws Exception {
when(mInm.getAllowedAssistantAdjustments(any())).thenReturn(List.of(KEY_TYPE));
assertThat(mController.getSummary()).isEqualTo("On");
when(mInm.getAllowedAssistantAdjustments(any())).thenReturn(List.of(KEY_IMPORTANCE));
assertThat(mController.getSummary()).isEqualTo("Off");
}
}

View File

@@ -0,0 +1,171 @@
/*
* 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.notification;
import static android.service.notification.Adjustment.KEY_TYPE;
import static android.service.notification.Adjustment.TYPE_CONTENT_RECOMMENDATION;
import static android.service.notification.Adjustment.TYPE_NEWS;
import static android.service.notification.Adjustment.TYPE_PROMOTION;
import static android.service.notification.Adjustment.TYPE_SOCIAL_MEDIA;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Flags;
import android.app.INotificationManager;
import android.content.Context;
import android.os.RemoteException;
import android.platform.test.flag.junit.SetFlagsRule;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
public class BundleTypePreferenceControllerTest {
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private static final String PREFERENCE_KEY = "preference_key";
private Context mContext;
BundleTypePreferenceController mController;
@Mock
INotificationManager mInm;
@Before
public void setUp() throws RemoteException {
MockitoAnnotations.initMocks(this);
when(mInm.getAllowedAssistantAdjustments(any())).thenReturn(List.of(KEY_TYPE));
when(mInm.getUnsupportedAdjustmentTypes()).thenReturn(List.of());
mSetFlagsRule.enableFlags(
android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION,
Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI);
mContext = RuntimeEnvironment.application;
mController = new BundleTypePreferenceController(mContext, PREFERENCE_KEY);
mController.mBackend.setNm(mInm);
}
@Test
public void isAvailable() throws RemoteException {
when(mInm.getAllowedAssistantAdjustments(any())).thenReturn(List.of(KEY_TYPE));
assertThat(mController.isAvailable()).isTrue();
}
@Test
public void isAvailable_flagEnabledNasDoesNotSupport_shouldReturnFalse()
throws RemoteException {
when(mInm.getUnsupportedAdjustmentTypes()).thenReturn(List.of(KEY_TYPE));
when(mInm.getAllowedAssistantAdjustments(any())).thenReturn(List.of(KEY_TYPE));
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void isAvailable_flagDisabledNasSupports_shouldReturnFalse() throws RemoteException {
mSetFlagsRule.disableFlags(Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI);
when(mInm.getUnsupportedAdjustmentTypes()).thenReturn(List.of());
when(mInm.getAllowedAssistantAdjustments(any())).thenReturn(List.of(KEY_TYPE));
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void isAvailable_flagEnabledNasDisabled_shouldReturnFalse() throws RemoteException {
when(mInm.getUnsupportedAdjustmentTypes()).thenReturn(List.of());
when(mInm.getAllowedAssistantAdjustments(any())).thenReturn(List.of());
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void isChecked_promotions() throws RemoteException {
mController = new BundleTypePreferenceController(mContext,
BundleTypePreferenceController.PROMO_KEY);
when(mInm.getAllowedAdjustmentKeyTypes()).thenReturn(new int[]{TYPE_PROMOTION});
assertThat(mController.isChecked()).isTrue();
when(mInm.getAllowedAdjustmentKeyTypes()).thenReturn(new int[]{});
assertThat(mController.isChecked()).isFalse();
}
@Test
public void isChecked_news() throws RemoteException {
mController = new BundleTypePreferenceController(mContext,
BundleTypePreferenceController.NEWS_KEY);
when(mInm.getAllowedAdjustmentKeyTypes()).thenReturn(new int[]{TYPE_NEWS});
assertThat(mController.isChecked()).isTrue();
when(mInm.getAllowedAdjustmentKeyTypes()).thenReturn(new int[]{});
assertThat(mController.isChecked()).isFalse();
}
@Test
public void isChecked_social() throws RemoteException {
mController = new BundleTypePreferenceController(mContext,
BundleTypePreferenceController.SOCIAL_KEY);
when(mInm.getAllowedAdjustmentKeyTypes()).thenReturn(new int[]{TYPE_SOCIAL_MEDIA});
assertThat(mController.isChecked()).isTrue();
when(mInm.getAllowedAdjustmentKeyTypes()).thenReturn(new int[]{});
assertThat(mController.isChecked()).isFalse();
}
@Test
public void isChecked_recs() throws RemoteException {
mController = new BundleTypePreferenceController(mContext,
BundleTypePreferenceController.RECS_KEY);
when(mInm.getAllowedAdjustmentKeyTypes()).thenReturn(
new int[]{TYPE_CONTENT_RECOMMENDATION});
assertThat(mController.isChecked()).isTrue();
when(mInm.getAllowedAdjustmentKeyTypes()).thenReturn(new int[]{});
assertThat(mController.isChecked()).isFalse();
}
@Test
public void isChecked_mixed() throws RemoteException {
mController = new BundleTypePreferenceController(mContext,
BundleTypePreferenceController.RECS_KEY);
when(mInm.getAllowedAdjustmentKeyTypes()).thenReturn(
new int[]{TYPE_PROMOTION, TYPE_CONTENT_RECOMMENDATION});
assertThat(mController.isChecked()).isTrue();
}
@Test
public void setChecked() throws RemoteException {
mController = new BundleTypePreferenceController(mContext,
BundleTypePreferenceController.PROMO_KEY);
mController.setChecked(false);
verify(mInm).setAssistantAdjustmentKeyTypeState(TYPE_PROMOTION, false);
mController.setChecked(true);
verify(mInm).setAssistantAdjustmentKeyTypeState(TYPE_PROMOTION, true);
}
}

View File

@@ -29,6 +29,7 @@ import com.android.settings.biometrics.fingerprint2.domain.interactor.Accessibil
import com.android.settings.biometrics.fingerprint2.domain.interactor.FoldStateInteractor import com.android.settings.biometrics.fingerprint2.domain.interactor.FoldStateInteractor
import com.android.settings.biometrics.fingerprint2.domain.interactor.OrientationInteractor import com.android.settings.biometrics.fingerprint2.domain.interactor.OrientationInteractor
import com.android.settings.biometrics.fingerprint2.lib.model.Default import com.android.settings.biometrics.fingerprint2.lib.model.Default
import com.android.settings.biometrics.fingerprint2.lib.model.Orientation
import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.rfps.ui.viewmodel.RFPSIconTouchViewModel import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.rfps.ui.viewmodel.RFPSIconTouchViewModel
import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.rfps.ui.viewmodel.RFPSViewModel import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.rfps.ui.viewmodel.RFPSViewModel
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.BackgroundViewModel import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.BackgroundViewModel
@@ -78,6 +79,7 @@ class Injector(step: FingerprintNavigationStep.UiStep) {
override val isEnabled: Boolean override val isEnabled: Boolean
get() = true get() = true
override fun announce(clazz: Class<*>, announcement: CharSequence?) {} override fun announce(clazz: Class<*>, announcement: CharSequence?) {}
override fun interrupt() {}
} }
var foldStateInteractor = var foldStateInteractor =
@@ -97,6 +99,7 @@ class Injector(step: FingerprintNavigationStep.UiStep) {
override val rotationFromDefault: Flow<Int> = rotation override val rotationFromDefault: Flow<Int> = rotation
override fun getRotationFromDefault(rotation: Int): Int = rotation override fun getRotationFromDefault(rotation: Int): Int = rotation
override val orientationChanged: Flow<Orientation> = flowOf(Orientation.Portrait)
} }
var gatekeeperViewModel = FingerprintGatekeeperViewModel(fingerprintManagerInteractor) var gatekeeperViewModel = FingerprintGatekeeperViewModel(fingerprintManagerInteractor)

View File

@@ -30,6 +30,7 @@ import com.android.settings.biometrics.fingerprint2.domain.interactor.Accessibil
import com.android.settings.biometrics.fingerprint2.domain.interactor.FoldStateInteractor import com.android.settings.biometrics.fingerprint2.domain.interactor.FoldStateInteractor
import com.android.settings.biometrics.fingerprint2.domain.interactor.OrientationInteractor import com.android.settings.biometrics.fingerprint2.domain.interactor.OrientationInteractor
import com.android.settings.biometrics.fingerprint2.lib.model.Default import com.android.settings.biometrics.fingerprint2.lib.model.Default
import com.android.settings.biometrics.fingerprint2.lib.model.Orientation
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.BackgroundViewModel import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.BackgroundViewModel
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollFindSensorViewModel import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollFindSensorViewModel
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollViewModel import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollViewModel
@@ -111,6 +112,8 @@ class FingerprintEnrollFindSensorViewModelV2Test {
override val isEnabled: Boolean override val isEnabled: Boolean
get() = true get() = true
override fun announce(clazz: Class<*>, announcement: CharSequence?) {} override fun announce(clazz: Class<*>, announcement: CharSequence?) {}
override fun interrupt() {
}
} }
foldStateInteractor = foldStateInteractor =
object : FoldStateInteractor { object : FoldStateInteractor {
@@ -128,6 +131,7 @@ class FingerprintEnrollFindSensorViewModelV2Test {
override val rotationFromDefault: Flow<Int> = flowOf(Surface.ROTATION_0) override val rotationFromDefault: Flow<Int> = flowOf(Surface.ROTATION_0)
override fun getRotationFromDefault(rotation: Int): Int = rotation override fun getRotationFromDefault(rotation: Int): Int = rotation
override val orientationChanged: Flow<Orientation> = flowOf(Orientation.Portrait)
} }
underTest = underTest =
FingerprintEnrollFindSensorViewModel( FingerprintEnrollFindSensorViewModel(