diff options
Diffstat (limited to 'packages')
9 files changed, 307 insertions, 134 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java index e302c98..33bd726 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java @@ -40,13 +40,14 @@ public class SystemUIApplication extends Application { * The classes of the stuff to start. */ private final Class<?>[] SERVICES = new Class[] { + com.android.systemui.tuner.TunerService.class, com.android.systemui.keyguard.KeyguardViewMediator.class, com.android.systemui.recents.Recents.class, com.android.systemui.volume.VolumeUI.class, com.android.systemui.statusbar.SystemBars.class, com.android.systemui.usb.StorageNotification.class, com.android.systemui.power.PowerUI.class, - com.android.systemui.media.RingtonePlayer.class + com.android.systemui.media.RingtonePlayer.class, }; /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java index 02e196e..2f63c73 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java @@ -18,14 +18,12 @@ package com.android.systemui.statusbar; import android.content.Context; import android.content.res.ColorStateList; -import android.database.ContentObserver; import android.graphics.Color; import android.graphics.PorterDuff; import android.graphics.drawable.Animatable; import android.graphics.drawable.Drawable; -import android.os.Handler; -import android.provider.Settings; import android.telephony.SubscriptionInfo; +import android.util.ArraySet; import android.util.AttributeSet; import android.util.Log; import android.view.LayoutInflater; @@ -40,6 +38,8 @@ import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.policy.NetworkController.IconState; import com.android.systemui.statusbar.policy.NetworkControllerImpl; import com.android.systemui.statusbar.policy.SecurityController; +import com.android.systemui.tuner.TunerService; +import com.android.systemui.tuner.TunerService.Tunable; import java.util.ArrayList; import java.util.List; @@ -48,7 +48,7 @@ import java.util.List; public class SignalClusterView extends LinearLayout implements NetworkControllerImpl.SignalCallback, - SecurityController.SecurityControllerCallback { + SecurityController.SecurityControllerCallback, Tunable { static final String TAG = "SignalClusterView"; static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @@ -105,14 +105,22 @@ public class SignalClusterView public SignalClusterView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - readBlacklist(); } - private void readBlacklist() { - mBlockAirplane = StatusBarIconController.isBlocked(getContext(), SLOT_AIRPLANE); - mBlockMobile = StatusBarIconController.isBlocked(getContext(), SLOT_MOBILE); - mBlockWifi = StatusBarIconController.isBlocked(getContext(), SLOT_WIFI); - mBlockEthernet = StatusBarIconController.isBlocked(getContext(), SLOT_ETHERNET); + @Override + public void onTuningChanged(String key, String newValue) { + if (!StatusBarIconController.ICON_BLACKLIST.equals(key)) { + return; + } + ArraySet<String> blockList = StatusBarIconController.getIconBlacklist(newValue); + mBlockAirplane = blockList.contains(SLOT_AIRPLANE); + mBlockMobile = blockList.contains(SLOT_MOBILE); + mBlockWifi = blockList.contains(SLOT_WIFI); + mBlockEthernet = blockList.contains(SLOT_ETHERNET); + + // Re-register to get new callbacks. + mNC.removeSignalCallback(SignalClusterView.this); + mNC.addSignalCallback(SignalClusterView.this); } public void setNetworkController(NetworkControllerImpl nc) { @@ -160,12 +168,10 @@ public class SignalClusterView for (PhoneState state : mPhoneStates) { mMobileSignalGroup.addView(state.mMobileGroup); } + TunerService.get(mContext).addTunable(this, StatusBarIconController.ICON_BLACKLIST); apply(); applyIconTint(); - getContext().getContentResolver().registerContentObserver( - Settings.Secure.getUriFor(StatusBarIconController.ICON_BLACKLIST), false, - mBlacklistObserver); } @Override @@ -178,7 +184,7 @@ public class SignalClusterView mAirplane = null; mMobileSignalGroup.removeAllViews(); mMobileSignalGroup = null; - getContext().getContentResolver().unregisterContentObserver(mBlacklistObserver); + TunerService.get(mContext).removeTunable(this); super.onDetachedFromWindow(); } @@ -528,14 +534,5 @@ public class SignalClusterView setTint(mMobileType, tint); } } - - private final ContentObserver mBlacklistObserver = new ContentObserver(new Handler()) { - public void onChange(boolean selfChange) { - readBlacklist(); - // Re-register to get new callbacks. - mNC.removeSignalCallback(SignalClusterView.this); - mNC.addSignalCallback(SignalClusterView.this); - }; - }; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 984c201..7490a5b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -3166,9 +3166,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, (SignalClusterView) mKeyguardStatusBar.findViewById(R.id.signal_cluster); final SignalClusterView signalClusterQs = (SignalClusterView) mHeader.findViewById(R.id.signal_cluster); - mNetworkController.addSignalCallback(signalCluster); - mNetworkController.addSignalCallback(signalClusterKeyguard); - mNetworkController.addSignalCallback(signalClusterQs); + mNetworkController.removeSignalCallback(signalCluster); + mNetworkController.removeSignalCallback(signalClusterKeyguard); + mNetworkController.removeSignalCallback(signalClusterQs); + if (mQSPanel != null && mQSPanel.getHost() != null) { + mQSPanel.getHost().destroy(); + } } private boolean mDemoModeAllowed; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java index 0ef0fd9..25a93dd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java @@ -19,13 +19,9 @@ package com.android.systemui.statusbar.phone; import android.content.Context; import android.content.Intent; import android.content.res.Resources; -import android.database.ContentObserver; -import android.net.Uri; -import android.os.Process; -import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; -import android.provider.Settings.Secure; +import android.os.Process; import android.util.Log; import com.android.systemui.R; @@ -35,25 +31,26 @@ import com.android.systemui.qs.tiles.BluetoothTile; import com.android.systemui.qs.tiles.CastTile; import com.android.systemui.qs.tiles.CellularTile; import com.android.systemui.qs.tiles.ColorInversionTile; +import com.android.systemui.qs.tiles.DndTile; import com.android.systemui.qs.tiles.FlashlightTile; import com.android.systemui.qs.tiles.HotspotTile; import com.android.systemui.qs.tiles.IntentTile; import com.android.systemui.qs.tiles.LocationTile; import com.android.systemui.qs.tiles.RotationLockTile; import com.android.systemui.qs.tiles.WifiTile; -import com.android.systemui.qs.tiles.DndTile; -import com.android.systemui.settings.CurrentUserTracker; import com.android.systemui.statusbar.policy.BluetoothController; import com.android.systemui.statusbar.policy.CastController; import com.android.systemui.statusbar.policy.FlashlightController; +import com.android.systemui.statusbar.policy.HotspotController; import com.android.systemui.statusbar.policy.KeyguardMonitor; import com.android.systemui.statusbar.policy.LocationController; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.RotationLockController; -import com.android.systemui.statusbar.policy.HotspotController; import com.android.systemui.statusbar.policy.SecurityController; import com.android.systemui.statusbar.policy.UserSwitcherController; import com.android.systemui.statusbar.policy.ZenModeController; +import com.android.systemui.tuner.TunerService; +import com.android.systemui.tuner.TunerService.Tunable; import java.util.ArrayList; import java.util.Arrays; @@ -63,7 +60,7 @@ import java.util.List; import java.util.Map; /** Platform implementation of the quick settings tile host **/ -public class QSTileHost implements QSTile.Host { +public class QSTileHost implements QSTile.Host, Tunable { private static final String TAG = "QSTileHost"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @@ -72,8 +69,7 @@ public class QSTileHost implements QSTile.Host { private final Context mContext; private final PhoneStatusBar mStatusBar; private final LinkedHashMap<String, QSTile<?>> mTiles = new LinkedHashMap<>(); - private final ArrayList<String> mTileSpecs = new ArrayList<>(); - private final Observer mObserver = new Observer(); + protected final ArrayList<String> mTileSpecs = new ArrayList<>(); private final BluetoothController mBluetooth; private final LocationController mLocation; private final RotationLockController mRotation; @@ -82,7 +78,6 @@ public class QSTileHost implements QSTile.Host { private final HotspotController mHotspot; private final CastController mCast; private final Looper mLooper; - protected final CurrentUserTracker mUserTracker; private final FlashlightController mFlashlight; private final UserSwitcherController mUserSwitcherController; private final KeyguardMonitor mKeyguard; @@ -116,22 +111,11 @@ public class QSTileHost implements QSTile.Host { ht.start(); mLooper = ht.getLooper(); - mUserTracker = new CurrentUserTracker(mContext) { - @Override - public void onUserSwitched(int newUserId) { - recreateTiles(); - for (QSTile<?> tile : mTiles.values()) { - tile.userSwitch(newUserId); - } - mSecurity.onUserSwitched(newUserId); - mNetwork.onUserSwitched(newUserId); - mObserver.register(); - } - }; - recreateTiles(); + TunerService.get(mContext).addTunable(this, TILES_SETTING); + } - mUserTracker.startTracking(); - mObserver.register(); + public void destroy() { + TunerService.get(mContext).removeTunable(this); } @Override @@ -221,10 +205,14 @@ public class QSTileHost implements QSTile.Host { public SecurityController getSecurityController() { return mSecurity; } - - private void recreateTiles() { + + @Override + public void onTuningChanged(String key, String newValue) { + if (!TILES_SETTING.equals(key)) { + return; + } if (DEBUG) Log.d(TAG, "Recreating tiles"); - final List<String> tileSpecs = loadTileSpecs(); + final List<String> tileSpecs = loadTileSpecs(newValue); if (tileSpecs.equals(mTileSpecs)) return; for (Map.Entry<String, QSTile<?>> tile : mTiles.entrySet()) { if (!tileSpecs.contains(tile.getKey())) { @@ -270,11 +258,9 @@ public class QSTileHost implements QSTile.Host { else throw new IllegalArgumentException("Bad tile spec: " + tileSpec); } - protected List<String> loadTileSpecs() { + protected List<String> loadTileSpecs(String tileList) { final Resources res = mContext.getResources(); final String defaultTileList = res.getString(R.string.quick_settings_tiles_default); - String tileList = Secure.getStringForUser(mContext.getContentResolver(), TILES_SETTING, - mUserTracker.getCurrentUserId()); if (tileList == null) { tileList = res.getString(R.string.quick_settings_tiles); if (DEBUG) Log.d(TAG, "Loaded tile specs from config: " + tileList); @@ -297,26 +283,4 @@ public class QSTileHost implements QSTile.Host { } return tiles; } - - private class Observer extends ContentObserver { - private boolean mRegistered; - - public Observer() { - super(new Handler(Looper.getMainLooper())); - } - - public void register() { - if (mRegistered) { - mContext.getContentResolver().unregisterContentObserver(this); - } - mContext.getContentResolver().registerContentObserver(Secure.getUriFor(TILES_SETTING), - false, this, mUserTracker.getCurrentUserId()); - mRegistered = true; - } - - @Override - public void onChange(boolean selfChange, Uri uri) { - recreateTiles(); - } - } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java index a268077..067e50e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java @@ -20,12 +20,10 @@ import android.animation.ArgbEvaluator; import android.animation.ValueAnimator; import android.content.Context; import android.content.res.ColorStateList; -import android.database.ContentObserver; import android.graphics.Color; import android.os.Bundle; import android.os.Handler; import android.os.SystemClock; -import android.provider.Settings; import android.text.TextUtils; import android.util.ArraySet; import android.view.View; @@ -44,6 +42,8 @@ import com.android.systemui.R; import com.android.systemui.statusbar.NotificationData; import com.android.systemui.statusbar.SignalClusterView; import com.android.systemui.statusbar.StatusBarIconView; +import com.android.systemui.tuner.TunerService; +import com.android.systemui.tuner.TunerService.Tunable; import java.io.PrintWriter; import java.util.ArrayList; @@ -53,7 +53,7 @@ import java.util.ArrayList; * limited to: notification icons, signal cluster, additional status icons, and clock in the status * bar. */ -public class StatusBarIconController { +public class StatusBarIconController implements Tunable { public static final long DEFAULT_TINT_ANIMATION_DURATION = 120; @@ -95,7 +95,7 @@ public class StatusBarIconController { private long mTransitionDeferringStartTime; private long mTransitionDeferringDuration; - private final ArraySet<String> mIconBlacklist; + private final ArraySet<String> mIconBlacklist = new ArraySet<>(); private final Runnable mTransitionDeferringDoneRunnable = new Runnable() { @Override @@ -126,14 +126,33 @@ public class StatusBarIconController { mDarkModeIconColorSingleTone = context.getColor(R.color.dark_mode_icon_color_single_tone); mLightModeIconColorSingleTone = context.getColor(R.color.light_mode_icon_color_single_tone); mHandler = new Handler(); - mIconBlacklist = getIconBlacklist(context); updateResources(); - context.getContentResolver().registerContentObserver( - Settings.Secure.getUriFor(StatusBarIconController.ICON_BLACKLIST), false, - mBlacklistObserver); + TunerService.get(mContext).addTunable(this, ICON_BLACKLIST); } + @Override + public void onTuningChanged(String key, String newValue) { + if (!ICON_BLACKLIST.equals(key)) { + return; + } + mIconBlacklist.clear(); + mIconBlacklist.addAll(getIconBlacklist(newValue)); + ArrayList<StatusBarIconView> views = new ArrayList<StatusBarIconView>(); + // Get all the current views. + for (int i = 0; i < mStatusIcons.getChildCount(); i++) { + views.add((StatusBarIconView) mStatusIcons.getChildAt(i)); + } + // Remove all the icons. + for (int i = views.size() - 1; i >= 0; i--) { + removeSystemIcon(views.get(i).getSlot(), i, i); + } + // Add them all back + for (int i = 0; i < views.size(); i++) { + addSystemIcon(views.get(i).getSlot(), i, i, views.get(i).getStatusBarIcon()); + } + }; + public void updateResources() { mIconSize = mContext.getResources().getDimensionPixelSize( com.android.internal.R.dimen.status_bar_icon_size); @@ -429,29 +448,7 @@ public class StatusBarIconController { mTransitionPending = false; } - private final ContentObserver mBlacklistObserver = new ContentObserver(new Handler()) { - public void onChange(boolean selfChange) { - mIconBlacklist.clear(); - mIconBlacklist.addAll(getIconBlacklist(mContext)); - ArrayList<StatusBarIconView> views = new ArrayList<StatusBarIconView>(); - // Get all the current views. - for (int i = 0; i < mStatusIcons.getChildCount(); i++) { - views.add((StatusBarIconView) mStatusIcons.getChildAt(i)); - } - // Remove all the icons. - for (int i = views.size() - 1; i >= 0; i--) { - removeSystemIcon(views.get(i).getSlot(), i, i); - } - // Add them all back - for (int i = 0; i < views.size(); i++) { - addSystemIcon(views.get(i).getSlot(), i, i, views.get(i).getStatusBarIcon()); - } - } - }; - - public static ArraySet<String> getIconBlacklist(Context context) { - String blackListStr = Settings.Secure.getString(context.getContentResolver(), - ICON_BLACKLIST); + public static ArraySet<String> getIconBlacklist(String blackListStr) { ArraySet<String> ret = new ArraySet<String>(); if (blackListStr != null) { String[] blacklist = blackListStr.split(","); @@ -463,8 +460,4 @@ public class StatusBarIconController { } return ret; } - - public static boolean isBlocked(Context context, String slot) { - return getIconBlacklist(context).contains(slot); - } } diff --git a/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java b/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java index 9f593fc..7472af9 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java @@ -15,6 +15,7 @@ */ package com.android.systemui.tuner; +import android.app.ActivityManager; import android.app.AlertDialog; import android.app.Fragment; import android.content.ClipData; @@ -49,6 +50,7 @@ import com.android.systemui.qs.tiles.IntentTile; import com.android.systemui.statusbar.phone.QSTileHost; import com.android.systemui.statusbar.policy.SecurityController; +import java.util.ArrayList; import java.util.List; public class QsTuner extends Fragment implements Callback { @@ -107,6 +109,12 @@ public class QsTuner extends Fragment implements Callback { return mScrollRoot; } + @Override + public void onDestroyView() { + mTileHost.destroy(); + super.onDestroyView(); + } + private void setupDropTarget() { QSTileView tileView = new QSTileView(getContext()); QSTile.State state = new QSTile.State(); @@ -187,7 +195,7 @@ public class QsTuner extends Fragment implements Callback { if (oldTile.equals(newTile)) { return; } - List<String> order = loadTileSpecs(); + List<String> order = new ArrayList<>(mTileSpecs); int index = order.indexOf(oldTile); if (index < 0) { Log.e(TAG, "Can't find " + oldTile); @@ -199,32 +207,33 @@ public class QsTuner extends Fragment implements Callback { } public void remove(String tile) { - List<String> tiles = loadTileSpecs(); + List<String> tiles = new ArrayList<>(mTileSpecs); tiles.remove(tile); setTiles(tiles); } public void add(String tile) { - List<String> tiles = loadTileSpecs(); + List<String> tiles = new ArrayList<>(mTileSpecs); tiles.add(tile); setTiles(tiles); } public void reset() { Secure.putStringForUser(getContext().getContentResolver(), - TILES_SETTING, "default", mUserTracker.getCurrentUserId()); + TILES_SETTING, "default", ActivityManager.getCurrentUser()); } private void setTiles(List<String> tiles) { Secure.putStringForUser(getContext().getContentResolver(), TILES_SETTING, - TextUtils.join(",", tiles), mUserTracker.getCurrentUserId()); + TextUtils.join(",", tiles), ActivityManager.getCurrentUser()); } public void showAddDialog() { - List<String> tiles = loadTileSpecs(); + List<String> tiles = mTileSpecs; String[] defaults = getContext().getString(R.string.quick_settings_tiles_default).split(","); final String[] available = new String[defaults.length + 1 - tiles.size()]; + final String[] availableTiles = new String[available.length]; int index = 0; for (int i = 0; i < defaults.length; i++) { if (tiles.contains(defaults[i])) { @@ -232,8 +241,10 @@ public class QsTuner extends Fragment implements Callback { } int resource = getLabelResource(defaults[i]); if (resource != 0) { + availableTiles[index] = defaults[i]; available[index++] = getContext().getString(resource); } else { + availableTiles[index] = defaults[i]; available[index++] = defaults[i]; } } @@ -243,7 +254,7 @@ public class QsTuner extends Fragment implements Callback { .setItems(available, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { if (which < available.length - 1) { - add(available[which]); + add(availableTiles[which]); } else { showBroadcastTileDialog(); } diff --git a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java index 8158a68..d4cc56d 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java @@ -15,6 +15,7 @@ */ package com.android.systemui.tuner; +import android.app.ActivityManager; import android.content.ContentResolver; import android.content.Context; import android.preference.SwitchPreference; @@ -23,28 +24,38 @@ import android.text.TextUtils; import android.util.AttributeSet; import com.android.systemui.statusbar.phone.StatusBarIconController; +import com.android.systemui.tuner.TunerService.Tunable; import java.util.Set; -public class StatusBarSwitch extends SwitchPreference { +public class StatusBarSwitch extends SwitchPreference implements Tunable { + + private Set<String> mBlacklist; public StatusBarSwitch(Context context, AttributeSet attrs) { super(context, attrs); - setChecked(!StatusBarIconController.isBlocked(getContext(), getKey())); + } + + @Override + public void onTuningChanged(String key, String newValue) { + if (!StatusBarIconController.ICON_BLACKLIST.equals(key)) { + return; + } + mBlacklist = StatusBarIconController.getIconBlacklist(newValue); + setChecked(!mBlacklist.contains(getKey())); } @Override protected boolean persistBoolean(boolean value) { - Set<String> blacklist = StatusBarIconController.getIconBlacklist(getContext()); if (!value) { // If not enabled add to blacklist. - if (!blacklist.contains(getKey())) { - blacklist.add(getKey()); - setList(blacklist); + if (!mBlacklist.contains(getKey())) { + mBlacklist.add(getKey()); + setList(mBlacklist); } } else { - if (blacklist != null && blacklist.remove(getKey())) { - setList(blacklist); + if (mBlacklist.remove(getKey())) { + setList(mBlacklist); } } return true; @@ -52,7 +63,7 @@ public class StatusBarSwitch extends SwitchPreference { private void setList(Set<String> blacklist) { ContentResolver contentResolver = getContext().getContentResolver(); - Settings.Secure.putString(contentResolver, StatusBarIconController.ICON_BLACKLIST, - TextUtils.join(",", blacklist)); + Settings.Secure.putStringForUser(contentResolver, StatusBarIconController.ICON_BLACKLIST, + TextUtils.join(",", blacklist), ActivityManager.getCurrentUser()); } } diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java index b40adaf..7ac7306 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java @@ -26,11 +26,14 @@ import android.preference.Preference; import android.preference.Preference.OnPreferenceChangeListener; import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceFragment; +import android.preference.PreferenceGroup; import android.preference.SwitchPreference; import android.provider.Settings.System; import android.view.MenuItem; import com.android.systemui.R; +import com.android.systemui.statusbar.phone.StatusBarIconController; +import com.android.systemui.tuner.TunerService.Tunable; public class TunerFragment extends PreferenceFragment { @@ -67,12 +70,42 @@ public class TunerFragment extends PreferenceFragment { updateBatteryPct(); getContext().getContentResolver().registerContentObserver( System.getUriFor(SHOW_PERCENT_SETTING), false, mSettingObserver); + + registerPrefs(getPreferenceScreen()); } @Override public void onPause() { super.onPause(); getContext().getContentResolver().unregisterContentObserver(mSettingObserver); + + unregisterPrefs(getPreferenceScreen()); + } + + private void registerPrefs(PreferenceGroup group) { + TunerService tunerService = TunerService.get(getContext()); + final int N = group.getPreferenceCount(); + for (int i = 0; i < N; i++) { + Preference pref = group.getPreference(i); + if (pref instanceof StatusBarSwitch) { + tunerService.addTunable((Tunable) pref, StatusBarIconController.ICON_BLACKLIST); + } else if (pref instanceof PreferenceGroup) { + registerPrefs((PreferenceGroup) pref); + } + } + } + + private void unregisterPrefs(PreferenceGroup group) { + TunerService tunerService = TunerService.get(getContext()); + final int N = group.getPreferenceCount(); + for (int i = 0; i < N; i++) { + Preference pref = group.getPreference(i); + if (pref instanceof Tunable) { + tunerService.removeTunable((Tunable) pref); + } else if (pref instanceof PreferenceGroup) { + registerPrefs((PreferenceGroup) pref); + } + } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java new file mode 100644 index 0000000..de5aaf6 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2015 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.tuner; + +import android.app.ActivityManager; +import android.content.ContentResolver; +import android.content.Context; +import android.database.ContentObserver; +import android.net.Uri; +import android.os.Handler; +import android.os.Looper; +import android.provider.Settings; +import android.util.ArrayMap; + +import com.android.systemui.SystemUI; +import com.android.systemui.SystemUIApplication; +import com.android.systemui.settings.CurrentUserTracker; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + + +public class TunerService extends SystemUI { + + private final Observer mObserver = new Observer(); + // Map of Uris we listen on to their settings keys. + private final ArrayMap<Uri, String> mListeningUris = new ArrayMap<>(); + // Map of settings keys to the listener. + private final HashMap<String, List<Tunable>> mTunableLookup = new HashMap<>(); + + private ContentResolver mContentResolver; + private int mCurrentUser; + private CurrentUserTracker mUserTracker; + + @Override + public void start() { + mContentResolver = mContext.getContentResolver(); + putComponent(TunerService.class, this); + + mCurrentUser = ActivityManager.getCurrentUser(); + mUserTracker = new CurrentUserTracker(mContext) { + @Override + public void onUserSwitched(int newUserId) { + mCurrentUser = newUserId; + reloadAll(); + reregisterAll(); + } + }; + mUserTracker.startTracking(); + } + + public void addTunable(Tunable tunable, String... keys) { + for (String key : keys) { + addTunable(tunable, key); + } + } + + private void addTunable(Tunable tunable, String key) { + if (!mTunableLookup.containsKey(key)) { + mTunableLookup.put(key, new ArrayList<Tunable>()); + } + mTunableLookup.get(key).add(tunable); + Uri uri = Settings.Secure.getUriFor(key); + if (!mListeningUris.containsKey(uri)) { + mListeningUris.put(uri, key); + mContentResolver.registerContentObserver(uri, false, mObserver, mCurrentUser); + } + // Send the first state. + String value = Settings.Secure.getStringForUser(mContentResolver, key, mCurrentUser); + tunable.onTuningChanged(key, value); + } + + public void removeTunable(Tunable tunable) { + for (List<Tunable> list : mTunableLookup.values()) { + list.remove(tunable); + } + } + + protected void reregisterAll() { + if (mListeningUris.size() == 0) { + return; + } + mContentResolver.unregisterContentObserver(mObserver); + for (Uri uri : mListeningUris.keySet()) { + mContentResolver.registerContentObserver(uri, false, mObserver, mCurrentUser); + } + } + + public void reloadSetting(Uri uri) { + String key = mListeningUris.get(uri); + String value = Settings.Secure.getStringForUser(mContentResolver, key, mCurrentUser); + for (Tunable tunable : mTunableLookup.get(key)) { + tunable.onTuningChanged(key, value); + } + } + + private void reloadAll() { + for (String key : mTunableLookup.keySet()) { + String value = Settings.Secure.getStringForUser(mContentResolver, key, + mCurrentUser); + for (Tunable tunable : mTunableLookup.get(key)) { + tunable.onTuningChanged(key, value); + } + } + } + + // Only used in other processes, such as the tuner. + private static TunerService sInstance; + + public static TunerService get(Context context) { + SystemUIApplication sysUi = (SystemUIApplication) context.getApplicationContext(); + TunerService service = sysUi.getComponent(TunerService.class); + if (service == null) { + // Can't get it as a component, must in the tuner, lets just create one for now. + return getStaticService(context); + } + return service; + } + + private static TunerService getStaticService(Context context) { + if (sInstance == null) { + sInstance = new TunerService(); + sInstance.mContext = context.getApplicationContext(); + sInstance.mComponents = new HashMap<>(); + sInstance.start(); + } + return sInstance; + } + + private class Observer extends ContentObserver { + public Observer() { + super(new Handler(Looper.getMainLooper())); + } + + @Override + public void onChange(boolean selfChange, Uri uri, int userId) { + if (userId == ActivityManager.getCurrentUser()) { + reloadSetting(uri); + } + } + } + + public interface Tunable { + void onTuningChanged(String key, String newValue); + } +} |