Tuner: Let Status bar be tuned
Also fix a crash in the QSTuner Bug: 21192440 Change-Id: Ideb8e34b93a4b456d758266dfc06545e7f7ab109
This commit is contained in:
@@ -1034,6 +1034,21 @@
|
||||
<!-- Name of quick settings -->
|
||||
<string name="quick_settings">Quick Settings</string>
|
||||
|
||||
<!-- Name of status bar -->
|
||||
<string name="status_bar">Status bar</string>
|
||||
|
||||
<!-- Name of the ethernet status bar icon. -->
|
||||
<string name="status_bar_ethernet">Ethernet</string>
|
||||
|
||||
<!-- Name of the alarm status bar icon. -->
|
||||
<string name="status_bar_alarm">Alarm</string>
|
||||
|
||||
<!-- Name of the work status bar icon. -->
|
||||
<string name="status_bar_work">Work profile</string>
|
||||
|
||||
<!-- Name of the airplane status bar icon. -->
|
||||
<string name="status_bar_airplane">Airplane mode</string>
|
||||
|
||||
<!-- Description for adding a quick settings tile -->
|
||||
<string name="add_tile">Add tile</string>
|
||||
|
||||
|
||||
@@ -15,16 +15,61 @@
|
||||
-->
|
||||
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:title="@string/system_ui_tuner">
|
||||
android:title="@string/system_ui_tuner">
|
||||
|
||||
<Preference
|
||||
android:key="qs_tuner"
|
||||
android:title="@string/quick_settings" />
|
||||
<Preference
|
||||
android:key="qs_tuner"
|
||||
android:title="@string/quick_settings" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="battery_pct"
|
||||
android:title="@string/show_battery_percentage"
|
||||
android:summary="@string/show_battery_percentage_summary"
|
||||
android:persistent="false" />
|
||||
<PreferenceScreen
|
||||
android:title="@string/status_bar" >
|
||||
|
||||
<com.android.systemui.tuner.StatusBarSwitch
|
||||
android:key="cast"
|
||||
android:title="@string/quick_settings_cast_title" />
|
||||
|
||||
<com.android.systemui.tuner.StatusBarSwitch
|
||||
android:key="hotspot"
|
||||
android:title="@string/quick_settings_hotspot_label" />
|
||||
|
||||
<com.android.systemui.tuner.StatusBarSwitch
|
||||
android:key="bluetooth"
|
||||
android:title="@string/quick_settings_bluetooth_label" />
|
||||
|
||||
<com.android.systemui.tuner.StatusBarSwitch
|
||||
android:key="zen"
|
||||
android:title="@string/quick_settings_dnd_label" />
|
||||
|
||||
<com.android.systemui.tuner.StatusBarSwitch
|
||||
android:key="alarm_clock"
|
||||
android:title="@string/status_bar_alarm" />
|
||||
|
||||
<com.android.systemui.tuner.StatusBarSwitch
|
||||
android:key="managed_profile"
|
||||
android:title="@string/status_bar_work" />
|
||||
|
||||
<com.android.systemui.tuner.StatusBarSwitch
|
||||
android:key="wifi"
|
||||
android:title="@string/quick_settings_wifi_label" />
|
||||
|
||||
<com.android.systemui.tuner.StatusBarSwitch
|
||||
android:key="ethernet"
|
||||
android:title="@string/status_bar_ethernet" />
|
||||
|
||||
<com.android.systemui.tuner.StatusBarSwitch
|
||||
android:key="mobile"
|
||||
android:title="@string/quick_settings_cellular_detail_title" />
|
||||
|
||||
<com.android.systemui.tuner.StatusBarSwitch
|
||||
android:key="airplane"
|
||||
android:title="@string/status_bar_airplane" />
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
<SwitchPreference
|
||||
android:key="battery_pct"
|
||||
android:title="@string/show_battery_percentage"
|
||||
android:summary="@string/show_battery_percentage_summary"
|
||||
android:persistent="false" />
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -18,10 +18,13 @@ 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.AttributeSet;
|
||||
import android.util.Log;
|
||||
@@ -33,6 +36,7 @@ import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.android.systemui.R;
|
||||
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;
|
||||
@@ -49,6 +53,11 @@ public class SignalClusterView
|
||||
static final String TAG = "SignalClusterView";
|
||||
static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
|
||||
private static final String SLOT_AIRPLANE = "airplane";
|
||||
private static final String SLOT_MOBILE = "mobile";
|
||||
private static final String SLOT_WIFI = "wifi";
|
||||
private static final String SLOT_ETHERNET = "ethernet";
|
||||
|
||||
NetworkControllerImpl mNC;
|
||||
SecurityController mSC;
|
||||
|
||||
@@ -81,6 +90,11 @@ public class SignalClusterView
|
||||
private int mEndPadding;
|
||||
private int mEndPaddingNothingVisible;
|
||||
|
||||
private boolean mBlockAirplane;
|
||||
private boolean mBlockMobile;
|
||||
private boolean mBlockWifi;
|
||||
private boolean mBlockEthernet;
|
||||
|
||||
public SignalClusterView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
@@ -91,6 +105,14 @@ 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);
|
||||
}
|
||||
|
||||
public void setNetworkController(NetworkControllerImpl nc) {
|
||||
@@ -141,6 +163,9 @@ public class SignalClusterView
|
||||
|
||||
apply();
|
||||
applyIconTint();
|
||||
getContext().getContentResolver().registerContentObserver(
|
||||
Settings.Secure.getUriFor(StatusBarIconController.ICON_BLACKLIST), false,
|
||||
mBlacklistObserver);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -153,6 +178,7 @@ public class SignalClusterView
|
||||
mAirplane = null;
|
||||
mMobileSignalGroup.removeAllViews();
|
||||
mMobileSignalGroup = null;
|
||||
getContext().getContentResolver().unregisterContentObserver(mBlacklistObserver);
|
||||
|
||||
super.onDetachedFromWindow();
|
||||
}
|
||||
@@ -172,7 +198,7 @@ public class SignalClusterView
|
||||
@Override
|
||||
public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
|
||||
boolean activityIn, boolean activityOut, String description) {
|
||||
mWifiVisible = statusIcon.visible;
|
||||
mWifiVisible = statusIcon.visible && !mBlockWifi;
|
||||
mWifiStrengthId = statusIcon.icon;
|
||||
mWifiDescription = statusIcon.contentDescription;
|
||||
|
||||
@@ -184,7 +210,7 @@ public class SignalClusterView
|
||||
int qsType, boolean activityIn, boolean activityOut, String typeContentDescription,
|
||||
String description, boolean isWide, int subId) {
|
||||
PhoneState state = getOrInflateState(subId);
|
||||
state.mMobileVisible = statusIcon.visible;
|
||||
state.mMobileVisible = statusIcon.visible && !mBlockMobile;
|
||||
state.mMobileStrengthId = statusIcon.icon;
|
||||
state.mMobileTypeId = statusType;
|
||||
state.mMobileDescription = statusIcon.contentDescription;
|
||||
@@ -196,7 +222,7 @@ public class SignalClusterView
|
||||
|
||||
@Override
|
||||
public void setEthernetIndicators(IconState state) {
|
||||
mEthernetVisible = state.visible;
|
||||
mEthernetVisible = state.visible && !mBlockEthernet;
|
||||
mEthernetIconId = state.icon;
|
||||
mEthernetDescription = state.contentDescription;
|
||||
|
||||
@@ -205,7 +231,7 @@ public class SignalClusterView
|
||||
|
||||
@Override
|
||||
public void setNoSims(boolean show) {
|
||||
mNoSimsVisible = show;
|
||||
mNoSimsVisible = show && !mBlockMobile;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -244,7 +270,7 @@ public class SignalClusterView
|
||||
|
||||
@Override
|
||||
public void setIsAirplaneMode(IconState icon) {
|
||||
mIsAirplaneMode = icon.visible;
|
||||
mIsAirplaneMode = icon.visible && !mBlockAirplane;
|
||||
mAirplaneIconId = icon.icon;
|
||||
mAirplaneContentDescription = icon.contentDescription;
|
||||
|
||||
@@ -502,5 +528,14 @@ 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);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.android.systemui.statusbar;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
@@ -49,10 +48,17 @@ public class StatusBarIconView extends AnimatedImageView {
|
||||
private int mNumberY;
|
||||
private String mNumberText;
|
||||
private Notification mNotification;
|
||||
private final boolean mBlocked;
|
||||
|
||||
public StatusBarIconView(Context context, String slot, Notification notification) {
|
||||
this(context, slot, notification, false);
|
||||
}
|
||||
|
||||
public StatusBarIconView(Context context, String slot, Notification notification,
|
||||
boolean blocked) {
|
||||
super(context);
|
||||
final Resources res = context.getResources();
|
||||
mBlocked = blocked;
|
||||
mSlot = slot;
|
||||
mNumberPain = new Paint();
|
||||
mNumberPain.setTextAlign(Paint.Align.CENTER);
|
||||
@@ -80,6 +86,7 @@ public class StatusBarIconView extends AnimatedImageView {
|
||||
|
||||
public StatusBarIconView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mBlocked = false;
|
||||
final Resources res = context.getResources();
|
||||
final int outerBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_size);
|
||||
final int imageBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_drawing_size);
|
||||
@@ -148,7 +155,7 @@ public class StatusBarIconView extends AnimatedImageView {
|
||||
invalidate();
|
||||
}
|
||||
if (!visibilityEquals) {
|
||||
setVisibility(icon.visible ? VISIBLE : GONE);
|
||||
setVisibility(icon.visible && !mBlocked ? VISIBLE : GONE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -281,4 +288,8 @@ public class StatusBarIconView extends AnimatedImageView {
|
||||
return "StatusBarIconView(slot=" + mSlot + " icon=" + mIcon
|
||||
+ " notification=" + mNotification + ")";
|
||||
}
|
||||
|
||||
public String getSlot() {
|
||||
return mSlot;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,10 +20,14 @@ 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;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AnimationUtils;
|
||||
@@ -53,6 +57,8 @@ public class StatusBarIconController {
|
||||
|
||||
public static final long DEFAULT_TINT_ANIMATION_DURATION = 120;
|
||||
|
||||
public static final String ICON_BLACKLIST = "icon_blacklist";
|
||||
|
||||
private Context mContext;
|
||||
private PhoneStatusBar mPhoneStatusBar;
|
||||
private Interpolator mLinearOutSlowIn;
|
||||
@@ -89,6 +95,8 @@ public class StatusBarIconController {
|
||||
private long mTransitionDeferringStartTime;
|
||||
private long mTransitionDeferringDuration;
|
||||
|
||||
private final ArraySet<String> mIconBlacklist;
|
||||
|
||||
private final Runnable mTransitionDeferringDoneRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -118,7 +126,12 @@ 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);
|
||||
}
|
||||
|
||||
public void updateResources() {
|
||||
@@ -130,11 +143,12 @@ public class StatusBarIconController {
|
||||
}
|
||||
|
||||
public void addSystemIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
|
||||
StatusBarIconView view = new StatusBarIconView(mContext, slot, null);
|
||||
boolean blocked = mIconBlacklist.contains(slot);
|
||||
StatusBarIconView view = new StatusBarIconView(mContext, slot, null, blocked);
|
||||
view.set(icon);
|
||||
mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize));
|
||||
view = new StatusBarIconView(mContext, slot, null);
|
||||
view = new StatusBarIconView(mContext, slot, null, blocked);
|
||||
view.set(icon);
|
||||
mStatusIconsKeyguard.addView(view, viewIndex, new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize));
|
||||
@@ -414,4 +428,43 @@ 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);
|
||||
ArraySet<String> ret = new ArraySet<String>();
|
||||
if (blackListStr != null) {
|
||||
String[] blacklist = blackListStr.split(",");
|
||||
for (String slot : blacklist) {
|
||||
if (!TextUtils.isEmpty(slot)) {
|
||||
ret.add(slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static boolean isBlocked(Context context, String slot) {
|
||||
return getIconBlacklist(context).contains(slot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings.Secure;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.DragEvent;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -32,7 +33,6 @@ import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.View.OnDragListener;
|
||||
import android.view.View.OnLongClickListener;
|
||||
import android.view.View.OnTouchListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
@@ -47,6 +47,7 @@ import com.android.systemui.qs.QSTile.ResourceIcon;
|
||||
import com.android.systemui.qs.QSTileView;
|
||||
import com.android.systemui.qs.tiles.IntentTile;
|
||||
import com.android.systemui.statusbar.phone.QSTileHost;
|
||||
import com.android.systemui.statusbar.policy.SecurityController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -174,7 +175,7 @@ public class QsTuner extends Fragment implements Callback {
|
||||
|
||||
public CustomHost(Context context) {
|
||||
super(context, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null);
|
||||
null, null, new BlankSecurityController());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -215,15 +216,8 @@ public class QsTuner extends Fragment implements Callback {
|
||||
}
|
||||
|
||||
private void setTiles(List<String> tiles) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < tiles.size(); i++) {
|
||||
if (builder.length() != 0) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append(tiles.get(i));
|
||||
}
|
||||
Secure.putStringForUser(getContext().getContentResolver(),
|
||||
TILES_SETTING, builder.toString(), mUserTracker.getCurrentUserId());
|
||||
Secure.putStringForUser(getContext().getContentResolver(), TILES_SETTING,
|
||||
TextUtils.join(",", tiles), mUserTracker.getCurrentUserId());
|
||||
}
|
||||
|
||||
public void showAddDialog() {
|
||||
@@ -282,6 +276,45 @@ public class QsTuner extends Fragment implements Callback {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static class BlankSecurityController implements SecurityController {
|
||||
@Override
|
||||
public boolean hasDeviceOwner() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasProfileOwner() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceOwnerName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProfileOwnerName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVpnEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserSwitched(int newUserId) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCallback(SecurityControllerCallback callback) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCallback(SecurityControllerCallback callback) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class DraggableTile extends QSTile<QSTile.State>
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.preference.SwitchPreference;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.android.systemui.statusbar.phone.StatusBarIconController;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class StatusBarSwitch extends SwitchPreference {
|
||||
|
||||
public StatusBarSwitch(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setChecked(!StatusBarIconController.isBlocked(getContext(), 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);
|
||||
}
|
||||
} else {
|
||||
if (blacklist != null && blacklist.remove(getKey())) {
|
||||
setList(blacklist);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void setList(Set<String> blacklist) {
|
||||
ContentResolver contentResolver = getContext().getContentResolver();
|
||||
Settings.Secure.putString(contentResolver, StatusBarIconController.ICON_BLACKLIST,
|
||||
TextUtils.join(",", blacklist));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user