Merge "Convert PrivacyItemController to Dependency"

This commit is contained in:
TreeHugger Robot
2019-01-24 23:47:33 +00:00
committed by Android (Google) Code Review
5 changed files with 123 additions and 18 deletions

View File

@@ -44,6 +44,7 @@ import com.android.systemui.plugins.PluginDependencyProvider;
import com.android.systemui.plugins.VolumeDialogController;
import com.android.systemui.power.EnhancedEstimates;
import com.android.systemui.power.PowerUI;
import com.android.systemui.privacy.PrivacyItemController;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.statusbar.AmbientPulseManager;
@@ -278,6 +279,7 @@ public class Dependency extends SystemUI {
@Inject Lazy<SensorPrivacyManager> mSensorPrivacyManager;
@Inject Lazy<AutoHideController> mAutoHideController;
@Inject Lazy<ForegroundServiceNotificationListener> mForegroundServiceNotificationListener;
@Inject Lazy<PrivacyItemController> mPrivacyItemController;
@Inject @Named(BG_LOOPER_NAME) Lazy<Looper> mBgLooper;
@Inject @Named(BG_HANDLER_NAME) Lazy<Handler> mBgHandler;
@Inject @Named(MAIN_HANDLER_NAME) Lazy<Handler> mMainHandler;
@@ -452,6 +454,8 @@ public class Dependency extends SystemUI {
mProviders.put(ForegroundServiceNotificationListener.class,
mForegroundServiceNotificationListener::get);
mProviders.put(ClockManager.class, mClockManager::get);
mProviders.put(PrivacyItemController.class, mPrivacyItemController::get);
// TODO(b/118592525): to support multi-display , we start to add something which is
// per-display, while others may be global. I think it's time to add

View File

@@ -30,8 +30,12 @@ import com.android.systemui.Dependency
import com.android.systemui.appops.AppOpItem
import com.android.systemui.appops.AppOpsController
import com.android.systemui.R
import java.lang.ref.WeakReference
import javax.inject.Inject
import javax.inject.Singleton
class PrivacyItemController(val context: Context, val callback: Callback) {
@Singleton
class PrivacyItemController @Inject constructor(val context: Context) {
companion object {
val OPS = intArrayOf(AppOpsManager.OP_CAMERA,
@@ -56,9 +60,10 @@ class PrivacyItemController(val context: Context, val callback: Callback) {
private val uiHandler = Dependency.get(Dependency.MAIN_HANDLER)
private var listening = false
val systemApp = PrivacyApplication(context.getString(R.string.device_services), context)
private val callbacks = mutableListOf<WeakReference<Callback>>()
private val notifyChanges = Runnable {
callback.privacyChanged(privacyList)
callbacks.forEach { it.get()?.privacyChanged(privacyList) }
}
private val updateListAndNotifyChanges = Runnable {
@@ -88,8 +93,8 @@ class PrivacyItemController(val context: Context, val callback: Callback) {
registerReceiver()
}
init {
registerReceiver()
private fun unregisterReceiver() {
context.unregisterReceiver(userSwitcherReceiver)
}
private fun registerReceiver() {
@@ -108,17 +113,41 @@ class PrivacyItemController(val context: Context, val callback: Callback) {
bgHandler.post(updateListAndNotifyChanges)
}
fun setListening(listen: Boolean) {
@VisibleForTesting
internal fun setListening(listen: Boolean) {
if (listening == listen) return
listening = listen
if (listening) {
appOpsController.addCallback(OPS, cb)
registerReceiver()
update(true)
} else {
appOpsController.removeCallback(OPS, cb)
unregisterReceiver()
}
}
private fun addCallback(callback: WeakReference<Callback>) {
callbacks.add(callback)
if (callbacks.isNotEmpty() && !listening) setListening(true)
// Notify this callback if we didn't set to listening
else uiHandler.post(NotifyChangesToCallback(callback.get(), privacyList))
}
private fun removeCallback(callback: WeakReference<Callback>) {
// Removes also if the callback is null
callbacks.removeIf { it.get()?.equals(callback.get()) ?: true }
if (callbacks.isEmpty()) setListening(false)
}
fun addCallback(callback: Callback) {
addCallback(WeakReference(callback))
}
fun removeCallback(callback: Callback) {
removeCallback(WeakReference(callback))
}
private fun updatePrivacyList() {
privacyList = currentUserIds.flatMap { appOpsController.getActiveAppOpsForUser(it) }
.mapNotNull { toPrivacyItem(it) }.distinct()
@@ -149,4 +178,13 @@ class PrivacyItemController(val context: Context, val callback: Callback) {
}
}
}
private class NotifyChangesToCallback(
private val callback: Callback?,
private val list: List<PrivacyItem>
) : Runnable {
override fun run() {
callback?.privacyChanged(list)
}
}
}

View File

@@ -180,14 +180,14 @@ public class QuickStatusBarHeader extends RelativeLayout implements
public QuickStatusBarHeader(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
NextAlarmController nextAlarmController, ZenModeController zenModeController,
BatteryController batteryController, StatusBarIconController statusBarIconController,
ActivityStarter activityStarter) {
ActivityStarter activityStarter, PrivacyItemController privacyItemController) {
super(context, attrs);
mAlarmController = nextAlarmController;
mZenController = zenModeController;
mBatteryController = batteryController;
mStatusBarIconController = statusBarIconController;
mActivityStarter = activityStarter;
mPrivacyItemController = new PrivacyItemController(context, mPICCallback);
mPrivacyItemController = privacyItemController;
mShownCount = getStoredShownCount();
}
@@ -512,7 +512,6 @@ public class QuickStatusBarHeader extends RelativeLayout implements
return;
}
mHeaderQsPanel.setListening(listening);
mPrivacyItemController.setListening(listening);
mListening = listening;
if (listening) {
@@ -520,9 +519,11 @@ public class QuickStatusBarHeader extends RelativeLayout implements
mAlarmController.addCallback(this);
mContext.registerReceiver(mRingerReceiver,
new IntentFilter(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION));
mPrivacyItemController.addCallback(mPICCallback);
} else {
mZenController.removeCallback(this);
mAlarmController.removeCallback(this);
mPrivacyItemController.removeCallback(mPICCallback);
mContext.unregisterReceiver(mRingerReceiver);
}
}

View File

@@ -173,7 +173,7 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,
mProvisionedController = Dependency.get(DeviceProvisionedController.class);
mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
mLocationController = Dependency.get(LocationController.class);
mPrivacyItemController = new PrivacyItemController(mContext, this);
mPrivacyItemController = Dependency.get(PrivacyItemController.class);
mSlotCast = context.getString(com.android.internal.R.string.status_bar_cast);
mSlotHotspot = context.getString(com.android.internal.R.string.status_bar_hotspot);
@@ -266,7 +266,7 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,
mNextAlarmController.addCallback(mNextAlarmCallback);
mDataSaver.addCallback(this);
mKeyguardMonitor.addCallback(this);
mPrivacyItemController.setListening(true);
mPrivacyItemController.addCallback(this);
SysUiServiceProvider.getComponent(mContext, CommandQueue.class).addCallback(this);
ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskListener);
@@ -294,7 +294,7 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,
mNextAlarmController.removeCallback(mNextAlarmCallback);
mDataSaver.removeCallback(this);
mKeyguardMonitor.removeCallback(this);
mPrivacyItemController.setListening(false);
mPrivacyItemController.removeCallback(this);
SysUiServiceProvider.getComponent(mContext, CommandQueue.class).removeCallback(this);
mContext.unregisterReceiver(mIntentReceiver);

View File

@@ -45,9 +45,12 @@ import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito.atLeastOnce
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.reset
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.MockitoAnnotations
@RunWith(AndroidTestingRunner::class)
@@ -73,6 +76,8 @@ class PrivacyItemControllerTest : SysuiTestCase() {
private lateinit var userManager: UserManager
@Captor
private lateinit var argCaptor: ArgumentCaptor<List<PrivacyItem>>
@Captor
private lateinit var argCaptorCallback: ArgumentCaptor<AppOpsController.Callback>
private lateinit var testableLooper: TestableLooper
private lateinit var privacyItemController: PrivacyItemController
@@ -95,7 +100,16 @@ class PrivacyItemControllerTest : SysuiTestCase() {
}
})).`when`(userManager).getProfiles(anyInt())
privacyItemController = PrivacyItemController(mContext, callback)
privacyItemController = PrivacyItemController(mContext)
}
@Test
fun testSetListeningTrueByAddingCallback() {
privacyItemController.addCallback(callback)
verify(appOpsController).addCallback(eq(PrivacyItemController.OPS),
any(AppOpsController.Callback::class.java))
testableLooper.processAllMessages()
verify(callback).privacyChanged(anyList())
}
@Test
@@ -103,8 +117,6 @@ class PrivacyItemControllerTest : SysuiTestCase() {
privacyItemController.setListening(true)
verify(appOpsController).addCallback(eq(PrivacyItemController.OPS),
any(AppOpsController.Callback::class.java))
testableLooper.processAllMessages()
verify(callback).privacyChanged(anyList())
}
@Test
@@ -121,7 +133,7 @@ class PrivacyItemControllerTest : SysuiTestCase() {
AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, "", 1)))
.`when`(appOpsController).getActiveAppOpsForUser(anyInt())
privacyItemController.setListening(true)
privacyItemController.addCallback(callback)
testableLooper.processAllMessages()
verify(callback).privacyChanged(capture(argCaptor))
assertEquals(1, argCaptor.value.size)
@@ -131,7 +143,7 @@ class PrivacyItemControllerTest : SysuiTestCase() {
fun testSystemApps() {
doReturn(listOf(AppOpItem(AppOpsManager.OP_COARSE_LOCATION, SYSTEM_UID, TEST_PACKAGE_NAME,
0))).`when`(appOpsController).getActiveAppOpsForUser(anyInt())
privacyItemController.setListening(true)
privacyItemController.addCallback(callback)
testableLooper.processAllMessages()
verify(callback).privacyChanged(capture(argCaptor))
assertEquals(1, argCaptor.value.size)
@@ -142,8 +154,8 @@ class PrivacyItemControllerTest : SysuiTestCase() {
@Test
fun testRegisterReceiver_allUsers() {
val spiedContext = spy(mContext)
val itemController = PrivacyItemController(spiedContext, callback)
val itemController = PrivacyItemController(spiedContext)
itemController.setListening(true)
verify(spiedContext, atLeastOnce()).registerReceiverAsUser(
eq(itemController.userSwitcherReceiver), eq(UserHandle.ALL), any(), eq(null),
eq(null))
@@ -170,4 +182,54 @@ class PrivacyItemControllerTest : SysuiTestCase() {
Intent(Intent.ACTION_MANAGED_PROFILE_REMOVED))
verify(userManager).getProfiles(anyInt())
}
@Test
fun testAddMultipleCallbacks() {
val otherCallback = mock(PrivacyItemController.Callback::class.java)
privacyItemController.addCallback(callback)
testableLooper.processAllMessages()
verify(callback).privacyChanged(anyList())
privacyItemController.addCallback(otherCallback)
testableLooper.processAllMessages()
verify(otherCallback).privacyChanged(anyList())
// Adding a callback should not unnecessarily call previous ones
verifyNoMoreInteractions(callback)
}
@Test
fun testMultipleCallbacksAreUpdated() {
doReturn(emptyList<AppOpItem>()).`when`(appOpsController).getActiveAppOpsForUser(anyInt())
val otherCallback = mock(PrivacyItemController.Callback::class.java)
privacyItemController.addCallback(callback)
privacyItemController.addCallback(otherCallback)
testableLooper.processAllMessages()
reset(callback)
reset(otherCallback)
verify(appOpsController).addCallback(any<IntArray>(), capture(argCaptorCallback))
argCaptorCallback.value.onActiveStateChanged(0, TEST_UID, "", true)
testableLooper.processAllMessages()
verify(callback).privacyChanged(anyList())
verify(otherCallback).privacyChanged(anyList())
}
@Test
fun testRemoveCallback() {
doReturn(emptyList<AppOpItem>()).`when`(appOpsController).getActiveAppOpsForUser(anyInt())
val otherCallback = mock(PrivacyItemController.Callback::class.java)
privacyItemController.addCallback(callback)
privacyItemController.addCallback(otherCallback)
testableLooper.processAllMessages()
reset(callback)
reset(otherCallback)
verify(appOpsController).addCallback(any<IntArray>(), capture(argCaptorCallback))
privacyItemController.removeCallback(callback)
argCaptorCallback.value.onActiveStateChanged(0, TEST_UID, "", true)
testableLooper.processAllMessages()
verify(callback, never()).privacyChanged(anyList())
verify(otherCallback).privacyChanged(anyList())
}
}