Merge "NoMan/SysUI: Clear LEDs only when entering the shade" into lmp-mr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
27ef018846
@@ -40,8 +40,10 @@ interface IStatusBarService
|
||||
// You need the STATUS_BAR_SERVICE permission
|
||||
void registerStatusBar(IStatusBar callbacks, out StatusBarIconList iconList,
|
||||
out int[] switches, out List<IBinder> binders);
|
||||
void onPanelRevealed();
|
||||
void onPanelRevealed(boolean clearNotificationEffects);
|
||||
void onPanelHidden();
|
||||
// Mark current notifications as "seen" and stop ringing, vibrating, blinking.
|
||||
void clearNotificationEffects();
|
||||
void onNotificationClick(String key);
|
||||
void onNotificationActionClick(String key, int actionIndex);
|
||||
void onNotificationError(String pkg, String tag, int id,
|
||||
|
||||
@@ -28,6 +28,7 @@ public interface DozeHost {
|
||||
void pulseWhileDozing(@NonNull PulseCallback callback, int reason);
|
||||
void stopDozing();
|
||||
boolean isPowerSaveActive();
|
||||
boolean isNotificationLightOn();
|
||||
|
||||
public interface Callback {
|
||||
void onNewNotifications();
|
||||
@@ -40,4 +41,4 @@ public interface DozeHost {
|
||||
void onPulseStarted();
|
||||
void onPulseFinished();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,17 @@ public class DozeService extends DreamService {
|
||||
private static final String NOTIFICATION_PULSE_ACTION = ACTION_BASE + ".notification_pulse";
|
||||
private static final String EXTRA_INSTANCE = "instance";
|
||||
|
||||
/**
|
||||
* Earliest time we pulse due to a notification light after the service started.
|
||||
*
|
||||
* <p>Incoming notification light events during the blackout period are
|
||||
* delayed to the earliest time defined by this constant.</p>
|
||||
*
|
||||
* <p>This delay avoids a pulse immediately after screen off, at which
|
||||
* point the notification light is re-enabled again by NoMan.</p>
|
||||
*/
|
||||
private static final int EARLIEST_LIGHT_PULSE_AFTER_START_MS = 10 * 1000;
|
||||
|
||||
private final String mTag = String.format(TAG + ".%08x", hashCode());
|
||||
private final Context mContext = this;
|
||||
private final DozeParameters mDozeParameters = new DozeParameters(mContext);
|
||||
@@ -77,6 +88,7 @@ public class DozeService extends DreamService {
|
||||
private boolean mPowerSaveActive;
|
||||
private boolean mCarMode;
|
||||
private long mNotificationPulseTime;
|
||||
private long mEarliestPulseDueToLight;
|
||||
private int mScheduleResetsRemaining;
|
||||
|
||||
public DozeService() {
|
||||
@@ -161,8 +173,9 @@ public class DozeService extends DreamService {
|
||||
}
|
||||
|
||||
mDreaming = true;
|
||||
listenForPulseSignals(true);
|
||||
rescheduleNotificationPulse(false /*predicate*/); // cancel any pending pulse alarms
|
||||
mEarliestPulseDueToLight = System.currentTimeMillis() + EARLIEST_LIGHT_PULSE_AFTER_START_MS;
|
||||
listenForPulseSignals(true);
|
||||
|
||||
// Ask the host to get things ready to start dozing.
|
||||
// Once ready, we call startDozing() at which point the CPU may suspend
|
||||
@@ -298,6 +311,12 @@ public class DozeService extends DreamService {
|
||||
if (listen) {
|
||||
resetNotificationResets();
|
||||
mHost.addCallback(mHostCallback);
|
||||
|
||||
// Continue to pulse for existing LEDs.
|
||||
mNotificationLightOn = mHost.isNotificationLightOn();
|
||||
if (mNotificationLightOn) {
|
||||
updateNotificationPulseDueToLight();
|
||||
}
|
||||
} else {
|
||||
mHost.removeCallback(mHostCallback);
|
||||
}
|
||||
@@ -308,21 +327,26 @@ public class DozeService extends DreamService {
|
||||
mScheduleResetsRemaining = mDozeParameters.getPulseScheduleResets();
|
||||
}
|
||||
|
||||
private void updateNotificationPulse() {
|
||||
if (DEBUG) Log.d(mTag, "updateNotificationPulse");
|
||||
private void updateNotificationPulseDueToLight() {
|
||||
long timeMs = System.currentTimeMillis();
|
||||
timeMs = Math.max(timeMs, mEarliestPulseDueToLight);
|
||||
updateNotificationPulse(timeMs);
|
||||
}
|
||||
|
||||
private void updateNotificationPulse(long notificationTimeMs) {
|
||||
if (DEBUG) Log.d(mTag, "updateNotificationPulse notificationTimeMs=" + notificationTimeMs);
|
||||
if (!mDozeParameters.getPulseOnNotifications()) return;
|
||||
if (mScheduleResetsRemaining <= 0) {
|
||||
if (DEBUG) Log.d(mTag, "No more schedule resets remaining");
|
||||
return;
|
||||
}
|
||||
final long now = System.currentTimeMillis();
|
||||
if ((now - mNotificationPulseTime) < mDozeParameters.getPulseDuration()) {
|
||||
if ((notificationTimeMs - mNotificationPulseTime) < mDozeParameters.getPulseDuration()) {
|
||||
if (DEBUG) Log.d(mTag, "Recently updated, not resetting schedule");
|
||||
return;
|
||||
}
|
||||
mScheduleResetsRemaining--;
|
||||
if (DEBUG) Log.d(mTag, "mScheduleResetsRemaining = " + mScheduleResetsRemaining);
|
||||
mNotificationPulseTime = now;
|
||||
mNotificationPulseTime = notificationTimeMs;
|
||||
rescheduleNotificationPulse(true /*predicate*/);
|
||||
}
|
||||
|
||||
@@ -404,14 +428,14 @@ public class DozeService extends DreamService {
|
||||
private final DozeHost.Callback mHostCallback = new DozeHost.Callback() {
|
||||
@Override
|
||||
public void onNewNotifications() {
|
||||
if (DEBUG) Log.d(mTag, "onNewNotifications");
|
||||
if (DEBUG) Log.d(mTag, "onNewNotifications (noop)");
|
||||
// noop for now
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBuzzBeepBlinked() {
|
||||
if (DEBUG) Log.d(mTag, "onBuzzBeepBlinked");
|
||||
updateNotificationPulse();
|
||||
updateNotificationPulse(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -420,7 +444,7 @@ public class DozeService extends DreamService {
|
||||
if (mNotificationLightOn == on) return;
|
||||
mNotificationLightOn = on;
|
||||
if (mNotificationLightOn) {
|
||||
updateNotificationPulse();
|
||||
updateNotificationPulseDueToLight();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1648,7 +1648,11 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
protected void handleVisibleToUserChanged(boolean visibleToUser) {
|
||||
try {
|
||||
if (visibleToUser) {
|
||||
mBarService.onPanelRevealed();
|
||||
// Only stop blinking, vibrating, ringing when the user went into the shade
|
||||
// manually (SHADE or SHADE_LOCKED).
|
||||
boolean clearNotificationEffects =
|
||||
(mState == StatusBarState.SHADE || mState == StatusBarState.SHADE_LOCKED);
|
||||
mBarService.onPanelRevealed(clearNotificationEffects);
|
||||
} else {
|
||||
mBarService.onPanelHidden();
|
||||
}
|
||||
|
||||
@@ -3795,6 +3795,16 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
* @param state The {@link StatusBarState} to set.
|
||||
*/
|
||||
public void setBarState(int state) {
|
||||
// If we're visible and switched to SHADE_LOCKED (the user dragged down
|
||||
// on the lockscreen), clear notification LED, vibration, ringing.
|
||||
// Other transitions are covered in handleVisibleToUserChanged().
|
||||
if (mVisible && mState != state && state == StatusBarState.SHADE_LOCKED) {
|
||||
try {
|
||||
mBarService.clearNotificationEffects();
|
||||
} catch (RemoteException e) {
|
||||
// Ignore.
|
||||
}
|
||||
}
|
||||
mState = state;
|
||||
mStatusBarWindowManager.setStatusBarState(state);
|
||||
}
|
||||
@@ -4126,6 +4136,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
|
||||
private final H mHandler = new H();
|
||||
|
||||
// Keeps the last reported state by fireNotificationLight.
|
||||
private boolean mNotificationLightOn;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PSB.DozeServiceHost[mCallbacks=" + mCallbacks.size() + "]";
|
||||
@@ -4144,6 +4157,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
}
|
||||
|
||||
public void fireNotificationLight(boolean on) {
|
||||
mNotificationLightOn = on;
|
||||
for (Callback callback : mCallbacks) {
|
||||
callback.onNotificationLight(on);
|
||||
}
|
||||
@@ -4185,6 +4199,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
return mBatteryController != null && mBatteryController.isPowerSave();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNotificationLightOn() {
|
||||
return mNotificationLightOn;
|
||||
}
|
||||
|
||||
private void handleStartDozing(@NonNull Runnable ready) {
|
||||
if (!mDozing) {
|
||||
mDozing = true;
|
||||
|
||||
@@ -26,8 +26,9 @@ public interface NotificationDelegate {
|
||||
void onNotificationError(int callingUid, int callingPid,
|
||||
String pkg, String tag, int id,
|
||||
int uid, int initialPid, String message, int userId);
|
||||
void onPanelRevealed();
|
||||
void onPanelRevealed(boolean clearEffects);
|
||||
void onPanelHidden();
|
||||
void clearEffects();
|
||||
void onNotificationVisibilityChanged(
|
||||
String[] newlyVisibleKeys, String[] noLongerVisibleKeys);
|
||||
void onNotificationExpansionChanged(String key, boolean userAction, boolean expanded);
|
||||
|
||||
@@ -123,7 +123,7 @@ import java.util.Objects;
|
||||
/** {@hide} */
|
||||
public class NotificationManagerService extends SystemService {
|
||||
static final String TAG = "NotificationService";
|
||||
static final boolean DBG = false;
|
||||
static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
|
||||
static final int MAX_PACKAGE_NOTIFICATIONS = 50;
|
||||
|
||||
@@ -577,9 +577,23 @@ public class NotificationManagerService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPanelRevealed() {
|
||||
public void onPanelRevealed(boolean clearEffects) {
|
||||
EventLogTags.writeNotificationPanelRevealed();
|
||||
if (clearEffects) {
|
||||
clearEffects();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPanelHidden() {
|
||||
EventLogTags.writeNotificationPanelHidden();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearEffects() {
|
||||
synchronized (mNotificationList) {
|
||||
if (DBG) Slog.d(TAG, "clearEffects");
|
||||
|
||||
// sound
|
||||
mSoundNotification = null;
|
||||
|
||||
@@ -610,11 +624,6 @@ public class NotificationManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPanelHidden() {
|
||||
EventLogTags.writeNotificationPanelHidden();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNotificationError(int callingUid, int callingPid, String pkg, String tag, int id,
|
||||
int uid, int initialPid, String message, int userId) {
|
||||
@@ -753,8 +762,10 @@ public class NotificationManagerService extends SystemService {
|
||||
// Keep track of screen on/off state, but do not turn off the notification light
|
||||
// until user passes through the lock screen or views the notification.
|
||||
mScreenOn = true;
|
||||
updateNotificationPulse();
|
||||
} else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
|
||||
mScreenOn = false;
|
||||
updateNotificationPulse();
|
||||
} else if (action.equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
|
||||
mInCall = TelephonyManager.EXTRA_STATE_OFFHOOK
|
||||
.equals(intent.getStringExtra(TelephonyManager.EXTRA_STATE));
|
||||
|
||||
@@ -26,7 +26,6 @@ import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.util.Slog;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.internal.statusbar.IStatusBar;
|
||||
import com.android.internal.statusbar.IStatusBarService;
|
||||
@@ -495,16 +494,26 @@ public class StatusBarManagerService extends IStatusBarService.Stub {
|
||||
}
|
||||
|
||||
/**
|
||||
* The status bar service should call this each time the user brings the panel from
|
||||
* invisible to visible in order to clear the notification light.
|
||||
* @param clearNotificationEffects whether to consider notifications as "shown" and stop
|
||||
* LED, vibration, and ringing
|
||||
*/
|
||||
@Override
|
||||
public void onPanelRevealed() {
|
||||
public void onPanelRevealed(boolean clearNotificationEffects) {
|
||||
enforceStatusBarService();
|
||||
long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
// tell the notification manager to turn off the lights.
|
||||
mNotificationDelegate.onPanelRevealed();
|
||||
mNotificationDelegate.onPanelRevealed(clearNotificationEffects);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearNotificationEffects() throws RemoteException {
|
||||
enforceStatusBarService();
|
||||
long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mNotificationDelegate.clearEffects();
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user