diff options
author | John Spurlock <jspurlock@google.com> | 2014-09-11 18:33:23 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-09-11 18:33:38 +0000 |
commit | 3e42b339800f5a3ac840e9545c36f3445b5c64b3 (patch) | |
tree | 3aab1ea88ccf8a10c57d92c5c44284f6e0b48ce7 /packages/SystemUI | |
parent | f563e7ece698230d63620047e4d7aeb32104b9a8 (diff) | |
parent | d06aa570374ecfe5c707140a12a309b1b7c07e08 (diff) | |
download | frameworks_base-3e42b339800f5a3ac840e9545c36f3445b5c64b3.zip frameworks_base-3e42b339800f5a3ac840e9545c36f3445b5c64b3.tar.gz frameworks_base-3e42b339800f5a3ac840e9545c36f3445b5c64b3.tar.bz2 |
Merge "Doze: Introduce a pulse period function." into lmp-dev
Diffstat (limited to 'packages/SystemUI')
6 files changed, 215 insertions, 71 deletions
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 5a1c318..f899572 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -191,11 +191,21 @@ <!-- Doze: maximum brightness to use when pulsing --> <integer name="doze_pulse_brightness">40</integer> - <!-- Doze: number of pulses when doing multiple pulses in quick succession --> - <integer name="doze_multipulse_count">3</integer> + <!-- Doze: period of time between pulses (start of pulse) when following the notification light + Format: <under_ms>:<period_ms>,...,<default_ms> --> + <string name="doze_pulse_period_function">60000:10000,300000:30000,1800000:60000,0</string> - <!-- Doze: interval between pulses when following the notification light --> - <integer name="doze_notification_pulse_interval">30000</integer> + <!-- Doze: pulse parameter - how long does it take to fade in? --> + <integer name="doze_pulse_duration_in">1000</integer> + + <!-- Doze: pulse parameter - once faded in, how long does it stay visible? --> + <integer name="doze_pulse_duration_visible">3000</integer> + + <!-- Doze: pulse parameter - how long does it take to fade out? --> + <integer name="doze_pulse_duration_out">1000</integer> + + <!-- Doze: pulse parameter - how long to wait before pulsing (if not starting immediately) --> + <integer name="doze_pulse_delay">1000</integer> <!-- Doze: alpha to apply to small icons when dozing --> <integer name="doze_small_icon_alpha">222</integer><!-- 87% of 0xff --> diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java index d17e263..1183582 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java @@ -42,6 +42,7 @@ import android.view.Display; import com.android.systemui.R; import com.android.systemui.SystemUIApplication; +import com.android.systemui.statusbar.phone.DozeParameters; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -54,11 +55,11 @@ public class DozeService extends DreamService { private static final String ACTION_BASE = "com.android.systemui.doze"; private static final String PULSE_ACTION = ACTION_BASE + ".pulse"; private static final String NOTIFICATION_PULSE_ACTION = ACTION_BASE + ".notification_pulse"; - private static final String EXTRA_PULSES = "pulses"; private final String mTag = String.format(TAG + ".%08x", hashCode()); private final Context mContext = this; private final Handler mHandler = new Handler(); + private final DozeParameters mDozeParameters = new DozeParameters(mContext); private Host mHost; private SensorManager mSensors; @@ -74,9 +75,8 @@ public class DozeService extends DreamService { private int mDisplayStateWhenOn; private boolean mNotificationLightOn; private PendingIntent mNotificationPulseIntent; - private int mMultipulseCount; - private int mNotificationPulseInterval; private boolean mPowerSaveActive; + private long mNotificationPulseTime; public DozeService() { if (DEBUG) Log.d(mTag, "new DozeService()"); @@ -94,9 +94,9 @@ public class DozeService extends DreamService { pw.print(" mMaxBrightness: "); pw.println(mMaxBrightness); pw.print(" mDisplayStateSupported: "); pw.println(mDisplayStateSupported); pw.print(" mNotificationLightOn: "); pw.println(mNotificationLightOn); - pw.print(" mMultipulseCount: "); pw.println(mMultipulseCount); - pw.print(" mNotificationPulseInterval: "); pw.println(mNotificationPulseInterval); pw.print(" mPowerSaveActive: "); pw.println(mPowerSaveActive); + pw.print(" mNotificationPulseTime: "); pw.println(mNotificationPulseTime); + mDozeParameters.dump(pw); } @Override @@ -127,11 +127,7 @@ public class DozeService extends DreamService { BRIGHTNESS_OFF, BRIGHTNESS_ON); mNotificationPulseIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(NOTIFICATION_PULSE_ACTION).setPackage(getPackageName()), - PendingIntent.FLAG_CANCEL_CURRENT); - mMultipulseCount = SystemProperties.getInt("doze.multipulses", - res.getInteger(R.integer.doze_multipulse_count)); - mNotificationPulseInterval = SystemProperties.getInt("doze.notification.pulse", - res.getInteger(R.integer.doze_notification_pulse_interval)); + PendingIntent.FLAG_UPDATE_CURRENT); mDisplayStateWhenOn = mDisplayStateSupported ? Display.STATE_DOZE : Display.STATE_ON; setDozeScreenState(mDisplayStateWhenOn); } @@ -159,6 +155,7 @@ public class DozeService extends DreamService { public void stayAwake(long millis) { if (mDreaming && millis > 0) { + if (DEBUG) Log.d(mTag, "stayAwake millis=" + millis); mWakeLock.acquire(millis); setDozeScreenState(mDisplayStateWhenOn); setDozeScreenBrightness(mMaxBrightness); @@ -218,21 +215,9 @@ public class DozeService extends DreamService { } } - private void requestMultipulse() { - requestPulse(mMultipulseCount); - } - - private void requestPulse() { - requestPulse(1); - } - - private void requestPulse(int pulses) { - requestPulse(pulses, true /*delayed*/); - } - - private void requestPulse(int pulses, boolean delayed) { + private void requestPulse(boolean delayed) { if (mHost != null) { - mHost.requestPulse(pulses, delayed, this); + mHost.requestPulse(delayed, this); } } @@ -281,9 +266,14 @@ public class DozeService extends DreamService { private void rescheduleNotificationPulse() { mAlarmManager.cancel(mNotificationPulseIntent); if (mNotificationLightOn) { - final long time = System.currentTimeMillis() + mNotificationPulseInterval; - if (DEBUG) Log.d(TAG, "Scheduling pulse for " + new Date(time)); - mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, time, mNotificationPulseIntent); + final long now = System.currentTimeMillis(); + final long age = now - mNotificationPulseTime; + final long period = mDozeParameters.getPulsePeriod(age); + final long time = now + period; + if (period > 0) { + if (DEBUG) Log.d(TAG, "Scheduling pulse in " + period + " for " + new Date(time)); + mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, time, mNotificationPulseIntent); + } } } @@ -314,11 +304,11 @@ public class DozeService extends DreamService { public void onReceive(Context context, Intent intent) { if (PULSE_ACTION.equals(intent.getAction())) { if (DEBUG) Log.d(mTag, "Received pulse intent"); - requestPulse(intent.getIntExtra(EXTRA_PULSES, mMultipulseCount)); + requestPulse(false /*delayed*/); } if (NOTIFICATION_PULSE_ACTION.equals(intent.getAction())) { if (DEBUG) Log.d(mTag, "Received notification pulse intent"); - requestPulse(); + requestPulse(true /*delayed*/); rescheduleNotificationPulse(); } } @@ -334,7 +324,8 @@ public class DozeService extends DreamService { @Override public void onBuzzBeepBlinked() { if (DEBUG) Log.d(mTag, "onBuzzBeepBlinked"); - requestMultipulse(); + mNotificationPulseTime = System.currentTimeMillis(); + requestPulse(true /*delayed*/); } @Override @@ -342,6 +333,10 @@ public class DozeService extends DreamService { if (DEBUG) Log.d(mTag, "onNotificationLight on=" + on); if (mNotificationLightOn == on) return; mNotificationLightOn = on; + if (mNotificationLightOn) { + mNotificationPulseTime = System.currentTimeMillis(); + requestPulse(true /*delayed*/); + } rescheduleNotificationPulse(); } @@ -358,7 +353,7 @@ public class DozeService extends DreamService { void addCallback(Callback callback); void removeCallback(Callback callback); void requestDoze(DozeService dozeService); - void requestPulse(int pulses, boolean delayed, DozeService dozeService); + void requestPulse(boolean delayed, DozeService dozeService); void dozingStopped(DozeService dozeService); boolean isPowerSaveActive(); @@ -409,7 +404,7 @@ public class DozeService extends DreamService { .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION).build()); } } - requestPulse(1, false /*delayed*/); + requestPulse(false /*delayed*/); setListening(true); // reregister, this sensor only fires once } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java new file mode 100644 index 0000000..e14ef12 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java @@ -0,0 +1,132 @@ +/* + * 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.os.SystemProperties; +import android.text.TextUtils; +import android.util.Log; +import android.util.MathUtils; + +import com.android.systemui.R; + +import java.io.PrintWriter; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class DozeParameters { + private static final String TAG = "DozeParameters"; + + private static final int MAX_DURATION = 10 * 1000; + + private final Context mContext; + + private StepFunction mPulsePeriodFunction; + + public DozeParameters(Context context) { + mContext = context; + } + + public void dump(PrintWriter pw) { + pw.println(" DozeParameters:"); + pw.print(" getPulseDuration(): "); pw.println(getPulseDuration()); + pw.print(" getPulseInDuration(): "); pw.println(getPulseInDuration()); + pw.print(" getPulseInVisibleDuration(): "); pw.println(getPulseVisibleDuration()); + pw.print(" getPulseOutDuration(): "); pw.println(getPulseOutDuration()); + pw.print(" getPulseStartDelay(): "); pw.println(getPulseStartDelay()); + pw.print(" getPulsePeriodFunction(): "); pw.println(getPulsePeriodFunction()); + } + + public int getPulseDuration() { + return getPulseInDuration() + getPulseVisibleDuration() + getPulseOutDuration(); + } + + public int getPulseInDuration() { + return getInt("doze.pulse.duration.in", R.integer.doze_pulse_duration_in); + } + + public int getPulseVisibleDuration() { + return getInt("doze.pulse.duration.visible", R.integer.doze_pulse_duration_visible); + } + + public int getPulseOutDuration() { + return getInt("doze.pulse.duration.out", R.integer.doze_pulse_duration_out); + } + + public int getPulseStartDelay() { + return getInt("doze.pulse.delay", R.integer.doze_pulse_delay); + } + + public long getPulsePeriod(long age) { + final String spec = getPulsePeriodFunction(); + if (mPulsePeriodFunction == null || !mPulsePeriodFunction.mSpec.equals(spec)) { + mPulsePeriodFunction = StepFunction.parse(spec); + } + return mPulsePeriodFunction != null ? mPulsePeriodFunction.evaluate(age) : 0; + } + + private String getPulsePeriodFunction() { + return getString("doze.pulse.period.function", R.string.doze_pulse_period_function); + } + + private int getInt(String propName, int resId) { + int value = SystemProperties.getInt(propName, mContext.getResources().getInteger(resId)); + return MathUtils.constrain(value, 0, MAX_DURATION); + } + + private String getString(String propName, int resId) { + return SystemProperties.get(propName, mContext.getString(resId)); + } + + private static class StepFunction { + private static final Pattern PATTERN = Pattern.compile("(\\d+?)(:(\\d+?))?", 0); + + private String mSpec; + private long[] mSteps; + private long[] mValues; + private long mDefault; + + public static StepFunction parse(String spec) { + if (TextUtils.isEmpty(spec)) return null; + try { + final StepFunction rt = new StepFunction(); + rt.mSpec = spec; + final String[] tokens = spec.split(","); + rt.mSteps = new long[tokens.length - 1]; + rt.mValues = new long[tokens.length - 1]; + for (int i = 0; i < tokens.length - 1; i++) { + final Matcher m = PATTERN.matcher(tokens[i]); + if (!m.matches()) throw new IllegalArgumentException("Bad token: " + tokens[i]); + rt.mSteps[i] = Long.parseLong(m.group(1)); + rt.mValues[i] = Long.parseLong(m.group(3)); + } + rt.mDefault = Long.parseLong(tokens[tokens.length - 1]); + return rt; + } catch (RuntimeException e) { + Log.w(TAG, "Error parsing spec: " + spec, e); + return null; + } + } + + public long evaluate(long x) { + for (int i = 0; i < mSteps.length; i++) { + if (x < mSteps[i]) return mValues[i]; + } + return mDefault; + } + } +} 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 5d4c831..271383f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -3949,7 +3949,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } public void wakeUpIfDozing(long time) { - if (mDozeServiceHost != null && mDozeServiceHost.isDozing()) { + if (mDozeServiceHost != null && mDozeServiceHost.isDozing() + && mScrimController.isPulsing()) { PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); pm.wakeUp(time); } @@ -4045,10 +4046,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } @Override - public void requestPulse(int pulses, boolean delayed, DozeService dozeService) { + public void requestPulse(boolean delayed, DozeService dozeService) { if (dozeService == null) return; dozeService.stayAwake(PROCESSING_TIME); - mHandler.obtainMessage(H.REQUEST_PULSE, pulses, delayed ? 1 : 0, dozeService) + mHandler.obtainMessage(H.REQUEST_PULSE, delayed ? 1 : 0, 0, dozeService) .sendToTarget(); } @@ -4073,9 +4074,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mCurrentDozeService.startDozing(); } - private void handleRequestPulse(int pulses, boolean delayed, DozeService dozeService) { + private void handleRequestPulse(boolean delayed, DozeService dozeService) { if (!dozeService.equals(mCurrentDozeService)) return; - final long stayAwake = mScrimController.pulse(pulses, delayed); + final long stayAwake = mScrimController.pulse(delayed); mCurrentDozeService.stayAwake(stayAwake); } @@ -4099,7 +4100,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, if (msg.what == REQUEST_DOZE) { handleRequestDoze((DozeService) msg.obj); } else if (msg.what == REQUEST_PULSE) { - handleRequestPulse(msg.arg1, msg.arg2 != 0, (DozeService) msg.obj); + handleRequestPulse(msg.arg1 != 0, (DozeService) msg.obj); } else if (msg.what == DOZING_STOPPED) { handleDozingStopped((DozeService) msg.obj); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index be48df7..57e5755 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -19,6 +19,7 @@ package com.android.systemui.statusbar.phone; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; +import android.content.Context; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.util.Log; @@ -36,7 +37,7 @@ import com.android.systemui.R; */ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { private static final String TAG = "ScrimController"; - private static final boolean DEBUG = false; + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); public static final long ANIMATION_DURATION = 220; @@ -46,17 +47,10 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { private static final float SCRIM_IN_FRONT_ALPHA = 0.75f; private static final int TAG_KEY_ANIM = R.id.scrim; - private static final long PULSE_IN_ANIMATION_DURATION = 1000; - private static final long PULSE_VISIBLE_DURATION = 3000; - private static final long PULSE_OUT_ANIMATION_DURATION = 1000; - private static final long PULSE_INVISIBLE_DURATION = 1000; - private static final long PULSE_DURATION = PULSE_IN_ANIMATION_DURATION - + PULSE_VISIBLE_DURATION + PULSE_OUT_ANIMATION_DURATION + PULSE_INVISIBLE_DURATION; - private static final long PRE_PULSE_DELAY = 1000; - private final View mScrimBehind; private final View mScrimInFront; private final UnlockMethodCache mUnlockMethodCache; + private final DozeParameters mDozeParameters; private boolean mKeyguardShowing; private float mFraction; @@ -72,16 +66,18 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { private Runnable mOnAnimationFinished; private boolean mAnimationStarted; private boolean mDozing; - private int mPulsesRemaining; + private long mPulseEndTime; private final Interpolator mInterpolator = new DecelerateInterpolator(); private final Interpolator mLinearOutSlowInInterpolator; public ScrimController(View scrimBehind, View scrimInFront) { mScrimBehind = scrimBehind; mScrimInFront = scrimInFront; - mUnlockMethodCache = UnlockMethodCache.getInstance(scrimBehind.getContext()); - mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(scrimBehind.getContext(), + final Context context = scrimBehind.getContext(); + mUnlockMethodCache = UnlockMethodCache.getInstance(context); + mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in); + mDozeParameters = new DozeParameters(context); } public void setKeyguardShowing(boolean showing) { @@ -137,19 +133,28 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { scheduleUpdate(); } - /** When dozing, fade screen contents in and out a few times using the front scrim. */ - public long pulse(int pulses, boolean delayed) { + /** When dozing, fade screen contents in and out using the front scrim. */ + public long pulse(boolean delayed) { if (!mDozing) return 0; - mPulsesRemaining = Math.max(pulses, mPulsesRemaining); - final long delay = delayed ? PRE_PULSE_DELAY : 0; + final long now = System.currentTimeMillis(); + if (DEBUG) Log.d(TAG, "pulse delayed=" + delayed + " mPulseEndTime=" + mPulseEndTime + + " now=" + now); + if (mPulseEndTime != 0 && mPulseEndTime > now) return mPulseEndTime - now; + final long delay = delayed ? mDozeParameters.getPulseStartDelay() : 0; mScrimInFront.postDelayed(mPulseIn, delay); - return delay + mPulsesRemaining * PULSE_DURATION; + mPulseEndTime = now + delay + mDozeParameters.getPulseDuration(); + return mPulseEndTime - now; + } + + public boolean isPulsing() { + return mDozing && mPulseEndTime != 0; } private void cancelPulsing() { - mPulsesRemaining = 0; + if (DEBUG) Log.d(TAG, "Cancel pulsing"); mScrimInFront.removeCallbacks(mPulseIn); mScrimInFront.removeCallbacks(mPulseOut); + mPulseEndTime = 0; } private void scheduleUpdate() { @@ -302,11 +307,9 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { private final Runnable mPulseIn = new Runnable() { @Override public void run() { - if (DEBUG) Log.d(TAG, "Pulse in, mDozing=" + mDozing - + " mPulsesRemaining=" + mPulsesRemaining); - if (!mDozing || mPulsesRemaining == 0) return; - mPulsesRemaining--; - mDurationOverride = PULSE_IN_ANIMATION_DURATION; + if (DEBUG) Log.d(TAG, "Pulse in, mDozing=" + mDozing); + if (!mDozing) return; + mDurationOverride = mDozeParameters.getPulseInDuration(); mAnimationDelay = 0; mAnimateChange = true; mOnAnimationFinished = mPulseInFinished; @@ -319,7 +322,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { public void run() { if (DEBUG) Log.d(TAG, "Pulse in finished, mDozing=" + mDozing); if (!mDozing) return; - mScrimInFront.postDelayed(mPulseOut, PULSE_VISIBLE_DURATION); + mScrimInFront.postDelayed(mPulseOut, mDozeParameters.getPulseVisibleDuration()); } }; @@ -328,7 +331,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { public void run() { if (DEBUG) Log.d(TAG, "Pulse out, mDozing=" + mDozing); if (!mDozing) return; - mDurationOverride = PULSE_OUT_ANIMATION_DURATION; + mDurationOverride = mDozeParameters.getPulseOutDuration(); mAnimationDelay = 0; mAnimateChange = true; mOnAnimationFinished = mPulseOutFinished; @@ -339,10 +342,8 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { private final Runnable mPulseOutFinished = new Runnable() { @Override public void run() { - if (DEBUG) Log.d(TAG, "Pulse out finished, mPulsesRemaining=" + mPulsesRemaining); - if (mPulsesRemaining > 0) { - mScrimInFront.postDelayed(mPulseIn, PULSE_INVISIBLE_DURATION); - } + if (DEBUG) Log.d(TAG, "Pulse out finished"); + mPulseEndTime = 0; } }; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java index a5217ab..42cfd39 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java @@ -100,6 +100,11 @@ public class StatusBarWindowView extends FrameLayout { if (!down) { return mService.onSpacePressed(); } + case KeyEvent.KEYCODE_VOLUME_DOWN: + case KeyEvent.KEYCODE_VOLUME_UP: + if (down) { + mService.wakeUpIfDozing(event.getEventTime()); + } } if (mService.interceptMediaKey(event)) { return true; |