Setup service for tunable things to use.
Change-Id: I13daa68d3d1ec5584fd84f356f4f5a0d1c0b853a
This commit is contained in:
@@ -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,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user