diff options
| author | 2019-02-12 11:32:44 -0500 | |
|---|---|---|
| committer | 2019-02-14 09:36:21 -0500 | |
| commit | a6ff80bfb55f7d26bfceac403455ec345fae67a3 (patch) | |
| tree | 23b096708de668f1118cc1de850537210e95e2c4 | |
| parent | 78e3b2daf69fc9beafba3fd30509eba12896a063 (diff) | |
"Fix" NPE in PhoneStatusBarPolicy
Callback returns a copy of the list
Makes PrivacyItemController dumpable
Test: atest
Test: adb shell dumpsys activity service com.android.systemui/.SystemUIService Dependency
Fixes: 124234367
Change-Id: I1400ee8294f34b129723bb0f0ce7745dafaf5545
4 files changed, 66 insertions, 2 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt index f7ca51d6f840..a6e48f8835c7 100644 --- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt @@ -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)" } diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt index 0f3393708bcd..625eacd7e2a7 100644 --- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt @@ -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 @@ -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, @@ -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 @@ -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 diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java index 2799191a886f..e0c5e59b73f3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -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; @@ -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; diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt index 5d3f6cacc80f..bb384dd52875 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt @@ -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 @@ -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 |