Merge "Add DeviceConfig flags to Privacy Indicators" into qt-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
9faaa2733a
@@ -106,5 +106,12 @@ public final class SystemUiDeviceConfigFlags {
|
|||||||
*/
|
*/
|
||||||
public static final String HASH_SALT_MAX_DAYS = "hash_salt_max_days";
|
public static final String HASH_SALT_MAX_DAYS = "hash_salt_max_days";
|
||||||
|
|
||||||
|
// Flag related to Privacy Indicators
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the Permissions Hub is showing.
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_PERMISSIONS_HUB_ENABLED = "permissions_hub_enabled";
|
||||||
|
|
||||||
private SystemUiDeviceConfigFlags() { }
|
private SystemUiDeviceConfigFlags() { }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,13 @@ import android.content.Context
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
|
import android.os.Message
|
||||||
import android.os.UserHandle
|
import android.os.UserHandle
|
||||||
import android.os.UserManager
|
import android.os.UserManager
|
||||||
|
import android.provider.DeviceConfig
|
||||||
import com.android.internal.annotations.VisibleForTesting
|
import com.android.internal.annotations.VisibleForTesting
|
||||||
|
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags
|
||||||
import com.android.systemui.Dependency.BG_HANDLER_NAME
|
import com.android.systemui.Dependency.BG_HANDLER_NAME
|
||||||
import com.android.systemui.Dependency.MAIN_HANDLER_NAME
|
import com.android.systemui.Dependency.MAIN_HANDLER_NAME
|
||||||
import com.android.systemui.R
|
import com.android.systemui.R
|
||||||
@@ -39,6 +43,9 @@ import javax.inject.Inject
|
|||||||
import javax.inject.Named
|
import javax.inject.Named
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
fun isPermissionsHubEnabled() = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY,
|
||||||
|
SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED, false)
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class PrivacyItemController @Inject constructor(
|
class PrivacyItemController @Inject constructor(
|
||||||
val context: Context,
|
val context: Context,
|
||||||
@@ -47,7 +54,8 @@ class PrivacyItemController @Inject constructor(
|
|||||||
@Named(BG_HANDLER_NAME) private val bgHandler: Handler
|
@Named(BG_HANDLER_NAME) private val bgHandler: Handler
|
||||||
) : Dumpable {
|
) : Dumpable {
|
||||||
|
|
||||||
companion object {
|
@VisibleForTesting
|
||||||
|
internal companion object {
|
||||||
val OPS = intArrayOf(AppOpsManager.OP_CAMERA,
|
val OPS = intArrayOf(AppOpsManager.OP_CAMERA,
|
||||||
AppOpsManager.OP_RECORD_AUDIO,
|
AppOpsManager.OP_RECORD_AUDIO,
|
||||||
AppOpsManager.OP_COARSE_LOCATION,
|
AppOpsManager.OP_COARSE_LOCATION,
|
||||||
@@ -57,6 +65,9 @@ class PrivacyItemController @Inject constructor(
|
|||||||
Intent.ACTION_MANAGED_PROFILE_REMOVED)
|
Intent.ACTION_MANAGED_PROFILE_REMOVED)
|
||||||
const val TAG = "PrivacyItemController"
|
const val TAG = "PrivacyItemController"
|
||||||
const val SYSTEM_UID = 1000
|
const val SYSTEM_UID = 1000
|
||||||
|
const val MSG_ADD_CALLBACK = 0
|
||||||
|
const val MSG_REMOVE_CALLBACK = 1
|
||||||
|
const val MSG_UPDATE_LISTENING_STATE = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -70,6 +81,7 @@ class PrivacyItemController @Inject constructor(
|
|||||||
val systemApp =
|
val systemApp =
|
||||||
PrivacyApplication(context.getString(R.string.device_services), SYSTEM_UID, context)
|
PrivacyApplication(context.getString(R.string.device_services), SYSTEM_UID, context)
|
||||||
private val callbacks = mutableListOf<WeakReference<Callback>>()
|
private val callbacks = mutableListOf<WeakReference<Callback>>()
|
||||||
|
private val messageHandler = H(WeakReference(this), uiHandler.looper)
|
||||||
|
|
||||||
private val notifyChanges = Runnable {
|
private val notifyChanges = Runnable {
|
||||||
val list = privacyList
|
val list = privacyList
|
||||||
@@ -81,6 +93,20 @@ class PrivacyItemController @Inject constructor(
|
|||||||
uiHandler.post(notifyChanges)
|
uiHandler.post(notifyChanges)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var indicatorsAvailable = isPermissionsHubEnabled()
|
||||||
|
@VisibleForTesting
|
||||||
|
internal val devicePropertyChangedListener =
|
||||||
|
object : DeviceConfig.OnPropertyChangedListener {
|
||||||
|
override fun onPropertyChanged(namespace: String, name: String, value: String?) {
|
||||||
|
if (DeviceConfig.NAMESPACE_PRIVACY.equals(namespace) &&
|
||||||
|
SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED.equals(name)) {
|
||||||
|
indicatorsAvailable = java.lang.Boolean.parseBoolean(value)
|
||||||
|
messageHandler.removeMessages(MSG_UPDATE_LISTENING_STATE)
|
||||||
|
messageHandler.sendEmptyMessage(MSG_UPDATE_LISTENING_STATE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val cb = object : AppOpsController.Callback {
|
private val cb = object : AppOpsController.Callback {
|
||||||
override fun onActiveStateChanged(
|
override fun onActiveStateChanged(
|
||||||
code: Int,
|
code: Int,
|
||||||
@@ -103,6 +129,11 @@ class PrivacyItemController @Inject constructor(
|
|||||||
registerReceiver()
|
registerReceiver()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
DeviceConfig.addOnPropertyChangedListener(
|
||||||
|
DeviceConfig.NAMESPACE_PRIVACY, context.mainExecutor, devicePropertyChangedListener)
|
||||||
|
}
|
||||||
|
|
||||||
private fun unregisterReceiver() {
|
private fun unregisterReceiver() {
|
||||||
context.unregisterReceiver(userSwitcherReceiver)
|
context.unregisterReceiver(userSwitcherReceiver)
|
||||||
}
|
}
|
||||||
@@ -123,8 +154,14 @@ class PrivacyItemController @Inject constructor(
|
|||||||
bgHandler.post(updateListAndNotifyChanges)
|
bgHandler.post(updateListAndNotifyChanges)
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
/**
|
||||||
internal fun setListening(listen: Boolean) {
|
* Updates listening status based on whether there are callbacks and the indicators are enabled
|
||||||
|
*
|
||||||
|
* This is only called from private (add/remove)Callback and from the config listener, all in
|
||||||
|
* main thread.
|
||||||
|
*/
|
||||||
|
private fun setListeningState() {
|
||||||
|
val listen = !callbacks.isEmpty() and indicatorsAvailable
|
||||||
if (listening == listen) return
|
if (listening == listen) return
|
||||||
listening = listen
|
listening = listen
|
||||||
if (listening) {
|
if (listening) {
|
||||||
@@ -134,32 +171,44 @@ class PrivacyItemController @Inject constructor(
|
|||||||
} else {
|
} else {
|
||||||
appOpsController.removeCallback(OPS, cb)
|
appOpsController.removeCallback(OPS, cb)
|
||||||
unregisterReceiver()
|
unregisterReceiver()
|
||||||
|
// Make sure that we remove all indicators and notify listeners if we are not
|
||||||
|
// listening anymore due to indicators being disabled
|
||||||
|
update(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addCallback(callback: WeakReference<Callback>) {
|
private fun addCallback(callback: WeakReference<Callback>) {
|
||||||
callbacks.add(callback)
|
callbacks.add(callback)
|
||||||
if (callbacks.isNotEmpty() && !listening) setListening(true)
|
if (callbacks.isNotEmpty() && !listening) {
|
||||||
|
messageHandler.removeMessages(MSG_UPDATE_LISTENING_STATE)
|
||||||
|
messageHandler.sendEmptyMessage(MSG_UPDATE_LISTENING_STATE)
|
||||||
|
}
|
||||||
// Notify this callback if we didn't set to listening
|
// Notify this callback if we didn't set to listening
|
||||||
else uiHandler.post(NotifyChangesToCallback(callback.get(), privacyList))
|
else if (listening) uiHandler.post(NotifyChangesToCallback(callback.get(), privacyList))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun removeCallback(callback: WeakReference<Callback>) {
|
private fun removeCallback(callback: WeakReference<Callback>) {
|
||||||
// Removes also if the callback is null
|
// Removes also if the callback is null
|
||||||
callbacks.removeIf { it.get()?.equals(callback.get()) ?: true }
|
callbacks.removeIf { it.get()?.equals(callback.get()) ?: true }
|
||||||
if (callbacks.isEmpty()) setListening(false)
|
if (callbacks.isEmpty()) {
|
||||||
|
messageHandler.removeMessages(MSG_UPDATE_LISTENING_STATE)
|
||||||
|
messageHandler.sendEmptyMessage(MSG_UPDATE_LISTENING_STATE)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addCallback(callback: Callback) {
|
fun addCallback(callback: Callback) {
|
||||||
addCallback(WeakReference(callback))
|
messageHandler.obtainMessage(MSG_ADD_CALLBACK, callback).sendToTarget()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeCallback(callback: Callback) {
|
fun removeCallback(callback: Callback) {
|
||||||
removeCallback(WeakReference(callback))
|
messageHandler.obtainMessage(MSG_REMOVE_CALLBACK, callback).sendToTarget()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updatePrivacyList() {
|
private fun updatePrivacyList() {
|
||||||
|
if (!listening) {
|
||||||
|
privacyList = emptyList()
|
||||||
|
return
|
||||||
|
}
|
||||||
val list = currentUserIds.flatMap { appOpsController.getActiveAppOpsForUser(it) }
|
val list = currentUserIds.flatMap { appOpsController.getActiveAppOpsForUser(it) }
|
||||||
.mapNotNull { toPrivacyItem(it) }.distinct()
|
.mapNotNull { toPrivacyItem(it) }.distinct()
|
||||||
privacyList = list
|
privacyList = list
|
||||||
@@ -217,4 +266,29 @@ class PrivacyItemController @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class H(
|
||||||
|
private val outerClass: WeakReference<PrivacyItemController>,
|
||||||
|
looper: Looper
|
||||||
|
) : Handler(looper) {
|
||||||
|
override fun handleMessage(msg: Message) {
|
||||||
|
super.handleMessage(msg)
|
||||||
|
when (msg.what) {
|
||||||
|
MSG_UPDATE_LISTENING_STATE -> outerClass.get()?.setListeningState()
|
||||||
|
|
||||||
|
MSG_ADD_CALLBACK -> {
|
||||||
|
if (msg.obj !is PrivacyItemController.Callback) return
|
||||||
|
outerClass.get()?.addCallback(
|
||||||
|
WeakReference(msg.obj as PrivacyItemController.Callback))
|
||||||
|
}
|
||||||
|
|
||||||
|
MSG_REMOVE_CALLBACK -> {
|
||||||
|
if (msg.obj !is PrivacyItemController.Callback) return
|
||||||
|
outerClass.get()?.removeCallback(
|
||||||
|
WeakReference(msg.obj as PrivacyItemController.Callback))
|
||||||
|
}
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -34,6 +34,7 @@ import android.media.AudioManager;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.provider.AlarmClock;
|
import android.provider.AlarmClock;
|
||||||
|
import android.provider.DeviceConfig;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.service.notification.ZenModeConfig;
|
import android.service.notification.ZenModeConfig;
|
||||||
import android.text.format.DateUtils;
|
import android.text.format.DateUtils;
|
||||||
@@ -54,6 +55,7 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
|
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
|
||||||
import com.android.settingslib.Utils;
|
import com.android.settingslib.Utils;
|
||||||
import com.android.systemui.BatteryMeterView;
|
import com.android.systemui.BatteryMeterView;
|
||||||
import com.android.systemui.DualToneHandler;
|
import com.android.systemui.DualToneHandler;
|
||||||
@@ -65,6 +67,7 @@ import com.android.systemui.privacy.OngoingPrivacyChip;
|
|||||||
import com.android.systemui.privacy.PrivacyDialogBuilder;
|
import com.android.systemui.privacy.PrivacyDialogBuilder;
|
||||||
import com.android.systemui.privacy.PrivacyItem;
|
import com.android.systemui.privacy.PrivacyItem;
|
||||||
import com.android.systemui.privacy.PrivacyItemController;
|
import com.android.systemui.privacy.PrivacyItemController;
|
||||||
|
import com.android.systemui.privacy.PrivacyItemControllerKt;
|
||||||
import com.android.systemui.qs.QSDetail.Callback;
|
import com.android.systemui.qs.QSDetail.Callback;
|
||||||
import com.android.systemui.statusbar.phone.PhoneStatusBarView;
|
import com.android.systemui.statusbar.phone.PhoneStatusBarView;
|
||||||
import com.android.systemui.statusbar.phone.StatusBarIconController;
|
import com.android.systemui.statusbar.phone.StatusBarIconController;
|
||||||
@@ -141,6 +144,7 @@ public class QuickStatusBarHeader extends RelativeLayout implements
|
|||||||
private OngoingPrivacyChip mPrivacyChip;
|
private OngoingPrivacyChip mPrivacyChip;
|
||||||
private Space mSpace;
|
private Space mSpace;
|
||||||
private BatteryMeterView mBatteryRemainingIcon;
|
private BatteryMeterView mBatteryRemainingIcon;
|
||||||
|
private boolean mPermissionsHubEnabled;
|
||||||
|
|
||||||
private PrivacyItemController mPrivacyItemController;
|
private PrivacyItemController mPrivacyItemController;
|
||||||
|
|
||||||
@@ -154,6 +158,20 @@ public class QuickStatusBarHeader extends RelativeLayout implements
|
|||||||
private boolean mHasTopCutout = false;
|
private boolean mHasTopCutout = false;
|
||||||
private boolean mPrivacyChipLogged = false;
|
private boolean mPrivacyChipLogged = false;
|
||||||
|
|
||||||
|
private final DeviceConfig.OnPropertyChangedListener mPropertyListener =
|
||||||
|
new DeviceConfig.OnPropertyChangedListener() {
|
||||||
|
@Override
|
||||||
|
public void onPropertyChanged(String namespace, String name, String value) {
|
||||||
|
if (DeviceConfig.NAMESPACE_PRIVACY.equals(namespace)
|
||||||
|
&& SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED.equals(
|
||||||
|
name)) {
|
||||||
|
mPermissionsHubEnabled = Boolean.valueOf(value);
|
||||||
|
StatusIconContainer iconContainer = findViewById(R.id.statusIcons);
|
||||||
|
iconContainer.setIgnoredSlots(getIgnoredIconSlots());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private PrivacyItemController.Callback mPICCallback = new PrivacyItemController.Callback() {
|
private PrivacyItemController.Callback mPICCallback = new PrivacyItemController.Callback() {
|
||||||
@Override
|
@Override
|
||||||
public void privacyChanged(List<PrivacyItem> privacyItems) {
|
public void privacyChanged(List<PrivacyItem> privacyItems) {
|
||||||
@@ -236,6 +254,12 @@ public class QuickStatusBarHeader extends RelativeLayout implements
|
|||||||
mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE);
|
mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE);
|
||||||
mRingerModeTextView.setSelected(true);
|
mRingerModeTextView.setSelected(true);
|
||||||
mNextAlarmTextView.setSelected(true);
|
mNextAlarmTextView.setSelected(true);
|
||||||
|
|
||||||
|
mPermissionsHubEnabled = PrivacyItemControllerKt.isPermissionsHubEnabled();
|
||||||
|
// Change the ignored slots when DeviceConfig flag changes
|
||||||
|
DeviceConfig.addOnPropertyChangedListener(DeviceConfig.NAMESPACE_PRIVACY,
|
||||||
|
mContext.getMainExecutor(), mPropertyListener);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> getIgnoredIconSlots() {
|
private List<String> getIgnoredIconSlots() {
|
||||||
@@ -244,8 +268,10 @@ public class QuickStatusBarHeader extends RelativeLayout implements
|
|||||||
com.android.internal.R.string.status_bar_camera));
|
com.android.internal.R.string.status_bar_camera));
|
||||||
ignored.add(mContext.getResources().getString(
|
ignored.add(mContext.getResources().getString(
|
||||||
com.android.internal.R.string.status_bar_microphone));
|
com.android.internal.R.string.status_bar_microphone));
|
||||||
ignored.add(mContext.getResources().getString(
|
if (mPermissionsHubEnabled) {
|
||||||
com.android.internal.R.string.status_bar_location));
|
ignored.add(mContext.getResources().getString(
|
||||||
|
com.android.internal.R.string.status_bar_location));
|
||||||
|
}
|
||||||
|
|
||||||
return ignored;
|
return ignored;
|
||||||
}
|
}
|
||||||
@@ -262,7 +288,7 @@ public class QuickStatusBarHeader extends RelativeLayout implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setChipVisibility(boolean chipVisible) {
|
private void setChipVisibility(boolean chipVisible) {
|
||||||
if (chipVisible) {
|
if (chipVisible && mPermissionsHubEnabled) {
|
||||||
mPrivacyChip.setVisibility(View.VISIBLE);
|
mPrivacyChip.setVisibility(View.VISIBLE);
|
||||||
// Makes sure that the chip is logged as viewed at most once each time QS is opened
|
// Makes sure that the chip is logged as viewed at most once each time QS is opened
|
||||||
// mListening makes sure that the callback didn't return after the user closed QS
|
// mListening makes sure that the callback didn't return after the user closed QS
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import com.android.systemui.SysUiServiceProvider;
|
|||||||
import com.android.systemui.UiOffloadThread;
|
import com.android.systemui.UiOffloadThread;
|
||||||
import com.android.systemui.privacy.PrivacyItem;
|
import com.android.systemui.privacy.PrivacyItem;
|
||||||
import com.android.systemui.privacy.PrivacyItemController;
|
import com.android.systemui.privacy.PrivacyItemController;
|
||||||
|
import com.android.systemui.privacy.PrivacyItemControllerKt;
|
||||||
import com.android.systemui.privacy.PrivacyType;
|
import com.android.systemui.privacy.PrivacyType;
|
||||||
import com.android.systemui.qs.tiles.DndTile;
|
import com.android.systemui.qs.tiles.DndTile;
|
||||||
import com.android.systemui.qs.tiles.RotationLockTile;
|
import com.android.systemui.qs.tiles.RotationLockTile;
|
||||||
@@ -82,7 +83,8 @@ public class PhoneStatusBarPolicy
|
|||||||
ZenModeController.Callback,
|
ZenModeController.Callback,
|
||||||
DeviceProvisionedListener,
|
DeviceProvisionedListener,
|
||||||
KeyguardMonitor.Callback,
|
KeyguardMonitor.Callback,
|
||||||
PrivacyItemController.Callback {
|
PrivacyItemController.Callback,
|
||||||
|
LocationController.LocationChangeCallback {
|
||||||
private static final String TAG = "PhoneStatusBarPolicy";
|
private static final String TAG = "PhoneStatusBarPolicy";
|
||||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||||
|
|
||||||
@@ -257,6 +259,7 @@ public class PhoneStatusBarPolicy
|
|||||||
mKeyguardMonitor.addCallback(this);
|
mKeyguardMonitor.addCallback(this);
|
||||||
mPrivacyItemController.addCallback(this);
|
mPrivacyItemController.addCallback(this);
|
||||||
mSensorPrivacyController.addCallback(mSensorPrivacyListener);
|
mSensorPrivacyController.addCallback(mSensorPrivacyListener);
|
||||||
|
mLocationController.addCallback(this);
|
||||||
|
|
||||||
SysUiServiceProvider.getComponent(mContext, CommandQueue.class).addCallback(this);
|
SysUiServiceProvider.getComponent(mContext, CommandQueue.class).addCallback(this);
|
||||||
}
|
}
|
||||||
@@ -635,6 +638,20 @@ public class PhoneStatusBarPolicy
|
|||||||
mIconController.setIconVisibility(mSlotLocation, showLocation);
|
mIconController.setIconVisibility(mSlotLocation, showLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLocationActiveChanged(boolean active) {
|
||||||
|
if (!PrivacyItemControllerKt.isPermissionsHubEnabled()) updateLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates the status view based on the current state of location requests.
|
||||||
|
private void updateLocation() {
|
||||||
|
if (mLocationController.isLocationActive()) {
|
||||||
|
mIconController.setIconVisibility(mSlotLocation, true);
|
||||||
|
} else {
|
||||||
|
mIconController.setIconVisibility(mSlotLocation, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
|
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
|||||||
@@ -249,6 +249,15 @@ public class StatusIconContainer extends AlphaOptimizedLinearLayout {
|
|||||||
requestLayout();
|
requestLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the list of ignored icon slots clearing the current list.
|
||||||
|
* @param slots names of the icons to ignore
|
||||||
|
*/
|
||||||
|
public void setIgnoredSlots(List<String> slots) {
|
||||||
|
mIgnoredSlots.clear();
|
||||||
|
addIgnoredSlots(slots);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Layout is happening from end -> start
|
* Layout is happening from end -> start
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -24,13 +24,14 @@ import android.content.pm.UserInfo
|
|||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.UserHandle
|
import android.os.UserHandle
|
||||||
import android.os.UserManager
|
import android.os.UserManager
|
||||||
import androidx.test.filters.SmallTest
|
import android.provider.DeviceConfig
|
||||||
|
import android.provider.Settings.RESET_MODE_PACKAGE_DEFAULTS
|
||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner
|
||||||
import android.testing.TestableLooper
|
import android.testing.TestableLooper
|
||||||
import android.testing.TestableLooper.RunWithLooper
|
import android.testing.TestableLooper.RunWithLooper
|
||||||
|
import androidx.test.filters.SmallTest
|
||||||
|
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags
|
||||||
import com.android.systemui.Dependency
|
import com.android.systemui.Dependency
|
||||||
import com.android.systemui.Dependency.BG_HANDLER
|
|
||||||
import com.android.systemui.Dependency.MAIN_HANDLER
|
|
||||||
import com.android.systemui.R
|
import com.android.systemui.R
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.appops.AppOpItem
|
import com.android.systemui.appops.AppOpItem
|
||||||
@@ -38,6 +39,7 @@ import com.android.systemui.appops.AppOpsController
|
|||||||
import org.hamcrest.Matchers.hasItem
|
import org.hamcrest.Matchers.hasItem
|
||||||
import org.hamcrest.Matchers.not
|
import org.hamcrest.Matchers.not
|
||||||
import org.hamcrest.Matchers.nullValue
|
import org.hamcrest.Matchers.nullValue
|
||||||
|
import org.junit.After
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Assert.assertThat
|
import org.junit.Assert.assertThat
|
||||||
import org.junit.Assert.assertTrue
|
import org.junit.Assert.assertTrue
|
||||||
@@ -106,6 +108,9 @@ class PrivacyItemControllerTest : SysuiTestCase() {
|
|||||||
mContext.addMockSystemService(UserManager::class.java, userManager)
|
mContext.addMockSystemService(UserManager::class.java, userManager)
|
||||||
mContext.getOrCreateTestableResources().addOverride(R.string.device_services,
|
mContext.getOrCreateTestableResources().addOverride(R.string.device_services,
|
||||||
DEVICE_SERVICES_STRING)
|
DEVICE_SERVICES_STRING)
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_PRIVACY,
|
||||||
|
SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED,
|
||||||
|
"true", false)
|
||||||
|
|
||||||
doReturn(listOf(object : UserInfo() {
|
doReturn(listOf(object : UserInfo() {
|
||||||
init {
|
init {
|
||||||
@@ -116,9 +121,15 @@ class PrivacyItemControllerTest : SysuiTestCase() {
|
|||||||
privacyItemController = PrivacyItemController(mContext)
|
privacyItemController = PrivacyItemController(mContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
fun tearDown() {
|
||||||
|
DeviceConfig.resetToDefaults(RESET_MODE_PACKAGE_DEFAULTS, DeviceConfig.NAMESPACE_PRIVACY)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testSetListeningTrueByAddingCallback() {
|
fun testSetListeningTrueByAddingCallback() {
|
||||||
privacyItemController.addCallback(callback)
|
privacyItemController.addCallback(callback)
|
||||||
|
testableLooper.processAllMessages()
|
||||||
verify(appOpsController).addCallback(eq(PrivacyItemController.OPS),
|
verify(appOpsController).addCallback(eq(PrivacyItemController.OPS),
|
||||||
any(AppOpsController.Callback::class.java))
|
any(AppOpsController.Callback::class.java))
|
||||||
testableLooper.processAllMessages()
|
testableLooper.processAllMessages()
|
||||||
@@ -126,18 +137,16 @@ class PrivacyItemControllerTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testSetListeningTrue() {
|
fun testSetListeningFalseByRemovingLastCallback() {
|
||||||
privacyItemController.setListening(true)
|
privacyItemController.addCallback(callback)
|
||||||
verify(appOpsController).addCallback(eq(PrivacyItemController.OPS),
|
testableLooper.processAllMessages()
|
||||||
|
verify(appOpsController, never()).removeCallback(any(IntArray::class.java),
|
||||||
any(AppOpsController.Callback::class.java))
|
any(AppOpsController.Callback::class.java))
|
||||||
}
|
privacyItemController.removeCallback(callback)
|
||||||
|
testableLooper.processAllMessages()
|
||||||
@Test
|
|
||||||
fun testSetListeningFalse() {
|
|
||||||
privacyItemController.setListening(true)
|
|
||||||
privacyItemController.setListening(false)
|
|
||||||
verify(appOpsController).removeCallback(eq(PrivacyItemController.OPS),
|
verify(appOpsController).removeCallback(eq(PrivacyItemController.OPS),
|
||||||
any(AppOpsController.Callback::class.java))
|
any(AppOpsController.Callback::class.java))
|
||||||
|
verify(callback).privacyChanged(emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -168,7 +177,8 @@ class PrivacyItemControllerTest : SysuiTestCase() {
|
|||||||
fun testRegisterReceiver_allUsers() {
|
fun testRegisterReceiver_allUsers() {
|
||||||
val spiedContext = spy(mContext)
|
val spiedContext = spy(mContext)
|
||||||
val itemController = PrivacyItemController(spiedContext)
|
val itemController = PrivacyItemController(spiedContext)
|
||||||
itemController.setListening(true)
|
itemController.addCallback(callback)
|
||||||
|
testableLooper.processAllMessages()
|
||||||
verify(spiedContext, atLeastOnce()).registerReceiverAsUser(
|
verify(spiedContext, atLeastOnce()).registerReceiverAsUser(
|
||||||
eq(itemController.userSwitcherReceiver), eq(UserHandle.ALL), any(), eq(null),
|
eq(itemController.userSwitcherReceiver), eq(UserHandle.ALL), any(), eq(null),
|
||||||
eq(null))
|
eq(null))
|
||||||
@@ -268,4 +278,16 @@ class PrivacyItemControllerTest : SysuiTestCase() {
|
|||||||
assertEquals(list, privacyList)
|
assertEquals(list, privacyList)
|
||||||
assertTrue(list !== privacyList)
|
assertTrue(list !== privacyList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testNotListeningWhenIndicatorsDisabled() {
|
||||||
|
privacyItemController.devicePropertyChangedListener.onPropertyChanged(
|
||||||
|
DeviceConfig.NAMESPACE_PRIVACY,
|
||||||
|
SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED,
|
||||||
|
"false")
|
||||||
|
privacyItemController.addCallback(callback)
|
||||||
|
testableLooper.processAllMessages()
|
||||||
|
verify(appOpsController, never()).addCallback(eq(PrivacyItemController.OPS),
|
||||||
|
any(AppOpsController.Callback::class.java))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user