diff options
author | John Spurlock <jspurlock@google.com> | 2014-03-12 14:54:28 -0400 |
---|---|---|
committer | John Spurlock <jspurlock@google.com> | 2014-03-12 17:26:09 -0400 |
commit | d389ff7d8930473cead3bd1b7b63c2fe5f6b51f1 (patch) | |
tree | c348eb95932c1cf851b8409740e893d389d4da4f /packages/SystemUI | |
parent | 5c719495724987a405e29b1623dfe613e9a4cdf5 (diff) | |
download | frameworks_base-d389ff7d8930473cead3bd1b7b63c2fe5f6b51f1.zip frameworks_base-d389ff7d8930473cead3bd1b7b63c2fe5f6b51f1.tar.gz frameworks_base-d389ff7d8930473cead3bd1b7b63c2fe5f6b51f1.tar.bz2 |
Move zen-mode systemui affordance to quick settings.
Remove the gesture-based invocation from the notifcation
panel, create a new QS tile to display current state.
Clicking the tile reveals an interstitial dialog for
confirmation of mode changes.
Change-Id: I6760ce3f097d5dcfd0af5177287dbf4ff632b47e
Diffstat (limited to 'packages/SystemUI')
8 files changed, 255 insertions, 412 deletions
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml index 56c1f4e..1693e01 100644 --- a/packages/SystemUI/res/layout/status_bar_expanded.xml +++ b/packages/SystemUI/res/layout/status_bar_expanded.xml @@ -58,12 +58,6 @@ android:layout_height="@dimen/notification_panel_header_height" /> - <com.android.systemui.statusbar.phone.ZenModeView - android:id="@+id/zenmode" - android:layout_width="match_parent" - android:layout_height="wrap_content" - /> - <TextView android:id="@+id/emergency_calls_only" android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Network.EmergencyOnly" diff --git a/packages/SystemUI/res/layout/status_bar_expanded_header.xml b/packages/SystemUI/res/layout/status_bar_expanded_header.xml index 25c516b..9aa7cfd 100644 --- a/packages/SystemUI/res/layout/status_bar_expanded_header.xml +++ b/packages/SystemUI/res/layout/status_bar_expanded_header.xml @@ -15,7 +15,7 @@ ** limitations under the License. --> -<com.android.systemui.statusbar.phone.PanelHeaderView +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui" android:id="@+id/header" @@ -106,4 +106,4 @@ android:contentDescription="@string/accessibility_notifications_button" /> </FrameLayout> -</com.android.systemui.statusbar.phone.PanelHeaderView> +</LinearLayout> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java index 237b7f7..6be6d4d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -20,7 +20,6 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.drawable.Drawable; -import android.provider.Settings; import android.util.AttributeSet; import android.util.EventLog; import android.view.MotionEvent; @@ -57,17 +56,6 @@ public class NotificationPanelView extends PanelView { mHandleBar = resources.getDrawable(R.drawable.status_bar_close); mHandleBarHeight = resources.getDimensionPixelSize(R.dimen.close_handle_height); mHandleView = findViewById(R.id.handle); - PanelHeaderView header = (PanelHeaderView) findViewById(R.id.header); - ZenModeView zenModeView = (ZenModeView) findViewById(R.id.zenmode); - zenModeView.setAdapter(new ZenModeViewAdapter(mContext) { - @Override - public void configure() { - if (mStatusBar != null) { - mStatusBar.startSettingsActivity(Settings.ACTION_ZEN_MODE_SETTINGS); - } - } - }); - header.setZenModeView(zenModeView); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelHeaderView.java deleted file mode 100644 index a28324d..0000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelHeaderView.java +++ /dev/null @@ -1,70 +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.statusbar.phone; - -import android.content.Context; -import android.util.AttributeSet; -import android.util.Log; -import android.view.MotionEvent; -import android.widget.LinearLayout; - -public class PanelHeaderView extends LinearLayout { - private static final String TAG = "PanelHeaderView"; - private static final boolean DEBUG = false; - - private ZenModeView mZenModeView; - - public PanelHeaderView(Context context) { - super(context); - } - - public PanelHeaderView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public void setZenModeView(ZenModeView zmv) { - mZenModeView = zmv; - } - - @Override - public boolean dispatchTouchEvent(MotionEvent ev) { - final boolean rt = super.dispatchTouchEvent(ev); - if (DEBUG) logTouchEvent("dispatchTouchEvent", rt, ev); - if (mZenModeView != null) { - mZenModeView.dispatchExternalTouchEvent(ev); - } - return rt; - } - - @Override - public boolean onInterceptTouchEvent(MotionEvent ev) { - final boolean rt = super.onInterceptTouchEvent(ev); - if (DEBUG) logTouchEvent("onInterceptTouchEvent", rt, ev); - return rt; - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - boolean rt = super.onTouchEvent(event); - if (DEBUG) logTouchEvent("onTouchEvent", rt, event); - return true; - } - - private void logTouchEvent(String method, boolean rt, MotionEvent ev) { - Log.d(TAG, method + " " + (rt ? "TRUE" : "FALSE") + " " + ev); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java index c1c8946..8170b5a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java @@ -52,13 +52,16 @@ import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.Profile; import android.provider.Settings; import android.security.KeyChain; +import android.text.TextUtils.TruncateAt; import android.util.Log; import android.util.Pair; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.Window; import android.view.WindowManager; import android.view.WindowManagerGlobal; +import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; @@ -586,6 +589,31 @@ class QuickSettings { }); parent.addView(airplaneTile); + // Zen Mode + final QuickSettingsBasicTile zenModeTile = new QuickSettingsBasicTile(mContext); + zenModeTile.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + showZenModeDialog(); + } + }); + mModel.addZenModeTile(zenModeTile, new QuickSettingsModel.RefreshCallback() { + @Override + public void refreshView(QuickSettingsTileView unused, State state) { + zenModeTile.setImageResource(state.iconId); + // TODO cut new assets + zenModeTile.getImageView().setAlpha(state.enabled ? 1 : .2f); + zenModeTile.getImageView().setScaleX(1.5f); + zenModeTile.getImageView().setScaleY(1.5f); + // for landscape version + zenModeTile.getTextView().setMaxLines(2); + zenModeTile.getTextView().setEllipsize(TruncateAt.END); + // TODO content description + zenModeTile.setText(state.label); + } + }); + parent.addView(zenModeTile); + // Bluetooth if (mModel.deviceSupportsBluetooth() || DEBUG_GONE_TILES) { @@ -864,6 +892,31 @@ class QuickSettings { dialog.show(); } + private void showZenModeDialog() { + final Dialog d = new Dialog(mContext); + d.requestWindowFeature(Window.FEATURE_NO_TITLE); + d.setCancelable(true); + d.setCanceledOnTouchOutside(true); + final ZenModeView v = new ZenModeView(mContext); + v.setAdapter(new ZenModeViewAdapter(mContext) { + @Override + public void configure() { + if (mStatusBarService != null) { + mStatusBarService.startSettingsActivity(Settings.ACTION_ZEN_MODE_SETTINGS); + } + d.dismiss(); + } + @Override + public void close() { + d.dismiss(); + } + }); + d.setContentView(v); + d.create(); + d.getWindow().setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY); + d.show(); + } + private void applyBluetoothStatus() { mModel.onBluetoothStateChange(mBluetoothState); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java index 174cad8..c3c281c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java @@ -38,6 +38,7 @@ import android.provider.Settings.SettingNotFoundException; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; +import android.view.WindowManager; import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodSubtype; @@ -112,6 +113,9 @@ class QuickSettingsModel implements BluetoothStateChangeCallback, public static class RotationLockState extends State { boolean visible = false; } + public static class ZenModeState extends State { + int zenMode = Settings.Global.ZEN_MODE_OFF; + } /** The callback to update a given tile. */ interface RefreshCallback { @@ -294,6 +298,25 @@ class QuickSettingsModel implements BluetoothStateChangeCallback, } } + /** ContentObserver to watch display color space adjustment */ + private class ZenModeObserver extends ContentObserver { + public ZenModeObserver(Handler handler) { + super(handler); + } + + @Override + public void onChange(boolean selfChange) { + onZenModeChanged(); + } + + public void startObserving() { + final ContentResolver cr = mContext.getContentResolver(); + cr.unregisterContentObserver(this); + cr.registerContentObserver( + Settings.Global.getUriFor(Settings.Global.ZEN_MODE), false, this); + } + } + /** Callback for changes to remote display routes. */ private class RemoteDisplayRouteCallback extends MediaRouter.SimpleCallback { @Override @@ -327,6 +350,7 @@ class QuickSettingsModel implements BluetoothStateChangeCallback, private final DisplayInversionObserver mInversionObserver; private final DisplayContrastObserver mContrastObserver; private final DisplayColorSpaceObserver mColorSpaceObserver; + private final ZenModeObserver mZenModeObserver; private final MediaRouter mMediaRouter; private final RemoteDisplayRouteCallback mRemoteDisplayRouteCallback; @@ -349,6 +373,10 @@ class QuickSettingsModel implements BluetoothStateChangeCallback, private RefreshCallback mAirplaneModeCallback; private State mAirplaneModeState = new State(); + private QuickSettingsTileView mZenModeTile; + private RefreshCallback mZenModeCallback; + private ZenModeState mZenModeState = new ZenModeState(); + private QuickSettingsTileView mWifiTile; private RefreshCallback mWifiCallback; private WifiState mWifiState = new WifiState(); @@ -445,6 +473,8 @@ class QuickSettingsModel implements BluetoothStateChangeCallback, mContrastObserver.startObserving(); mColorSpaceObserver = new DisplayColorSpaceObserver(mHandler); mColorSpaceObserver.startObserving(); + mZenModeObserver = new ZenModeObserver(mHandler); + mZenModeObserver.startObserving(); mMediaRouter = (MediaRouter)context.getSystemService(Context.MEDIA_ROUTER_SERVICE); rebindMediaRouterAsCurrentUser(); @@ -567,6 +597,30 @@ class QuickSettingsModel implements BluetoothStateChangeCallback, mAirplaneModeCallback.refreshView(mAirplaneModeTile, mAirplaneModeState); } + // Zen Mode + void addZenModeTile(QuickSettingsTileView view, RefreshCallback cb) { + mZenModeTile = view; + mZenModeCallback = cb; + onZenModeChanged(); + } + private void onZenModeChanged() { + final int mode = Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF); + mZenModeState.enabled = mode != Settings.Global.ZEN_MODE_OFF; + mZenModeState.zenMode = mode; + if (mode == Settings.Global.ZEN_MODE_FULL) { + mZenModeState.iconId = R.drawable.stat_sys_zen_full; + mZenModeState.label = ZenModeView.modeToLabel(ZenModeView.Adapter.MODE_FULL); + } else if (mode == Settings.Global.ZEN_MODE_LIMITED) { + mZenModeState.iconId = R.drawable.stat_sys_zen_limited; + mZenModeState.label = ZenModeView.modeToLabel(ZenModeView.Adapter.MODE_LIMITED); + } else { + mZenModeState.iconId = R.drawable.stat_sys_zen_limited; + mZenModeState.label = ZenModeView.modeToLabel(ZenModeView.Adapter.MODE_LIMITED); + } + mZenModeCallback.refreshView(mZenModeTile, mZenModeState); + } + // Wifi void addWifiTile(QuickSettingsTileView view, RefreshCallback cb) { mWifiTile = view; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeView.java index fa7f96a..d1c7a41 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeView.java @@ -19,22 +19,16 @@ package com.android.systemui.statusbar.phone; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; -import android.animation.ValueAnimator.AnimatorUpdateListener; import android.content.Context; -import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; -import android.graphics.Rect; import android.graphics.Typeface; import android.graphics.drawable.ShapeDrawable; import android.graphics.drawable.shapes.PathShape; -import android.os.AsyncTask; -import android.os.Vibrator; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.TextPaint; import android.text.method.LinkMovementMethod; -import android.text.style.RelativeSizeSpan; import android.text.style.URLSpan; import android.util.AttributeSet; import android.util.Log; @@ -62,7 +56,7 @@ public class ZenModeView extends RelativeLayout { private static final Typeface CONDENSED = Typeface.create("sans-serif-condensed", Typeface.NORMAL); private static final int GRAY = 0xff999999; //TextAppearance.StatusBar.Expanded.Network - private static final int BACKGROUND = 0xff1d3741; //0x3333b5e5; + private static final int BACKGROUND = 0xff282828; private static final long DURATION = new ValueAnimator().getDuration(); private static final long BOUNCE_DURATION = DURATION / 3; private static final float BOUNCE_SCALE = 0.8f; @@ -73,23 +67,14 @@ public class ZenModeView extends RelativeLayout { private final Context mContext; private final Paint mPathPaint; - private final TextView mHintText; - private final ModeSpinner mModeSpinner; - private final ImageView mCloseButton; private final ImageView mSettingsButton; - private final Rect mLayoutRect = new Rect(); + private final ModeSpinner mModeSpinner; + private final TextView mActionButton; + private final View mDivider; private final UntilPager mUntilPager; private final AlarmWarning mAlarmWarning; - private final int mPopDuration; - - private float mDownY; - private int mDownBottom; - private boolean mPeekable = true; - private boolean mClosing; - private int mBottom; - private int mWidthSpec; + private Adapter mAdapter; - private boolean mPopped; public ZenModeView(Context context) { this(context, null); @@ -100,34 +85,22 @@ public class ZenModeView extends RelativeLayout { if (DEBUG) log("new %s()", getClass().getSimpleName()); mContext = context; - mPathPaint = new Paint(Paint.ANTI_ALIAS_FLAG); - mPathPaint.setStyle(Paint.Style.STROKE); - mPathPaint.setColor(GRAY); - mPathPaint.setStrokeWidth(5); - final int iconSize = mContext.getResources() .getDimensionPixelSize(com.android.internal.R.dimen.notification_large_icon_width); final int topRowSize = iconSize * 2 / 3; + final int p = topRowSize / 7; - mCloseButton = new ImageView(mContext); - mCloseButton.setAlpha(0f); - mCloseButton.setImageDrawable(sd(closePath(topRowSize), topRowSize, mPathPaint)); - addView(mCloseButton, new LayoutParams(topRowSize, topRowSize)); - mCloseButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - bounce(v, null); - close(); - } - }); + mPathPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + mPathPaint.setStyle(Paint.Style.STROKE); + mPathPaint.setColor(GRAY); + mPathPaint.setStrokeWidth(p / 2); mSettingsButton = new ImageView(mContext); - mSettingsButton.setAlpha(0f); - final int p = topRowSize / 7; mSettingsButton.setPadding(p, p, p, p); mSettingsButton.setImageResource(R.drawable.ic_notify_settings_normal); LayoutParams lp = new LayoutParams(topRowSize, topRowSize); - lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); + lp.topMargin = p; + lp.leftMargin = p; addView(mSettingsButton, lp); mSettingsButton.setOnClickListener(new View.OnClickListener() { @Override @@ -140,65 +113,65 @@ public class ZenModeView extends RelativeLayout { }); mModeSpinner = new ModeSpinner(mContext); - mModeSpinner.setAlpha(0); - mModeSpinner.setEnabled(false); mModeSpinner.setId(android.R.id.title); lp = new LayoutParams(LayoutParams.WRAP_CONTENT, topRowSize); - lp.addRule(RelativeLayout.CENTER_HORIZONTAL); + lp.topMargin = p; + lp.addRule(CENTER_HORIZONTAL); addView(mModeSpinner, lp); - mUntilPager = new UntilPager(mContext, mPathPaint, iconSize); + mActionButton = new TextView(mContext); + mActionButton.setTextColor(GRAY); + mActionButton.setTypeface(CONDENSED); + mActionButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, mActionButton.getTextSize() * 1.2f); + mActionButton.setAllCaps(true); + mActionButton.setGravity(Gravity.CENTER); + mActionButton.setPadding(p, 0, p * 2, 0); + lp = new LayoutParams(LayoutParams.WRAP_CONTENT, topRowSize); + lp.topMargin = p; + lp.addRule(ALIGN_PARENT_RIGHT); + lp.addRule(ALIGN_BASELINE, mModeSpinner.getId()); + addView(mActionButton, lp); + mActionButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + bounce(v, null); + beginOrEnd(); + } + }); + + mDivider = new View(mContext); + mDivider.setId(android.R.id.empty); + mDivider.setBackgroundColor(GRAY); + lp = new LayoutParams(LayoutParams.MATCH_PARENT, 2); + lp.addRule(BELOW, mModeSpinner.getId()); + lp.topMargin = p; + lp.bottomMargin = p; + addView(mDivider, lp); + + mUntilPager = new UntilPager(mContext, mPathPaint, iconSize * 3 / 4); mUntilPager.setId(android.R.id.tabhost); - mUntilPager.setAlpha(0); lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); - lp.addRule(BELOW, mModeSpinner.getId()); + lp.addRule(BELOW, mDivider.getId()); addView(mUntilPager, lp); mAlarmWarning = new AlarmWarning(mContext); - mAlarmWarning.setAlpha(0); lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); lp.addRule(CENTER_HORIZONTAL); lp.addRule(BELOW, mUntilPager.getId()); + lp.bottomMargin = p; addView(mAlarmWarning, lp); - - mHintText = new TextView(mContext); - mHintText.setTypeface(CONDENSED); - mHintText.setText("Swipe down for Limited Interruptions"); - mHintText.setGravity(Gravity.CENTER); - mHintText.setTextColor(GRAY); - addView(mHintText, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); - - mPopDuration = mContext.getResources().getInteger(R.integer.blinds_pop_duration_ms); - } - - private boolean isApplicable() { - return mAdapter != null && mAdapter.isApplicable(); } - private void close() { - mClosing = true; - final int startBottom = mBottom; - final int max = mPeekable ? getExpandedBottom() : startBottom; - mHintText.animate().alpha(1).setUpdateListener(new AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - final float f = animation.getAnimatedFraction(); - final int hintBottom = mHintText.getBottom(); - final boolean isDone = f == 1; - setPeeked(hintBottom + (int)((1-f) * (startBottom - hintBottom)), max, isDone); - if (isDone) { - mPeekable = true; - mPopped = false; - mClosing = false; - mModeSpinner.updateState(); - if (mAdapter != null) { - mAdapter.cancel(); - } - } - } - }).start(); - mUntilPager.animate().alpha(0).start(); - mAlarmWarning.animate().alpha(0).start(); + private void beginOrEnd() { + if (mAdapter == null) return; + if (mAdapter.getMode() == mAdapter.getCommittedMode()) { + // end + mAdapter.setCommittedMode(Adapter.MODE_OFF); + } else { + // begin + mAdapter.setCommittedMode(mAdapter.getMode()); + } + mAdapter.close(); } public void setAdapter(Adapter adapter) { @@ -218,180 +191,41 @@ public class ZenModeView extends RelativeLayout { } private void updateState(boolean animate) { - final boolean applicable = isApplicable(); - setVisibility(applicable ? VISIBLE : GONE); - if (!applicable) { - return; - } - if (mAdapter != null && mAdapter.getMode() == Adapter.MODE_OFF && !mPeekable) { - close(); - } else { - mModeSpinner.updateState(); - mUntilPager.updateState(); - mAlarmWarning.updateState(animate); - final float settingsAlpha = getSettingsButtonAlpha(); - if (settingsAlpha != mSettingsButton.getAlpha()) { - if (animate) { - mSettingsButton.animate().alpha(settingsAlpha).start(); - } else { - mSettingsButton.setAlpha(settingsAlpha); - } - } - if (mPeekable && mAdapter != null && mAdapter.getMode() != Adapter.MODE_OFF) { - if (DEBUG) log("panic expand!"); - mPeekable = false; - mModeSpinner.setEnabled(true); - mBottom = getExpandedBottom(); - setExpanded(1); + mModeSpinner.updateState(); + mUntilPager.updateState(); + mAlarmWarning.updateState(animate); + final float settingsAlpha = isFull() ? 0 : SETTINGS_ALPHA; + if (settingsAlpha != mSettingsButton.getAlpha()) { + if (animate) { + mSettingsButton.animate().alpha(settingsAlpha).start(); + } else { + mSettingsButton.setAlpha(settingsAlpha); } } + final boolean committed = mAdapter != null + && mAdapter.getMode() == mAdapter.getCommittedMode(); + mActionButton.setText(committed ? "End" : "Begin"); } - private float getSettingsButtonAlpha() { - final boolean full = mAdapter != null && mAdapter.getMode() == Adapter.MODE_FULL; - final boolean collapsed = mHintText.getAlpha() == 1; - return full || collapsed ? 0 : SETTINGS_ALPHA; - } - - private static Path closePath(int size) { - final int pad = size / 4; - final Path p = new Path(); - p.moveTo(pad, pad); - p.lineTo(size - pad, size - pad); - p.moveTo(size - pad, pad); - p.lineTo(pad, size - pad); - return p; + private boolean isFull() { + return mAdapter != null && mAdapter.getMode() == Adapter.MODE_FULL; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (DEBUG) log("onMeasure %s %s", MeasureSpec.toString(widthMeasureSpec), MeasureSpec.toString(heightMeasureSpec)); - final boolean widthExact = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY; - - if (!widthExact || (widthMeasureSpec != mWidthSpec)) { - if (DEBUG) log(" super.onMeasure"); - final int hms = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - super.onMeasure(widthMeasureSpec, hms); - mBottom = mPeekable ? mHintText.getMeasuredHeight() : getExpandedBottom(); - mWidthSpec = widthMeasureSpec; + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + if (!isFull()) { + final LayoutParams lp = (LayoutParams) mModeSpinner.getLayoutParams(); + final int mh = vh(mModeSpinner) + vh(mDivider) + vh(mUntilPager) + lp.topMargin; + setMeasuredDimension(getMeasuredWidth(), mh); } - if (DEBUG) log("mBottom (OM) = " + mBottom); - setMeasuredDimension(getMeasuredWidth(), mBottom); - if (DEBUG) log(" mw=%s mh=%s", - toString(getMeasuredWidthAndState()), toString(getMeasuredHeightAndState())); - } - - private static String toString(int sizeAndState) { - final int size = sizeAndState & MEASURED_SIZE_MASK; - final boolean tooSmall = (sizeAndState & MEASURED_STATE_TOO_SMALL) != 0; - return size + (tooSmall ? "TOO SMALL" : ""); - } - - @Override - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - mLayoutRect.set(left, top, right, bottom); - if (DEBUG) log("onLayout %s %s %dx%d", changed, - mLayoutRect.toShortString(), mLayoutRect.width(), mLayoutRect.height()); - super.onLayout(changed, left, top, right, bottom); } - @Override - public boolean dispatchTouchEvent(MotionEvent ev) { - final boolean rt = super.dispatchTouchEvent(ev); - if (DEBUG) logTouchEvent("dispatchTouchEvent", rt, ev); - return rt; - } - - @Override - public boolean onInterceptTouchEvent(MotionEvent ev) { - final boolean rt = super.onInterceptTouchEvent(ev); - if (DEBUG) logTouchEvent("onInterceptTouchEvent", rt, ev); - if (isApplicable() - && ev.getAction() == MotionEvent.ACTION_DOWN - && ev.getY() > mCloseButton.getBottom() - && mPeekable) { - return true; - } - return rt; - } - - private static void logTouchEvent(String method, boolean rt, MotionEvent event) { - final String action = MotionEvent.actionToString(event.getAction()); - Log.d(TAG, method + " " + (rt ? "TRUE" : "FALSE") + " " + action); - } - - private int getExpandedBottom() { - int b = mModeSpinner.getMeasuredHeight() + mUntilPager.getMeasuredHeight(); - if (mAlarmWarning.getAlpha() == 1) b += mAlarmWarning.getMeasuredHeight(); - return b; - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - boolean rt = super.onTouchEvent(event); - if (DEBUG) logTouchEvent("onTouchEvent", rt, event); - if (!isApplicable() || !mPeekable) { - return rt; - } - if (event.getAction() == MotionEvent.ACTION_DOWN) { - mDownY = event.getY(); - if (DEBUG) log(" mDownY=" + mDownY); - mDownBottom = mBottom; - return true; - } else if (event.getAction() == MotionEvent.ACTION_MOVE) { - final float dy = event.getY() - mDownY; - if (!mPopped) { - mPopped = true; - AsyncTask.execute(mPopVibration); - } - setPeeked(mDownBottom + (int)dy, getExpandedBottom(), false); - } else if (event.getAction() == MotionEvent.ACTION_UP - || event.getAction() == MotionEvent.ACTION_CANCEL) { - final float dy = event.getY() - mDownY; - setPeeked(mDownBottom + (int)dy, getExpandedBottom(), true); - if (mPeekable) { - close(); - } - } - return rt; - } - - private void setPeeked(int peeked, int max, boolean isDone) { - if (DEBUG) log("setPeeked=" + peeked); - final int min = mHintText.getBottom(); - peeked = Math.max(min, Math.min(peeked, max)); - if (!isDone && mBottom == peeked) { - return; - } - if (peeked == max && isDone) { - mPeekable = false; - mModeSpinner.setEnabled(true); - if (mAdapter != null) { - mAdapter.setMode(Adapter.MODE_LIMITED); - } - } - if (peeked == min) { - mPeekable = true; - mModeSpinner.setEnabled(false); - } - if (DEBUG) log(" mBottom=" + peeked); - mBottom = peeked; - final float f = (peeked - min) / (float)(max - min); - setExpanded(f); - requestLayout(); - } - - private void setExpanded(float f) { - if (DEBUG) log("setExpanded " + f); - final int a = (int)(Color.alpha(BACKGROUND) * f); - setBackgroundColor(Color.argb(a, - Color.red(BACKGROUND), Color.green(BACKGROUND), Color.blue(BACKGROUND))); - mHintText.setAlpha(1 - f); - mCloseButton.setAlpha(f); - mModeSpinner.setAlpha(f); - mUntilPager.setAlpha(f); - mSettingsButton.setAlpha(f * getSettingsButtonAlpha()); + private int vh(View v) { + LayoutParams lp = (LayoutParams) v.getLayoutParams(); + return v.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; } private static void log(String msg, Object... args) { @@ -406,12 +240,6 @@ public class ZenModeView extends RelativeLayout { return sd; } - public void dispatchExternalTouchEvent(MotionEvent ev) { - if (isApplicable()) { - onTouchEvent(ev); - } - } - private static void bounce(final View v, final Runnable midBounce) { v.animate().scaleX(BOUNCE_SCALE).scaleY(BOUNCE_SCALE).setDuration(DURATION / 3) .setListener(new AnimatorListenerAdapter() { @@ -429,13 +257,18 @@ public class ZenModeView extends RelativeLayout { }).start(); } - private final Runnable mPopVibration = new Runnable() { - @Override - public void run() { - Vibrator v = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE); - v.vibrate(mPopDuration); - } - }; + public static String modeToString(int mode) { + if (mode == Adapter.MODE_OFF) return "MODE_OFF"; + if (mode == Adapter.MODE_LIMITED) return "MODE_LIMITED"; + if (mode == Adapter.MODE_FULL) return "MODE_FULL"; + throw new IllegalArgumentException("Invalid mode: " + mode); + } + + public static String modeToLabel(int mode) { + if (mode == Adapter.MODE_LIMITED) return "Limited interruptions"; + if (mode == Adapter.MODE_FULL) return "Zero interruptions"; + throw new UnsupportedOperationException("Unsupported mode: " + mode); + } private final class UntilPager extends RelativeLayout { private final ImageView mPrev; @@ -448,6 +281,7 @@ public class ZenModeView extends RelativeLayout { public UntilPager(Context context, Paint pathPaint, int iconSize) { super(context); mText1 = new TextView(mContext); + mText1.setTextSize(TypedValue.COMPLEX_UNIT_PX, mText1.getTextSize() * 1.2f); mText1.setTypeface(CONDENSED); mText1.setTextColor(GRAY); mText1.setGravity(Gravity.CENTER); @@ -456,6 +290,7 @@ public class ZenModeView extends RelativeLayout { mText = mText1; mText2 = new TextView(mContext); + mText2.setTextSize(TypedValue.COMPLEX_UNIT_PX, mText1.getTextSize()); mText2.setTypeface(CONDENSED); mText2.setTextColor(GRAY); mText2.setAlpha(0); @@ -478,7 +313,7 @@ public class ZenModeView extends RelativeLayout { }); lp = new LayoutParams(iconSize, iconSize); - lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); + lp.addRule(ALIGN_PARENT_RIGHT); final View v2 = new View(mContext); v2.setBackgroundColor(BACKGROUND); addView(v2, lp); @@ -532,9 +367,7 @@ public class ZenModeView extends RelativeLayout { } private void setText(final TextView textView, final ExitCondition ec) { - SpannableStringBuilder ss = new SpannableStringBuilder(ec.line1 + "\n" + ec.line2); - ss.setSpan(new RelativeSizeSpan(1.5f), (ec.line1 + "\n").length(), ss.length(), - Spannable.SPAN_INCLUSIVE_EXCLUSIVE); + SpannableStringBuilder ss = new SpannableStringBuilder(ec.summary); if (ec.action != null) { ss.setSpan(new CustomLinkSpan() { @Override @@ -542,7 +375,7 @@ public class ZenModeView extends RelativeLayout { // TODO wire up links Toast.makeText(mContext, ec.action, Toast.LENGTH_SHORT).show(); } - }, (ec.line1 + "\n").length(), ss.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE); + }, 0, ss.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE); textView.setMovementMethod(LinkMovementMethod.getInstance()); } else { textView.setMovementMethod(null); @@ -558,7 +391,7 @@ public class ZenModeView extends RelativeLayout { } private Path prevPath(int size) { - final int hp = size / 3; + final int hp = size * 3 / 8; final int vp = size / 4; final Path p = new Path(); p.moveTo(size - hp, vp); @@ -568,7 +401,7 @@ public class ZenModeView extends RelativeLayout { } private Path nextPath(int size) { - final int hp = size / 3; + final int hp = size * 3 / 8; final int vp = size / 4; Path p = new Path(); p.moveTo(hp, vp); @@ -603,12 +436,14 @@ public class ZenModeView extends RelativeLayout { public static final int MODE_LIMITED = 1; public static final int MODE_FULL = 2; - boolean isApplicable(); void configure(); + void close(); int getMode(); void setMode(int mode); + int getCommittedMode(); + void setCommittedMode(int mode); void select(ExitCondition ec); - void cancel(); + void init(); void setCallbacks(Callbacks callbacks); ExitCondition getExitCondition(int d); int getExitConditionCount(); @@ -637,38 +472,38 @@ public class ZenModeView extends RelativeLayout { } @Override - public View getDropDownView(int position, View convertView, ViewGroup parent) { + public View getDropDownView(final int position, View convertView, ViewGroup parent) { if (DEBUG) log("getDropDownView %s cv=%s parent=%s", position, convertView, parent); final TextView tv = convertView != null ? (TextView) convertView : new TextView(context); final int mode = getItem(position); - tv.setText(modeToString(mode)); + tv.setText(modeToLabel(mode)); + final boolean inDropdown = parent instanceof ListView; if (convertView == null) { if (DEBUG) log(" setting up view"); tv.setTextColor(GRAY); tv.setTypeface(CONDENSED); tv.setAllCaps(true); - tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, tv.getTextSize() * 1.5f); + tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, tv.getTextSize() * 1.2f); final int p = (int) tv.getTextSize() / 2; - if (parent instanceof ListView) { - tv.setPadding(p, p, p, p); + if (inDropdown) { + tv.setPadding(p, p, 0, p); } else { tv.setGravity(Gravity.CENTER_HORIZONTAL); - tv.setPadding(p, 0, p, 0); + tv.setPadding(p, 0, 0, 0); } } tv.setOnTouchListener(new OnTouchListener(){ @Override public boolean onTouch(View v, MotionEvent event) { - if (DEBUG) log("onTouch %s %s", tv.getText(), - MotionEvent.actionToString(event.getAction())); - if (mAdapter != null) { + if (DEBUG) log("onTouch %s %s inDropdown=%s", tv.getText(), + MotionEvent.actionToString(event.getAction()), inDropdown); + if (inDropdown && mAdapter != null) { mAdapter.setMode(mode); } return false; } - }); return tv; } @@ -688,16 +523,10 @@ public class ZenModeView extends RelativeLayout { if (getAdapter().getItem(i).equals(mode)) { if (DEBUG) log(" setting selection = " + i); setSelection(i, true); - return; + onDetachedFromWindow(); } } } - - private String modeToString(int mode) { - if (mode == Adapter.MODE_LIMITED) return "Limited interruptions"; - if (mode == Adapter.MODE_FULL) return "Zero interruptions"; - throw new UnsupportedOperationException("Unsupported mode: " + mode); - } } private final class AlarmWarning extends LinearLayout { @@ -724,29 +553,12 @@ public class ZenModeView extends RelativeLayout { } public void updateState(boolean animate) { - final boolean visible = mAdapter != null && mAdapter.getMode() == Adapter.MODE_FULL; - final float alpha = visible ? 1 : 0; + final float alpha = isFull() ? 1 : 0; if (alpha == getAlpha()) { return; } if (animate) { - final boolean in = alpha == 1; - animate().alpha(alpha).setUpdateListener(new AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - if (mPeekable || mClosing) { - return; - } - float f = animation.getAnimatedFraction(); - if (!in) { - f = 1 - f; - } - ZenModeView.this.mBottom = mUntilPager.getBottom() - + (int)(mAlarmWarning.getMeasuredHeight() * f); - if (DEBUG) log("mBottom (AW) = " + mBottom); - requestLayout(); - } - }).start(); + animate().alpha(alpha).start(); } else { setAlpha(alpha); requestLayout(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeViewAdapter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeViewAdapter.java index 39c4faa..d2067a4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeViewAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeViewAdapter.java @@ -35,23 +35,19 @@ public abstract class ZenModeViewAdapter implements ZenModeView.Adapter { private final Handler mHandler = new Handler(); private final SettingsObserver mObserver; private final List<ExitCondition> mExits = Arrays.asList( - newExit("Until you delete this", "Until", "You delete this")); + newExit("Until you turn this off", "Until", "You turn this off")); private Callbacks mCallbacks; private int mExitIndex; - private boolean mDeviceProvisioned; private int mMode; + private int mCommittedMode; public ZenModeViewAdapter(Context context) { mContext = context; mResolver = mContext.getContentResolver(); mObserver = new SettingsObserver(mHandler); mObserver.init(); - } - - @Override - public boolean isApplicable() { - return mDeviceProvisioned; + init(); } @Override @@ -61,6 +57,18 @@ public abstract class ZenModeViewAdapter implements ZenModeView.Adapter { @Override public void setMode(int mode) { + if (mode == mMode) return; + mMode = mode; + dispatchChanged(); + } + + @Override + public int getCommittedMode() { + return mCommittedMode; + } + + @Override + public void setCommittedMode(int mode) { final int v = mode == MODE_LIMITED ? Settings.Global.ZEN_MODE_LIMITED : mode == MODE_FULL ? Settings.Global.ZEN_MODE_FULL : Settings.Global.ZEN_MODE_OFF; @@ -74,12 +82,21 @@ public abstract class ZenModeViewAdapter implements ZenModeView.Adapter { } @Override - public void cancel() { + public void init() { if (mExitIndex != 0) { mExitIndex = 0; - mHandler.post(mChange); + dispatchChanged(); + } + final int mode = mCommittedMode == MODE_FULL ? MODE_FULL : MODE_LIMITED; + if (mode != mMode) { + mMode = mode; + dispatchChanged(); } - setMode(MODE_OFF); + } + + private void dispatchChanged() { + mHandler.removeCallbacks(mChanged); + mHandler.post(mChanged); } @Override @@ -111,7 +128,7 @@ public abstract class ZenModeViewAdapter implements ZenModeView.Adapter { return; } mExitIndex = i; - mHandler.post(mChange); + dispatchChanged(); } private static ExitCondition newExit(String summary, String line1, String line2) { @@ -122,7 +139,7 @@ public abstract class ZenModeViewAdapter implements ZenModeView.Adapter { return rt; } - private final Runnable mChange = new Runnable() { + private final Runnable mChanged = new Runnable() { public void run() { if (mCallbacks == null) { return; @@ -145,24 +162,19 @@ public abstract class ZenModeViewAdapter implements ZenModeView.Adapter { mResolver.registerContentObserver( Settings.Global.getUriFor(Settings.Global.ZEN_MODE), false, this); - mResolver.registerContentObserver( - Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED), - false, this); } @Override public void onChange(boolean selfChange) { loadSettings(); - mChange.run(); // already on handler + mChanged.run(); // already on handler } private void loadSettings() { - mDeviceProvisioned = Settings.Global.getInt(mResolver, - Settings.Global.DEVICE_PROVISIONED, 0) != 0; - mMode = getMode(); + mCommittedMode = getModeFromSetting(); } - private int getMode() { + private int getModeFromSetting() { final int v = Settings.Global.getInt(mResolver, Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF); if (v == Settings.Global.ZEN_MODE_LIMITED) return MODE_LIMITED; |