summaryrefslogtreecommitdiffstats
path: root/packages/SystemUI/src/com/android/systemui/volume
diff options
context:
space:
mode:
authorJohn Spurlock <jspurlock@google.com>2014-11-08 12:40:19 -0500
committerJohn Spurlock <jspurlock@google.com>2014-11-10 08:32:23 -0500
commitbb4a702e6fe44cb026097db13492f8345b38ee97 (patch)
treebd39584ed56730b3543a6d5ddd8a036a99d8391d /packages/SystemUI/src/com/android/systemui/volume
parentaed8e76172477c884ec7bef659f050d0817efb7d (diff)
downloadframeworks_base-bb4a702e6fe44cb026097db13492f8345b38ee97.zip
frameworks_base-bb4a702e6fe44cb026097db13492f8345b38ee97.tar.gz
frameworks_base-bb4a702e6fe44cb026097db13492f8345b38ee97.tar.bz2
Volume dialog: Add zen mode icons and notification access.
- Add icon above text to all three zen mode states, update text style. - Remove zentoast. - Update shared borderless rect background, masks now support shapes. - Update size of volume stream icons. - Ensure all volume icons are expressions of white. - Make volume icons testable via new demo mode command. - Add a divider + secondary icon to access the notification slider. - Animate the transition when accessing notification slider. Bug: 18206097 Bug: 16303068 Bug: 18102850 Change-Id: I5eb6f820dc317e89be272cc78f6c80ed969ad5e9
Diffstat (limited to 'packages/SystemUI/src/com/android/systemui/volume')
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeComponent.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java153
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/ZenToast.java163
6 files changed, 160 insertions, 189 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java b/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
index f7f5047..2f02f7c 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
@@ -17,7 +17,6 @@
package com.android.systemui.volume;
import android.content.Context;
-import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
@@ -30,8 +29,6 @@ import com.android.systemui.R;
import java.util.Objects;
public class SegmentedButtons extends LinearLayout {
- private static final Typeface MEDIUM = Typeface.create("sans-serif-medium", Typeface.NORMAL);
- private static final Typeface BOLD = Typeface.create("sans-serif", Typeface.BOLD);
private static final int LABEL_RES_KEY = R.id.label;
private final Context mContext;
@@ -63,15 +60,17 @@ public class SegmentedButtons extends LinearLayout {
final Object tag = c.getTag();
final boolean selected = Objects.equals(mSelectedValue, tag);
c.setSelected(selected);
- c.setTypeface(selected ? BOLD : MEDIUM);
+ c.getCompoundDrawables()[1].setTint(mContext.getResources().getColor(selected
+ ? R.color.segmented_button_selected : R.color.segmented_button_unselected));
}
fireOnSelected();
}
- public void addButton(int labelResId, Object value) {
+ public void addButton(int labelResId, int iconResId, Object value) {
final Button b = (Button) mInflater.inflate(R.layout.segmented_button, this, false);
b.setTag(LABEL_RES_KEY, labelResId);
b.setText(labelResId);
+ b.setCompoundDrawablesWithIntrinsicBounds(0, iconResId, 0, 0);
final LayoutParams lp = (LayoutParams) b.getLayoutParams();
if (getChildCount() == 0) {
lp.leftMargin = lp.rightMargin = 0; // first button has no margin
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeComponent.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeComponent.java
index 3c186c2..31adc95 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeComponent.java
@@ -16,8 +16,9 @@
package com.android.systemui.volume;
+import com.android.systemui.DemoMode;
import com.android.systemui.statusbar.policy.ZenModeController;
-public interface VolumeComponent {
+public interface VolumeComponent extends DemoMode {
ZenModeController getZenController();
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
index 360dee5..247cc51 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
@@ -16,6 +16,9 @@
package com.android.systemui.volume;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.BroadcastReceiver;
@@ -42,6 +45,8 @@ import android.media.VolumeProvider;
import android.media.session.MediaController;
import android.media.session.MediaController.PlaybackInfo;
import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.os.Message;
@@ -59,12 +64,15 @@ import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import com.android.internal.R;
+import com.android.systemui.DemoMode;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.statusbar.policy.ZenModeController;
@@ -76,7 +84,7 @@ import java.io.PrintWriter;
*
* @hide
*/
-public class VolumePanel extends Handler {
+public class VolumePanel extends Handler implements DemoMode {
private static final String TAG = "VolumePanel";
private static boolean LOGD = Log.isLoggable(TAG, Log.DEBUG);
@@ -129,6 +137,8 @@ public class VolumePanel extends Handler {
private static final int IC_AUDIO_VOL = com.android.systemui.R.drawable.ic_audio_vol;
private static final int IC_AUDIO_VOL_MUTE = com.android.systemui.R.drawable.ic_audio_vol_mute;
+ private static final int IC_AUDIO_BT = com.android.systemui.R.drawable.ic_audio_bt;
+ private static final int IC_AUDIO_BT_MUTE = com.android.systemui.R.drawable.ic_audio_bt_mute;
private final String mTag;
protected final Context mContext;
@@ -142,6 +152,7 @@ public class VolumePanel extends Handler {
private float mDisabledAlpha;
private int mLastRingerMode = AudioManager.RINGER_MODE_NORMAL;
private int mLastRingerProgress = 0;
+ private int mDemoIcon;
// True if we want to play tones on the system stream when the master stream is specified.
private final boolean mPlayMasterStreamTones;
@@ -166,12 +177,13 @@ public class VolumePanel extends Handler {
/** All the slider controls mapped by stream type */
private SparseArray<StreamControl> mStreamControls;
private final AccessibilityManager mAccessibilityManager;
+ private final SecondaryIconTransition mSecondaryIconTransition;
private enum StreamResources {
BluetoothSCOStream(AudioManager.STREAM_BLUETOOTH_SCO,
R.string.volume_icon_description_bluetooth,
- R.drawable.ic_audio_bt,
- R.drawable.ic_audio_bt,
+ IC_AUDIO_BT,
+ IC_AUDIO_BT_MUTE,
false),
RingerStream(AudioManager.STREAM_RING,
R.string.volume_icon_description_ringer,
@@ -180,8 +192,8 @@ public class VolumePanel extends Handler {
false),
VoiceStream(AudioManager.STREAM_VOICE_CALL,
R.string.volume_icon_description_incall,
- R.drawable.ic_audio_phone,
- R.drawable.ic_audio_phone,
+ com.android.systemui.R.drawable.ic_audio_phone,
+ com.android.systemui.R.drawable.ic_audio_phone,
false),
AlarmStream(AudioManager.STREAM_ALARM,
R.string.volume_alarm,
@@ -246,6 +258,8 @@ public class VolumePanel extends Handler {
ImageView icon;
SeekBar seekbarView;
TextView suppressorView;
+ View divider;
+ ImageView secondaryIcon;
int iconRes;
int iconMuteRes;
int iconSuppressedRes;
@@ -339,6 +353,7 @@ public class VolumePanel extends Handler {
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
mAccessibilityManager = (AccessibilityManager) context.getSystemService(
Context.ACCESSIBILITY_SERVICE);
+ mSecondaryIconTransition = new SecondaryIconTransition();
// For now, only show master volume if master volume is supported
final Resources res = context.getResources();
@@ -381,6 +396,8 @@ public class VolumePanel extends Handler {
mActiveStreamType = -1;
mAudioManager.forceVolumeControlStream(mActiveStreamType);
setZenPanelVisible(false);
+ mDemoIcon = 0;
+ mSecondaryIconTransition.cancel();
}
});
@@ -604,10 +621,12 @@ public class VolumePanel extends Handler {
mStreamControls = new SparseArray<StreamControl>(STREAMS.length);
+ final StreamResources notificationStream = StreamResources.NotificationStream;
for (int i = 0; i < STREAMS.length; i++) {
StreamResources streamRes = STREAMS[i];
final int streamType = streamRes.streamType;
+ final boolean isNotification = isNotificationOrRing(streamType);
final StreamControl sc = new StreamControl();
sc.streamType = streamType;
@@ -620,8 +639,8 @@ public class VolumePanel extends Handler {
sc.iconRes = streamRes.iconRes;
sc.iconMuteRes = streamRes.iconMuteRes;
sc.icon.setImageResource(sc.iconRes);
- sc.icon.setClickable(isNotificationOrRing(streamType));
- if (sc.icon.isClickable()) {
+ sc.icon.setClickable(isNotification);
+ if (isNotification) {
sc.icon.setSoundEffectsEnabled(false);
sc.icon.setOnClickListener(new OnClickListener() {
@Override
@@ -636,6 +655,23 @@ public class VolumePanel extends Handler {
sc.suppressorView =
(TextView) sc.group.findViewById(com.android.systemui.R.id.suppressor);
sc.suppressorView.setVisibility(View.GONE);
+ final boolean showSecondary = !isNotification && notificationStream.show;
+ sc.divider = sc.group.findViewById(com.android.systemui.R.id.divider);
+ sc.secondaryIcon = (ImageView) sc.group
+ .findViewById(com.android.systemui.R.id.secondary_icon);
+ sc.secondaryIcon.setImageResource(com.android.systemui.R.drawable.ic_ringer_audible);
+ sc.secondaryIcon.setContentDescription(res.getString(notificationStream.descRes));
+ sc.secondaryIcon.setClickable(showSecondary);
+ sc.divider.setVisibility(showSecondary ? View.VISIBLE : View.GONE);
+ sc.secondaryIcon.setVisibility(showSecondary ? View.VISIBLE : View.GONE);
+ if (showSecondary) {
+ sc.secondaryIcon.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mSecondaryIconTransition.start(sc);
+ }
+ });
+ }
final int plusOne = (streamType == AudioSystem.STREAM_BLUETOOTH_SCO ||
streamType == AudioSystem.STREAM_VOICE_CALL) ? 1 : 0;
sc.seekbarView.setMax(getStreamMaxVolume(streamType) + plusOne);
@@ -696,7 +732,7 @@ public class VolumePanel extends Handler {
}
muted = ringerMode == AudioManager.RINGER_MODE_VIBRATE;
}
- sc.icon.setImageResource(muted ? sc.iconMuteRes : sc.iconRes);
+ sc.icon.setImageResource(mDemoIcon != 0 ? mDemoIcon : muted ? sc.iconMuteRes : sc.iconRes);
}
private void updateSliderSupressor(StreamControl sc) {
@@ -800,7 +836,8 @@ public class VolumePanel extends Handler {
}
private void updateTimeoutDelay() {
- mTimeoutDelay = sSafetyWarning != null ? TIMEOUT_DELAY_SAFETY_WARNING
+ mTimeoutDelay = mDemoIcon != 0 ? TIMEOUT_DELAY_EXPANDED
+ : sSafetyWarning != null ? TIMEOUT_DELAY_SAFETY_WARNING
: mActiveStreamType == AudioManager.STREAM_MUSIC ? TIMEOUT_DELAY_SHORT
: mZenPanelExpanded ? TIMEOUT_DELAY_EXPANDED
: isZenPanelVisible() ? TIMEOUT_DELAY_COLLAPSED
@@ -995,7 +1032,7 @@ public class VolumePanel extends Handler {
(AudioManager.DEVICE_OUT_BLUETOOTH_A2DP |
AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)) != 0) {
- setMusicIcon(R.drawable.ic_audio_bt, R.drawable.ic_audio_bt_mute);
+ setMusicIcon(IC_AUDIO_BT, IC_AUDIO_BT_MUTE);
} else {
setMusicIcon(IC_AUDIO_VOL, IC_AUDIO_VOL_MUTE);
}
@@ -1075,6 +1112,12 @@ public class VolumePanel extends Handler {
updateSliderProgress(sc, index);
updateSliderEnabled(sc, isMuted(streamType),
(flags & AudioManager.FLAG_FIXED_VOLUME) != 0);
+ // check for secondary-icon transition completion
+ if (isNotificationOrRing(streamType) && mSecondaryIconTransition.isRunning()) {
+ mSecondaryIconTransition.cancel(); // safe to reset
+ sc.seekbarView.setAlpha(0); sc.seekbarView.animate().alpha(1);
+ mZenPanel.setAlpha(0); mZenPanel.animate().alpha(1);
+ }
}
if (!isShowing()) {
@@ -1406,6 +1449,22 @@ public class VolumePanel extends Handler {
return mZenController;
}
+ @Override
+ public void dispatchDemoCommand(String command, Bundle args) {
+ if (!COMMAND_VOLUME.equals(command)) return;
+ String icon = args.getString("icon");
+ final String iconMute = args.getString("iconmute");
+ final boolean mute = iconMute != null;
+ icon = mute ? iconMute : icon;
+ icon = icon.endsWith("Stream") ? icon : (icon + "Stream");
+ final StreamResources sr = StreamResources.valueOf(icon);
+ mDemoIcon = mute ? sr.iconMuteRes : sr.iconRes;
+ final int forcedStreamType = StreamResources.MediaStream.streamType;
+ mAudioManager.forceVolumeControlStream(forcedStreamType);
+ mAudioManager.adjustStreamVolume(forcedStreamType, AudioManager.ADJUST_SAME,
+ AudioManager.FLAG_SHOW_UI);
+ }
+
private final OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
@@ -1445,6 +1504,80 @@ public class VolumePanel extends Handler {
}
};
+ private final class SecondaryIconTransition extends AnimatorListenerAdapter
+ implements Runnable {
+ private static final int ANIMATION_TIME = 400;
+ private static final int WAIT_FOR_SWITCH_TIME = 1000;
+
+ private final int mAnimationTime = (int)(ANIMATION_TIME * ValueAnimator.getDurationScale());
+ private final int mFadeOutTime = mAnimationTime / 2;
+ private final int mDelayTime = mAnimationTime / 3;
+
+ private final Interpolator mIconInterpolator =
+ AnimationUtils.loadInterpolator(mContext, android.R.interpolator.fast_out_slow_in);
+
+ private StreamControl mTarget;
+
+ public void start(StreamControl sc) {
+ if (sc == null) throw new IllegalArgumentException();
+ if (mTarget != null) {
+ cancel();
+ }
+ mTarget = sc;
+ mTimeoutDelay = mAnimationTime + WAIT_FOR_SWITCH_TIME;
+ resetTimeout();
+ mTarget.secondaryIcon.setClickable(false);
+ final int N = mTarget.group.getChildCount();
+ for (int i = 0; i < N; i++) {
+ final View child = mTarget.group.getChildAt(i);
+ if (child != mTarget.secondaryIcon) {
+ child.animate().alpha(0).setDuration(mFadeOutTime).start();
+ }
+ }
+ mTarget.secondaryIcon.animate()
+ .translationXBy(mTarget.icon.getX() - mTarget.secondaryIcon.getX())
+ .setInterpolator(mIconInterpolator)
+ .setStartDelay(mDelayTime)
+ .setDuration(mAnimationTime - mDelayTime)
+ .setListener(this)
+ .start();
+ }
+
+ public boolean isRunning() {
+ return mTarget != null;
+ }
+
+ public void cancel() {
+ if (mTarget == null) return;
+ mTarget.secondaryIcon.setClickable(true);
+ final int N = mTarget.group.getChildCount();
+ for (int i = 0; i < N; i++) {
+ final View child = mTarget.group.getChildAt(i);
+ if (child != mTarget.secondaryIcon) {
+ child.animate().cancel();
+ child.setAlpha(1);
+ }
+ }
+ mTarget.secondaryIcon.animate().cancel();
+ mTarget.secondaryIcon.setTranslationX(0);
+ mTarget = null;
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (mTarget == null) return;
+ AsyncTask.execute(this);
+ }
+
+ @Override
+ public void run() {
+ if (mTarget == null) return;
+ mAudioManager.forceVolumeControlStream(StreamResources.NotificationStream.streamType);
+ mAudioManager.adjustStreamVolume(StreamResources.NotificationStream.streamType,
+ AudioManager.ADJUST_SAME, AudioManager.FLAG_SHOW_UI);
+ }
+ }
+
public interface Callback {
void onZenSettings();
void onInteraction();
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
index 0fe6d89..5232a17 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
@@ -10,6 +10,7 @@ import android.media.session.ISessionController;
import android.media.session.MediaController;
import android.media.session.MediaSessionManager;
import android.net.Uri;
+import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
import android.provider.Settings;
@@ -184,6 +185,11 @@ public class VolumeUI extends SystemUI {
public ZenModeController getZenController() {
return mPanel.getZenController();
}
+
+ @Override
+ public void dispatchDemoCommand(String command, Bundle args) {
+ mPanel.dispatchDemoCommand(command, args);
+ }
}
private final class RemoteVolumeController extends IRemoteVolumeController.Stub {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index 28ecbf9..b325653 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -80,7 +80,6 @@ public class ZenModePanel extends LinearLayout {
private final Interpolator mFastOutSlowInInterpolator;
private final int mSubheadWarningColor;
private final int mSubheadColor;
- private final ZenToast mZenToast;
private String mTag = TAG + "/" + Integer.toHexString(System.identityHashCode(this));
@@ -115,7 +114,6 @@ public class ZenModePanel extends LinearLayout {
final Resources res = mContext.getResources();
mSubheadWarningColor = res.getColor(R.color.system_warning_color);
mSubheadColor = res.getColor(R.color.qs_subhead);
- mZenToast = new ZenToast(mContext);
if (DEBUG) Log.d(mTag, "new ZenModePanel");
}
@@ -124,10 +122,12 @@ public class ZenModePanel extends LinearLayout {
super.onFinishInflate();
mZenButtons = (SegmentedButtons) findViewById(R.id.zen_buttons);
- mZenButtons.addButton(R.string.interruption_level_none, Global.ZEN_MODE_NO_INTERRUPTIONS);
- mZenButtons.addButton(R.string.interruption_level_priority,
+ mZenButtons.addButton(R.string.interruption_level_none, R.drawable.ic_zen_none,
+ Global.ZEN_MODE_NO_INTERRUPTIONS);
+ mZenButtons.addButton(R.string.interruption_level_priority, R.drawable.ic_zen_important,
Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
- mZenButtons.addButton(R.string.interruption_level_all, Global.ZEN_MODE_OFF);
+ mZenButtons.addButton(R.string.interruption_level_all, R.drawable.ic_zen_all,
+ Global.ZEN_MODE_OFF);
mZenButtons.setCallback(mZenButtonsCallback);
mZenSubhead = findViewById(R.id.zen_subhead);
@@ -160,7 +160,6 @@ public class ZenModePanel extends LinearLayout {
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (DEBUG) Log.d(mTag, "onAttachedToWindow");
- mZenToast.hide();
mAttachedZen = getSelectedZen(-1);
mSessionZen = mAttachedZen;
mSessionExitCondition = copy(mExitCondition);
@@ -193,10 +192,6 @@ public class ZenModePanel extends LinearLayout {
if (selectedZen == Global.ZEN_MODE_NO_INTERRUPTIONS) {
mPrefs.trackNoneSelected();
}
- if (selectedZen == Global.ZEN_MODE_NO_INTERRUPTIONS
- || selectedZen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
- mZenToast.show(selectedZen);
- }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenToast.java b/packages/SystemUI/src/com/android/systemui/volume/ZenToast.java
deleted file mode 100644
index d887712..0000000
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenToast.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2014 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.volume;
-
-import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
-import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.graphics.PixelFormat;
-import android.os.Handler;
-import android.os.Message;
-import android.os.UserHandle;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnAttachStateChangeListener;
-import android.view.WindowManager;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.android.systemui.R;
-
-public class ZenToast {
- private static final String ACTION_SHOW = ZenToast.class.getName() + ".SHOW";
- private static final String ACTION_HIDE = ZenToast.class.getName() + ".HIDE";
- private static final String EXTRA_ZEN = "zen";
- private static final String EXTRA_TEXT = "text";
-
- private static final int MSG_SHOW = 1;
- private static final int MSG_HIDE = 2;
-
- private final Context mContext;
- private final WindowManager mWindowManager;
-
- private View mZenToast;
-
- public ZenToast(Context context) {
- mContext = context;
- mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
- final IntentFilter filter = new IntentFilter();
- filter.addAction(ACTION_SHOW);
- filter.addAction(ACTION_HIDE);
- mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler);
- }
-
- public void show(int zen) {
- mHandler.removeMessages(MSG_HIDE);
- mHandler.removeMessages(MSG_SHOW);
- mHandler.obtainMessage(MSG_SHOW, zen, 0).sendToTarget();
- }
-
- public void hide() {
- mHandler.removeMessages(MSG_HIDE);
- mHandler.removeMessages(MSG_SHOW);
- mHandler.obtainMessage(MSG_HIDE).sendToTarget();
- }
-
- private void handleShow(int zen, String overrideText) {
- handleHide();
-
- String text;
- final int iconRes;
- switch (zen) {
- case ZEN_MODE_NO_INTERRUPTIONS:
- text = mContext.getString(R.string.zen_no_interruptions);
- iconRes = R.drawable.ic_zen_none;
- break;
- case ZEN_MODE_IMPORTANT_INTERRUPTIONS:
- text = mContext.getString(R.string.zen_important_interruptions);
- iconRes = R.drawable.ic_zen_important;
- break;
- default:
- return;
- }
- if (overrideText != null) {
- text = overrideText;
- }
- final Resources res = mContext.getResources();
- final WindowManager.LayoutParams params = new WindowManager.LayoutParams();
- params.height = WindowManager.LayoutParams.WRAP_CONTENT;
- params.width = res.getDimensionPixelSize(R.dimen.zen_toast_width);
- params.format = PixelFormat.TRANSLUCENT;
- params.windowAnimations = R.style.ZenToastAnimations;
- params.type = WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
- params.setTitle(getClass().getSimpleName());
- params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
- | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
- params.gravity = Gravity.CENTER;
- params.packageName = mContext.getPackageName();
- mZenToast = LayoutInflater.from(mContext).inflate(R.layout.zen_toast, null);
- final TextView message = (TextView) mZenToast.findViewById(android.R.id.message);
- message.setText(text);
- final ImageView icon = (ImageView) mZenToast.findViewById(android.R.id.icon);
- icon.setImageResource(iconRes);
- mZenToast.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
- @Override
- public void onViewDetachedFromWindow(View v) {
- // noop
- }
-
- @Override
- public void onViewAttachedToWindow(View v) {
- mZenToast.announceForAccessibility(message.getText());
- }
- });
- mWindowManager.addView(mZenToast, params);
- final int animDuration = res.getInteger(R.integer.zen_toast_animation_duration);
- final int visibleDuration = res.getInteger(R.integer.zen_toast_visible_duration);
- mHandler.sendEmptyMessageDelayed(MSG_HIDE, animDuration + visibleDuration);
- }
-
- private void handleHide() {
- if (mZenToast != null) {
- mWindowManager.removeView(mZenToast);
- mZenToast = null;
- }
- }
-
- private final Handler mHandler = new Handler() {
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_SHOW:
- handleShow(msg.arg1, null);
- break;
- case MSG_HIDE:
- handleHide();
- break;
- }
- }
- };
-
- private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (ACTION_SHOW.equals(intent.getAction())) {
- final int zen = intent.getIntExtra(EXTRA_ZEN, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
- final String text = intent.getStringExtra(EXTRA_TEXT);
- handleShow(zen, text);
- } else if (ACTION_HIDE.equals(intent.getAction())) {
- handleHide();
- }
- }
- };
-}