diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
index fc0b568a9acf9..51adc1eccdffd 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
@@ -28,25 +28,42 @@
androidprv:layout_maxWidth="@dimen/keyguard_security_width"
androidprv:layout_maxHeight="@dimen/keyguard_security_height"
android:gravity="center_horizontal|top">
-
+ android:layout_gravity="center_horizontal|top">
+
+
+
-
-
+
diff --git a/packages/SystemUI/res/drawable/ic_aod_charging_24dp.xml b/packages/SystemUI/res/drawable/ic_aod_charging_24dp.xml
new file mode 100644
index 0000000000000..6134b8f754573
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_aod_charging_24dp.xml
@@ -0,0 +1,24 @@
+
+
+
+
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 93ae7634fcd5c..c5bcb6e917029 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -565,6 +565,9 @@
Display brightness
+
+ Charging
+
2G-3G data is paused
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index f8f4f2a8b8fc9..26558377c3cc6 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -35,6 +35,7 @@ import android.widget.TextClock;
import android.widget.TextView;
import com.android.internal.widget.LockPatternUtils;
+import com.android.systemui.ChargingView;
import java.util.Locale;
@@ -50,6 +51,7 @@ public class KeyguardStatusView extends GridLayout {
private TextClock mClockView;
private TextView mOwnerInfo;
private ViewGroup mClockContainer;
+ private ChargingView mBatteryDoze;
private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
@@ -114,6 +116,7 @@ public class KeyguardStatusView extends GridLayout {
mDateView.setShowCurrentUserTime(true);
mClockView.setShowCurrentUserTime(true);
mOwnerInfo = (TextView) findViewById(R.id.owner_info);
+ mBatteryDoze = (ChargingView) findViewById(R.id.battery_doze);
boolean shouldMarquee = KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive();
setEnableMarquee(shouldMarquee);
@@ -273,10 +276,11 @@ public class KeyguardStatusView extends GridLayout {
final int N = mClockContainer.getChildCount();
for (int i = 0; i < N; i++) {
View child = mClockContainer.getChildAt(i);
- if (child == mClockView) {
+ if (child == mClockView || child == mBatteryDoze) {
continue;
}
child.setAlpha(dark ? 0 : 1);
}
+ mBatteryDoze.setDark(dark);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/ChargingView.java b/packages/SystemUI/src/com/android/systemui/ChargingView.java
new file mode 100644
index 0000000000000..555cc740c373c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/ChargingView.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2017 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;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.widget.ImageView;
+
+import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+
+/**
+ * A view that only shows its drawable while the phone is charging.
+ *
+ * Also reloads its drawable upon density changes.
+ */
+public class ChargingView extends ImageView implements
+ BatteryController.BatteryStateChangeCallback,
+ ConfigurationController.ConfigurationListener {
+
+ private BatteryController mBatteryController;
+ private int mImageResource;
+ private boolean mCharging;
+ private boolean mDark;
+
+ public ChargingView(Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+
+ TypedArray a = context.obtainStyledAttributes(attrs, new int[]{android.R.attr.src});
+ int srcResId = a.getResourceId(0, 0);
+
+ if (srcResId != 0) {
+ mImageResource = srcResId;
+ }
+
+ a.recycle();
+
+ updateVisibility();
+ }
+
+ @Override
+ public void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ mBatteryController = Dependency.get(BatteryController.class);
+ mBatteryController.addCallback(this);
+ Dependency.get(ConfigurationController.class).addCallback(this);
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ mBatteryController.removeCallback(this);
+ Dependency.get(ConfigurationController.class).removeCallback(this);
+ }
+
+ @Override
+ public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
+ mCharging = charging;
+ updateVisibility();
+ }
+
+ @Override
+ public void onDensityOrFontScaleChanged() {
+ setImageResource(mImageResource);
+ }
+
+ public void setDark(boolean dark) {
+ mDark = dark;
+ updateVisibility();
+ }
+
+ private void updateVisibility() {
+ setVisibility(mCharging && mDark ? VISIBLE : INVISIBLE);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index fb92a67c6aac7..850e55e07299d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -340,17 +340,23 @@ public class KeyguardIndicationController {
}
protected class BaseKeyguardCallback extends KeyguardUpdateMonitorCallback {
+ public static final int HIDE_DELAY_MS = 5000;
private int mLastSuccessiveErrorMessage = -1;
@Override
public void onRefreshBatteryInfo(KeyguardUpdateMonitor.BatteryStatus status) {
boolean isChargingOrFull = status.status == BatteryManager.BATTERY_STATUS_CHARGING
|| status.status == BatteryManager.BATTERY_STATUS_FULL;
+ boolean wasPluggedIn = mPowerPluggedIn;
mPowerPluggedIn = status.isPluggedIn() && isChargingOrFull;
mPowerCharged = status.isCharged();
mChargingWattage = status.maxChargingWattage;
mChargingSpeed = status.getChargingSpeed(mSlowThreshold, mFastThreshold);
updateIndication();
+ if (!wasPluggedIn && mPowerPluggedIn && mDozing) {
+ showTransientIndication(computePowerIndication());
+ hideTransientIndicationDelayed(HIDE_DELAY_MS);
+ }
}
@Override
@@ -402,7 +408,7 @@ public class KeyguardIndicationController {
showTransientIndication(errString, errorColor);
// We want to keep this message around in case the screen was off
mHandler.removeMessages(MSG_HIDE_TRANSIENT);
- hideTransientIndicationDelayed(5000);
+ hideTransientIndicationDelayed(HIDE_DELAY_MS);
} else {
mMessageToShowOnScreenOn = errString;
}
@@ -416,7 +422,7 @@ public class KeyguardIndicationController {
showTransientIndication(mMessageToShowOnScreenOn, errorColor);
// We want to keep this message around in case the screen was off
mHandler.removeMessages(MSG_HIDE_TRANSIENT);
- hideTransientIndicationDelayed(5000);
+ hideTransientIndicationDelayed(HIDE_DELAY_MS);
mMessageToShowOnScreenOn = null;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
index 48ff1c15252f5..641fe69f2f787 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
@@ -45,7 +45,7 @@ public interface BatteryController extends DemoMode, Dumpable,
* has occurred.
*/
interface BatteryStateChangeCallback {
- void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging);
- void onPowerSaveChanged(boolean isPowerSave);
+ default void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {}
+ default void onPowerSaveChanged(boolean isPowerSave) {}
}
}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index c58b527b7dab4..24f6f896325b1 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -72,6 +72,7 @@ import android.view.WindowManagerPolicy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IAppOpsService;
import com.android.internal.app.IBatteryStats;
+import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.ArrayUtils;
import com.android.server.EventLogTags;
@@ -194,6 +195,7 @@ public final class PowerManagerService extends SystemService
private final Context mContext;
private final ServiceThread mHandlerThread;
private final PowerManagerHandler mHandler;
+ private final AmbientDisplayConfiguration mAmbientDisplayConfiguration;
private final BatterySaverPolicy mBatterySaverPolicy;
private LightsManager mLightsManager;
@@ -516,6 +518,9 @@ public final class PowerManagerService extends SystemService
// True if theater mode is enabled
private boolean mTheaterModeEnabled;
+ // True if always on display is enabled
+ private boolean mAlwaysOnEnabled;
+
// True if double tap to wake is enabled
private boolean mDoubleTapWakeEnabled;
@@ -608,6 +613,7 @@ public final class PowerManagerService extends SystemService
mHandlerThread.start();
mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
mConstants = new Constants(mHandler);
+ mAmbientDisplayConfiguration = new AmbientDisplayConfiguration(mContext);
mBatterySaverPolicy = new BatterySaverPolicy(mHandler);
synchronized (mLock) {
@@ -640,6 +646,7 @@ public final class PowerManagerService extends SystemService
mHandlerThread.start();
mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
mConstants = new Constants(mHandler);
+ mAmbientDisplayConfiguration = new AmbientDisplayConfiguration(mContext);
mDisplaySuspendBlocker = null;
mWakeLockSuspendBlocker = null;
}
@@ -765,6 +772,9 @@ public final class PowerManagerService extends SystemService
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.THEATER_MODE_ON),
false, mSettingsObserver, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.Secure.getUriFor(
+ Settings.Secure.DOZE_ALWAYS_ON),
+ false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.DOUBLE_TAP_TO_WAKE),
false, mSettingsObserver, UserHandle.USER_ALL);
@@ -863,6 +873,7 @@ public final class PowerManagerService extends SystemService
Settings.Global.STAY_ON_WHILE_PLUGGED_IN, BatteryManager.BATTERY_PLUGGED_AC);
mTheaterModeEnabled = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.THEATER_MODE_ON, 0) == 1;
+ mAlwaysOnEnabled = mAmbientDisplayConfiguration.alwaysOnEnabled(UserHandle.USER_CURRENT);
if (mSupportsDoubleTapWakeConfig) {
boolean doubleTapWakeEnabled = Settings.Secure.getIntForUser(resolver,
@@ -1702,6 +1713,11 @@ public final class PowerManagerService extends SystemService
return false;
}
+ // On Always On Display, SystemUI shows the charging indicator
+ if (mAlwaysOnEnabled && mWakefulness == WAKEFULNESS_DOZING) {
+ return false;
+ }
+
// Otherwise wake up!
return true;
}