Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7e5d596e authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Convert PrivacyItemController to Dependency"

parents cd989d40 04f83eb5
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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
+43 −5
Original line number Diff line number Diff line
@@ -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,15 +113,39 @@ 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() {
@@ -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)
        }
    }
}
 No newline at end of file
+4 −3
Original line number Diff line number Diff line
@@ -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);
        }
    }
+3 −3
Original line number Diff line number Diff line
@@ -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);

+69 −7
Original line number Diff line number Diff line
@@ -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,18 +100,25 @@ class PrivacyItemControllerTest : SysuiTestCase() {
            }
        })).`when`(userManager).getProfiles(anyInt())

        privacyItemController = PrivacyItemController(mContext, callback)
        privacyItemController = PrivacyItemController(mContext)
    }

    @Test
    fun testSetListeningTrue() {
        privacyItemController.setListening(true)
    fun testSetListeningTrueByAddingCallback() {
        privacyItemController.addCallback(callback)
        verify(appOpsController).addCallback(eq(PrivacyItemController.OPS),
                any(AppOpsController.Callback::class.java))
        testableLooper.processAllMessages()
        verify(callback).privacyChanged(anyList())
    }

    @Test
    fun testSetListeningTrue() {
        privacyItemController.setListening(true)
        verify(appOpsController).addCallback(eq(PrivacyItemController.OPS),
                any(AppOpsController.Callback::class.java))
    }

    @Test
    fun testSetListeningFalse() {
        privacyItemController.setListening(true)
@@ -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())
    }
}
 No newline at end of file