Merge "Update show system experiment behavior." into tm-dev
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 07c770f..d8d9c7f 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7230,6 +7230,13 @@
          */
         public static final String LOCATION_SHOW_SYSTEM_OPS = "locationShowSystemOps";
 
+
+        /**
+         * Whether or not an indicator experiment has started.
+         * @hide
+         */
+        public static final String LOCATION_INDICATOR_EXPERIMENT_STARTED =
+                "locationIndicatorExperimentStarted";
         /**
          * A flag containing settings used for biometric weak
          * @hide
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
index f52c6ed..3e50acb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
@@ -86,6 +86,7 @@
     private boolean mShouldDisplayAllAccesses;
     private boolean mShowSystemAccessesFlag;
     private boolean mShowSystemAccessesSetting;
+    private boolean mExperimentStarted;
 
     @Inject
     public LocationControllerImpl(Context context, AppOpsController appOpsController,
@@ -107,6 +108,9 @@
         mShouldDisplayAllAccesses = getAllAccessesSetting();
         mShowSystemAccessesFlag = getShowSystemFlag();
         mShowSystemAccessesSetting = getShowSystemSetting();
+        mExperimentStarted = getExperimentStarted();
+        toggleSystemSettingIfExperimentJustStarted();
+
         mContentObserver = new ContentObserver(mBackgroundHandler) {
             @Override
             public void onChange(boolean selfChange) {
@@ -123,8 +127,15 @@
                 DeviceConfig.NAMESPACE_PRIVACY,
                 backgroundHandler::post,
                 properties -> {
+                    // Update the Device Config flag which controls the experiment to display
+                    // location accesses.
                     mShouldDisplayAllAccesses = getAllAccessesSetting();
-                    mShowSystemAccessesFlag = getShowSystemSetting();
+                    // Update the Device Config flag which controls the experiment to display
+                    // system location accesses.
+                    mShowSystemAccessesFlag = getShowSystemFlag();
+                    // Update the local flag for the system accesses experiment and potentially
+                    // update the behavior based on the flag value.
+                    toggleSystemSettingIfExperimentJustStarted();
                     updateActiveLocationRequests();
                 });
 
@@ -222,6 +233,33 @@
         return mSecureSettings.getInt(Settings.Secure.LOCATION_SHOW_SYSTEM_OPS, 0) == 1;
     }
 
+    private boolean getExperimentStarted() {
+        return mSecureSettings
+                .getInt(Settings.Secure.LOCATION_INDICATOR_EXPERIMENT_STARTED, 0) == 1;
+    }
+
+    private void toggleSystemSettingIfExperimentJustStarted() {
+        // mShowSystemAccessesFlag indicates whether the Device Config flag is flipped
+        // by an experiment. mExperimentStarted is the local device value which indicates the last
+        // value the device has seen for the Device Config flag.
+        // The local device value is needed to determine that the Device Config flag was just
+        // flipped, as the experiment behavior should only happen once after the experiment is
+        // enabled.
+        if (mShowSystemAccessesFlag && !mExperimentStarted) {
+            // If the Device Config flag is enabled, but the local device setting is not then the
+            // experiment just started. Update the local flag to match and enable the experiment
+            // behavior by flipping the show system setting value.
+            mSecureSettings.putInt(Settings.Secure.LOCATION_INDICATOR_EXPERIMENT_STARTED, 1);
+            mSecureSettings.putInt(Settings.Secure.LOCATION_SHOW_SYSTEM_OPS, 1);
+            mExperimentStarted = true;
+        } else if (!mShowSystemAccessesFlag && mExperimentStarted) {
+            // If the Device Config flag is disabled, but the local device flag is enabled then
+            // update the local device flag to match.
+            mSecureSettings.putInt(Settings.Secure.LOCATION_INDICATOR_EXPERIMENT_STARTED, 0);
+            mExperimentStarted = false;
+        }
+    }
+
     /**
      * Returns true if there currently exist active high power location requests.
      */
@@ -249,7 +287,6 @@
         }
         boolean hadActiveLocationRequests = mAreActiveLocationRequests;
         boolean shouldDisplay = false;
-        boolean showSystem = mShowSystemAccessesFlag || mShowSystemAccessesSetting;
         boolean systemAppOp = false;
         boolean nonSystemAppOp = false;
         boolean isSystemApp;
@@ -267,7 +304,7 @@
                     nonSystemAppOp = true;
                 }
 
-                shouldDisplay = showSystem || shouldDisplay || !isSystemApp;
+                shouldDisplay = mShowSystemAccessesSetting || shouldDisplay || !isSystemApp;
             }
         }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java
index 12cfb32..14e0878 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java
@@ -51,7 +51,7 @@
 import com.android.systemui.statusbar.policy.LocationController.LocationChangeCallback;
 import com.android.systemui.util.DeviceConfigProxy;
 import com.android.systemui.util.DeviceConfigProxyFake;
-import com.android.systemui.util.settings.SecureSettings;
+import com.android.systemui.util.settings.FakeSettings;
 
 import com.google.common.collect.ImmutableList;
 
@@ -70,11 +70,11 @@
     private TestableLooper mTestableLooper;
     private DeviceConfigProxy mDeviceConfigProxy;
     private UiEventLoggerFake mUiEventLogger;
+    private FakeSettings mSecureSettings;
 
     @Mock private PackageManager mPackageManager;
     @Mock private AppOpsController mAppOpsController;
     @Mock private UserTracker mUserTracker;
-    @Mock private SecureSettings mSecureSettings;
 
     @Before
     public void setup() {
@@ -85,7 +85,7 @@
                 .thenReturn(ImmutableList.of(new UserInfo(0, "name", 0)));
         mDeviceConfigProxy = new DeviceConfigProxyFake();
         mUiEventLogger = new UiEventLoggerFake();
-
+        mSecureSettings = new FakeSettings();
         mTestableLooper = TestableLooper.get(this);
 
         mLocationController = new LocationControllerImpl(mContext,
@@ -248,8 +248,7 @@
 
     @Test
     public void testCallbackNotified_additionalOps_shouldShowSystem() {
-        when(mSecureSettings.getInt(Settings.Secure.LOCATION_SHOW_SYSTEM_OPS, 0))
-                .thenReturn(1);
+        mSecureSettings.putInt(Settings.Secure.LOCATION_SHOW_SYSTEM_OPS, 1);
         LocationChangeCallback callback = mock(LocationChangeCallback.class);
         mLocationController.addCallback(callback);
         mDeviceConfigProxy.setProperty(
@@ -282,8 +281,7 @@
 
         verify(callback, times(1)).onLocationActiveChanged(false);
 
-        when(mSecureSettings.getInt(Settings.Secure.LOCATION_SHOW_SYSTEM_OPS, 0))
-                .thenReturn(0);
+        mSecureSettings.putInt(Settings.Secure.LOCATION_SHOW_SYSTEM_OPS, 0);
         mLocationController.onActiveStateChanged(AppOpsManager.OP_FINE_LOCATION, 0,
                 "com.system.app", true);
 
@@ -367,4 +365,46 @@
         // No new callbacks
         verify(callback).onLocationSettingsChanged(anyBoolean());
     }
+
+    @Test
+    public void testExperimentFlipsSystemFlag() throws Exception {
+        mSecureSettings.putInt(Settings.Secure.LOCATION_SHOW_SYSTEM_OPS, 0);
+        mDeviceConfigProxy.setProperty(
+                DeviceConfig.NAMESPACE_PRIVACY,
+                SystemUiDeviceConfigFlags.PROPERTY_LOCATION_INDICATORS_SMALL_ENABLED,
+                "true",
+                true);
+        // Show system experiment not running
+        mDeviceConfigProxy.setProperty(
+                DeviceConfig.NAMESPACE_PRIVACY,
+                SystemUiDeviceConfigFlags.PROPERTY_LOCATION_INDICATORS_SHOW_SYSTEM,
+                "false",
+                false);
+        mTestableLooper.processAllMessages();
+
+        // Flip experiment on
+        mDeviceConfigProxy.setProperty(
+                DeviceConfig.NAMESPACE_PRIVACY,
+                SystemUiDeviceConfigFlags.PROPERTY_LOCATION_INDICATORS_SHOW_SYSTEM,
+                "true",
+                true);
+        mTestableLooper.processAllMessages();
+
+        // Verify settings were flipped
+        assertThat(mSecureSettings.getInt(Settings.Secure.LOCATION_SHOW_SYSTEM_OPS))
+                .isEqualTo(1);
+        assertThat(mSecureSettings.getInt(Settings.Secure.LOCATION_INDICATOR_EXPERIMENT_STARTED))
+                .isEqualTo(1);
+
+        // Flip experiment off
+        mDeviceConfigProxy.setProperty(
+                DeviceConfig.NAMESPACE_PRIVACY,
+                SystemUiDeviceConfigFlags.PROPERTY_LOCATION_INDICATORS_SHOW_SYSTEM,
+                "false",
+                false);
+        mTestableLooper.processAllMessages();
+
+        assertThat(mSecureSettings.getInt(Settings.Secure.LOCATION_INDICATOR_EXPERIMENT_STARTED))
+                .isEqualTo(0);
+    }
 }
\ No newline at end of file