Loading packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt +2 −0 Original line number Diff line number Diff line Loading @@ -62,4 +62,6 @@ data class PrivacyApplication(val packageName: String, val uid: Int, val context context.packageManager.getApplicationLabel(it) as String } ?: packageName } override fun toString() = "PrivacyApplication(packageName=$packageName, uid=$uid)" } packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt +26 −2 Original line number Diff line number Diff line Loading @@ -31,6 +31,9 @@ import com.android.systemui.Dependency.MAIN_HANDLER_NAME import com.android.systemui.R import com.android.systemui.appops.AppOpItem import com.android.systemui.appops.AppOpsController import com.android.systemui.Dumpable import java.io.FileDescriptor import java.io.PrintWriter import java.lang.ref.WeakReference import javax.inject.Inject import javax.inject.Named Loading @@ -42,7 +45,7 @@ class PrivacyItemController @Inject constructor( private val appOpsController: AppOpsController, @Named(MAIN_HANDLER_NAME) private val uiHandler: Handler, @Named(BG_HANDLER_NAME) private val bgHandler: Handler ) { ) : Dumpable { companion object { val OPS = intArrayOf(AppOpsManager.OP_CAMERA, Loading @@ -56,7 +59,10 @@ class PrivacyItemController @Inject constructor( const val SYSTEM_UID = 1000 } private var privacyList = emptyList<PrivacyItem>() @VisibleForTesting internal var privacyList = emptyList<PrivacyItem>() get() = field.toList() // Provides a shallow copy of the list private val userManager = context.getSystemService(UserManager::class.java) private var currentUserIds = emptyList<Int>() private var listening = false Loading Loading @@ -189,4 +195,22 @@ class PrivacyItemController @Inject constructor( callback?.privacyChanged(list) } } override fun dump(fd: FileDescriptor?, pw: PrintWriter?, args: Array<out String>?) { pw?.println("PrivacyItemController state:") pw?.println(" Listening: $listening") pw?.println(" Current user ids: $currentUserIds") pw?.println(" Privacy Items:") privacyList.forEach { pw?.print(" ") pw?.println(it.toString()) } pw?.println(" Callbacks:") callbacks.forEach { it.get()?.let { pw?.print(" ") pw?.println(it.toString()) } } } } No newline at end of file packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +11 −0 Original line number Diff line number Diff line Loading @@ -92,6 +92,8 @@ import com.android.systemui.statusbar.policy.UserInfoController; import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.util.NotificationChannels; import java.io.PrintWriter; import java.io.StringWriter; import java.util.List; import java.util.Locale; Loading Loading @@ -793,6 +795,15 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks, boolean showMicrophone = false; boolean showLocation = false; for (PrivacyItem item : items) { if (item == null /* b/124234367 */) { if (DEBUG) { Log.e(TAG, "updatePrivacyItems - null item found"); StringWriter out = new StringWriter(); mPrivacyItemController.dump(null, new PrintWriter(out), null); Log.e(TAG, out.toString()); } continue; } switch (item.getPrivacyType()) { case TYPE_CAMERA: showCamera = true; Loading packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt +27 −0 Original line number Diff line number Diff line Loading @@ -35,7 +35,12 @@ import com.android.systemui.R import com.android.systemui.SysuiTestCase import com.android.systemui.appops.AppOpItem import com.android.systemui.appops.AppOpsController import org.hamcrest.Matchers.hasItem import org.hamcrest.Matchers.not import org.hamcrest.Matchers.nullValue import org.junit.Assert.assertEquals import org.junit.Assert.assertThat import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith Loading Loading @@ -240,4 +245,26 @@ class PrivacyItemControllerTest : SysuiTestCase() { verify(callback, never()).privacyChanged(anyList()) verify(otherCallback).privacyChanged(anyList()) } @Test fun testListShouldNotHaveNull() { doReturn(listOf(AppOpItem(AppOpsManager.OP_ACTIVATE_VPN, TEST_UID, "", 0), AppOpItem(AppOpsManager.OP_COARSE_LOCATION, TEST_UID, "", 0))) .`when`(appOpsController).getActiveAppOpsForUser(anyInt()) privacyItemController.addCallback(callback) testableLooper.processAllMessages() verify(callback).privacyChanged(capture(argCaptor)) assertEquals(1, argCaptor.value.size) assertThat(argCaptor.value, not(hasItem(nullValue()))) } @Test fun testListShouldBeCopy() { val list = listOf(PrivacyItem(PrivacyType.TYPE_CAMERA, PrivacyApplication("", TEST_UID, mContext))) privacyItemController.privacyList = list assertEquals(list, privacyItemController.privacyList) assertTrue(list !== privacyItemController.privacyList) } } No newline at end of file Loading
packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt +2 −0 Original line number Diff line number Diff line Loading @@ -62,4 +62,6 @@ data class PrivacyApplication(val packageName: String, val uid: Int, val context context.packageManager.getApplicationLabel(it) as String } ?: packageName } override fun toString() = "PrivacyApplication(packageName=$packageName, uid=$uid)" }
packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt +26 −2 Original line number Diff line number Diff line Loading @@ -31,6 +31,9 @@ import com.android.systemui.Dependency.MAIN_HANDLER_NAME import com.android.systemui.R import com.android.systemui.appops.AppOpItem import com.android.systemui.appops.AppOpsController import com.android.systemui.Dumpable import java.io.FileDescriptor import java.io.PrintWriter import java.lang.ref.WeakReference import javax.inject.Inject import javax.inject.Named Loading @@ -42,7 +45,7 @@ class PrivacyItemController @Inject constructor( private val appOpsController: AppOpsController, @Named(MAIN_HANDLER_NAME) private val uiHandler: Handler, @Named(BG_HANDLER_NAME) private val bgHandler: Handler ) { ) : Dumpable { companion object { val OPS = intArrayOf(AppOpsManager.OP_CAMERA, Loading @@ -56,7 +59,10 @@ class PrivacyItemController @Inject constructor( const val SYSTEM_UID = 1000 } private var privacyList = emptyList<PrivacyItem>() @VisibleForTesting internal var privacyList = emptyList<PrivacyItem>() get() = field.toList() // Provides a shallow copy of the list private val userManager = context.getSystemService(UserManager::class.java) private var currentUserIds = emptyList<Int>() private var listening = false Loading Loading @@ -189,4 +195,22 @@ class PrivacyItemController @Inject constructor( callback?.privacyChanged(list) } } override fun dump(fd: FileDescriptor?, pw: PrintWriter?, args: Array<out String>?) { pw?.println("PrivacyItemController state:") pw?.println(" Listening: $listening") pw?.println(" Current user ids: $currentUserIds") pw?.println(" Privacy Items:") privacyList.forEach { pw?.print(" ") pw?.println(it.toString()) } pw?.println(" Callbacks:") callbacks.forEach { it.get()?.let { pw?.print(" ") pw?.println(it.toString()) } } } } No newline at end of file
packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +11 −0 Original line number Diff line number Diff line Loading @@ -92,6 +92,8 @@ import com.android.systemui.statusbar.policy.UserInfoController; import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.util.NotificationChannels; import java.io.PrintWriter; import java.io.StringWriter; import java.util.List; import java.util.Locale; Loading Loading @@ -793,6 +795,15 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks, boolean showMicrophone = false; boolean showLocation = false; for (PrivacyItem item : items) { if (item == null /* b/124234367 */) { if (DEBUG) { Log.e(TAG, "updatePrivacyItems - null item found"); StringWriter out = new StringWriter(); mPrivacyItemController.dump(null, new PrintWriter(out), null); Log.e(TAG, out.toString()); } continue; } switch (item.getPrivacyType()) { case TYPE_CAMERA: showCamera = true; Loading
packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt +27 −0 Original line number Diff line number Diff line Loading @@ -35,7 +35,12 @@ import com.android.systemui.R import com.android.systemui.SysuiTestCase import com.android.systemui.appops.AppOpItem import com.android.systemui.appops.AppOpsController import org.hamcrest.Matchers.hasItem import org.hamcrest.Matchers.not import org.hamcrest.Matchers.nullValue import org.junit.Assert.assertEquals import org.junit.Assert.assertThat import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith Loading Loading @@ -240,4 +245,26 @@ class PrivacyItemControllerTest : SysuiTestCase() { verify(callback, never()).privacyChanged(anyList()) verify(otherCallback).privacyChanged(anyList()) } @Test fun testListShouldNotHaveNull() { doReturn(listOf(AppOpItem(AppOpsManager.OP_ACTIVATE_VPN, TEST_UID, "", 0), AppOpItem(AppOpsManager.OP_COARSE_LOCATION, TEST_UID, "", 0))) .`when`(appOpsController).getActiveAppOpsForUser(anyInt()) privacyItemController.addCallback(callback) testableLooper.processAllMessages() verify(callback).privacyChanged(capture(argCaptor)) assertEquals(1, argCaptor.value.size) assertThat(argCaptor.value, not(hasItem(nullValue()))) } @Test fun testListShouldBeCopy() { val list = listOf(PrivacyItem(PrivacyType.TYPE_CAMERA, PrivacyApplication("", TEST_UID, mContext))) privacyItemController.privacyList = list assertEquals(list, privacyItemController.privacyList) assertTrue(list !== privacyItemController.privacyList) } } No newline at end of file