Merge changes from topic "catalyst" into main

* changes:
  [Catalyst] Support restriction for Sound settings
  Add SettingsPreferenceBindingFactory and support restriction
  Implement RestrictedPreferenceHelperProvider for restricted preference
This commit is contained in:
Jacky Wang
2024-11-06 06:50:12 +00:00
committed by Android (Google) Code Review
11 changed files with 164 additions and 60 deletions

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.ListView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AlertDialog.Builder;
import androidx.preference.ListPreferenceDialogFragmentCompat;
@@ -40,11 +41,14 @@ import androidx.preference.PreferenceViewHolder;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedPreferenceHelper;
import com.android.settingslib.RestrictedPreferenceHelperProvider;
import java.util.ArrayList;
import java.util.List;
public class RestrictedListPreference extends CustomListPreference {
public class RestrictedListPreference extends CustomListPreference implements
RestrictedPreferenceHelperProvider {
private final RestrictedPreferenceHelper mHelper;
private final List<RestrictedItem> mRestrictedItems = new ArrayList<>();
private boolean mRequiresActiveUnlockedProfile = false;
@@ -61,6 +65,11 @@ public class RestrictedListPreference extends CustomListPreference {
mHelper = new RestrictedPreferenceHelper(context, this, attrs);
}
@Override
public @NonNull RestrictedPreferenceHelper getRestrictedPreferenceHelper() {
return mHelper;
}
@Override
public void onBindViewHolder(PreferenceViewHolder 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.PreferenceScreenRegistry;
import com.android.settingslib.metadata.ProvidePreferenceScreenOptions;
import com.android.settingslib.preference.PreferenceBindingFactory;
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory;
import com.google.android.setupcompat.util.WizardManagerHelper;
@@ -76,6 +77,7 @@ public class SettingsApplication extends Application {
if (Flags.catalyst()) {
PreferenceScreenRegistry.INSTANCE.setPreferenceScreensSupplier(
this::getPreferenceScreens);
PreferenceBindingFactory.setDefaultFactory(new SettingsPreferenceBindingFactory());
}
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

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

View File

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

View File

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

View File

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

View File

@@ -33,11 +33,13 @@ import androidx.preference.PreferenceViewHolder;
import com.android.settings.R;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedPreferenceHelper;
import com.android.settingslib.RestrictedPreferenceHelperProvider;
/**
* 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;
private int mSelectedPreference;
@@ -64,6 +66,11 @@ public class BubblePreference extends Preference implements RadioGroup.OnChecked
setLayoutResource(R.layout.bubble_preference);
}
@Override
public @NonNull RestrictedPreferenceHelper getRestrictedPreferenceHelper() {
return mHelper;
}
public void setSelectedPreference(int preference) {
mSelectedPreference = preference;
notifyChanged();

View File

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

View File

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