Updates for QS DND tile

- Make detail panels not close when turned off
 - Add auto-rule state for DND tile

Test: manual
Change-Id: I533cf0a27c54e84cd74ede72dcf10e2e5f9a070f
Fixes: 34765805
This commit is contained in:
Jason Monk
2017-04-05 09:29:53 -04:00
parent 2d008a5fc1
commit be3235abcd
9 changed files with 402 additions and 174 deletions

View File

@@ -18,104 +18,155 @@
<com.android.systemui.volume.ZenModePanel xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/zen_mode_panel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:orientation="vertical" >
<com.android.systemui.volume.SegmentedButtons
android:id="@+id/zen_buttons"
android:background="@drawable/segmented_buttons_background"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp" />
<RelativeLayout
android:id="@+id/zen_introduction"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:background="@drawable/zen_introduction_message_background"
android:theme="@*android:style/ThemeOverlay.DeviceDefault.Accent.Light">
<ImageView
android:id="@+id/zen_introduction_confirm"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginEnd="8dp"
android:layout_alignParentEnd="true"
android:background="@drawable/btn_borderless_rect"
android:clickable="true"
android:contentDescription="@string/accessibility_desc_close"
android:scaleType="center"
android:src="@drawable/ic_close"
android:tint="@android:color/white" />
<TextView
android:id="@+id/zen_introduction_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginStart="24dp"
android:textDirection="locale"
android:lineSpacingMultiplier="1.20029"
android:layout_toStartOf="@id/zen_introduction_confirm"
android:textAppearance="@style/TextAppearance.QS.Introduction" />
<TextView
android:id="@+id/zen_introduction_customize"
style="@style/QSBorderlessButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_marginEnd="12dp"
android:layout_below="@id/zen_introduction_message"
android:clickable="true"
android:focusable="true"
android:text="@string/zen_priority_customize_button"
android:textAppearance="@style/TextAppearance.QS.DetailButton.White" />
<View
android:layout_width="0dp"
android:layout_height="16dp"
android:layout_below="@id/zen_introduction_message"
android:layout_alignParentEnd="true" />
</RelativeLayout>
android:layout_height="match_parent"
android:clipChildren="false" >
<LinearLayout
android:id="@+id/zen_conditions"
android:id="@+id/edit_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="4dp"
android:layout_marginStart="4dp"
android:paddingBottom="@dimen/zen_mode_condition_detail_bottom_padding"
android:orientation="horizontal" >
android:layout_height="match_parent"
android:background="?android:attr/colorPrimary"
android:clipChildren="false"
android:orientation="vertical">
<com.android.systemui.volume.SegmentedButtons
android:id="@+id/zen_buttons"
android:background="@drawable/segmented_buttons_background"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp" />
<RelativeLayout
android:id="@+id/zen_introduction"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:background="@drawable/zen_introduction_message_background"
android:theme="@*android:style/ThemeOverlay.DeviceDefault.Accent.Light">
<ImageView
android:id="@+id/zen_introduction_confirm"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginEnd="8dp"
android:layout_alignParentEnd="true"
android:background="@drawable/btn_borderless_rect"
android:clickable="true"
android:contentDescription="@string/accessibility_desc_close"
android:scaleType="center"
android:src="@drawable/ic_close"
android:tint="@android:color/white" />
<TextView
android:id="@+id/zen_introduction_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginStart="24dp"
android:textDirection="locale"
android:lineSpacingMultiplier="1.20029"
android:layout_toStartOf="@id/zen_introduction_confirm"
android:textAppearance="@style/TextAppearance.QS.Introduction" />
<TextView
android:id="@+id/zen_introduction_customize"
style="@style/QSBorderlessButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_marginEnd="12dp"
android:layout_below="@id/zen_introduction_message"
android:clickable="true"
android:focusable="true"
android:text="@string/zen_priority_customize_button"
android:textAppearance="@style/TextAppearance.QS.DetailButton.White" />
<View
android:layout_width="0dp"
android:layout_height="16dp"
android:layout_below="@id/zen_introduction_message"
android:layout_alignParentEnd="true" />
</RelativeLayout>
<LinearLayout
android:id="@+id/zen_conditions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="4dp"
android:layout_marginStart="4dp"
android:paddingBottom="@dimen/zen_mode_condition_detail_bottom_padding"
android:orientation="horizontal" >
<RadioGroup
android:id="@+id/zen_radio_buttons"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
android:id="@+id/zen_radio_buttons"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<LinearLayout
android:id="@+id/zen_radio_buttons_content"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"/>
android:id="@+id/zen_radio_buttons_content"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"/>
</LinearLayout>
<TextView
android:id="@+id/zen_alarm_warning"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="18dp"
android:layout_marginEnd="16dp"
android:textDirection="locale"
android:lineSpacingMultiplier="1.20029"
android:textAppearance="@style/TextAppearance.QS.Warning" />
</LinearLayout>
<TextView
android:id="@+id/zen_alarm_warning"
<LinearLayout
android:id="@android:id/empty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="18dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="?android:attr/colorPrimary"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@android:id/icon"
android:layout_width="56dp"
android:layout_height="56dp"
android:alpha="?android:attr/disabledAlpha"
android:tint="?android:attr/colorForeground" />
<TextView
android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:textAppearance="@style/TextAppearance.QS.DetailEmpty"/>
</LinearLayout>
<LinearLayout
android:id="@+id/auto_rule"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/colorPrimary"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:textDirection="locale"
android:lineSpacingMultiplier="1.20029"
android:textAppearance="@style/TextAppearance.QS.Warning" />
android:layout_marginTop="16dp"
android:layout_marginBottom="8dp"
android:orientation="vertical">
<TextView
android:id="@android:id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.QS.DetailItemPrimary"/>
</LinearLayout>
</com.android.systemui.volume.ZenModePanel>

View File

@@ -1975,13 +1975,13 @@
<string name="dnd_is_off">Do Not Disturb is off</string>
<!-- Prompt for when Do not disturb is on from automatic rule in QS [CHAR LIMIT=NONE] -->
<string name="qs_dnd_prompt_auto_rule">Do Not Disturb was turned on by an automatic rule (<xliff:g name="rule">%s</xliff:g>). Keep current settings?</string>
<string name="qs_dnd_prompt_auto_rule">Do Not Disturb was turned on by an automatic rule (<xliff:g name="rule">%s</xliff:g>).</string>
<!-- Prompt for when Do not disturb is on from app in QS [CHAR LIMIT=NONE] -->
<string name="qs_dnd_prompt_app">Do Not Disturb was turned on by an app (<xliff:g name="app">%s</xliff:g>). Keep current settings?</string>
<string name="qs_dnd_prompt_app">Do Not Disturb was turned on by an app (<xliff:g name="app">%s</xliff:g>).</string>
<!-- Prompt for when Do not disturb is on from automatic rule or app in QS [CHAR LIMIT=NONE] -->
<string name="qs_dnd_prompt_auto_rule_app">Do Not Disturb was turned on by an automatic rule or app. Keep current settings?</string>
<string name="qs_dnd_prompt_auto_rule_app">Do Not Disturb was turned on by an automatic rule or app.</string>
<!-- Description of Do Not Disturb option in QS that ends at the specified time[CHAR LIMIT=20] -->
<string name="qs_dnd_until">Until <xliff:g name="time">%s</xliff:g></string>

View File

@@ -158,6 +158,7 @@ public class SystemUIApplication extends Application implements SysUiServiceProv
* the main process.
* <p>This method must only be called from the main thread.</p>
*/
public void startServicesIfNeeded() {
startServicesIfNeeded(SERVICES);
}

View File

@@ -81,8 +81,8 @@ public class QSDetailItems extends FrameLayout {
mItemList.setAdapter(mAdapter);
mEmpty = findViewById(android.R.id.empty);
mEmpty.setVisibility(GONE);
mEmptyText = (TextView) mEmpty.findViewById(android.R.id.title);
mEmptyIcon = (ImageView) mEmpty.findViewById(android.R.id.icon);
mEmptyText = mEmpty.findViewById(android.R.id.title);
mEmptyIcon = mEmpty.findViewById(android.R.id.icon);
}
@Override
@@ -104,8 +104,10 @@ public class QSDetailItems extends FrameLayout {
}
public void setEmptyState(int icon, int text) {
mEmptyIcon.setImageResource(icon);
mEmptyText.setText(text);
mEmptyIcon.post(() -> {
mEmptyIcon.setImageResource(icon);
mEmptyText.setText(text);
});
}
@Override

View File

@@ -73,6 +73,7 @@ public abstract class QSTileImpl<TState extends State> implements QSTile {
private String mTileSpec;
private EnforcedAdmin mEnforcedAdmin;
private boolean mShowingDetail;
public abstract TState newTileState();
@@ -286,11 +287,16 @@ public abstract class QSTileImpl<TState extends State> implements QSTile {
}
private void handleShowDetail(boolean show) {
mShowingDetail = show;
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).onShowDetail(show);
}
}
protected boolean isShowingDetail() {
return mShowingDetail;
}
private void handleToggleStateChanged(boolean state) {
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).onToggleStateChanged(state);

View File

@@ -35,10 +35,10 @@ import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.plugins.qs.QSTile.BooleanState;
import com.android.systemui.qs.QSDetailItems;
import com.android.systemui.qs.QSDetailItems.Item;
import com.android.systemui.qs.QSHost;
import com.android.systemui.plugins.qs.QSTile.BooleanState;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.BluetoothController;
@@ -99,10 +99,6 @@ public class BluetoothTile extends QSTileImpl<BooleanState> {
return;
}
showDetail(true);
if (!mState.value) {
mState.value = true;
mController.setBluetoothEnabled(true);
}
}
@Override
@@ -176,6 +172,9 @@ public class BluetoothTile extends QSTileImpl<BooleanState> {
@Override
public void onBluetoothStateChange(boolean enabled) {
refreshState();
if (isShowingDetail()) {
mDetailAdapter.updateItems();
}
}
@Override
@@ -187,6 +186,9 @@ public class BluetoothTile extends QSTileImpl<BooleanState> {
}
});
refreshState();
if (isShowingDetail()) {
mDetailAdapter.updateItems();
}
}
};
@@ -223,7 +225,6 @@ public class BluetoothTile extends QSTileImpl<BooleanState> {
public void setToggleState(boolean state) {
MetricsLogger.action(mContext, MetricsEvent.QS_BLUETOOTH_TOGGLE, state);
mController.setBluetoothEnabled(state);
showDetail(false);
}
@Override
@@ -235,8 +236,6 @@ public class BluetoothTile extends QSTileImpl<BooleanState> {
public View createDetailView(Context context, View convertView, ViewGroup parent) {
mItems = QSDetailItems.convertOrInflate(context, convertView, parent);
mItems.setTagSuffix("Bluetooth");
mItems.setEmptyState(R.drawable.ic_qs_bluetooth_detail_empty,
R.string.quick_settings_bluetooth_detail_empty_text);
mItems.setCallback(this);
updateItems();
setItemsVisible(mState.value);
@@ -250,6 +249,13 @@ public class BluetoothTile extends QSTileImpl<BooleanState> {
private void updateItems() {
if (mItems == null) return;
if (mController.isBluetoothEnabled()) {
mItems.setEmptyState(R.drawable.ic_qs_bluetooth_detail_empty,
R.string.quick_settings_bluetooth_detail_empty_text);
} else {
mItems.setEmptyState(R.drawable.ic_qs_bluetooth_detail_empty,
R.string.bt_is_off);
}
ArrayList<Item> items = new ArrayList<Item>();
final Collection<CachedBluetoothDevice> devices = mController.getDevices();
if (devices != null) {

View File

@@ -16,16 +16,25 @@
package com.android.systemui.qs.tiles;
import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
import static android.provider.Settings.Global.ZEN_MODE_OFF;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.UserManager;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenModeConfig.ZenRule;
import android.service.quicksettings.Tile;
import android.util.Slog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnAttachStateChangeListener;
@@ -41,9 +50,9 @@ import com.android.systemui.R;
import com.android.systemui.SysUIToast;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.qs.QSHost;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.qs.QSTile.BooleanState;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.volume.ZenModePanel;
@@ -129,10 +138,9 @@ public class DndTile extends QSTileImpl<BooleanState> {
@Override
protected void handleClick() {
if (mState.value) {
mController.setZen(Global.ZEN_MODE_OFF, null, TAG);
mController.setZen(ZEN_MODE_OFF, null, TAG);
} else {
int zen = Prefs.getInt(mContext, Prefs.Key.DND_FAVORITE_ZEN, Global.ZEN_MODE_ALARMS);
mController.setZen(zen, null, TAG);
mController.setZen(ZEN_MODE_ALARMS, null, TAG);
}
}
@@ -147,8 +155,6 @@ public class DndTile extends QSTileImpl<BooleanState> {
return;
}
showDetail(true);
int zen = Prefs.getInt(mContext, Prefs.Key.DND_FAVORITE_ZEN, Global.ZEN_MODE_ALARMS);
mController.setZen(zen, null, TAG);
}
@Override
@@ -159,7 +165,7 @@ public class DndTile extends QSTileImpl<BooleanState> {
@Override
protected void handleUpdateState(BooleanState state, Object arg) {
final int zen = arg instanceof Integer ? (Integer) arg : mController.getZen();
final boolean newValue = zen != Global.ZEN_MODE_OFF;
final boolean newValue = zen != ZEN_MODE_OFF;
final boolean valueChanged = state.value != newValue;
state.dualTarget = true;
state.value = newValue;
@@ -178,7 +184,7 @@ public class DndTile extends QSTileImpl<BooleanState> {
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_dnd_none_on);
break;
case Global.ZEN_MODE_ALARMS:
case ZEN_MODE_ALARMS:
state.icon = ResourceIcon.get(R.drawable.ic_qs_dnd_on);
state.label = mContext.getString(R.string.quick_settings_dnd_alarms_label);
state.contentDescription = mContext.getString(
@@ -187,13 +193,10 @@ public class DndTile extends QSTileImpl<BooleanState> {
default:
state.icon = TOTAL_SILENCE.equals(state.icon) ? mDisableTotalSilence : mDisable;
state.label = mContext.getString(R.string.quick_settings_dnd_label);
state.contentDescription = mContext.getString(
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_dnd);
break;
}
if (mShowingDetail && !state.value) {
showDetail(false);
}
if (valueChanged) {
fireToggleStateChanged(state.value);
}
@@ -249,6 +252,16 @@ public class DndTile extends QSTileImpl<BooleanState> {
private final ZenModeController.Callback mZenCallback = new ZenModeController.Callback() {
public void onZenChanged(int zen) {
refreshState(zen);
if (isShowingDetail()) {
mDetailAdapter.updatePanel();
}
}
@Override
public void onConfigChanged(ZenModeConfig config) {
if (isShowingDetail()) {
mDetailAdapter.updatePanel();
}
}
};
@@ -263,6 +276,9 @@ public class DndTile extends QSTileImpl<BooleanState> {
private final class DndDetailAdapter implements DetailAdapter, OnAttachStateChangeListener {
private ZenModePanel mZenPanel;
private boolean mAuto;
@Override
public CharSequence getTitle() {
return mContext.getString(R.string.quick_settings_dnd_label);
@@ -282,8 +298,12 @@ public class DndTile extends QSTileImpl<BooleanState> {
public void setToggleState(boolean state) {
MetricsLogger.action(mContext, MetricsEvent.QS_DND_TOGGLE, state);
if (!state) {
mController.setZen(Global.ZEN_MODE_OFF, null, TAG);
showDetail(false);
mController.setZen(ZEN_MODE_OFF, null, TAG);
mAuto = false;
} else {
int zen = Prefs.getInt(mContext, Prefs.Key.DND_FAVORITE_ZEN,
ZEN_MODE_ALARMS);
mController.setZen(zen, null, TAG);
}
}
@@ -294,15 +314,65 @@ public class DndTile extends QSTileImpl<BooleanState> {
@Override
public View createDetailView(Context context, View convertView, ViewGroup parent) {
final ZenModePanel zmp = convertView != null ? (ZenModePanel) convertView
mZenPanel = convertView != null ? (ZenModePanel) convertView
: (ZenModePanel) LayoutInflater.from(context).inflate(
R.layout.zen_mode_panel, parent, false);
if (convertView == null) {
zmp.init(mController);
zmp.addOnAttachStateChangeListener(this);
zmp.setCallback(mZenModePanelCallback);
mZenPanel.init(mController);
mZenPanel.addOnAttachStateChangeListener(this);
mZenPanel.setCallback(mZenModePanelCallback);
mZenPanel.setEmptyState(R.drawable.ic_qs_dnd_off, R.string.dnd_is_off);
}
return zmp;
updatePanel();
return mZenPanel;
}
private void updatePanel() {
if (mZenPanel == null) return;
mAuto = false;
if (mController.getZen() == ZEN_MODE_OFF) {
mZenPanel.setState(ZenModePanel.STATE_OFF);
} else {
ZenModeConfig config = mController.getConfig();
String summary = "";
if (config.manualRule != null && config.manualRule.enabler != null) {
summary = getOwnerCaption(config.manualRule.enabler);
}
for (ZenRule automaticRule : config.automaticRules.values()) {
if (automaticRule.isAutomaticActive()) {
if (summary.isEmpty()) {
summary = mContext.getString(R.string.qs_dnd_prompt_auto_rule,
automaticRule.name);
} else {
summary = mContext.getString(R.string.qs_dnd_prompt_auto_rule_app);
}
}
}
if (summary.isEmpty()) {
mZenPanel.setState(ZenModePanel.STATE_MODIFY);
} else {
mAuto = true;
mZenPanel.setState(ZenModePanel.STATE_AUTO_RULE);
mZenPanel.setAutoText(summary);
}
}
}
private String getOwnerCaption(String owner) {
final PackageManager pm = mContext.getPackageManager();
try {
final ApplicationInfo info = pm.getApplicationInfo(owner, 0);
if (info != null) {
final CharSequence seq = info.loadLabel(pm);
if (seq != null) {
final String str = seq.toString().trim();
return mContext.getString(R.string.qs_dnd_prompt_app, str);
}
}
} catch (Throwable e) {
Slog.w(TAG, "Error loading owner caption", e);
}
return "";
}
@Override
@@ -313,6 +383,7 @@ public class DndTile extends QSTileImpl<BooleanState> {
@Override
public void onViewDetachedFromWindow(View v) {
mShowingDetail = false;
mZenPanel = null;
}
}

View File

@@ -32,6 +32,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settingslib.wifi.AccessPoint;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.R.string;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.qs.QSDetailItems;
@@ -98,7 +99,9 @@ public class WifiTile extends QSTileImpl<SignalState> {
}
@Override
protected DetailAdapter createDetailAdapter() { return new WifiDetailAdapter(); }
protected DetailAdapter createDetailAdapter() {
return new WifiDetailAdapter();
}
@Override
public QSIconView createTileView(Context context) {
@@ -125,10 +128,6 @@ public class WifiTile extends QSTileImpl<SignalState> {
return;
}
showDetail(true);
if (!mState.value) {
mController.setWifiEnabled(true);
mState.value = true;
}
}
@Override
@@ -234,15 +233,15 @@ public class WifiTile extends QSTileImpl<SignalState> {
@Override
public String toString() {
return new StringBuilder("CallbackInfo[")
.append("enabled=").append(enabled)
.append(",connected=").append(connected)
.append(",wifiSignalIconId=").append(wifiSignalIconId)
.append(",enabledDesc=").append(enabledDesc)
.append(",activityIn=").append(activityIn)
.append(",activityOut=").append(activityOut)
.append(",wifiSignalContentDescription=").append(wifiSignalContentDescription)
.append(",isTransient=").append(isTransient)
.append(']').toString();
.append("enabled=").append(enabled)
.append(",connected=").append(connected)
.append(",wifiSignalIconId=").append(wifiSignalIconId)
.append(",enabledDesc=").append(enabledDesc)
.append(",activityIn=").append(activityIn)
.append(",activityOut=").append(activityOut)
.append(",wifiSignalContentDescription=").append(wifiSignalContentDescription)
.append(",isTransient=").append(isTransient)
.append(']').toString();
}
}
@@ -261,9 +260,14 @@ public class WifiTile extends QSTileImpl<SignalState> {
mInfo.activityOut = activityOut;
mInfo.wifiSignalContentDescription = qsIcon.contentDescription;
mInfo.isTransient = isTransient;
if (isShowingDetail()) {
mDetailAdapter.updateItems();
}
refreshState(mInfo);
}
};
}
;
protected class WifiDetailAdapter implements DetailAdapter,
NetworkController.AccessPointController.AccessPointCallback, QSDetailItems.Callback {
@@ -290,7 +294,6 @@ public class WifiTile extends QSTileImpl<SignalState> {
if (DEBUG) Log.d(TAG, "setToggleState " + state);
MetricsLogger.action(mContext, MetricsEvent.QS_WIFI_TOGGLE, state);
mController.setWifiEnabled(state);
showDetail(false);
}
@Override
@@ -307,8 +310,6 @@ public class WifiTile extends QSTileImpl<SignalState> {
mItems = QSDetailItems.convertOrInflate(context, convertView, parent);
mItems.setTagSuffix("Wifi");
mItems.setCallback(this);
mItems.setEmptyState(R.drawable.ic_qs_wifi_detail_empty,
R.string.quick_settings_wifi_detail_empty_text);
updateItems();
setItemsVisible(mState.value);
return mItems;
@@ -352,6 +353,13 @@ public class WifiTile extends QSTileImpl<SignalState> {
private void updateItems() {
if (mItems == null) return;
if (mSignalCallback.mInfo.enabled) {
mItems.setEmptyState(R.drawable.ic_qs_wifi_detail_empty,
R.string.quick_settings_wifi_detail_empty_text);
} else {
mItems.setEmptyState(R.drawable.ic_qs_wifi_detail_empty,
R.string.wifi_is_off);
}
Item[] items = null;
if (mAccessPoints != null) {
items = new Item[mAccessPoints.length];

View File

@@ -36,6 +36,7 @@ import android.service.notification.ZenModeConfig;
import android.service.notification.ZenModeConfig.ZenRule;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.text.format.DateUtils;
import android.util.ArraySet;
import android.util.AttributeSet;
import android.util.Log;
@@ -45,6 +46,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioButton;
@@ -55,6 +57,7 @@ import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Prefs;
import com.android.systemui.R;
import com.android.systemui.R.string;
import com.android.systemui.statusbar.policy.ZenModeController;
import java.io.FileDescriptor;
@@ -65,10 +68,14 @@ import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.Objects;
public class ZenModePanel extends LinearLayout {
public class ZenModePanel extends FrameLayout {
private static final String TAG = "ZenModePanel";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
public static final int STATE_MODIFY = 0;
public static final int STATE_AUTO_RULE = 1;
public static final int STATE_OFF = 2;
private static final int SECONDS_MS = 1000;
private static final int MINUTES_MS = 60 * SECONDS_MS;
@@ -86,6 +93,8 @@ public class ZenModePanel extends LinearLayout {
public static final Intent ZEN_PRIORITY_SETTINGS
= new Intent(Settings.ACTION_ZEN_MODE_PRIORITY_SETTINGS);
private static final long TRANSITION_DURATION = 300;
private final Context mContext;
protected final LayoutInflater mInflater;
private final H mHandler = new H();
@@ -124,6 +133,13 @@ public class ZenModePanel extends LinearLayout {
protected int mZenModeConditionLayoutId;
protected int mZenModeButtonLayoutId;
private View mEmpty;
private TextView mEmptyText;
private ImageView mEmptyIcon;
private View mAutoRule;
private TextView mAutoTitle;
private int mState = STATE_MODIFY;
private ViewGroup mEdit;
public ZenModePanel(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -156,7 +172,7 @@ public class ZenModePanel extends LinearLayout {
}
protected void createZenButtons() {
mZenButtons = (SegmentedButtons) findViewById(R.id.zen_buttons);
mZenButtons = findViewById(R.id.zen_buttons);
mZenButtons.addButton(R.string.interruption_level_none_twoline,
R.string.interruption_level_none_with_warning,
Global.ZEN_MODE_NO_INTERRUPTIONS);
@@ -174,30 +190,75 @@ public class ZenModePanel extends LinearLayout {
super.onFinishInflate();
createZenButtons();
mZenIntroduction = findViewById(R.id.zen_introduction);
mZenIntroductionMessage = (TextView) findViewById(R.id.zen_introduction_message);
mZenIntroductionMessage = findViewById(R.id.zen_introduction_message);
mZenIntroductionConfirm = findViewById(R.id.zen_introduction_confirm);
mZenIntroductionConfirm.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
confirmZenIntroduction();
}
});
mZenIntroductionCustomize = (TextView) findViewById(R.id.zen_introduction_customize);
mZenIntroductionCustomize.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
confirmZenIntroduction();
if (mCallback != null) {
mCallback.onPrioritySettings();
}
mZenIntroductionConfirm.setOnClickListener(v -> confirmZenIntroduction());
mZenIntroductionCustomize = findViewById(R.id.zen_introduction_customize);
mZenIntroductionCustomize.setOnClickListener(v -> {
confirmZenIntroduction();
if (mCallback != null) {
mCallback.onPrioritySettings();
}
});
mConfigurableTexts.add(mZenIntroductionCustomize, R.string.zen_priority_customize_button);
mZenConditions = (LinearLayout) findViewById(R.id.zen_conditions);
mZenAlarmWarning = (TextView) findViewById(R.id.zen_alarm_warning);
mZenRadioGroup = (RadioGroup) findViewById(R.id.zen_radio_buttons);
mZenRadioGroupContent = (LinearLayout) findViewById(R.id.zen_radio_buttons_content);
mZenConditions = findViewById(R.id.zen_conditions);
mZenAlarmWarning = findViewById(R.id.zen_alarm_warning);
mZenRadioGroup = findViewById(R.id.zen_radio_buttons);
mZenRadioGroupContent = findViewById(R.id.zen_radio_buttons_content);
mEdit = findViewById(R.id.edit_container);
mEmpty = findViewById(android.R.id.empty);
mEmpty.setVisibility(INVISIBLE);
mEmptyText = mEmpty.findViewById(android.R.id.title);
mEmptyIcon = mEmpty.findViewById(android.R.id.icon);
mAutoRule = findViewById(R.id.auto_rule);
mAutoTitle = mAutoRule.findViewById(android.R.id.title);
mAutoRule.setVisibility(INVISIBLE);
}
public void setEmptyState(int icon, int text) {
mEmptyIcon.post(() -> {
mEmptyIcon.setImageResource(icon);
mEmptyText.setText(text);
});
}
public void setAutoText(CharSequence text) {
mAutoTitle.post(() -> mAutoTitle.setText(text));
}
public void setState(int state) {
if (mState == state) return;
transitionFrom(getView(mState), getView(state));
mState = state;
}
private void transitionFrom(View from, View to) {
from.post(() -> {
// TODO: Better transitions
to.setAlpha(0);
to.setVisibility(VISIBLE);
to.bringToFront();
to.animate().cancel();
to.animate().alpha(1)
.setDuration(TRANSITION_DURATION)
.withEndAction(() -> from.setVisibility(INVISIBLE))
.start();
});
}
private View getView(int state) {
switch (state) {
case STATE_AUTO_RULE:
return mAutoRule;
case STATE_OFF:
return mEmpty;
default:
return mEdit;
}
}
@Override
@@ -232,6 +293,7 @@ public class ZenModePanel extends LinearLayout {
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (DEBUG) Log.d(mTag, "onAttachedToWindow");
setExpanded(true);
mAttached = true;
mAttachedZen = getSelectedZen(-1);
mSessionZen = mAttachedZen;
@@ -246,6 +308,7 @@ public class ZenModePanel extends LinearLayout {
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (DEBUG) Log.d(mTag, "onDetachedFromWindow");
setExpanded(false);
checkForAttachedZenChange();
mAttached = false;
mAttachedZen = -1;
@@ -285,7 +348,7 @@ public class ZenModePanel extends LinearLayout {
if (expanded == mExpanded) return;
if (DEBUG) Log.d(mTag, "setExpanded " + expanded);
mExpanded = expanded;
if (mExpanded && isShown()) {
if (mExpanded) {
ensureSelection();
}
updateWidgets();
@@ -317,10 +380,10 @@ public class ZenModePanel extends LinearLayout {
protected void addZenConditions(int count) {
for (int i = 0; i < count; i++) {
final View rb = mInflater.inflate(mZenModeButtonLayoutId, this, false);
final View rb = mInflater.inflate(mZenModeButtonLayoutId, mEdit, false);
rb.setId(i);
mZenRadioGroup.addView(rb);
final View rbc = mInflater.inflate(mZenModeConditionLayoutId, this, false);
final View rbc = mInflater.inflate(mZenModeConditionLayoutId, mEdit, false);
rbc.setId(i + count);
mZenRadioGroupContent.addView(rbc);
}
@@ -368,13 +431,26 @@ public class ZenModePanel extends LinearLayout {
private void handleUpdateManualRule(ZenRule rule) {
final int zen = rule != null ? rule.zenMode : Global.ZEN_MODE_OFF;
handleUpdateZen(zen);
final Condition c = rule != null ? rule.condition : null;
final Condition c = rule == null ? null
: rule.condition != null ? rule.condition
: createCondition(rule.conditionId);
handleExitConditionChanged(c);
}
private Condition createCondition(Uri conditionId) {
if (ZenModeConfig.isValidCountdownConditionId(conditionId)) {
long time = ZenModeConfig.tryParseCountdownConditionId(conditionId);
int mins = (int) ((time - System.currentTimeMillis() + DateUtils.MINUTE_IN_MILLIS / 2)
/ DateUtils.MINUTE_IN_MILLIS);
Condition c = ZenModeConfig.toTimeCondition(mContext, time, mins,
ActivityManager.getCurrentUser(), false);
return c;
}
return null;
}
private void handleUpdateZen(int zen) {
if (mSessionZen != -1 && mSessionZen != zen) {
setExpanded(isShown());
mSessionZen = zen;
}
mZenButtons.setSelectedValue(zen, false /* fromClick */);
@@ -391,15 +467,20 @@ public class ZenModePanel extends LinearLayout {
private void handleExitConditionChanged(Condition exitCondition) {
setExitCondition(exitCondition);
if (DEBUG) Log.d(mTag, "handleExitConditionChanged " + mExitCondition);
if (exitCondition == null) return;
final int N = getVisibleConditions();
for (int i = 0; i < N; i++) {
final ConditionTag tag = getConditionTagAt(i);
if (tag != null) {
if (sameConditionId(tag.condition, mExitCondition)) {
bind(exitCondition, mZenRadioGroupContent.getChildAt(i), i);
}
if (tag != null && sameConditionId(tag.condition, mExitCondition)) {
bind(exitCondition, mZenRadioGroupContent.getChildAt(i), i);
return;
}
}
if (mCountdownConditionSupported && ZenModeConfig.isValidCountdownConditionId(
exitCondition.id)) {
bind(exitCondition, mZenRadioGroupContent.getChildAt(COUNTDOWN_CONDITION_INDEX),
COUNTDOWN_CONDITION_INDEX);
}
}
private Condition getSelectedCondition() {
@@ -519,7 +600,7 @@ public class ZenModePanel extends LinearLayout {
}
}
// ensure something is selected
if (mExpanded && isShown()) {
if (mExpanded) {
ensureSelection();
}
mZenConditions.setVisibility(mSessionZen != Global.ZEN_MODE_OFF ? View.VISIBLE : View.GONE);
@@ -597,7 +678,9 @@ public class ZenModePanel extends LinearLayout {
if (foreverTag == null) return;
if (DEBUG) Log.d(mTag, "Selecting a default");
final int favoriteIndex = mPrefs.getMinuteIndex();
if (favoriteIndex == -1 || !mCountdownConditionSupported) {
if (mExitCondition != null && mExitCondition.equals(mTimeCondition)) {
getConditionTagAt(COUNTDOWN_CONDITION_INDEX).rb.setChecked(true);
} else if (favoriteIndex == -1 || !mCountdownConditionSupported) {
foreverTag.rb.setChecked(true);
} else {
mTimeCondition = ZenModeConfig.toTimeCondition(mContext,