Loading core/java/android/permission/PermissionUsageHelper.java +0 −19 Original line number Diff line number Diff line Loading @@ -86,12 +86,6 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis */ private static final String PROPERTY_CAMERA_MIC_ICONS_ENABLED = "camera_mic_icons_enabled"; /** * Whether to show the location indicators. */ private static final String PROPERTY_LOCATION_INDICATORS_ENABLED = "location_indicators_enabled"; /** * How long after an access to show it as "recent" */ Loading @@ -112,11 +106,6 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis PROPERTY_CAMERA_MIC_ICONS_ENABLED, true); } private static boolean shouldShowLocationIndicator() { return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY, PROPERTY_LOCATION_INDICATORS_ENABLED, false); } private static long getRecentThreshold(Long now) { return now - DeviceConfig.getLong(DeviceConfig.NAMESPACE_PRIVACY, RECENT_ACCESS_TIME_MS, DEFAULT_RECENT_TIME_MS); Loading @@ -127,11 +116,6 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis RUNNING_ACCESS_TIME_MS, DEFAULT_RUNNING_TIME_MS); } private static final List<String> LOCATION_OPS = List.of( OPSTR_COARSE_LOCATION, OPSTR_FINE_LOCATION ); private static final List<String> MIC_OPS = List.of( OPSTR_PHONE_CALL_MICROPHONE, OPSTR_RECEIVE_AMBIENT_TRIGGER_AUDIO, Loading Loading @@ -300,9 +284,6 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis } List<String> ops = new ArrayList<>(CAMERA_OPS); if (shouldShowLocationIndicator()) { ops.addAll(LOCATION_OPS); } if (includeMicrophoneUsage) { ops.addAll(MIC_OPS); } Loading core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java +0 −5 Original line number Diff line number Diff line Loading @@ -132,11 +132,6 @@ public final class SystemUiDeviceConfigFlags { */ public static final String PROPERTY_MIC_CAMERA_ENABLED = "camera_mic_icons_enabled"; /** * Whether to show app ops chip for location. */ public static final String PROPERTY_LOCATION_INDICATORS_ENABLED = "location_indicators_enabled"; /** * Whether to show privacy chip for media projection. */ Loading location/java/android/location/flags/location.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -187,3 +187,11 @@ flag { description: "Adds missing attribution tags in the Fused and Gnss overlay" bug: "403337028" } flag { name: "location_indicators_enabled" namespace: "location" description: "Enables modified location privacy item behavior" bug: "419834493" } No newline at end of file packages/SystemUI/multivalentTests/src/com/android/systemui/privacy/PrivacyConfigFlagsTest.kt +34 −20 Original line number Diff line number Diff line Loading @@ -16,8 +16,11 @@ package com.android.systemui.privacy import android.location.flags.Flags import android.platform.test.annotations.EnableFlags import android.platform.test.flag.junit.FlagsParameterization import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf import android.provider.DeviceConfig import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.config.sysui.SystemUiDeviceConfigFlags import com.android.systemui.SysuiTestCase Loading @@ -36,33 +39,39 @@ import org.mockito.Mockito.atLeastOnce import org.mockito.Mockito.never import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations import platform.test.runner.parameterized.ParameterizedAndroidJunit4 import platform.test.runner.parameterized.Parameters @RunWith(AndroidJUnit4::class) @RunWith(ParameterizedAndroidJunit4::class) @SmallTest @android.platform.test.annotations.EnabledOnRavenwood class PrivacyConfigFlagsTest : SysuiTestCase() { class PrivacyConfigFlagsTest(flags: FlagsParameterization) : SysuiTestCase() { companion object { private const val MIC_CAMERA = SystemUiDeviceConfigFlags.PROPERTY_MIC_CAMERA_ENABLED private const val LOCATION = SystemUiDeviceConfigFlags.PROPERTY_LOCATION_INDICATORS_ENABLED private const val MEDIA_PROJECTION = SystemUiDeviceConfigFlags.PROPERTY_MEDIA_PROJECTION_INDICATORS_ENABLED @JvmStatic @Parameters(name = "{0}") fun getParams(): List<FlagsParameterization> { return allCombinationsOf(Flags.FLAG_LOCATION_INDICATORS_ENABLED) } } init { mSetFlagsRule.setFlagsParameterization(flags) } private lateinit var privacyConfig: PrivacyConfig @Mock private lateinit var callback: PrivacyConfig.Callback @Mock private lateinit var dumpManager: DumpManager @Mock private lateinit var callback: PrivacyConfig.Callback @Mock private lateinit var dumpManager: DumpManager private lateinit var executor: FakeExecutor private lateinit var deviceConfigProxy: DeviceConfigProxy fun createPrivacyConfig(): PrivacyConfig { return PrivacyConfig( executor, deviceConfigProxy, dumpManager) return PrivacyConfig(executor, deviceConfigProxy, dumpManager) } @Before Loading @@ -78,11 +87,13 @@ class PrivacyConfigFlagsTest : SysuiTestCase() { } @Test @EnableFlags(Flags.FLAG_LOCATION_INDICATORS_ENABLED) fun testMicCameraListeningByDefault() { assertTrue(privacyConfig.micCameraAvailable) } @Test @EnableFlags(Flags.FLAG_LOCATION_INDICATORS_ENABLED) fun testMicCameraChanged() { changeMicCamera(false) // default is true executor.runAllReady() Loading @@ -93,6 +104,7 @@ class PrivacyConfigFlagsTest : SysuiTestCase() { } @Test @EnableFlags(Flags.FLAG_LOCATION_INDICATORS_ENABLED) fun testMediaProjectionChanged() { changeMediaProjection(false) // default is true executor.runAllReady() Loading @@ -103,8 +115,9 @@ class PrivacyConfigFlagsTest : SysuiTestCase() { } @Test @EnableFlags(Flags.FLAG_LOCATION_INDICATORS_ENABLED) fun testLocationChanged() { changeLocation(true) changeMicCamera(true) executor.runAllReady() verify(callback).onFlagLocationChanged(true) Loading @@ -112,8 +125,8 @@ class PrivacyConfigFlagsTest : SysuiTestCase() { } @Test @EnableFlags(Flags.FLAG_LOCATION_INDICATORS_ENABLED) fun testMicCamAndLocationChanged() { changeLocation(true) changeMicCamera(false) executor.runAllReady() Loading @@ -125,6 +138,7 @@ class PrivacyConfigFlagsTest : SysuiTestCase() { } @Test @EnableFlags(Flags.FLAG_LOCATION_INDICATORS_ENABLED) fun testMicDeleted_stillAvailable() { changeMicCamera(true) executor.runAllReady() Loading @@ -136,7 +150,7 @@ class PrivacyConfigFlagsTest : SysuiTestCase() { } private fun changeMicCamera(value: Boolean?) = changeProperty(MIC_CAMERA, value) private fun changeLocation(value: Boolean?) = changeProperty(LOCATION, value) private fun changeMediaProjection(value: Boolean?) = changeProperty(MEDIA_PROJECTION, value) private fun changeProperty(name: String, value: Boolean?) { Loading @@ -144,7 +158,7 @@ class PrivacyConfigFlagsTest : SysuiTestCase() { DeviceConfig.NAMESPACE_PRIVACY, name, value?.toString(), false false, ) } } packages/SystemUI/src/com/android/systemui/privacy/PrivacyConfig.kt +42 −42 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.privacy import android.location.flags.Flags.locationIndicatorsEnabled import android.provider.DeviceConfig import com.android.internal.annotations.VisibleForTesting import com.android.internal.annotations.WeaklyReferencedCallback Loading @@ -33,21 +34,21 @@ import java.lang.ref.WeakReference import javax.inject.Inject @SysUISingleton class PrivacyConfig @Inject constructor( class PrivacyConfig @Inject constructor( @Main private val uiExecutor: DelayableExecutor, private val deviceConfigProxy: DeviceConfigProxy, dumpManager: DumpManager dumpManager: DumpManager, ) : Dumpable { @VisibleForTesting internal companion object { const val TAG = "PrivacyConfig" private const val MIC_CAMERA = SystemUiDeviceConfigFlags.PROPERTY_MIC_CAMERA_ENABLED private const val LOCATION = SystemUiDeviceConfigFlags.PROPERTY_LOCATION_INDICATORS_ENABLED private const val MEDIA_PROJECTION = SystemUiDeviceConfigFlags.PROPERTY_MEDIA_PROJECTION_INDICATORS_ENABLED private const val DEFAULT_MIC_CAMERA = true private const val DEFAULT_LOCATION = false private const val DEFAULT_MEDIA_PROJECTION = true } Loading @@ -55,8 +56,10 @@ class PrivacyConfig @Inject constructor( var micCameraAvailable = isMicCameraEnabled() private set var locationAvailable = isLocationEnabled() var locationAvailable = locationIndicatorsEnabled() private set var mediaProjectionAvailable = isMediaProjectionEnabled() private set Loading @@ -69,8 +72,7 @@ class PrivacyConfig @Inject constructor( callbacks.forEach { it.get()?.onFlagMicCameraChanged(micCameraAvailable) } } if (properties.keyset.contains(LOCATION)) { locationAvailable = properties.getBoolean(LOCATION, DEFAULT_LOCATION) if (locationAvailable) { callbacks.forEach { it.get()?.onFlagLocationChanged(locationAvailable) } } Loading @@ -89,22 +91,24 @@ class PrivacyConfig @Inject constructor( deviceConfigProxy.addOnPropertiesChangedListener( DeviceConfig.NAMESPACE_PRIVACY, uiExecutor, devicePropertiesChangedListener) devicePropertiesChangedListener, ) } private fun isMicCameraEnabled(): Boolean { return deviceConfigProxy.getBoolean(DeviceConfig.NAMESPACE_PRIVACY, MIC_CAMERA, DEFAULT_MIC_CAMERA) } private fun isLocationEnabled(): Boolean { return deviceConfigProxy.getBoolean(DeviceConfig.NAMESPACE_PRIVACY, LOCATION, DEFAULT_LOCATION) return deviceConfigProxy.getBoolean( DeviceConfig.NAMESPACE_PRIVACY, MIC_CAMERA, DEFAULT_MIC_CAMERA, ) } private fun isMediaProjectionEnabled(): Boolean { return deviceConfigProxy.getBoolean(DeviceConfig.NAMESPACE_PRIVACY, MEDIA_PROJECTION, DEFAULT_MEDIA_PROJECTION) return deviceConfigProxy.getBoolean( DeviceConfig.NAMESPACE_PRIVACY, MEDIA_PROJECTION, DEFAULT_MEDIA_PROJECTION, ) } fun addCallback(callback: Callback) { Loading @@ -116,9 +120,7 @@ class PrivacyConfig @Inject constructor( } private fun addCallback(callback: WeakReference<Callback>) { uiExecutor.execute { callbacks.add(callback) } uiExecutor.execute { callbacks.add(callback) } } private fun removeCallback(callback: WeakReference<Callback>) { Loading @@ -137,9 +139,7 @@ class PrivacyConfig @Inject constructor( ipw.println("mediaProjectionAvailable: $mediaProjectionAvailable") ipw.println("Callbacks:") ipw.withIncreasedIndent { callbacks.forEach { callback -> callback.get()?.let { ipw.println(it) } } callbacks.forEach { callback -> callback.get()?.let { ipw.println(it) } } } } ipw.flush() Loading Loading
core/java/android/permission/PermissionUsageHelper.java +0 −19 Original line number Diff line number Diff line Loading @@ -86,12 +86,6 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis */ private static final String PROPERTY_CAMERA_MIC_ICONS_ENABLED = "camera_mic_icons_enabled"; /** * Whether to show the location indicators. */ private static final String PROPERTY_LOCATION_INDICATORS_ENABLED = "location_indicators_enabled"; /** * How long after an access to show it as "recent" */ Loading @@ -112,11 +106,6 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis PROPERTY_CAMERA_MIC_ICONS_ENABLED, true); } private static boolean shouldShowLocationIndicator() { return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY, PROPERTY_LOCATION_INDICATORS_ENABLED, false); } private static long getRecentThreshold(Long now) { return now - DeviceConfig.getLong(DeviceConfig.NAMESPACE_PRIVACY, RECENT_ACCESS_TIME_MS, DEFAULT_RECENT_TIME_MS); Loading @@ -127,11 +116,6 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis RUNNING_ACCESS_TIME_MS, DEFAULT_RUNNING_TIME_MS); } private static final List<String> LOCATION_OPS = List.of( OPSTR_COARSE_LOCATION, OPSTR_FINE_LOCATION ); private static final List<String> MIC_OPS = List.of( OPSTR_PHONE_CALL_MICROPHONE, OPSTR_RECEIVE_AMBIENT_TRIGGER_AUDIO, Loading Loading @@ -300,9 +284,6 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis } List<String> ops = new ArrayList<>(CAMERA_OPS); if (shouldShowLocationIndicator()) { ops.addAll(LOCATION_OPS); } if (includeMicrophoneUsage) { ops.addAll(MIC_OPS); } Loading
core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java +0 −5 Original line number Diff line number Diff line Loading @@ -132,11 +132,6 @@ public final class SystemUiDeviceConfigFlags { */ public static final String PROPERTY_MIC_CAMERA_ENABLED = "camera_mic_icons_enabled"; /** * Whether to show app ops chip for location. */ public static final String PROPERTY_LOCATION_INDICATORS_ENABLED = "location_indicators_enabled"; /** * Whether to show privacy chip for media projection. */ Loading
location/java/android/location/flags/location.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -187,3 +187,11 @@ flag { description: "Adds missing attribution tags in the Fused and Gnss overlay" bug: "403337028" } flag { name: "location_indicators_enabled" namespace: "location" description: "Enables modified location privacy item behavior" bug: "419834493" } No newline at end of file
packages/SystemUI/multivalentTests/src/com/android/systemui/privacy/PrivacyConfigFlagsTest.kt +34 −20 Original line number Diff line number Diff line Loading @@ -16,8 +16,11 @@ package com.android.systemui.privacy import android.location.flags.Flags import android.platform.test.annotations.EnableFlags import android.platform.test.flag.junit.FlagsParameterization import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf import android.provider.DeviceConfig import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.config.sysui.SystemUiDeviceConfigFlags import com.android.systemui.SysuiTestCase Loading @@ -36,33 +39,39 @@ import org.mockito.Mockito.atLeastOnce import org.mockito.Mockito.never import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations import platform.test.runner.parameterized.ParameterizedAndroidJunit4 import platform.test.runner.parameterized.Parameters @RunWith(AndroidJUnit4::class) @RunWith(ParameterizedAndroidJunit4::class) @SmallTest @android.platform.test.annotations.EnabledOnRavenwood class PrivacyConfigFlagsTest : SysuiTestCase() { class PrivacyConfigFlagsTest(flags: FlagsParameterization) : SysuiTestCase() { companion object { private const val MIC_CAMERA = SystemUiDeviceConfigFlags.PROPERTY_MIC_CAMERA_ENABLED private const val LOCATION = SystemUiDeviceConfigFlags.PROPERTY_LOCATION_INDICATORS_ENABLED private const val MEDIA_PROJECTION = SystemUiDeviceConfigFlags.PROPERTY_MEDIA_PROJECTION_INDICATORS_ENABLED @JvmStatic @Parameters(name = "{0}") fun getParams(): List<FlagsParameterization> { return allCombinationsOf(Flags.FLAG_LOCATION_INDICATORS_ENABLED) } } init { mSetFlagsRule.setFlagsParameterization(flags) } private lateinit var privacyConfig: PrivacyConfig @Mock private lateinit var callback: PrivacyConfig.Callback @Mock private lateinit var dumpManager: DumpManager @Mock private lateinit var callback: PrivacyConfig.Callback @Mock private lateinit var dumpManager: DumpManager private lateinit var executor: FakeExecutor private lateinit var deviceConfigProxy: DeviceConfigProxy fun createPrivacyConfig(): PrivacyConfig { return PrivacyConfig( executor, deviceConfigProxy, dumpManager) return PrivacyConfig(executor, deviceConfigProxy, dumpManager) } @Before Loading @@ -78,11 +87,13 @@ class PrivacyConfigFlagsTest : SysuiTestCase() { } @Test @EnableFlags(Flags.FLAG_LOCATION_INDICATORS_ENABLED) fun testMicCameraListeningByDefault() { assertTrue(privacyConfig.micCameraAvailable) } @Test @EnableFlags(Flags.FLAG_LOCATION_INDICATORS_ENABLED) fun testMicCameraChanged() { changeMicCamera(false) // default is true executor.runAllReady() Loading @@ -93,6 +104,7 @@ class PrivacyConfigFlagsTest : SysuiTestCase() { } @Test @EnableFlags(Flags.FLAG_LOCATION_INDICATORS_ENABLED) fun testMediaProjectionChanged() { changeMediaProjection(false) // default is true executor.runAllReady() Loading @@ -103,8 +115,9 @@ class PrivacyConfigFlagsTest : SysuiTestCase() { } @Test @EnableFlags(Flags.FLAG_LOCATION_INDICATORS_ENABLED) fun testLocationChanged() { changeLocation(true) changeMicCamera(true) executor.runAllReady() verify(callback).onFlagLocationChanged(true) Loading @@ -112,8 +125,8 @@ class PrivacyConfigFlagsTest : SysuiTestCase() { } @Test @EnableFlags(Flags.FLAG_LOCATION_INDICATORS_ENABLED) fun testMicCamAndLocationChanged() { changeLocation(true) changeMicCamera(false) executor.runAllReady() Loading @@ -125,6 +138,7 @@ class PrivacyConfigFlagsTest : SysuiTestCase() { } @Test @EnableFlags(Flags.FLAG_LOCATION_INDICATORS_ENABLED) fun testMicDeleted_stillAvailable() { changeMicCamera(true) executor.runAllReady() Loading @@ -136,7 +150,7 @@ class PrivacyConfigFlagsTest : SysuiTestCase() { } private fun changeMicCamera(value: Boolean?) = changeProperty(MIC_CAMERA, value) private fun changeLocation(value: Boolean?) = changeProperty(LOCATION, value) private fun changeMediaProjection(value: Boolean?) = changeProperty(MEDIA_PROJECTION, value) private fun changeProperty(name: String, value: Boolean?) { Loading @@ -144,7 +158,7 @@ class PrivacyConfigFlagsTest : SysuiTestCase() { DeviceConfig.NAMESPACE_PRIVACY, name, value?.toString(), false false, ) } }
packages/SystemUI/src/com/android/systemui/privacy/PrivacyConfig.kt +42 −42 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.privacy import android.location.flags.Flags.locationIndicatorsEnabled import android.provider.DeviceConfig import com.android.internal.annotations.VisibleForTesting import com.android.internal.annotations.WeaklyReferencedCallback Loading @@ -33,21 +34,21 @@ import java.lang.ref.WeakReference import javax.inject.Inject @SysUISingleton class PrivacyConfig @Inject constructor( class PrivacyConfig @Inject constructor( @Main private val uiExecutor: DelayableExecutor, private val deviceConfigProxy: DeviceConfigProxy, dumpManager: DumpManager dumpManager: DumpManager, ) : Dumpable { @VisibleForTesting internal companion object { const val TAG = "PrivacyConfig" private const val MIC_CAMERA = SystemUiDeviceConfigFlags.PROPERTY_MIC_CAMERA_ENABLED private const val LOCATION = SystemUiDeviceConfigFlags.PROPERTY_LOCATION_INDICATORS_ENABLED private const val MEDIA_PROJECTION = SystemUiDeviceConfigFlags.PROPERTY_MEDIA_PROJECTION_INDICATORS_ENABLED private const val DEFAULT_MIC_CAMERA = true private const val DEFAULT_LOCATION = false private const val DEFAULT_MEDIA_PROJECTION = true } Loading @@ -55,8 +56,10 @@ class PrivacyConfig @Inject constructor( var micCameraAvailable = isMicCameraEnabled() private set var locationAvailable = isLocationEnabled() var locationAvailable = locationIndicatorsEnabled() private set var mediaProjectionAvailable = isMediaProjectionEnabled() private set Loading @@ -69,8 +72,7 @@ class PrivacyConfig @Inject constructor( callbacks.forEach { it.get()?.onFlagMicCameraChanged(micCameraAvailable) } } if (properties.keyset.contains(LOCATION)) { locationAvailable = properties.getBoolean(LOCATION, DEFAULT_LOCATION) if (locationAvailable) { callbacks.forEach { it.get()?.onFlagLocationChanged(locationAvailable) } } Loading @@ -89,22 +91,24 @@ class PrivacyConfig @Inject constructor( deviceConfigProxy.addOnPropertiesChangedListener( DeviceConfig.NAMESPACE_PRIVACY, uiExecutor, devicePropertiesChangedListener) devicePropertiesChangedListener, ) } private fun isMicCameraEnabled(): Boolean { return deviceConfigProxy.getBoolean(DeviceConfig.NAMESPACE_PRIVACY, MIC_CAMERA, DEFAULT_MIC_CAMERA) } private fun isLocationEnabled(): Boolean { return deviceConfigProxy.getBoolean(DeviceConfig.NAMESPACE_PRIVACY, LOCATION, DEFAULT_LOCATION) return deviceConfigProxy.getBoolean( DeviceConfig.NAMESPACE_PRIVACY, MIC_CAMERA, DEFAULT_MIC_CAMERA, ) } private fun isMediaProjectionEnabled(): Boolean { return deviceConfigProxy.getBoolean(DeviceConfig.NAMESPACE_PRIVACY, MEDIA_PROJECTION, DEFAULT_MEDIA_PROJECTION) return deviceConfigProxy.getBoolean( DeviceConfig.NAMESPACE_PRIVACY, MEDIA_PROJECTION, DEFAULT_MEDIA_PROJECTION, ) } fun addCallback(callback: Callback) { Loading @@ -116,9 +120,7 @@ class PrivacyConfig @Inject constructor( } private fun addCallback(callback: WeakReference<Callback>) { uiExecutor.execute { callbacks.add(callback) } uiExecutor.execute { callbacks.add(callback) } } private fun removeCallback(callback: WeakReference<Callback>) { Loading @@ -137,9 +139,7 @@ class PrivacyConfig @Inject constructor( ipw.println("mediaProjectionAvailable: $mediaProjectionAvailable") ipw.println("Callbacks:") ipw.withIncreasedIndent { callbacks.forEach { callback -> callback.get()?.let { ipw.println(it) } } callbacks.forEach { callback -> callback.get()?.let { ipw.println(it) } } } } ipw.flush() Loading