diff options
Diffstat (limited to 'packages/SystemUI/src')
23 files changed, 714 insertions, 108 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java index 5e48258..b9ffdbb 100755 --- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java +++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java @@ -402,6 +402,11 @@ public class BatteryMeterView extends View implements DemoMode { } } + @Override + public boolean hasOverlappingRendering() { + return false; + } + private boolean mDemoMode; private BatteryTracker mDemoTracker = new BatteryTracker(); diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java index bbda536..a26c534 100644 --- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java +++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java @@ -29,11 +29,13 @@ import android.view.Gravity; import android.view.MotionEvent; import android.view.ScaleGestureDetector; import android.view.ScaleGestureDetector.OnScaleGestureListener; +import android.view.VelocityTracker; import android.view.View; import android.view.ViewConfiguration; import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.ExpandableView; +import com.android.systemui.statusbar.FlingAnimationUtils; import com.android.systemui.statusbar.policy.ScrollAdapter; public class ExpandHelper implements Gefingerpoken { @@ -49,7 +51,7 @@ public class ExpandHelper implements Gefingerpoken { private static final String TAG = "ExpandHelper"; protected static final boolean DEBUG = false; protected static final boolean DEBUG_SCALE = false; - private static final long EXPAND_DURATION = 250; + private static final float EXPAND_DURATION = 0.3f; // Set to false to disable focus-based gestures (spread-finger vertical pull). private static final boolean USE_DRAG = true; @@ -112,6 +114,8 @@ public class ExpandHelper implements Gefingerpoken { private int mGravity; private ScrollAdapter mScrollAdapter; + private FlingAnimationUtils mFlingAnimationUtils; + private VelocityTracker mVelocityTracker; private OnScaleGestureListener mScaleGestureListener = new ScaleGestureDetector.SimpleOnScaleGestureListener() { @@ -171,7 +175,6 @@ public class ExpandHelper implements Gefingerpoken { mScaler = new ViewScaler(); mGravity = Gravity.TOP; mScaleAnimation = ObjectAnimator.ofFloat(mScaler, "height", 0f); - mScaleAnimation.setDuration(EXPAND_DURATION); mPopDuration = mContext.getResources().getInteger(R.integer.blinds_pop_duration_ms); mPullGestureMinXSpan = mContext.getResources().getDimension(R.dimen.pull_span_min); @@ -179,6 +182,7 @@ public class ExpandHelper implements Gefingerpoken { mTouchSlop = configuration.getScaledTouchSlop(); mSGD = new ScaleGestureDetector(context, mScaleGestureListener); + mFlingAnimationUtils = new FlingAnimationUtils(context, EXPAND_DURATION); } private void updateExpansion() { @@ -260,6 +264,7 @@ public class ExpandHelper implements Gefingerpoken { if (!isEnabled()) { return false; } + trackVelocity(ev); final int action = ev.getAction(); if (DEBUG_SCALE) Log.d(TAG, "intercept: act=" + MotionEvent.actionToString(action) + " expanding=" + mExpanding + @@ -279,6 +284,7 @@ public class ExpandHelper implements Gefingerpoken { if (mExpanding) { mLastMotionY = ev.getRawY(); + maybeRecycleVelocityTracker(ev); return true; } else { if ((action == MotionEvent.ACTION_MOVE) && 0 != (mExpansionStyle & BLINDS)) { @@ -323,15 +329,52 @@ public class ExpandHelper implements Gefingerpoken { case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: if (DEBUG) Log.d(TAG, "up/cancel"); - finishExpanding(false); + finishExpanding(false, getCurrentVelocity()); clearView(); break; } mLastMotionY = ev.getRawY(); + maybeRecycleVelocityTracker(ev); return mExpanding; } } + private void trackVelocity(MotionEvent event) { + int action = event.getActionMasked(); + switch(action) { + case MotionEvent.ACTION_DOWN: + if (mVelocityTracker == null) { + mVelocityTracker = VelocityTracker.obtain(); + } else { + mVelocityTracker.clear(); + } + mVelocityTracker.addMovement(event); + break; + case MotionEvent.ACTION_MOVE: + mVelocityTracker.addMovement(event); + break; + default: + break; + } + } + + private void maybeRecycleVelocityTracker(MotionEvent event) { + if (event.getActionMasked() == MotionEvent.ACTION_CANCEL + || event.getActionMasked() == MotionEvent.ACTION_UP) { + mVelocityTracker.recycle(); + mVelocityTracker = null; + } + } + + private float getCurrentVelocity() { + if (mVelocityTracker != null) { + mVelocityTracker.computeCurrentVelocity(1000); + return mVelocityTracker.getYVelocity(); + } else { + return 0f; + } + } + public void setEnabled(boolean enable) { mEnabled = enable; } @@ -349,6 +392,7 @@ public class ExpandHelper implements Gefingerpoken { if (!isEnabled()) { return false; } + trackVelocity(ev); final int action = ev.getActionMasked(); if (DEBUG_SCALE) Log.d(TAG, "touch: act=" + MotionEvent.actionToString(action) + " expanding=" + mExpanding + @@ -438,11 +482,12 @@ public class ExpandHelper implements Gefingerpoken { case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: if (DEBUG) Log.d(TAG, "up/cancel"); - finishExpanding(false); + finishExpanding(false, getCurrentVelocity()); clearView(); break; } mLastMotionY = ev.getRawY(); + maybeRecycleVelocityTracker(ev); return mResizedView != null; } @@ -476,7 +521,7 @@ public class ExpandHelper implements Gefingerpoken { return true; } - private void finishExpanding(boolean force) { + private void finishExpanding(boolean force, float velocity) { if (!mExpanding) return; if (DEBUG) Log.d(TAG, "scale in finishing on view: " + mResizedView); @@ -506,6 +551,7 @@ public class ExpandHelper implements Gefingerpoken { mScaleAnimation.removeListener(this); } }); + mFlingAnimationUtils.apply(mScaleAnimation, currentHeight, targetHeight, velocity); mScaleAnimation.start(); } else { mCallback.setUserLockedChild(mResizedView, false); @@ -529,7 +575,7 @@ public class ExpandHelper implements Gefingerpoken { * Use this to abort any pending expansions in progress. */ public void cancel() { - finishExpanding(true); + finishExpanding(true, 0f /* velocity */); clearView(); // reset the gesture detector diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java index 333b8b4..13c15f5 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java @@ -32,7 +32,6 @@ import android.os.Handler; import android.os.PowerManager; import android.os.SystemProperties; import android.os.Vibrator; -import android.service.dreams.DozeHardware; import android.service.dreams.DreamService; import android.util.Log; import android.util.MathUtils; @@ -55,7 +54,6 @@ public class DozeService extends DreamService { private final Handler mHandler = new Handler(); private Host mHost; - private DozeHardware mDozeHardware; private SensorManager mSensors; private Sensor mSigMotionSensor; private PowerManager mPowerManager; @@ -77,7 +75,6 @@ public class DozeService extends DreamService { protected void dumpOnHandler(FileDescriptor fd, PrintWriter pw, String[] args) { super.dumpOnHandler(fd, pw, args); pw.print(" mDreaming: "); pw.println(mDreaming); - pw.print(" mDozeHardware: "); pw.println(mDozeHardware); pw.print(" mTeaseReceiverRegistered: "); pw.println(mTeaseReceiverRegistered); pw.print(" mSigMotionSensor: "); pw.println(mSigMotionSensor); pw.print(" mSigMotionConfigured: "); pw.println(mSigMotionConfigured); @@ -123,9 +120,7 @@ public class DozeService extends DreamService { @Override public void onDreamingStarted() { super.onDreamingStarted(); - mDozeHardware = getDozeHardware(); - if (DEBUG) Log.d(mTag, "onDreamingStarted canDoze=" + canDoze() - + " dozeHardware=" + mDozeHardware); + if (DEBUG) Log.d(mTag, "onDreamingStarted canDoze=" + canDoze()); mDreaming = true; listenForTeaseSignals(true); requestDoze(); @@ -162,7 +157,6 @@ public class DozeService extends DreamService { super.onDreamingStopped(); mDreaming = false; - mDozeHardware = null; if (mWakeLock.isHeld()) { mWakeLock.release(); } @@ -292,6 +286,11 @@ public class DozeService extends DreamService { @Override public void onNewNotifications() { if (DEBUG) Log.d(mTag, "onNewNotifications"); + // noop for now + } + @Override + public void onBuzzBeepBlinked() { + if (DEBUG) Log.d(mTag, "onBuzzBeepBlinked"); requestTease(); } }; @@ -305,6 +304,7 @@ public class DozeService extends DreamService { public interface Callback { void onNewNotifications(); + void onBuzzBeepBlinked(); } } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java index d76a2fe..42da282 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java @@ -93,10 +93,10 @@ public class CellularTile extends QSTile<QSTile.SignalState> { final Resources r = mContext.getResources(); state.iconId = cb.noSim ? R.drawable.stat_sys_no_sim - : cb.enabled && (cb.mobileSignalIconId > 0) + : cb.enabled && (cb.mobileSignalIconId > 0) && !cb.airplaneModeEnabled ? cb.mobileSignalIconId : R.drawable.ic_qs_signal_no_signal; - state.overlayIconId = cb.enabled && (cb.dataTypeIconId > 0) && !cb.wifiEnabled + state.overlayIconId = cb.enabled && (cb.dataTypeIconId > 0) && !cb.wifiConnected ? cb.dataTypeIconId : 0; state.filter = state.iconId != R.drawable.stat_sys_no_sim; @@ -132,6 +132,8 @@ public class CellularTile extends QSTile<QSTile.SignalState> { private static final class CallbackInfo { boolean enabled; boolean wifiEnabled; + boolean wifiConnected; + boolean airplaneModeEnabled; int mobileSignalIconId; String signalContentDescription; int dataTypeIconId; @@ -144,12 +146,15 @@ public class CellularTile extends QSTile<QSTile.SignalState> { private final NetworkSignalChangedCallback mCallback = new NetworkSignalChangedCallback() { private boolean mWifiEnabled; + private boolean mWifiConnected; + private boolean mAirplaneModeEnabled; @Override - public void onWifiSignalChanged(boolean enabled, int wifiSignalIconId, + public void onWifiSignalChanged(boolean enabled, boolean connected, int wifiSignalIconId, boolean activityIn, boolean activityOut, String wifiSignalContentDescriptionId, String description) { mWifiEnabled = enabled; + mWifiConnected = connected; } @Override @@ -161,6 +166,8 @@ public class CellularTile extends QSTile<QSTile.SignalState> { final CallbackInfo info = new CallbackInfo(); // TODO pool? info.enabled = enabled; info.wifiEnabled = mWifiEnabled; + info.wifiConnected = mWifiConnected; + info.airplaneModeEnabled = mAirplaneModeEnabled; info.mobileSignalIconId = mobileSignalIconId; info.signalContentDescription = mobileSignalContentDescriptionId; info.dataTypeIconId = dataTypeIconId; @@ -174,7 +181,7 @@ public class CellularTile extends QSTile<QSTile.SignalState> { @Override public void onAirplaneModeChanged(boolean enabled) { - // noop + mAirplaneModeEnabled = enabled; } public void onMobileDataEnabled(boolean enabled) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java index 35dfdda..e0b465e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java @@ -24,7 +24,6 @@ import android.content.SharedPreferences; import com.android.systemui.R; import com.android.systemui.qs.QSTile; import com.android.systemui.statusbar.policy.HotspotController; -import com.android.systemui.statusbar.policy.KeyguardMonitor; /** Quick settings tile: Hotspot **/ public class HotspotTile extends QSTile<QSTile.BooleanState> { @@ -32,14 +31,12 @@ public class HotspotTile extends QSTile<QSTile.BooleanState> { private static final long MILLIS_PER_DAY = 1000 * 60 * 60 * 24; private final HotspotController mController; - private final KeyguardMonitor mKeyguard; private final Callback mCallback = new Callback(); private final long mTimeToShowTile; public HotspotTile(Host host) { super(host); mController = host.getHotspotController(); - mKeyguard = host.getKeyguardMonitor(); mTimeToShowTile = MILLIS_PER_DAY * mContext.getResources().getInteger(R.integer.days_to_show_hotspot); @@ -54,10 +51,8 @@ public class HotspotTile extends QSTile<QSTile.BooleanState> { public void setListening(boolean listening) { if (listening) { mController.addCallback(mCallback); - mKeyguard.addCallback(mCallback); } else { mController.removeCallback(mCallback); - mKeyguard.removeCallback(mCallback); } } @@ -69,8 +64,7 @@ public class HotspotTile extends QSTile<QSTile.BooleanState> { @Override protected void handleUpdateState(BooleanState state, Object arg) { - state.visible = !(mKeyguard.isSecure() && mKeyguard.isShowing()) - && mController.isHotspotSupported() && isHotspotRecentlyUsed(); + state.visible = mController.isHotspotSupported() && isHotspotRecentlyUsed(); state.label = mContext.getString(R.string.quick_settings_hotspot_label); state.value = mController.isHotspotEnabled(); @@ -87,16 +81,11 @@ public class HotspotTile extends QSTile<QSTile.BooleanState> { return context.getSharedPreferences(context.getPackageName(), 0); } - private final class Callback implements HotspotController.Callback, KeyguardMonitor.Callback { + private final class Callback implements HotspotController.Callback { @Override public void onHotspotChanged(boolean enabled) { refreshState(); } - - @Override - public void onKeyguardChanged() { - refreshState(); - } }; /** diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java index 900c7b2..1707b32 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java @@ -143,6 +143,7 @@ public class WifiTile extends QSTile<QSTile.SignalState> { private static final class CallbackInfo { boolean enabled; + boolean connected; int wifiSignalIconId; String enabledDesc; boolean activityIn; @@ -153,6 +154,7 @@ public class WifiTile extends QSTile<QSTile.SignalState> { 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) @@ -164,12 +166,13 @@ public class WifiTile extends QSTile<QSTile.SignalState> { private final NetworkSignalChangedCallback mCallback = new NetworkSignalChangedCallback() { @Override - public void onWifiSignalChanged(boolean enabled, int wifiSignalIconId, + public void onWifiSignalChanged(boolean enabled, boolean connected, int wifiSignalIconId, boolean activityIn, boolean activityOut, String wifiSignalContentDescriptionId, String description) { if (DEBUG) Log.d(TAG, "onWifiSignalChanged enabled=" + enabled); final CallbackInfo info = new CallbackInfo(); info.enabled = enabled; + info.connected = connected; info.wifiSignalIconId = wifiSignalIconId; info.enabledDesc = description; info.activityIn = activityIn; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index eb44002..a82c907 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java @@ -54,6 +54,7 @@ public class CommandQueue extends IStatusBar.Stub { private static final int MSG_SET_WINDOW_STATE = 13 << MSG_SHIFT; private static final int MSG_SHOW_RECENT_APPS = 14 << MSG_SHIFT; private static final int MSG_HIDE_RECENT_APPS = 15 << MSG_SHIFT; + private static final int MSG_BUZZ_BEEP_BLINKED = 16 << MSG_SHIFT; public static final int FLAG_EXCLUDE_NONE = 0; public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0; @@ -93,6 +94,7 @@ public class CommandQueue extends IStatusBar.Stub { public void showSearchPanel(); public void hideSearchPanel(); public void setWindowState(int window, int state); + public void buzzBeepBlinked(); } public CommandQueue(Callbacks callbacks, StatusBarIconList list) { @@ -221,6 +223,12 @@ public class CommandQueue extends IStatusBar.Stub { } } + public void buzzBeepBlinked() { + synchronized (mList) { + mHandler.removeMessages(MSG_BUZZ_BEEP_BLINKED); + mHandler.sendEmptyMessage(MSG_BUZZ_BEEP_BLINKED); + } + } private final class H extends Handler { public void handleMessage(Message msg) { @@ -295,6 +303,9 @@ public class CommandQueue extends IStatusBar.Stub { case MSG_SET_WINDOW_STATE: mCallbacks.setWindowState(msg.arg1, msg.arg2); break; + case MSG_BUZZ_BEEP_BLINKED: + mCallbacks.buzzBeepBlinked(); + break; } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java index 517a4e8..e9989ab 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java @@ -19,6 +19,7 @@ package com.android.systemui.statusbar; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; +import android.animation.ValueAnimator; import android.content.Context; import android.view.MotionEvent; import android.view.View; @@ -46,22 +47,23 @@ public class DragDownHelper implements Gefingerpoken { private float mInitialTouchY; private boolean mDraggingDown; private float mTouchSlop; - private OnDragDownListener mOnDragDownListener; + private DragDownCallback mDragDownCallback; private View mHost; private final int[] mTemp2 = new int[2]; private boolean mDraggedFarEnough; private ExpandableView mStartingChild; private Interpolator mInterpolator; + private float mLastHeight; public DragDownHelper(Context context, View host, ExpandHelper.Callback callback, - OnDragDownListener onDragDownListener) { + DragDownCallback dragDownCallback) { mMinDragDistance = context.getResources().getDimensionPixelSize( R.dimen.keyguard_drag_down_min_distance); mInterpolator = AnimationUtils.loadInterpolator(context, android.R.interpolator.fast_out_slow_in); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); mCallback = callback; - mOnDragDownListener = onDragDownListener; + mDragDownCallback = dragDownCallback; mHost = host; } @@ -86,7 +88,7 @@ public class DragDownHelper implements Gefingerpoken { captureStartingChild(mInitialTouchX, mInitialTouchY); mInitialTouchY = y; mInitialTouchX = x; - mOnDragDownListener.onTouchSlopExceeded(); + mDragDownCallback.onTouchSlopExceeded(); return true; } break; @@ -104,29 +106,32 @@ public class DragDownHelper implements Gefingerpoken { switch (event.getActionMasked()) { case MotionEvent.ACTION_MOVE: - final float h = y - mInitialTouchY; + mLastHeight = y - mInitialTouchY; captureStartingChild(mInitialTouchX, mInitialTouchY); if (mStartingChild != null) { - handleExpansion(h, mStartingChild); + handleExpansion(mLastHeight, mStartingChild); + } else { + mDragDownCallback.setEmptyDragAmount(mLastHeight); } - if (h > mMinDragDistance) { + if (mLastHeight > mMinDragDistance) { if (!mDraggedFarEnough) { mDraggedFarEnough = true; - mOnDragDownListener.onThresholdReached(); + mDragDownCallback.onThresholdReached(); } } else { if (mDraggedFarEnough) { mDraggedFarEnough = false; - mOnDragDownListener.onDragDownReset(); + mDragDownCallback.onDragDownReset(); } } return true; case MotionEvent.ACTION_UP: - if (mDraggedFarEnough) { + if (mDraggedFarEnough && mDragDownCallback.onDraggedDown(mStartingChild)) { if (mStartingChild != null) { mCallback.setUserLockedChild(mStartingChild, false); + } else { + mDragDownCallback.setEmptyDragAmount(0f); } - mOnDragDownListener.onDraggedDown(mStartingChild); mDraggingDown = false; } else { stopDragging(); @@ -183,12 +188,27 @@ public class DragDownHelper implements Gefingerpoken { anim.start(); } + private void cancelExpansion() { + ValueAnimator anim = ValueAnimator.ofFloat(mLastHeight, 0); + anim.setInterpolator(mInterpolator); + anim.setDuration(SPRING_BACK_ANIMATION_LENGTH_MS); + anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + mDragDownCallback.setEmptyDragAmount((Float) animation.getAnimatedValue()); + } + }); + anim.start(); + } + private void stopDragging() { if (mStartingChild != null) { cancelExpansion(mStartingChild); + } else { + cancelExpansion(); } mDraggingDown = false; - mOnDragDownListener.onDragDownReset(); + mDragDownCallback.onDragDownReset(); } private ExpandableView findView(float x, float y) { @@ -198,10 +218,15 @@ public class DragDownHelper implements Gefingerpoken { return mCallback.getChildAtRawPosition(x, y); } - public interface OnDragDownListener { - void onDraggedDown(View startingChild); + public interface DragDownCallback { + + /** + * @return true if the interaction is accepted, false if it should be cancelled + */ + boolean onDraggedDown(View startingChild); void onDragDownReset(); void onThresholdReached(); void onTouchSlopExceeded(); + void setEmptyDragAmount(float amount); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java b/packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java index 9968bbc..9f0f84e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar; +import android.animation.Animator; import android.animation.ValueAnimator; import android.content.Context; import android.view.ViewPropertyAnimator; @@ -72,7 +73,7 @@ public class FlingAnimationUtils { * @param endValue the end value of the animator * @param velocity the current velocity of the motion */ - public void apply(ValueAnimator animator, float currValue, float endValue, float velocity) { + public void apply(Animator animator, float currValue, float endValue, float velocity) { apply(animator, currValue, endValue, velocity, Math.abs(endValue - currValue)); } @@ -101,7 +102,7 @@ public class FlingAnimationUtils { * @param maxDistance the maximum distance for this interaction; the maximum animation length * gets multiplied by the ratio between the actual distance and this value */ - public void apply(ValueAnimator animator, float currValue, float endValue, float velocity, + public void apply(Animator animator, float currValue, float endValue, float velocity, float maxDistance) { AnimatorProperties properties = getProperties(currValue, endValue, velocity, maxDistance); @@ -168,7 +169,7 @@ public class FlingAnimationUtils { * @param maxDistance the maximum distance for this interaction; the maximum animation length * gets multiplied by the ratio between the actual distance and this value */ - public void applyDismissing(ValueAnimator animator, float currValue, float endValue, + public void applyDismissing(Animator animator, float currValue, float endValue, float velocity, float maxDistance) { AnimatorProperties properties = getDismissingProperties(currValue, endValue, velocity, maxDistance); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java index 845e0ae..19bf121 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java @@ -28,6 +28,8 @@ import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.util.AttributeSet; +import android.view.View; +import android.view.ViewAnimationUtils; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import android.widget.ImageView; @@ -69,6 +71,16 @@ public class KeyguardAffordanceView extends ImageView { private int mCircleColor; private boolean mIsLeft; private float mArrowAlpha = 0.0f; + private View mPreviewView; + private float mCircleStartRadius; + private float mMaxCircleSize; + private Animator mPreviewClipper; + private AnimatorListenerAdapter mClipEndListener = new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mPreviewClipper = null; + } + }; private AnimatorListenerAdapter mCircleEndListener = new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { @@ -136,6 +148,7 @@ public class KeyguardAffordanceView extends ImageView { super.onLayout(changed, left, top, right, bottom); mCenterX = getWidth() / 2; mCenterY = getHeight() / 2; + mMaxCircleSize = getMaxCircleSize(); } @Override @@ -149,6 +162,10 @@ public class KeyguardAffordanceView extends ImageView { canvas.restore(); } + public void setPreviewView(View v) { + mPreviewView = v; + } + private void drawArrow(Canvas canvas) { if (mArrowAlpha > 0) { canvas.save(); @@ -183,6 +200,11 @@ public class KeyguardAffordanceView extends ImageView { private void updateCircleColor() { float fraction = 0.5f + 0.5f * Math.max(0.0f, Math.min(1.0f, (mCircleRadius - mMinBackgroundRadius) / (0.5f * mMinBackgroundRadius))); + if (mPreviewView != null) { + float finishingFraction = 1 - Math.max(0, mCircleRadius - mCircleStartRadius) + / (mMaxCircleSize - mCircleStartRadius); + fraction *= finishingFraction; + } int color = Color.argb((int) (Color.alpha(mCircleColor) * fraction), Color.red(mCircleColor), Color.green(mCircleColor), Color.blue(mCircleColor)); @@ -191,6 +213,8 @@ public class KeyguardAffordanceView extends ImageView { public void finishAnimation(float velocity, final Runnable mAnimationEndRunnable) { cancelAnimator(mCircleAnimator); + cancelAnimator(mPreviewClipper); + mCircleStartRadius = mCircleRadius; float maxCircleSize = getMaxCircleSize(); ValueAnimator animatorToRadius = getAnimatorToRadius(maxCircleSize); mFlingAnimationUtils.applyDismissing(animatorToRadius, mCircleRadius, maxCircleSize, @@ -203,6 +227,16 @@ public class KeyguardAffordanceView extends ImageView { }); animatorToRadius.start(); setImageAlpha(0, true); + if (mPreviewView != null) { + mPreviewView.setVisibility(View.VISIBLE); + mPreviewClipper = ViewAnimationUtils.createCircularReveal( + mPreviewView, getLeft() + mCenterX, getTop() + mCenterY, mCircleRadius, + maxCircleSize); + mFlingAnimationUtils.applyDismissing(mPreviewClipper, mCircleRadius, maxCircleSize, + velocity, maxCircleSize); + mPreviewClipper.addListener(mClipEndListener); + mPreviewClipper.start(); + } } private float getMaxCircleSize() { @@ -234,6 +268,11 @@ public class KeyguardAffordanceView extends ImageView { if (mCircleAnimator == null) { mCircleRadius = circleRadius; invalidate(); + if (nowHidden) { + if (mPreviewView != null) { + mPreviewView.setVisibility(View.INVISIBLE); + } + } } else if (!mCircleWillBeHidden) { // We just update the end value @@ -244,6 +283,7 @@ public class KeyguardAffordanceView extends ImageView { } } else { cancelAnimator(mCircleAnimator); + cancelAnimator(mPreviewClipper); ValueAnimator animator = getAnimatorToRadius(circleRadius); Interpolator interpolator = circleRadius == 0.0f ? mDisappearInterpolator @@ -255,6 +295,22 @@ public class KeyguardAffordanceView extends ImageView { duration = Math.min(duration, CIRCLE_DISAPPEAR_MAX_DURATION); animator.setDuration(duration); animator.start(); + if (mPreviewView != null) { + mPreviewView.setVisibility(View.VISIBLE); + mPreviewClipper = ViewAnimationUtils.createCircularReveal( + mPreviewView, getLeft() + mCenterX, getTop() + mCenterY, mCircleRadius, + circleRadius); + mPreviewClipper.setInterpolator(interpolator); + mPreviewClipper.setDuration(duration); + mPreviewClipper.addListener(mClipEndListener); + mPreviewClipper.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mPreviewView.setVisibility(View.INVISIBLE); + } + }); + mPreviewClipper.start(); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java index f5d4889..8bae19a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java @@ -167,6 +167,11 @@ public class SignalClusterView apply(); } + @Override + public boolean hasOverlappingRendering() { + return false; + } + private void applyInetProblem(ImageView iv) { iv.setColorFilter(Build.IS_DEBUGGABLE && mInetProblem ? PROBLEM_FILTER : null); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java index a8a0cb1..9cc559f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java @@ -67,7 +67,6 @@ public class KeyguardAffordanceHelper { private Animator mSwipeAnimator; private int mMinBackgroundRadius; private boolean mMotionPerformedByUser; - private PowerManager mPM; private AnimatorListenerAdapter mFlingEndListener = new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { @@ -89,11 +88,12 @@ public class KeyguardAffordanceHelper { mLeftIcon.setIsLeft(true); mCenterIcon = mCallback.getCenterIcon(); mRightIcon = mCallback.getRightIcon(); + mLeftIcon.setPreviewView(mCallback.getLeftPreview()); + mRightIcon.setPreviewView(mCallback.getRightPreview()); updateIcon(mLeftIcon, 0.0f, SWIPE_RESTING_ALPHA_AMOUNT, false); updateIcon(mCenterIcon, 0.0f, SWIPE_RESTING_ALPHA_AMOUNT, false); updateIcon(mRightIcon, 0.0f, SWIPE_RESTING_ALPHA_AMOUNT, false); initDimens(); - mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); } private void initDimens() { @@ -334,7 +334,6 @@ public class KeyguardAffordanceHelper { float absTranslation = Math.abs(translation); if (absTranslation > Math.abs(mTranslationOnDown) + mMinTranslationAmount || mMotionPerformedByUser) { - userActivity(); mMotionPerformedByUser = true; } if (translation != mTranslation || isReset) { @@ -387,11 +386,6 @@ public class KeyguardAffordanceHelper { return translation * BACKGROUND_RADIUS_SCALE_FACTOR + mMinBackgroundRadius; } - - private void userActivity() { - mPM.userActivity(SystemClock.uptimeMillis(), false); - } - public void animateHideLeftRightIcon() { updateIcon(mRightIcon, 0f, 0f, true); updateIcon(mLeftIcon, 0f, 0f, true); @@ -475,5 +469,9 @@ public class KeyguardAffordanceHelper { KeyguardAffordanceView getCenterIcon(); KeyguardAffordanceView getRightIcon(); + + View getLeftPreview(); + + View getRightPreview(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java index b9f012c..b5f517d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -30,6 +30,7 @@ import android.provider.MediaStore; import android.util.AttributeSet; import android.util.Log; import android.view.View; +import android.view.ViewGroup; import android.view.accessibility.AccessibilityManager; import android.widget.FrameLayout; import android.widget.ImageView; @@ -40,6 +41,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.R; import com.android.systemui.statusbar.policy.FlashlightController; import com.android.systemui.statusbar.KeyguardAffordanceView; +import com.android.systemui.statusbar.policy.PreviewInflater; /** * Implementation for the bottom area of the Keyguard, including camera/phone affordance and status @@ -61,6 +63,10 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL private KeyguardAffordanceView mPhoneImageView; private KeyguardAffordanceView mLockIcon; private View mIndicationText; + private ViewGroup mPreviewContainer; + + private View mPhonePreview; + private View mCameraPreview; private ActivityStarter mActivityStarter; private UnlockMethodCache mUnlockMethodCache; @@ -88,6 +94,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL protected void onFinishInflate() { super.onFinishInflate(); mLockPatternUtils = new LockPatternUtils(mContext); + mPreviewContainer = (ViewGroup) findViewById(R.id.preview_container); mCameraImageView = (KeyguardAffordanceView) findViewById(R.id.camera_button); mPhoneImageView = (KeyguardAffordanceView) findViewById(R.id.phone_button); mLockIcon = (KeyguardAffordanceView) findViewById(R.id.lock_icon); @@ -101,6 +108,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL updateTrust(); setClipChildren(false); setClipToPadding(false); + inflatePreviews(); } public void setActivityStarter(ActivityStarter activityStarter) { @@ -239,6 +247,14 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL return mCameraImageView; } + public View getPhonePreview() { + return mPhonePreview; + } + + public View getCameraPreview() { + return mCameraPreview; + } + public KeyguardAffordanceView getLockIcon() { return mLockIcon; } @@ -258,6 +274,20 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL updateCameraVisibility(); } + private void inflatePreviews() { + PreviewInflater inflater = new PreviewInflater(mContext, new LockPatternUtils(mContext)); + mPhonePreview = inflater.inflatePreview(PHONE_INTENT); + mCameraPreview = inflater.inflatePreview(getCameraIntent()); + if (mPhonePreview != null) { + mPreviewContainer.addView(mPhonePreview); + mPhonePreview.setVisibility(View.INVISIBLE); + } + if (mCameraPreview != null) { + mPreviewContainer.addView(mCameraPreview); + mCameraPreview.setVisibility(View.INVISIBLE); + } + } + private final BroadcastReceiver mDevicePolicyReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { post(new Runnable() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java index 319096d..a15d35e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java @@ -36,7 +36,6 @@ public class KeyguardClockPositionAlgorithm { private static final float CLOCK_SCALE_FADE_END = 0.75f; private static final float CLOCK_SCALE_FADE_END_NO_NOTIFS = 0.5f; - private static final float CLOCK_ADJ_TOP_PADDING_MULTIPLIER_MIN = 1.4f; private static final float CLOCK_ADJ_TOP_PADDING_MULTIPLIER_MAX = 3.2f; @@ -50,6 +49,8 @@ public class KeyguardClockPositionAlgorithm { private int mNotificationCount; private int mHeight; private int mKeyguardStatusHeight; + private float mEmptyDragAmount; + private float mDensity; /** * The number (fractional) of notifications the "more" card counts when calculating how many @@ -81,16 +82,18 @@ public class KeyguardClockPositionAlgorithm { mMoreCardNotificationAmount = (float) res.getDimensionPixelSize(R.dimen.notification_summary_height) / res.getDimensionPixelSize(R.dimen.notification_min_height); + mDensity = res.getDisplayMetrics().density; } public void setup(int maxKeyguardNotifications, int maxPanelHeight, float expandedHeight, - int notificationCount, int height, int keyguardStatusHeight) { + int notificationCount, int height, int keyguardStatusHeight, float emptyDragAmount) { mMaxKeyguardNotifications = maxKeyguardNotifications; mMaxPanelHeight = maxPanelHeight; mExpandedHeight = expandedHeight; mNotificationCount = notificationCount; mHeight = height; mKeyguardStatusHeight = keyguardStatusHeight; + mEmptyDragAmount = emptyDragAmount; } public void run(Result result) { @@ -116,6 +119,7 @@ public class KeyguardClockPositionAlgorithm { float progress = distanceToScaleEnd / (startPadding - scaleEnd); progress = Math.max(0.0f, Math.min(progress, 1.0f)); progress = mAccelerateInterpolator.getInterpolation(progress); + progress *= Math.pow(1 + mEmptyDragAmount / mDensity / 300, 0.3f); return progress; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPreviewContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPreviewContainer.java new file mode 100644 index 0000000..7579039 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPreviewContainer.java @@ -0,0 +1,70 @@ +/* + * 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.graphics.Canvas; +import android.graphics.Color; +import android.graphics.ColorFilter; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.WindowInsets; +import android.widget.FrameLayout; + +/** + * A view group which contains the preview of phone/camera and draws a black bar at the bottom as + * the fake navigation bar. + */ +public class KeyguardPreviewContainer extends FrameLayout { + + private Drawable mBlackBarDrawable = new Drawable() { + @Override + public void draw(Canvas canvas) { + canvas.save(); + canvas.clipRect(0, getHeight() - getPaddingBottom(), getWidth(), getHeight()); + canvas.drawColor(Color.BLACK); + canvas.restore(); + } + + @Override + public void setAlpha(int alpha) { + // noop + } + + @Override + public void setColorFilter(ColorFilter cf) { + // noop + } + + @Override + public int getOpacity() { + return android.graphics.PixelFormat.OPAQUE; + } + }; + + public KeyguardPreviewContainer(Context context, AttributeSet attrs) { + super(context, attrs); + setBackground(mBlackBarDrawable); + } + + @Override + public WindowInsets onApplyWindowInsets(WindowInsets insets) { + setPadding(0, 0, 0, insets.getStableInsetBottom()); + return super.onApplyWindowInsets(insets); + } +} 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 11a38b5..909972a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -45,8 +45,6 @@ import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.stack.StackStateAnimator; -import java.util.ArrayList; - public class NotificationPanelView extends PanelView implements ExpandableView.OnHeightChangedListener, ObservableScrollView.Listener, View.OnClickListener, NotificationStackScrollLayout.OnOverscrollTopChangedListener, @@ -112,6 +110,7 @@ public class NotificationPanelView extends PanelView implements private boolean mUnlockIconActive; private int mNotificationsHeaderCollideDistance; private int mUnlockMoveDistance; + private float mEmptyDragAmount; private Interpolator mFastOutSlowInInterpolator; private Interpolator mFastOutLinearInterpolator; @@ -236,7 +235,8 @@ public class NotificationPanelView extends PanelView implements getExpandedHeight(), mNotificationStackScroller.getNotGoneChildCount(), getHeight(), - mKeyguardStatusView.getHeight()); + mKeyguardStatusView.getHeight(), + mEmptyDragAmount); mClockPositionAlgorithm.run(mClockPositionResult); if (animate || mClockAnimator != null) { startClockAnimation(mClockPositionResult.clockY); @@ -1257,6 +1257,20 @@ public class NotificationPanelView extends PanelView implements } @Override + public View getLeftPreview() { + return getLayoutDirection() == LAYOUT_DIRECTION_RTL + ? mKeyguardBottomArea.getCameraPreview() + : mKeyguardBottomArea.getPhonePreview(); + } + + @Override + public View getRightPreview() { + return getLayoutDirection() == LAYOUT_DIRECTION_RTL + ? mKeyguardBottomArea.getPhonePreview() + : mKeyguardBottomArea.getCameraPreview(); + } + + @Override protected float getPeekHeight() { if (mNotificationStackScroller.getNotGoneChildCount() > 0) { return mNotificationStackScroller.getPeekHeight(); @@ -1307,4 +1321,15 @@ public class NotificationPanelView extends PanelView implements public void setLaunchTransitionEndRunnable(Runnable r) { mLaunchAnimationEndRunnable = r; } + + public void setEmptyDragAmount(float amount) { + float factor = 1f; + if (mNotificationStackScroller.getNotGoneChildCount() > 0) { + factor = 0.6f; + } else if (!mStatusBar.hasNotifications()) { + factor = 0.4f; + } + mEmptyDragAmount = amount * factor; + positionClockAndNotifications(); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 13fad7b..2123bd9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -70,7 +70,6 @@ import android.os.Message; import android.os.PowerManager; import android.os.RemoteException; import android.os.SystemClock; -import android.os.Trace; import android.os.UserHandle; import android.provider.Settings; import android.service.notification.NotificationListenerService.RankingMap; @@ -130,6 +129,7 @@ import com.android.systemui.statusbar.SignalClusterView; import com.android.systemui.statusbar.SpeedBumpView; import com.android.systemui.statusbar.StatusBarIconView; import com.android.systemui.statusbar.StatusBarState; +import com.android.systemui.statusbar.policy.NextAlarmController; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback; import com.android.systemui.statusbar.policy.BluetoothControllerImpl; @@ -159,7 +159,7 @@ import java.util.Collections; import java.util.List; public class PhoneStatusBar extends BaseStatusBar implements DemoMode, - DragDownHelper.OnDragDownListener, ActivityStarter { + DragDownHelper.DragDownCallback, ActivityStarter { static final String TAG = "PhoneStatusBar"; public static final boolean DEBUG = BaseStatusBar.DEBUG; public static final boolean SPEW = false; @@ -224,6 +224,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, KeyguardUserSwitcher mKeyguardUserSwitcher; FlashlightController mFlashlightController; UserSwitcherController mUserSwitcherController; + NextAlarmController mNextAlarmController; KeyguardMonitor mKeyguardMonitor; int mNaturalBarHeight = -1; @@ -282,7 +283,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private long mKeyguardFadingAwayDuration; int mKeyguardMaxNotificationCount; - View mDateTimeView; // carrier/wifi label private TextView mCarrierLabel; @@ -453,6 +453,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private Runnable mLaunchTransitionEndRunnable; private boolean mLaunchTransitionFadingAway; + private boolean mHasNotifications; + private static final int VISIBLE_LOCATIONS = ViewState.LOCATION_FIRST_CARD | ViewState.LOCATION_TOP_STACK_PEEKING | ViewState.LOCATION_MAIN_AREA @@ -702,12 +704,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, (KeyguardIndicationTextView) mStatusBarWindow.findViewById( R.id.keyguard_indication_text)); - mDateTimeView = mHeader.findViewById(R.id.datetime); - if (mDateTimeView != null) { - mDateTimeView.setOnClickListener(mClockClickListener); - mDateTimeView.setEnabled(true); - } - mTickerEnabled = res.getBoolean(R.bool.enable_ticker); if (mTickerEnabled) { final ViewStub tickerStub = (ViewStub) mStatusBarView.findViewById(R.id.ticker_stub); @@ -784,6 +780,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mFlashlightController = new FlashlightController(mContext); mKeyguardBottomArea.setFlashlightController(mFlashlightController); mUserSwitcherController = new UserSwitcherController(mContext); + mNextAlarmController = new NextAlarmController(mContext); mKeyguardMonitor = new KeyguardMonitor(); mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext, @@ -815,6 +812,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mUserInfoController.reloadUserInfo(); mHeader.setBatteryController(mBatteryController); + mHeader.setNextAlarmController(mNextAlarmController); PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mBroadcastReceiver.onReceive(mContext, @@ -1317,8 +1315,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, updateExpandedViewPos(EXPANDED_LEAVE_ALONE); if (CLOSE_PANEL_WHEN_EMPTIED && mNotificationData.size() == 0 - && !mNotificationPanel.isTracking() && mState != StatusBarState.KEYGUARD) { - animateCollapsePanels(); + && !mNotificationPanel.isTracking()) { + if (mState == StatusBarState.SHADE) { + animateCollapsePanels(); + } else if (mState == StatusBarState.SHADE_LOCKED) { + goToKeyguard(); + } } } setAreThereNotifications(); @@ -1614,6 +1616,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, findAndUpdateMediaNotifications(); updateCarrierLabelVisibility(false); + + // TODO: Multiuser handling! + mHasNotifications = any; } public void findAndUpdateMediaNotifications() { @@ -2346,6 +2351,13 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } @Override // CommandQueue + public void buzzBeepBlinked() { + if (mDozeServiceHost != null) { + mDozeServiceHost.fireBuzzBeepBlinked(); + } + } + + @Override // CommandQueue public void setSystemUiVisibility(int vis, int mask) { final int oldVal = mSystemUiVisibility; final int newVal = (oldVal&~mask) | (vis&mask); @@ -2795,6 +2807,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, if (mBatteryController != null) { mBatteryController.dump(fd, pw, args); } + if (mNextAlarmController != null) { + mNextAlarmController.dump(fd, pw, args); + } } private String hunStateToString(Entry entry) { @@ -2851,6 +2866,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned) { if (onlyProvisioned && !isDeviceProvisioned()) return; + final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing(); dismissKeyguardThenExecute(new OnDismissAction() { @Override public boolean onDismiss() { @@ -2861,7 +2877,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); mContext.startActivityAsUser( intent, new UserHandle(UserHandle.USER_CURRENT)); - mWindowManagerService.overridePendingAppTransition(null, 0, 0, null); + if (keyguardShowing) { + mWindowManagerService.overridePendingAppTransition( + null, 0, 0, null); + } } catch (RemoteException e) { } } @@ -2886,11 +2905,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, String action = intent.getAction(); if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) { int flags = CommandQueue.FLAG_EXCLUDE_NONE; - if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) { - String reason = intent.getStringExtra("reason"); - if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) { - flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL; - } + String reason = intent.getStringExtra("reason"); + if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) { + flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL; } animateCollapsePanels(flags); } @@ -3592,8 +3609,17 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, // ---------------------- DragDownHelper.OnDragDownListener ------------------------------------ @Override - public void onDraggedDown(View startingChild) { - goToLockedShade(startingChild); + public boolean onDraggedDown(View startingChild) { + if (mHasNotifications) { + + // We have notifications, go to locked shade. + goToLockedShade(startingChild); + return true; + } else { + + // No notifications - abort gesture. + return false; + } } @Override @@ -3601,6 +3627,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mStackScroller.setDimmed(true /* dimmed */, true /* animated */); } + @Override public void onThresholdReached() { mStackScroller.setDimmed(false /* dimmed */, true /* animate */); } @@ -3610,6 +3637,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mStackScroller.removeLongPressCallback(); } + @Override + public void setEmptyDragAmount(float amount) { + mNotificationPanel.setEmptyDragAmount(amount); + } + /** * If secure with redaction: Show bouncer, go to unlocked shade. * @@ -3720,6 +3752,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, notifyUiVisibilityChanged(mSystemUiVisibility); } + public boolean hasNotifications() { + return mHasNotifications; + } + private final class ShadeUpdates { private final ArraySet<String> mVisibleNotifications = new ArraySet<String>(); private final ArraySet<String> mNewVisibleNotifications = new ArraySet<String>(); @@ -3757,6 +3793,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private DozeService mCurrentDozeService; + public void fireBuzzBeepBlinked() { + for (Callback callback : mCallbacks) { + callback.onBuzzBeepBlinked(); + } + } + public void fireNewNotifications() { for (Callback callback : mCallbacks) { callback.onNewNotifications(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java index 65359ee..7b40d72 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java @@ -16,6 +16,8 @@ package com.android.systemui.statusbar.phone; +import android.app.AlarmClockInfo; +import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.graphics.Outline; @@ -31,18 +33,20 @@ import android.widget.RelativeLayout; import android.widget.Switch; import android.widget.TextView; +import com.android.keyguard.KeyguardStatusView; import com.android.systemui.R; import com.android.systemui.qs.QSPanel; import com.android.systemui.qs.QSTile; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.KeyguardUserSwitcher; +import com.android.systemui.statusbar.policy.NextAlarmController; import com.android.systemui.statusbar.policy.UserInfoController; /** * The view to manage the header area in the expanded status bar. */ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickListener, - BatteryController.BatteryStateChangeCallback { + BatteryController.BatteryStateChangeCallback, NextAlarmController.NextAlarmChangeCallback { private boolean mExpanded; private boolean mListening; @@ -52,7 +56,8 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL private ViewGroup mSystemIconsContainer; private View mSystemIconsSuperContainer; - private View mDateTime; + private View mDateGroup; + private View mClock; private View mTime; private View mAmPm; private View mKeyguardCarrierText; @@ -68,9 +73,12 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL private Switch mQsDetailHeaderSwitch; private View mEmergencyCallsOnly; private TextView mBatteryLevel; + private TextView mAlarmStatus; private boolean mShowEmergencyCallsOnly; private boolean mKeyguardUserSwitcherShowing; + private boolean mAlarmShowing; + private AlarmClockInfo mNextAlarm; private int mCollapsedHeight; private int mExpandedHeight; @@ -84,9 +92,13 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL private int mMultiUserKeyguardMargin; private int mSystemIconsSwitcherHiddenExpandedMargin; private int mClockMarginBottomExpanded; + private int mClockMarginBottomCollapsed; private int mMultiUserSwitchWidthCollapsed; private int mMultiUserSwitchWidthExpanded; + private int mMultiUserSwitchWidthKeyguard; private int mBatteryPaddingEnd; + private int mBatteryMarginExpanded; + private int mBatteryMarginKeyguard; /** * In collapsed QS, the clock and avatar are scaled down a bit post-layout to allow for a nice @@ -94,9 +106,11 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL */ private float mClockCollapsedScaleFactor; private float mAvatarCollapsedScaleFactor; + private float mAvatarKeyguardScaleFactor; private ActivityStarter mActivityStarter; private BatteryController mBatteryController; + private NextAlarmController mNextAlarmController; private QSPanel mQSPanel; private KeyguardUserSwitcher mKeyguardUserSwitcher; @@ -113,7 +127,8 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL mSystemIconsSuperContainer = findViewById(R.id.system_icons_super_container); mSystemIconsContainer = (ViewGroup) findViewById(R.id.system_icons_container); mSystemIconsSuperContainer.setOnClickListener(this); - mDateTime = findViewById(R.id.datetime); + mDateGroup = findViewById(R.id.date_group); + mClock = findViewById(R.id.clock); mTime = findViewById(R.id.time_view); mAmPm = findViewById(R.id.am_pm_view); mKeyguardCarrierText = findViewById(R.id.keyguard_carrier_text); @@ -129,6 +144,8 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL mQsDetailHeaderSwitch = (Switch) mQsDetailHeader.findViewById(android.R.id.toggle); mEmergencyCallsOnly = findViewById(R.id.header_emergency_calls_only); mBatteryLevel = (TextView) findViewById(R.id.battery_level); + mAlarmStatus = (TextView) findViewById(R.id.alarm_status); + mAlarmStatus.setOnClickListener(this); loadDimens(); updateVisibilities(); updateClockScale(); @@ -175,18 +192,29 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL R.dimen.system_icons_switcher_hidden_expanded_margin); mClockMarginBottomExpanded = getResources().getDimensionPixelSize(R.dimen.clock_expanded_bottom_margin); + mClockMarginBottomCollapsed = + getResources().getDimensionPixelSize(R.dimen.clock_collapsed_bottom_margin); mMultiUserSwitchWidthCollapsed = getResources().getDimensionPixelSize(R.dimen.multi_user_switch_width_collapsed); mMultiUserSwitchWidthExpanded = getResources().getDimensionPixelSize(R.dimen.multi_user_switch_width_expanded); + mMultiUserSwitchWidthKeyguard = + getResources().getDimensionPixelSize(R.dimen.multi_user_switch_width_keyguard); mAvatarCollapsedScaleFactor = getResources().getDimensionPixelSize(R.dimen.multi_user_avatar_collapsed_size) / (float) mMultiUserAvatar.getLayoutParams().width; + mAvatarKeyguardScaleFactor = + getResources().getDimensionPixelSize(R.dimen.multi_user_avatar_keyguard_size) + / (float) mMultiUserAvatar.getLayoutParams().width; mClockCollapsedScaleFactor = (float) getResources().getDimensionPixelSize(R.dimen.qs_time_collapsed_size) / (float) getResources().getDimensionPixelSize(R.dimen.qs_time_expanded_size); mBatteryPaddingEnd = getResources().getDimensionPixelSize(R.dimen.battery_level_padding_end); + mBatteryMarginExpanded = + getResources().getDimensionPixelSize(R.dimen.header_battery_margin_expanded); + mBatteryMarginKeyguard = + getResources().getDimensionPixelSize(R.dimen.header_battery_margin_keyguard); } public void setActivityStarter(ActivityStarter activityStarter) { @@ -197,6 +225,10 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL mBatteryController = batteryController; } + public void setNextAlarmController(NextAlarmController nextAlarmController) { + mNextAlarmController = nextAlarmController; + } + public int getCollapsedHeight() { return mKeyguardShowing ? mKeyguardHeight : mCollapsedHeight; } @@ -210,7 +242,7 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL return; } mListening = listening; - updateBatteryListening(); + updateListeners(); } public void setExpanded(boolean expanded, boolean overscrolled) { @@ -234,6 +266,7 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL updateAvatarScale(); updateClockLp(); updateBatteryLevelPaddingEnd(); + updateBatteryLevelLp(); mStatusIconClipper.update(); } } @@ -282,10 +315,15 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL } else { setBackgroundResource(R.drawable.notification_header_bg); } - mDateTime.setVisibility(onKeyguardAndCollapsed ? View.INVISIBLE : View.VISIBLE); + mDateGroup.setVisibility(onKeyguardAndCollapsed ? View.INVISIBLE : View.VISIBLE); + mClock.setVisibility(onKeyguardAndCollapsed ? View.INVISIBLE : View.VISIBLE); mKeyguardCarrierText.setVisibility(onKeyguardAndCollapsed ? View.VISIBLE : View.GONE); - mDateCollapsed.setVisibility(mExpanded && !mOverscrolled ? View.GONE : View.VISIBLE); - mDateExpanded.setVisibility(mExpanded && !mOverscrolled ? View.VISIBLE : View.GONE); + mDateCollapsed.setVisibility(mExpanded && !mOverscrolled && mAlarmShowing + ? View.VISIBLE : View.GONE); + mDateExpanded.setVisibility(mExpanded && !mOverscrolled && mAlarmShowing + ? View.GONE : View.VISIBLE); + mAlarmStatus.setVisibility(mExpanded && !mOverscrolled && mAlarmShowing + ? View.VISIBLE : View.GONE); mSettingsButton.setVisibility(mExpanded && !mOverscrolled ? View.VISIBLE : View.GONE); mQsDetailHeader.setVisibility(mExpanded ? View.VISIBLE : View.GONE); if (mStatusIcons != null) { @@ -319,21 +357,26 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL mSystemIconsSuperContainer.setLayoutParams(lp); } - private void updateBatteryListening() { + private void updateListeners() { if (mListening) { mBatteryController.addStateChangedCallback(this); + mNextAlarmController.addStateChangedCallback(this); } else { mBatteryController.removeStateChangedCallback(this); + mNextAlarmController.removeStateChangedCallback(this); } } private void updateAvatarScale() { - if (!mExpanded || mOverscrolled) { - mMultiUserSwitch.setScaleX(mAvatarCollapsedScaleFactor); - mMultiUserSwitch.setScaleY(mAvatarCollapsedScaleFactor); - } else { + if (mExpanded && !mOverscrolled) { mMultiUserSwitch.setScaleX(1f); mMultiUserSwitch.setScaleY(1f); + } else if (mKeyguardShowing) { + mMultiUserSwitch.setScaleX(mAvatarKeyguardScaleFactor); + mMultiUserSwitch.setScaleY(mAvatarKeyguardScaleFactor); + } else { + mMultiUserSwitch.setScaleX(mAvatarCollapsedScaleFactor); + mMultiUserSwitch.setScaleY(mAvatarCollapsedScaleFactor); } } @@ -375,15 +418,26 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL // could not care less } + @Override + public void onNextAlarmChanged(AlarmClockInfo nextAlarm) { + mNextAlarm = nextAlarm; + if (nextAlarm != null) { + mAlarmStatus.setText(KeyguardStatusView.formatNextAlarm(getContext(), nextAlarm)); + } + mAlarmShowing = nextAlarm != null; + updateVisibilities(); + } + + private void updateClickTargets() { setClickable(!mKeyguardShowing || mExpanded); - mDateTime.setClickable(mExpanded); boolean keyguardSwitcherAvailable = mKeyguardUserSwitcher != null && mKeyguardShowing && !mExpanded; mMultiUserSwitch.setClickable(mExpanded || keyguardSwitcherAvailable); mMultiUserSwitch.setKeyguardMode(keyguardSwitcherAvailable); mSystemIconsSuperContainer.setClickable(mExpanded); + mAlarmStatus.setClickable(mNextAlarm != null && mNextAlarm.getShowIntent() != null); } private void updateZTranslation() { @@ -404,29 +458,29 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL } private void updateClockLp() { - int marginBottom = mExpanded && !mOverscrolled ? mClockMarginBottomExpanded : 0; - LayoutParams lp = (LayoutParams) mDateTime.getLayoutParams(); - int rule = mExpanded && !mOverscrolled ? TRUE : 0; - if (marginBottom != lp.bottomMargin - || lp.getRules()[RelativeLayout.ALIGN_PARENT_BOTTOM] != rule) { + int marginBottom = mExpanded && !mOverscrolled + ? mClockMarginBottomExpanded + : mClockMarginBottomCollapsed; + LayoutParams lp = (LayoutParams) mDateGroup.getLayoutParams(); + if (marginBottom != lp.bottomMargin) { lp.bottomMargin = marginBottom; - lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, rule); - mDateTime.setLayoutParams(lp); + mDateGroup.setLayoutParams(lp); } } private void updateMultiUserSwitch() { int marginEnd; + int width; if (mExpanded && !mOverscrolled) { marginEnd = mMultiUserExpandedMargin; + width = mMultiUserSwitchWidthExpanded; } else if (mKeyguardShowing) { marginEnd = mMultiUserKeyguardMargin; + width = mMultiUserSwitchWidthKeyguard; } else { marginEnd = mMultiUserCollapsedMargin; + width = mMultiUserSwitchWidthCollapsed; } - int width = mExpanded && !mOverscrolled - ? mMultiUserSwitchWidthExpanded - : mMultiUserSwitchWidthCollapsed; MarginLayoutParams lp = (MarginLayoutParams) mMultiUserSwitch.getLayoutParams(); if (marginEnd != lp.getMarginEnd() || lp.width != width) { lp.setMarginEnd(marginEnd); @@ -435,6 +489,17 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL } } + private void updateBatteryLevelLp() { + int marginStart = mExpanded && !mOverscrolled + ? mBatteryMarginExpanded + : mBatteryMarginKeyguard; + MarginLayoutParams lp = (MarginLayoutParams) mBatteryLevel.getLayoutParams(); + if (marginStart != lp.getMarginStart()) { + lp.setMarginStart(marginStart); + mBatteryLevel.setLayoutParams(lp); + } + } + public void setExpansion(float t) { float height = mCollapsedHeight + t * (mExpandedHeight - mCollapsedHeight); if (height < mCollapsedHeight) { @@ -481,6 +546,7 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL updateMultiUserSwitch(); updateClickTargets(); updateBatteryLevelPaddingEnd(); + updateAvatarScale(); mStatusIconClipper.update(); } @@ -499,6 +565,11 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL startSettingsActivity(); } else if (v == mSystemIconsSuperContainer) { startBatteryActivity(); + } else if (v == mAlarmStatus && mNextAlarm != null) { + PendingIntent showIntent = mNextAlarm.getShowIntent(); + if (showIntent != null && showIntent.isActivity()) { + mActivityStarter.startActivity(showIntent.getIntent()); + } } } @@ -613,7 +684,8 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL private void handleShowingDetail(final QSTile.DetailAdapter detail) { final boolean showingDetail = detail != null; - transition(mDateTime, !showingDetail); + transition(mClock, !showingDetail); + transition(mDateGroup, !showingDetail); transition(mQsDetailHeader, showingDetail); if (showingDetail) { mQsDetailHeaderTitle.setText(detail.getTitle()); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java index 6d8b400..b64dcbe 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java @@ -24,7 +24,7 @@ public interface NetworkController { void setWifiEnabled(boolean enabled); public interface NetworkSignalChangedCallback { - void onWifiSignalChanged(boolean enabled, int wifiSignalIconId, + void onWifiSignalChanged(boolean enabled, boolean connected, int wifiSignalIconId, boolean activityIn, boolean activityOut, String wifiSignalContentDescriptionId, String description); void onMobileDataSignalChanged(boolean enabled, int mobileSignalIconId, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java index 2b08902..4fc2e06 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -401,7 +401,7 @@ public class NetworkControllerImpl extends BroadcastReceiver boolean wifiOut = wifiEnabled && mWifiSsid != null && (mWifiActivity == WifiManager.DATA_ACTIVITY_INOUT || mWifiActivity == WifiManager.DATA_ACTIVITY_OUT); - cb.onWifiSignalChanged(mWifiEnabled, mQSWifiIconId, wifiIn, wifiOut, + cb.onWifiSignalChanged(mWifiEnabled, mWifiConnected, mQSWifiIconId, wifiIn, wifiOut, mContentDescriptionWifi, wifiDesc); boolean mobileIn = mDataConnected && (mDataActivity == TelephonyManager.DATA_ACTIVITY_INOUT @@ -573,9 +573,11 @@ public class NetworkControllerImpl extends BroadcastReceiver switch(mServiceState.getVoiceRegState()) { case ServiceState.STATE_POWER_OFF: retVal = false; + break; case ServiceState.STATE_OUT_OF_SERVICE: case ServiceState.STATE_EMERGENCY_ONLY: retVal = mServiceState.getDataRegState() == ServiceState.STATE_IN_SERVICE; + break; default: retVal = true; } @@ -597,8 +599,8 @@ public class NetworkControllerImpl extends BroadcastReceiver private final void updateTelephonySignalStrength() { Rlog.d(TAG, "updateTelephonySignalStrength: hasService=" + hasService() + " ss=" + mSignalStrength); - if (false/*!hasService()*/) { - if (CHATTY) Log.d(TAG, "updateTelephonySignalStrength: !hasService()"); + if (!hasService()) { + if (true/*CHATTY*/) Log.d(TAG, "updateTelephonySignalStrength: !hasService()"); mPhoneSignalIconId = R.drawable.stat_sys_signal_null; mQSPhoneSignalIconId = R.drawable.ic_qs_signal_no_signal; mDataSignalIconId = R.drawable.stat_sys_signal_null; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NextAlarmController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NextAlarmController.java new file mode 100644 index 0000000..ca71521 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NextAlarmController.java @@ -0,0 +1,84 @@ +/* + * 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.policy; + +import android.app.AlarmClockInfo; +import android.app.AlarmManager; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.UserHandle; + +import java.io.FileDescriptor; +import java.io.PrintWriter; +import java.util.ArrayList; + +public class NextAlarmController extends BroadcastReceiver { + + private final ArrayList<NextAlarmChangeCallback> mChangeCallbacks = new ArrayList<>(); + + private AlarmManager mAlarmManager; + private AlarmClockInfo mNextAlarm; + + public NextAlarmController(Context context) { + mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_USER_SWITCHED); + filter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED); + context.registerReceiver(this, filter); + updateNextAlarm(); + } + + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + pw.println("NextAlarmController state:"); + pw.print(" mNextAlarm="); pw.println(mNextAlarm); + } + + public void addStateChangedCallback(NextAlarmChangeCallback cb) { + mChangeCallbacks.add(cb); + cb.onNextAlarmChanged(mNextAlarm); + } + + public void removeStateChangedCallback(NextAlarmChangeCallback cb) { + mChangeCallbacks.remove(cb); + } + + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + if (action.equals(Intent.ACTION_USER_SWITCHED) + || action.equals(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED)) { + updateNextAlarm(); + } + } + + private void updateNextAlarm() { + mNextAlarm = mAlarmManager.getNextAlarmClock(UserHandle.USER_CURRENT); + fireNextAlarmChanged(); + } + + private void fireNextAlarmChanged() { + int n = mChangeCallbacks.size(); + for (int i = 0; i < n; i++) { + mChangeCallbacks.get(i).onNextAlarmChanged(mNextAlarm); + } + } + + public interface NextAlarmChangeCallback { + void onNextAlarmChanged(AlarmClockInfo nextAlarm); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java new file mode 100644 index 0000000..d405172 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java @@ -0,0 +1,127 @@ +/* + * 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.policy; + +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.pm.UserInfo; +import android.os.UserHandle; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; + +import com.android.internal.widget.LockPatternUtils; +import com.android.keyguard.KeyguardActivityLauncher; +import com.android.systemui.statusbar.phone.KeyguardPreviewContainer; + +import java.util.List; + +/** + * Utility class to inflate previews for phone and camera affordance. + */ +public class PreviewInflater { + + private static final String TAG = "PreviewInflater"; + + private static final String META_DATA_KEYGUARD_LAYOUT = "com.android.keyguard.layout"; + + private Context mContext; + private LockPatternUtils mLockPatternUtils; + + public PreviewInflater(Context context, LockPatternUtils lockPatternUtils) { + mContext = context; + mLockPatternUtils = lockPatternUtils; + } + + public View inflatePreview(Intent intent) { + WidgetInfo info = getWidgetInfo(intent); + if (info == null) { + return null; + } + View v = inflateWidgetView(info); + if (v == null) { + return null; + } + KeyguardPreviewContainer container = new KeyguardPreviewContainer(mContext, null); + container.addView(v); + return container; + } + + private View inflateWidgetView(WidgetInfo widgetInfo) { + View widgetView = null; + try { + Context appContext = mContext.createPackageContext( + widgetInfo.contextPackage, Context.CONTEXT_RESTRICTED); + LayoutInflater appInflater = (LayoutInflater) + appContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + appInflater = appInflater.cloneInContext(appContext); + widgetView = appInflater.inflate(widgetInfo.layoutId, null, false); + } catch (PackageManager.NameNotFoundException|RuntimeException e) { + Log.w(TAG, "Error creating widget view", e); + } + return widgetView; + } + + private WidgetInfo getWidgetInfo(Intent intent) { + WidgetInfo info = new WidgetInfo(); + PackageManager packageManager = mContext.getPackageManager(); + final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser( + intent, PackageManager.MATCH_DEFAULT_ONLY, mLockPatternUtils.getCurrentUser()); + if (appList.size() == 0) { + return null; + } + ResolveInfo resolved = packageManager.resolveActivityAsUser(intent, + PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA, + mLockPatternUtils.getCurrentUser()); + if (wouldLaunchResolverActivity(resolved, appList)) { + return null; + } + if (resolved == null || resolved.activityInfo == null) { + return null; + } + if (resolved.activityInfo.metaData == null || resolved.activityInfo.metaData.isEmpty()) { + return null; + } + int layoutId = resolved.activityInfo.metaData.getInt(META_DATA_KEYGUARD_LAYOUT); + if (layoutId == 0) { + return null; + } + info.contextPackage = resolved.activityInfo.packageName; + info.layoutId = layoutId; + return info; + } + + private boolean wouldLaunchResolverActivity(ResolveInfo resolved, List<ResolveInfo> appList) { + // If the list contains the above resolved activity, then it can't be + // ResolverActivity itself. + for (int i = 0; i < appList.size(); i++) { + ResolveInfo tmp = appList.get(i); + if (tmp.activityInfo.name.equals(resolved.activityInfo.name) + && tmp.activityInfo.packageName.equals(resolved.activityInfo.packageName)) { + return false; + } + } + return true; + } + + private static class WidgetInfo { + String contextPackage; + int layoutId; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java index d0f61f0..a123bf7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java @@ -95,6 +95,10 @@ public class TvStatusBar extends BaseStatusBar { public void setWindowState(int window, int state) { } + @Override // CommandQueue + public void buzzBeepBlinked() { + } + @Override protected WindowManager.LayoutParams getSearchLayoutParams( LayoutParams layoutParams) { |
