diff options
7 files changed, 252 insertions, 18 deletions
| diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index de69df559ac2..7829df5f578a 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -7044,6 +7044,12 @@ public final class Settings {          public static final String NOTIFICATION_BADGING = "notification_badging";          /** +         * Comma separated list of QS tiles that have been auto-added already. +         * @hide +         */ +        public static final String QS_AUTO_ADDED_TILES = "qs_auto_tiles"; + +        /**           * This are the settings to be backed up.           *           * NOTE: Settings are backed up and restored in the order they appear @@ -7140,7 +7146,8 @@ public final class Settings {              ASSIST_GESTURE_SILENCE_ALERTS_ENABLED,              ASSIST_GESTURE_WAKE_ENABLED,              VR_DISPLAY_MODE, -            NOTIFICATION_BADGING +            NOTIFICATION_BADGING, +            QS_AUTO_ADDED_TILES,          };          /** diff --git a/packages/SystemUI/src/com/android/systemui/Prefs.java b/packages/SystemUI/src/com/android/systemui/Prefs.java index 3cc81dfb45d7..4437d314a7c2 100644 --- a/packages/SystemUI/src/com/android/systemui/Prefs.java +++ b/packages/SystemUI/src/com/android/systemui/Prefs.java @@ -47,6 +47,7 @@ public final class Prefs {          Key.QS_INVERT_COLORS_ADDED,          Key.QS_WORK_ADDED,          Key.QS_NIGHTDISPLAY_ADDED, +        Key.SEEN_MULTI_USER,      })      public @interface Key {          @Deprecated @@ -62,12 +63,18 @@ public final class Prefs {          String DND_FAVORITE_BUCKET_INDEX = "DndCountdownMinuteIndex";          String DND_NONE_SELECTED = "DndNoneSelected";          String DND_FAVORITE_ZEN = "DndFavoriteZen"; +        String QS_DATA_SAVER_DIALOG_SHOWN = "QsDataSaverDialogShown"; +        @Deprecated          String QS_HOTSPOT_ADDED = "QsHotspotAdded"; +        @Deprecated          String QS_DATA_SAVER_ADDED = "QsDataSaverAdded"; -        String QS_DATA_SAVER_DIALOG_SHOWN = "QsDataSaverDialogShown"; +        @Deprecated          String QS_INVERT_COLORS_ADDED = "QsInvertColorsAdded"; +        @Deprecated          String QS_WORK_ADDED = "QsWorkAdded"; +        @Deprecated          String QS_NIGHTDISPLAY_ADDED = "QsNightDisplayAdded"; +        String SEEN_MULTI_USER = "HasSeenMultiUser";      }      public static boolean getBoolean(Context context, @Key String key, boolean defaultValue) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/AutoAddTracker.java b/packages/SystemUI/src/com/android/systemui/qs/AutoAddTracker.java new file mode 100644 index 000000000000..f960dc5b4a47 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/AutoAddTracker.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package com.android.systemui.qs; + +import static com.android.systemui.statusbar.phone.AutoTileManager.HOTSPOT; +import static com.android.systemui.statusbar.phone.AutoTileManager.INVERSION; +import static com.android.systemui.statusbar.phone.AutoTileManager.NIGHT; +import static com.android.systemui.statusbar.phone.AutoTileManager.SAVER; +import static com.android.systemui.statusbar.phone.AutoTileManager.WORK; + +import android.content.Context; +import android.database.ContentObserver; +import android.os.Handler; +import android.provider.Settings.Secure; +import android.text.TextUtils; +import android.util.ArraySet; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.systemui.Prefs; +import com.android.systemui.Prefs.Key; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +public class AutoAddTracker { + +    private static final String[][] CONVERT_PREFS = { +            {Key.QS_HOTSPOT_ADDED, HOTSPOT}, +            {Key.QS_DATA_SAVER_ADDED, SAVER}, +            {Key.QS_INVERT_COLORS_ADDED, INVERSION}, +            {Key.QS_WORK_ADDED, WORK}, +            {Key.QS_NIGHTDISPLAY_ADDED, NIGHT}, +    }; + +    private final ArraySet<String> mAutoAdded; +    private final Context mContext; + +    public AutoAddTracker(Context context) { +        mContext = context; +        mAutoAdded = new ArraySet<>(getAdded()); +        for (String[] convertPref : CONVERT_PREFS) { +            if (Prefs.getBoolean(context, convertPref[0], false)) { +                setTileAdded(convertPref[1]); +                Prefs.putBoolean(context, convertPref[0], false); +            } +        } +        mContext.getContentResolver().registerContentObserver( +                Secure.getUriFor(Secure.QS_AUTO_ADDED_TILES), false, mObserver); +    } + +    public boolean isAdded(String tile) { +        return mAutoAdded.contains(tile); +    } + +    public void setTileAdded(String tile) { +        if (mAutoAdded.add(tile)) { +            saveTiles(); +        } +    } + +    public void destroy() { +        mContext.getContentResolver().unregisterContentObserver(mObserver); +    } + +    private void saveTiles() { +        Secure.putString(mContext.getContentResolver(), Secure.QS_AUTO_ADDED_TILES, +                TextUtils.join(",", mAutoAdded)); +    } + +    private Collection<String> getAdded() { +        String current = Secure.getString(mContext.getContentResolver(), Secure.QS_AUTO_ADDED_TILES); +        if (current == null) { +            return Collections.emptyList(); +        } +        return Arrays.asList(current.split(",")); +    } + +    @VisibleForTesting +    protected final ContentObserver mObserver = new ContentObserver(new Handler()) { +        @Override +        public void onChange(boolean selfChange) { +            mAutoAdded.addAll(getAdded()); +        } +    }; +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java index 7512efaba733..1bd90fa9ca08 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java @@ -24,6 +24,7 @@ import com.android.internal.app.NightDisplayController;  import com.android.systemui.Dependency;  import com.android.systemui.Prefs;  import com.android.systemui.Prefs.Key; +import com.android.systemui.qs.AutoAddTracker;  import com.android.systemui.qs.QSTileHost;  import com.android.systemui.qs.SecureSetting;  import com.android.systemui.statusbar.policy.DataSaverController; @@ -36,39 +37,47 @@ import com.android.systemui.statusbar.policy.HotspotController.Callback;   */  public class AutoTileManager { +    public static final String HOTSPOT = "hotspot"; +    public static final String SAVER = "saver"; +    public static final String INVERSION = "inversion"; +    public static final String WORK = "work"; +    public static final String NIGHT = "night";      private final Context mContext;      private final QSTileHost mHost;      private final Handler mHandler; +    private final AutoAddTracker mAutoTracker;      public AutoTileManager(Context context, QSTileHost host) { +        mAutoTracker = new AutoAddTracker(context);          mContext = context;          mHost = host;          mHandler = new Handler((Looper) Dependency.get(Dependency.BG_LOOPER)); -        if (!Prefs.getBoolean(context, Key.QS_HOTSPOT_ADDED, false)) { +        if (!mAutoTracker.isAdded(HOTSPOT)) {              Dependency.get(HotspotController.class).addCallback(mHotspotCallback);          } -        if (!Prefs.getBoolean(context, Key.QS_DATA_SAVER_ADDED, false)) { +        if (!mAutoTracker.isAdded(SAVER)) {              Dependency.get(DataSaverController.class).addCallback(mDataSaverListener);          } -        if (!Prefs.getBoolean(context, Key.QS_INVERT_COLORS_ADDED, false)) { +        if (!mAutoTracker.isAdded(INVERSION)) {              mColorsSetting = new SecureSetting(mContext, mHandler,                      Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED) {                  @Override                  protected void handleValueChanged(int value, boolean observedChange) { +                    if (mAutoTracker.isAdded(INVERSION)) return;                      if (value != 0) { -                        mHost.addTile("inversion"); -                        Prefs.putBoolean(mContext, Key.QS_INVERT_COLORS_ADDED, true); +                        mHost.addTile(INVERSION); +                        mAutoTracker.setTileAdded(INVERSION);                          mHandler.post(() -> mColorsSetting.setListening(false));                      }                  }              };              mColorsSetting.setListening(true);          } -        if (!Prefs.getBoolean(context, Key.QS_WORK_ADDED, false)) { +        if (!mAutoTracker.isAdded(WORK)) {              Dependency.get(ManagedProfileController.class).addCallback(mProfileCallback);          } -        if (!Prefs.getBoolean(context, Key.QS_NIGHTDISPLAY_ADDED, false) +        if (!mAutoTracker.isAdded(NIGHT)                  && NightDisplayController.isAvailable(mContext)) {              Dependency.get(NightDisplayController.class).setListener(mNightDisplayCallback);          } @@ -76,6 +85,7 @@ public class AutoTileManager {      public void destroy() {          mColorsSetting.setListening(false); +        mAutoTracker.destroy();          Dependency.get(HotspotController.class).removeCallback(mHotspotCallback);          Dependency.get(DataSaverController.class).removeCallback(mDataSaverListener);          Dependency.get(ManagedProfileController.class).removeCallback(mProfileCallback); @@ -86,9 +96,10 @@ public class AutoTileManager {              new ManagedProfileController.Callback() {                  @Override                  public void onManagedProfileChanged() { +                    if (mAutoTracker.isAdded(WORK)) return;                      if (Dependency.get(ManagedProfileController.class).hasActiveProfile()) { -                        mHost.addTile("work"); -                        Prefs.putBoolean(mContext, Key.QS_WORK_ADDED, true); +                        mHost.addTile(WORK); +                        mAutoTracker.setTileAdded(WORK);                          mHandler.post(() -> Dependency.get(ManagedProfileController.class)                                  .removeCallback(mProfileCallback));                      } @@ -104,9 +115,10 @@ public class AutoTileManager {      private final DataSaverController.Listener mDataSaverListener = new Listener() {          @Override          public void onDataSaverChanged(boolean isDataSaving) { +            if (mAutoTracker.isAdded(SAVER)) return;              if (isDataSaving) { -                mHost.addTile("saver"); -                Prefs.putBoolean(mContext, Key.QS_DATA_SAVER_ADDED, true); +                mHost.addTile(SAVER); +                mAutoTracker.setTileAdded(SAVER);                  mHandler.post(() -> Dependency.get(DataSaverController.class).removeCallback(                          mDataSaverListener));              } @@ -116,9 +128,10 @@ public class AutoTileManager {      private final HotspotController.Callback mHotspotCallback = new Callback() {          @Override          public void onHotspotChanged(boolean enabled) { +            if (mAutoTracker.isAdded(HOTSPOT)) return;              if (enabled) { -                mHost.addTile("hotspot"); -                Prefs.putBoolean(mContext, Key.QS_HOTSPOT_ADDED, true); +                mHost.addTile(HOTSPOT); +                mAutoTracker.setTileAdded(HOTSPOT);                  mHandler.post(() -> Dependency.get(HotspotController.class)                          .removeCallback(mHotspotCallback));              } @@ -144,8 +157,9 @@ public class AutoTileManager {          }          private void addNightTile() { -            mHost.addTile("night"); -            Prefs.putBoolean(mContext, Key.QS_NIGHTDISPLAY_ADDED, true); +            if (mAutoTracker.isAdded(NIGHT)) return; +            mHost.addTile(NIGHT); +            mAutoTracker.setTileAdded(NIGHT);              mHandler.post(() -> Dependency.get(NightDisplayController.class)                      .setListener(null));          } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java index c30bb9a2e6e8..f393dcd368cd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java @@ -30,6 +30,8 @@ import android.widget.Button;  import android.widget.FrameLayout;  import com.android.systemui.Dependency; +import com.android.systemui.Prefs; +import com.android.systemui.Prefs.Key;  import com.android.systemui.R;  import com.android.systemui.plugins.ActivityStarter;  import com.android.systemui.plugins.qs.DetailAdapter; @@ -74,7 +76,8 @@ public class MultiUserSwitch extends FrameLayout implements View.OnClickListener          if (mUserListener == null) {              return false;          } -        return mUserListener.getUserCount() != 0; +        return mUserListener.getUserCount() != 0 +                && Prefs.getBoolean(getContext(), Key.SEEN_MULTI_USER, false);      }      public void setUserSwitcherController(UserSwitcherController userSwitcherController) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java index e0f4429f9998..700c01a55ad6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java @@ -57,6 +57,8 @@ import com.android.settingslib.RestrictedLockUtils;  import com.android.settingslib.Utils;  import com.android.systemui.Dependency;  import com.android.systemui.GuestResumeSessionReceiver; +import com.android.systemui.Prefs; +import com.android.systemui.Prefs.Key;  import com.android.systemui.R;  import com.android.systemui.SystemUI;  import com.android.systemui.SystemUISecondaryUserService; @@ -235,6 +237,9 @@ public class UserSwitcherController {                          }                      }                  } +                if (records.size() > 1 || guestRecord != null) { +                    Prefs.putBoolean(mContext, Key.SEEN_MULTI_USER, true); +                }                  boolean systemCanCreateUsers = !mUserManager.hasBaseUserRestriction(                                  UserManager.DISALLOW_ADD_USER, UserHandle.SYSTEM); diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/AutoAddTrackerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/AutoAddTrackerTest.java new file mode 100644 index 000000000000..40f8059fecbf --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/AutoAddTrackerTest.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package com.android.systemui.qs; + +import static com.android.systemui.statusbar.phone.AutoTileManager.INVERSION; +import static com.android.systemui.statusbar.phone.AutoTileManager.SAVER; +import static com.android.systemui.statusbar.phone.AutoTileManager.WORK; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.provider.Settings.Secure; +import android.support.test.filters.SmallTest; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper.RunWithLooper; + +import com.android.systemui.Prefs; +import com.android.systemui.Prefs.Key; +import com.android.systemui.SysuiTestCase; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidTestingRunner.class) +@RunWithLooper +@SmallTest +public class AutoAddTrackerTest extends SysuiTestCase { + +    private AutoAddTracker mAutoTracker; + +    @Test +    public void testMigration() { +        Prefs.putBoolean(mContext, Key.QS_DATA_SAVER_ADDED, true); +        Prefs.putBoolean(mContext, Key.QS_WORK_ADDED, true); +        mAutoTracker = new AutoAddTracker(mContext); + +        assertTrue(mAutoTracker.isAdded(SAVER)); +        assertTrue(mAutoTracker.isAdded(WORK)); +        assertFalse(mAutoTracker.isAdded(INVERSION)); + +        assertFalse(Prefs.getBoolean(mContext, Key.QS_DATA_SAVER_ADDED, false)); +        assertFalse(Prefs.getBoolean(mContext, Key.QS_WORK_ADDED, false)); + +        mAutoTracker.destroy(); +    } + +    @Test +    public void testChangeFromBackup() { +        mAutoTracker = new AutoAddTracker(mContext); + +        assertFalse(mAutoTracker.isAdded(SAVER)); + +        Secure.putString(mContext.getContentResolver(), Secure.QS_AUTO_ADDED_TILES, SAVER); +        mAutoTracker.mObserver.onChange(false); + +        assertTrue(mAutoTracker.isAdded(SAVER)); + +        mAutoTracker.destroy(); +    } + +    @Test +    public void testSetAdded() { +        mAutoTracker = new AutoAddTracker(mContext); + +        assertFalse(mAutoTracker.isAdded(SAVER)); +        mAutoTracker.setTileAdded(SAVER); + +        assertTrue(mAutoTracker.isAdded(SAVER)); + +        mAutoTracker.destroy(); +    } + +    @Test +    public void testPersist() { +        mAutoTracker = new AutoAddTracker(mContext); + +        assertFalse(mAutoTracker.isAdded(SAVER)); +        mAutoTracker.setTileAdded(SAVER); + +        mAutoTracker.destroy(); +        mAutoTracker = new AutoAddTracker(mContext); + +        assertTrue(mAutoTracker.isAdded(SAVER)); + +        mAutoTracker.destroy(); +    } + +}
\ No newline at end of file |