summaryrefslogtreecommitdiffstats
path: root/services/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'services/core/java')
-rw-r--r--services/core/java/com/android/server/BluetoothManagerService.java19
-rw-r--r--services/core/java/com/android/server/UiModeManagerService.java27
-rwxr-xr-xservices/core/java/com/android/server/am/ActivityRecord.java10
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java64
-rw-r--r--services/core/java/com/android/server/am/PendingIntentRecord.java9
-rw-r--r--services/core/java/com/android/server/display/AutomaticBrightnessController.java56
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java24
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java13
-rw-r--r--services/core/java/com/android/server/display/LogicalDisplay.java32
-rw-r--r--services/core/java/com/android/server/power/Notifier.java38
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java40
-rw-r--r--services/core/java/com/android/server/wm/AccessibilityController.java24
-rw-r--r--services/core/java/com/android/server/wm/CircularDisplayMask.java8
-rw-r--r--services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java4
-rw-r--r--services/core/java/com/android/server/wm/Session.java10
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java30
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java44
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java4
18 files changed, 363 insertions, 93 deletions
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 32a6a2f..0c726f3 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -41,6 +41,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
@@ -51,6 +52,7 @@ import android.provider.Settings;
import android.util.Log;
import java.io.FileDescriptor;
+import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
@@ -1523,17 +1525,24 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
- writer.println("enabled: " + mEnable);
- writer.println("state: " + mState);
- writer.println("address: " + mAddress);
- writer.println("name: " + mName);
+ writer.println("Bluetooth Status");
+ writer.println(" enabled: " + mEnable);
+ writer.println(" state: " + mState);
+ writer.println(" address: " + mAddress);
+ writer.println(" name: " + mName + "\n");
+ writer.flush();
+
if (mBluetooth == null) {
writer.println("Bluetooth Service not connected");
} else {
try {
- writer.println(mBluetooth.dump());
+ ParcelFileDescriptor pfd = ParcelFileDescriptor.dup(fd);
+ mBluetooth.dump(pfd);
+ pfd.close();
} catch (RemoteException re) {
writer.println("RemoteException while calling Bluetooth Service");
+ } catch (IOException re) {
+ writer.println("IOException attempting to dup() fd");
}
}
}
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index d1b4569..282f6a9 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -156,7 +156,7 @@ final class UiModeManagerService extends SystemService {
@Override
public void onStart() {
final Context context = getContext();
- mTwilightManager = getLocalService(TwilightManager.class);
+
final PowerManager powerManager =
(PowerManager) context.getSystemService(Context.POWER_SERVICE);
mWakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG);
@@ -183,7 +183,11 @@ final class UiModeManagerService extends SystemService {
mNightMode = Settings.Secure.getInt(context.getContentResolver(),
Settings.Secure.UI_NIGHT_MODE, UiModeManager.MODE_NIGHT_AUTO);
- mTwilightManager.registerListener(mTwilightListener, mHandler);
+ // Update the initial, static configurations.
+ synchronized (this) {
+ updateConfigurationLocked();
+ sendConfigurationLocked();
+ }
publishBinderService(Context.UI_MODE_SERVICE, mService);
}
@@ -292,8 +296,11 @@ final class UiModeManagerService extends SystemService {
pw.print(" mSetUiMode=0x"); pw.println(Integer.toHexString(mSetUiMode));
pw.print(" mHoldingConfiguration="); pw.print(mHoldingConfiguration);
pw.print(" mSystemReady="); pw.println(mSystemReady);
- pw.print(" mTwilightService.getCurrentState()=");
- pw.println(mTwilightManager.getCurrentState());
+ if (mTwilightManager != null) {
+ // We may not have a TwilightManager.
+ pw.print(" mTwilightService.getCurrentState()=");
+ pw.println(mTwilightManager.getCurrentState());
+ }
}
}
@@ -301,6 +308,10 @@ final class UiModeManagerService extends SystemService {
public void onBootPhase(int phase) {
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
synchronized (mLock) {
+ mTwilightManager = getLocalService(TwilightManager.class);
+ if (mTwilightManager != null) {
+ mTwilightManager.registerListener(mTwilightListener, mHandler);
+ }
mSystemReady = true;
mCarModeEnabled = mDockState == Intent.EXTRA_DOCK_STATE_CAR;
updateComputedNightModeLocked();
@@ -626,9 +637,11 @@ final class UiModeManagerService extends SystemService {
}
private void updateComputedNightModeLocked() {
- TwilightState state = mTwilightManager.getCurrentState();
- if (state != null) {
- mComputedNightMode = state.isNight();
+ if (mTwilightManager != null) {
+ TwilightState state = mTwilightManager.getCurrentState();
+ if (state != null) {
+ mComputedNightMode = state.isNight();
+ }
}
}
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index b1b2a5c..cb780b1 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -474,10 +474,16 @@ final class ActivityRecord {
AttributeCache.Entry ent = AttributeCache.instance().get(packageName,
realTheme, com.android.internal.R.styleable.Window, userId);
+ final boolean translucent = ent.array.getBoolean(
+ com.android.internal.R.styleable.Window_windowIsTranslucent, false)
+ || (!ent.array.hasValue(
+ com.android.internal.R.styleable.Window_windowIsTranslucent)
+ && ent.array.getBoolean(
+ com.android.internal.R.styleable.Window_windowSwipeToDismiss,
+ false));
fullscreen = ent != null && !ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowIsFloating, false)
- && !ent.array.getBoolean(
- com.android.internal.R.styleable.Window_windowIsTranslucent, false);
+ && !translucent;
noDisplay = ent != null && ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowNoDisplay, false);
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 32787d8..0630cad 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -69,6 +69,7 @@ import android.hardware.display.DisplayManagerGlobal;
import android.hardware.display.VirtualDisplay;
import android.hardware.input.InputManager;
import android.hardware.input.InputManagerInternal;
+import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.Debug;
@@ -855,6 +856,11 @@ public final class ActivityStackSupervisor implements DisplayListener {
ActivityContainer container = (ActivityContainer)iContainer;
synchronized (mService) {
+ if (container != null && container.mParentActivity != null &&
+ container.mParentActivity.state != ActivityState.RESUMED) {
+ // Cannot start a child activity if the parent is not resumed.
+ return ActivityManager.START_CANCELED;
+ }
final int realCallingPid = Binder.getCallingPid();
final int realCallingUid = Binder.getCallingUid();
int callingPid;
@@ -3788,18 +3794,21 @@ public final class ActivityStackSupervisor implements DisplayListener {
@Override
public final int startActivity(Intent intent) {
mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
- int userId = mService.handleIncomingUser(Binder.getCallingPid(),
+ final int userId = mService.handleIncomingUser(Binder.getCallingPid(),
Binder.getCallingUid(), mCurrentUser, false,
ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
+
// TODO: Switch to user app stacks here.
- intent.addFlags(FORCE_NEW_TASK_FLAGS);
String mimeType = intent.getType();
- if (mimeType == null && intent.getData() != null
- && "content".equals(intent.getData().getScheme())) {
- mimeType = mService.getProviderMimeType(intent.getData(), userId);
+ final Uri data = intent.getData();
+ if (mimeType == null && data != null && "content".equals(data.getScheme())) {
+ mimeType = mService.getProviderMimeType(data, userId);
}
- return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null, 0,
- 0, null, null, null, null, userId, this, null);
+ checkEmbeddedAllowedInner(userId, intent, mimeType);
+
+ intent.addFlags(FORCE_NEW_TASK_FLAGS);
+ return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null,
+ 0, 0, null, null, null, null, userId, this, null);
}
@Override
@@ -3810,21 +3819,19 @@ public final class ActivityStackSupervisor implements DisplayListener {
throw new IllegalArgumentException("Bad PendingIntent object");
}
- return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
- null, 0, FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
- }
-
- private void checkEmbeddedAllowedInner(Intent intent, String resolvedType) {
- int userId = mService.handleIncomingUser(Binder.getCallingPid(),
+ final int userId = mService.handleIncomingUser(Binder.getCallingPid(),
Binder.getCallingUid(), mCurrentUser, false,
ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
- if (resolvedType == null) {
- resolvedType = intent.getType();
- if (resolvedType == null && intent.getData() != null
- && "content".equals(intent.getData().getScheme())) {
- resolvedType = mService.getProviderMimeType(intent.getData(), userId);
- }
- }
+
+ final PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;
+ checkEmbeddedAllowedInner(userId, pendingIntent.key.requestIntent,
+ pendingIntent.key.requestResolvedType);
+
+ return pendingIntent.sendInner(0, null, null, null, null, null, null, 0,
+ FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
+ }
+
+ private void checkEmbeddedAllowedInner(int userId, Intent intent, String resolvedType) {
ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, userId);
if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
throw new SecurityException(
@@ -3832,23 +3839,6 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
}
- /** Throw a SecurityException if allowEmbedded is not true */
- @Override
- public final void checkEmbeddedAllowed(Intent intent) {
- checkEmbeddedAllowedInner(intent, null);
- }
-
- /** Throw a SecurityException if allowEmbedded is not true */
- @Override
- public final void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) {
- if (!(intentSender instanceof PendingIntentRecord)) {
- throw new IllegalArgumentException("Bad PendingIntent object");
- }
- PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;
- checkEmbeddedAllowedInner(pendingIntent.key.requestIntent,
- pendingIntent.key.requestResolvedType);
- }
-
@Override
public IBinder asBinder() {
return this;
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index ffaa03d..7bdfced 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -29,6 +29,8 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Slog;
+import com.android.server.am.ActivityStackSupervisor.ActivityContainer;
+
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
@@ -201,6 +203,13 @@ final class PendingIntentRecord extends IIntentSender.Stub {
IBinder resultTo, String resultWho, int requestCode,
int flagsMask, int flagsValues, Bundle options, IActivityContainer container) {
synchronized(owner) {
+ final ActivityContainer activityContainer = (ActivityContainer)container;
+ if (activityContainer != null && activityContainer.mParentActivity != null &&
+ activityContainer.mParentActivity.state
+ != ActivityStack.ActivityState.RESUMED) {
+ // Cannot start a child activity if the parent is not resumed.
+ return ActivityManager.START_CANCELED;
+ }
if (!canceled) {
sent = true;
if ((key.flags&PendingIntent.FLAG_ONE_SHOT) != 0) {
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index d919bf6..93d37f1 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -52,20 +52,9 @@ class AutomaticBrightnessController {
// auto-brightness adjustment setting.
private static final float SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT_MAX_GAMMA = 3.0f;
- // Light sensor event rate in milliseconds.
- private static final int LIGHT_SENSOR_RATE_MILLIS = 1000;
-
// Period of time in which to consider light samples in milliseconds.
private static final int AMBIENT_LIGHT_HORIZON = 10000;
- // Stability requirements in milliseconds for accepting a new brightness level. This is used
- // for debouncing the light sensor. Different constants are used to debounce the light sensor
- // when adapting to brighter or darker environments. This parameter controls how quickly
- // brightness changes occur in response to an observed change in light level that exceeds the
- // hysteresis threshold.
- private static final long BRIGHTENING_LIGHT_DEBOUNCE = 4000;
- private static final long DARKENING_LIGHT_DEBOUNCE = 8000;
-
// Hysteresis constraints for brightening or darkening.
// The recent lux must have changed by at least this fraction relative to the
// current ambient lux before a change will be considered.
@@ -121,6 +110,22 @@ class AutomaticBrightnessController {
private final int mScreenBrightnessRangeMaximum;
private final float mDozeScaleFactor;
+ // Light sensor event rate in milliseconds.
+ private final int mLightSensorRate;
+
+ // Stability requirements in milliseconds for accepting a new brightness level. This is used
+ // for debouncing the light sensor. Different constants are used to debounce the light sensor
+ // when adapting to brighter or darker environments. This parameter controls how quickly
+ // brightness changes occur in response to an observed change in light level that exceeds the
+ // hysteresis threshold.
+ private final long mBrighteningLightDebounceConfig;
+ private final long mDarkeningLightDebounceConfig;
+
+ // If true immediately after the screen is turned on the controller will try to adjust the
+ // brightness based on the current sensor reads. If false, the controller will collect more data
+ // and only then decide whether to change brightness.
+ private final boolean mResetAmbientLuxAfterWarmUpConfig;
+
// Amount of time to delay auto-brightness after screen on while waiting for
// the light sensor to warm-up in milliseconds.
// May be 0 if no warm-up is required.
@@ -176,7 +181,9 @@ class AutomaticBrightnessController {
public AutomaticBrightnessController(Callbacks callbacks, Looper looper,
SensorManager sensorManager, Spline autoBrightnessSpline, int lightSensorWarmUpTime,
- int brightnessMin, int brightnessMax, float dozeScaleFactor) {
+ int brightnessMin, int brightnessMax, float dozeScaleFactor,
+ int lightSensorRate, long brighteningLightDebounceConfig,
+ long darkeningLightDebounceConfig, boolean resetAmbientLuxAfterWarmUpConfig) {
mCallbacks = callbacks;
mTwilight = LocalServices.getService(TwilightManager.class);
mSensorManager = sensorManager;
@@ -185,9 +192,13 @@ class AutomaticBrightnessController {
mScreenBrightnessRangeMaximum = brightnessMax;
mLightSensorWarmUpTimeConfig = lightSensorWarmUpTime;
mDozeScaleFactor = dozeScaleFactor;
+ mLightSensorRate = lightSensorRate;
+ mBrighteningLightDebounceConfig = brighteningLightDebounceConfig;
+ mDarkeningLightDebounceConfig = darkeningLightDebounceConfig;
+ mResetAmbientLuxAfterWarmUpConfig = resetAmbientLuxAfterWarmUpConfig;
mHandler = new AutomaticBrightnessHandler(looper);
- mAmbientLightRingBuffer = new AmbientLightRingBuffer();
+ mAmbientLightRingBuffer = new AmbientLightRingBuffer(mLightSensorRate);
if (!DEBUG_PRETEND_LIGHT_SENSOR_ABSENT) {
mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
@@ -226,6 +237,9 @@ class AutomaticBrightnessController {
pw.println(" mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum);
pw.println(" mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum);
pw.println(" mLightSensorWarmUpTimeConfig=" + mLightSensorWarmUpTimeConfig);
+ pw.println(" mBrighteningLightDebounceConfig=" + mBrighteningLightDebounceConfig);
+ pw.println(" mDarkeningLightDebounceConfig=" + mDarkeningLightDebounceConfig);
+ pw.println(" mResetAmbientLuxAfterWarmUpConfig=" + mResetAmbientLuxAfterWarmUpConfig);
pw.println();
pw.println("Automatic Brightness Controller State:");
@@ -252,13 +266,13 @@ class AutomaticBrightnessController {
mLightSensorEnabled = true;
mLightSensorEnableTime = SystemClock.uptimeMillis();
mSensorManager.registerListener(mLightSensorListener, mLightSensor,
- LIGHT_SENSOR_RATE_MILLIS * 1000, mHandler);
+ mLightSensorRate * 1000, mHandler);
return true;
}
} else {
if (mLightSensorEnabled) {
mLightSensorEnabled = false;
- mAmbientLuxValid = false;
+ mAmbientLuxValid = !mResetAmbientLuxAfterWarmUpConfig;
mRecentLightSamples = 0;
mAmbientLightRingBuffer.clear();
mHandler.removeMessages(MSG_UPDATE_AMBIENT_LUX);
@@ -347,7 +361,7 @@ class AutomaticBrightnessController {
}
earliestValidTime = mAmbientLightRingBuffer.getTime(i);
}
- return earliestValidTime + BRIGHTENING_LIGHT_DEBOUNCE;
+ return earliestValidTime + mBrighteningLightDebounceConfig;
}
private long nextAmbientLightDarkeningTransition(long time) {
@@ -359,7 +373,7 @@ class AutomaticBrightnessController {
}
earliestValidTime = mAmbientLightRingBuffer.getTime(i);
}
- return earliestValidTime + DARKENING_LIGHT_DEBOUNCE;
+ return earliestValidTime + mDarkeningLightDebounceConfig;
}
private void updateAmbientLux() {
@@ -420,7 +434,7 @@ class AutomaticBrightnessController {
// should be enough time to decide whether we should actually transition to the new
// weighted ambient lux or not.
nextTransitionTime =
- nextTransitionTime > time ? nextTransitionTime : time + LIGHT_SENSOR_RATE_MILLIS;
+ nextTransitionTime > time ? nextTransitionTime : time + mLightSensorRate;
if (DEBUG) {
Slog.d(TAG, "updateAmbientLux: Scheduling ambient lux update for "
+ nextTransitionTime + TimeUtils.formatUptime(nextTransitionTime));
@@ -559,8 +573,6 @@ class AutomaticBrightnessController {
// Proportional extra capacity of the buffer beyond the expected number of light samples
// in the horizon
private static final float BUFFER_SLACK = 1.5f;
- private static final int DEFAULT_CAPACITY =
- (int) Math.ceil(AMBIENT_LIGHT_HORIZON * BUFFER_SLACK / LIGHT_SENSOR_RATE_MILLIS);
private float[] mRingLux;
private long[] mRingTime;
private int mCapacity;
@@ -571,8 +583,8 @@ class AutomaticBrightnessController {
private int mEnd;
private int mCount;
- public AmbientLightRingBuffer() {
- this(DEFAULT_CAPACITY);
+ public AmbientLightRingBuffer(long lightSensorRate) {
+ this((int) Math.ceil(AMBIENT_LIGHT_HORIZON * BUFFER_SLACK / lightSensorRate));
}
public AmbientLightRingBuffer(int initialCapacity) {
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 09dc477..5f0ad9f 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -46,7 +46,6 @@ import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.text.TextUtils;
-import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
@@ -832,6 +831,24 @@ public final class DisplayManagerService extends SystemService {
}
}
+ private void setDisplayOffsetsInternal(int displayId, int x, int y) {
+ synchronized (mSyncRoot) {
+ LogicalDisplay display = mLogicalDisplays.get(displayId);
+ if (display == null) {
+ return;
+ }
+ if (display.getDisplayOffsetXLocked() != x
+ || display.getDisplayOffsetYLocked() != y) {
+ if (DEBUG) {
+ Slog.d(TAG, "Display " + displayId + " burn-in offset set to ("
+ + x + ", " + y + ")");
+ }
+ display.setDisplayOffsetsLocked(x, y);
+ scheduleTraversalLocked(false);
+ }
+ }
+ }
+
private void clearViewportsLocked() {
mDefaultViewport.valid = false;
mExternalTouchViewport.valid = false;
@@ -1513,5 +1530,10 @@ public final class DisplayManagerService extends SystemService {
float requestedRefreshRate, boolean inTraversal) {
setDisplayPropertiesInternal(displayId, hasContent, requestedRefreshRate, inTraversal);
}
+
+ @Override
+ public void setDisplayOffsets(int displayId, int x, int y) {
+ setDisplayOffsetsInternal(displayId, x, y);
+ }
}
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 78610ff..cf1f4b0 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -302,6 +302,15 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mAllowAutoBrightnessWhileDozingConfig = resources.getBoolean(
com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing);
+ int lightSensorRate = resources.getInteger(
+ com.android.internal.R.integer.config_autoBrightnessLightSensorRate);
+ long brighteningLightDebounce = resources.getInteger(
+ com.android.internal.R.integer.config_autoBrightnessBrighteningLightDebounce);
+ long darkeningLightDebounce = resources.getInteger(
+ com.android.internal.R.integer.config_autoBrightnessDarkeningLightDebounce);
+ boolean autoBrightnessResetAmbientLuxAfterWarmUp = resources.getBoolean(
+ com.android.internal.R.bool.config_autoBrightnessResetAmbientLuxAfterWarmUp);
+
if (mUseSoftwareAutoBrightnessConfig) {
int[] lux = resources.getIntArray(
com.android.internal.R.array.config_autoBrightnessLevels);
@@ -336,7 +345,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mAutomaticBrightnessController = new AutomaticBrightnessController(this,
handler.getLooper(), sensorManager, screenAutoBrightnessSpline,
lightSensorWarmUpTimeConfig, screenBrightnessRangeMinimum,
- mScreenBrightnessRangeMaximum, dozeScaleFactor);
+ mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate,
+ brighteningLightDebounce, darkeningLightDebounce,
+ autoBrightnessResetAmbientLuxAfterWarmUp);
}
}
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 6c57eec..3bb7818 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -76,6 +76,10 @@ final class LogicalDisplay {
// The pending requested refresh rate. 0 if no request is pending.
private float mRequestedRefreshRate;
+ // The display offsets to apply to the display projection.
+ private int mDisplayOffsetX;
+ private int mDisplayOffsetY;
+
// Temporary rectangle used when needed.
private final Rect mTempLayerStackRect = new Rect();
private final Rect mTempDisplayRect = new Rect();
@@ -313,6 +317,10 @@ final class LogicalDisplay {
mTempDisplayRect.set(displayRectLeft, displayRectTop,
displayRectLeft + displayRectWidth, displayRectTop + displayRectHeight);
+ mTempDisplayRect.left += mDisplayOffsetX;
+ mTempDisplayRect.right += mDisplayOffsetX;
+ mTempDisplayRect.top += mDisplayOffsetY;
+ mTempDisplayRect.bottom += mDisplayOffsetY;
device.setProjectionInTransactionLocked(orientation, mTempLayerStackRect, mTempDisplayRect);
}
@@ -356,10 +364,34 @@ final class LogicalDisplay {
return mRequestedRefreshRate;
}
+ /**
+ * Gets the burn-in offset in X.
+ */
+ public int getDisplayOffsetXLocked() {
+ return mDisplayOffsetX;
+ }
+
+ /**
+ * Gets the burn-in offset in Y.
+ */
+ public int getDisplayOffsetYLocked() {
+ return mDisplayOffsetY;
+ }
+
+ /**
+ * Sets the burn-in offsets.
+ */
+ public void setDisplayOffsetsLocked(int x, int y) {
+ mDisplayOffsetX = x;
+ mDisplayOffsetY = y;
+ }
+
public void dumpLocked(PrintWriter pw) {
pw.println("mDisplayId=" + mDisplayId);
pw.println("mLayerStack=" + mLayerStack);
pw.println("mHasContent=" + mHasContent);
+ pw.println("mRequestedRefreshRate=" + mRequestedRefreshRate);
+ pw.println("mDisplayOffset=(" + mDisplayOffsetX + ", " + mDisplayOffsetY + ")");
pw.println("mPrimaryDisplayDevice=" + (mPrimaryDisplayDevice != null ?
mPrimaryDisplayDevice.getNameLocked() : "null"));
pw.println("mBaseDisplayInfo=" + mBaseDisplayInfo);
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 1349926..c48367e 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -78,6 +78,7 @@ final class Notifier {
private static final int MSG_USER_ACTIVITY = 1;
private static final int MSG_BROADCAST = 2;
private static final int MSG_WIRELESS_CHARGING_STARTED = 3;
+ private static final int MSG_SCREEN_BRIGHTNESS_BOOST_CHANGED = 4;
private final Object mLock = new Object();
@@ -92,6 +93,7 @@ final class Notifier {
private final NotifierHandler mHandler;
private final Intent mScreenOnIntent;
private final Intent mScreenOffIntent;
+ private final Intent mScreenBrightnessBoostIntent;
// The current interactive state.
private int mActualInteractiveState;
@@ -128,6 +130,10 @@ final class Notifier {
mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
mScreenOffIntent.addFlags(
Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
+ mScreenBrightnessBoostIntent =
+ new Intent(PowerManager.ACTION_SCREEN_BRIGHTNESS_BOOST_CHANGED);
+ mScreenBrightnessBoostIntent.addFlags(
+ Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
// Initialize interactive state for battery stats.
try {
@@ -349,6 +355,19 @@ final class Notifier {
}
/**
+ * Called when screen brightness boost begins or ends.
+ */
+ public void onScreenBrightnessBoostChanged() {
+ if (DEBUG) {
+ Slog.d(TAG, "onScreenBrightnessBoostChanged");
+ }
+
+ mSuspendBlocker.acquire();
+ Message msg = mHandler.obtainMessage(MSG_SCREEN_BRIGHTNESS_BOOST_CHANGED);
+ msg.setAsynchronous(true);
+ mHandler.sendMessage(msg);
+ }
+ /**
* Called when there has been user activity.
*/
public void onUserActivity(int event, int uid) {
@@ -457,6 +476,22 @@ final class Notifier {
}
}
+ private void sendBrightnessBoostChangedBroadcast() {
+ if (DEBUG) {
+ Slog.d(TAG, "Sending brightness boost changed broadcast.");
+ }
+
+ mContext.sendOrderedBroadcastAsUser(mScreenBrightnessBoostIntent, UserHandle.ALL, null,
+ mScreeBrightnessBoostChangedDone, mHandler, 0, null, null);
+ }
+
+ private final BroadcastReceiver mScreeBrightnessBoostChangedDone = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ mSuspendBlocker.release();
+ }
+ };
+
private void sendWakeUpBroadcast() {
if (DEBUG) {
Slog.d(TAG, "Sending wake up broadcast.");
@@ -539,6 +574,9 @@ final class Notifier {
case MSG_WIRELESS_CHARGING_STARTED:
playWirelessChargingStartedSound();
break;
+ case MSG_SCREEN_BRIGHTNESS_BOOST_CHANGED:
+ sendBrightnessBoostChangedBroadcast();
+ break;
}
}
}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 9786b42..9d6cc5e 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -128,6 +128,7 @@ public final class PowerManagerService extends SystemService
private static final int WAKE_LOCK_PROXIMITY_SCREEN_OFF = 1 << 4;
private static final int WAKE_LOCK_STAY_AWAKE = 1 << 5; // only set if already awake
private static final int WAKE_LOCK_DOZE = 1 << 6;
+ private static final int WAKE_LOCK_DRAW = 1 << 7;
// Summarizes the user activity state.
private static final int USER_ACTIVITY_SCREEN_BRIGHT = 1 << 0;
@@ -1079,6 +1080,9 @@ public final class PowerManagerService extends SystemService
case PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON:
Slog.i(TAG, "Going to sleep due to power button (uid " + uid +")...");
break;
+ case PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON:
+ Slog.i(TAG, "Going to sleep due to sleep button (uid " + uid +")...");
+ break;
case PowerManager.GO_TO_SLEEP_REASON_HDMI:
Slog.i(TAG, "Going to sleep due to HDMI standby (uid " + uid +")...");
break;
@@ -1398,12 +1402,15 @@ public final class PowerManagerService extends SystemService
case PowerManager.DOZE_WAKE_LOCK:
mWakeLockSummary |= WAKE_LOCK_DOZE;
break;
+ case PowerManager.DRAW_WAKE_LOCK:
+ mWakeLockSummary |= WAKE_LOCK_DRAW;
+ break;
}
}
// Cancel wake locks that make no sense based on the current state.
if (mWakefulness != WAKEFULNESS_DOZING) {
- mWakeLockSummary &= ~WAKE_LOCK_DOZE;
+ mWakeLockSummary &= ~(WAKE_LOCK_DOZE | WAKE_LOCK_DRAW);
}
if (mWakefulness == WAKEFULNESS_ASLEEP
|| (mWakeLockSummary & WAKE_LOCK_DOZE) != 0) {
@@ -1422,6 +1429,9 @@ public final class PowerManagerService extends SystemService
mWakeLockSummary |= WAKE_LOCK_CPU;
}
}
+ if ((mWakeLockSummary & WAKE_LOCK_DRAW) != 0) {
+ mWakeLockSummary |= WAKE_LOCK_CPU;
+ }
if (DEBUG_SPEW) {
Slog.d(TAG, "updateWakeLockSummaryLocked: mWakefulness="
@@ -1845,6 +1855,10 @@ public final class PowerManagerService extends SystemService
if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) {
mDisplayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager;
+ if (mDisplayPowerRequest.dozeScreenState == Display.STATE_DOZE_SUSPEND
+ && (mWakeLockSummary & WAKE_LOCK_DRAW) != 0) {
+ mDisplayPowerRequest.dozeScreenState = Display.STATE_DOZE;
+ }
mDisplayPowerRequest.dozeScreenBrightness =
mDozeScreenBrightnessOverrideFromDreamManager;
} else {
@@ -1886,6 +1900,7 @@ public final class PowerManagerService extends SystemService
}
}
mScreenBrightnessBoostInProgress = false;
+ mNotifier.onScreenBrightnessBoostChanged();
userActivityNoUpdateLocked(now,
PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
}
@@ -2261,7 +2276,10 @@ public final class PowerManagerService extends SystemService
Slog.i(TAG, "Brightness boost activated (uid " + uid +")...");
mLastScreenBrightnessBoostTime = eventTime;
- mScreenBrightnessBoostInProgress = true;
+ if (!mScreenBrightnessBoostInProgress) {
+ mScreenBrightnessBoostInProgress = true;
+ mNotifier.onScreenBrightnessBoostChanged();
+ }
mDirty |= DIRTY_SCREEN_BRIGHTNESS_BOOST;
userActivityNoUpdateLocked(eventTime,
@@ -2270,6 +2288,12 @@ public final class PowerManagerService extends SystemService
}
}
+ private boolean isScreenBrightnessBoostedInternal() {
+ synchronized (mLock) {
+ return mScreenBrightnessBoostInProgress;
+ }
+ }
+
/**
* Called when a screen brightness boost timeout has occurred.
*
@@ -2712,6 +2736,8 @@ public final class PowerManagerService extends SystemService
return "PROXIMITY_SCREEN_OFF_WAKE_LOCK";
case PowerManager.DOZE_WAKE_LOCK:
return "DOZE_WAKE_LOCK ";
+ case PowerManager.DRAW_WAKE_LOCK:
+ return "DRAW_WAKE_LOCK ";
default:
return "??? ";
}
@@ -3202,6 +3228,16 @@ public final class PowerManagerService extends SystemService
}
@Override // Binder call
+ public boolean isScreenBrightnessBoosted() {
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ return isScreenBrightnessBoostedInternal();
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override // Binder call
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 08754f9..37ca0db 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -397,8 +397,6 @@ final class AccessibilityController {
private final class MagnifiedViewport {
- private static final int DEFAUTLT_BORDER_WIDTH_DIP = 5;
-
private final SparseArray<WindowState> mTempWindowStates =
new SparseArray<WindowState>();
@@ -411,6 +409,8 @@ final class AccessibilityController {
private final Region mMagnifiedBounds = new Region();
private final Region mOldMagnifiedBounds = new Region();
+ private final Path mCircularPath;
+
private final MagnificationSpec mMagnificationSpec = MagnificationSpec.obtain();
private final WindowManager mWindowManager;
@@ -425,12 +425,22 @@ final class AccessibilityController {
public MagnifiedViewport() {
mWindowManager = (WindowManager) mContext.getSystemService(Service.WINDOW_SERVICE);
- mBorderWidth = TypedValue.applyDimension(
- TypedValue.COMPLEX_UNIT_DIP, DEFAUTLT_BORDER_WIDTH_DIP,
- mContext.getResources().getDisplayMetrics());
+ mBorderWidth = mContext.getResources().getDimension(
+ com.android.internal.R.dimen.accessibility_magnification_indicator_width);
mHalfBorderWidth = (int) Math.ceil(mBorderWidth / 2);
mDrawBorderInset = (int) mBorderWidth / 2;
mWindow = new ViewportWindow(mContext);
+
+ if (mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_windowIsRound)) {
+ mCircularPath = new Path();
+ mWindowManager.getDefaultDisplay().getRealSize(mTempPoint);
+ final int centerXY = mTempPoint.x / 2;
+ mCircularPath.addCircle(centerXY, centerXY, centerXY, Path.Direction.CW);
+ } else {
+ mCircularPath = null;
+ }
+
recomputeBoundsLocked();
}
@@ -459,6 +469,10 @@ final class AccessibilityController {
Region availableBounds = mTempRegion1;
availableBounds.set(0, 0, screenWidth, screenHeight);
+ if (mCircularPath != null) {
+ availableBounds.setPath(mCircularPath, availableBounds);
+ }
+
Region nonMagnifiedBounds = mTempRegion4;
nonMagnifiedBounds.set(0, 0, 0, 0);
diff --git a/services/core/java/com/android/server/wm/CircularDisplayMask.java b/services/core/java/com/android/server/wm/CircularDisplayMask.java
index 9fdfc47..7c2da2d 100644
--- a/services/core/java/com/android/server/wm/CircularDisplayMask.java
+++ b/services/core/java/com/android/server/wm/CircularDisplayMask.java
@@ -50,9 +50,10 @@ class CircularDisplayMask {
private int mRotation;
private boolean mVisible;
private boolean mDimensionsUnequal = false;
+ private int mMaskThickness;
public CircularDisplayMask(Display display, SurfaceSession session, int zOrder,
- int screenOffset) {
+ int screenOffset, int maskThickness) {
mScreenSize = new Point();
display.getSize(mScreenSize);
if (mScreenSize.x != mScreenSize.y) {
@@ -84,6 +85,7 @@ class CircularDisplayMask {
mPaint.setAntiAlias(true);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
mScreenOffset = screenOffset;
+ mMaskThickness = maskThickness;
}
private void drawIfNeeded() {
@@ -121,8 +123,8 @@ class CircularDisplayMask {
int circleRadius = mScreenSize.x / 2;
c.drawColor(Color.BLACK);
- // The radius is reduced by 1 to provide an anti aliasing effect on the display edges.
- c.drawCircle(circleRadius, circleRadius, circleRadius - 1, mPaint);
+ // The radius is reduced by mMaskThickness to provide an anti aliasing effect on the display edges.
+ c.drawCircle(circleRadius, circleRadius, circleRadius - mMaskThickness, mPaint);
mSurface.unlockCanvasAndPost(c);
}
diff --git a/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java b/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java
index 62f2b48..5e4bd8b 100644
--- a/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java
+++ b/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java
@@ -93,7 +93,9 @@ class EmulatorDisplayOverlay {
}
c.drawColor(Color.TRANSPARENT, PorterDuff.Mode.SRC);
mSurfaceControl.setPosition(0, 0);
- mOverlay.setBounds(0, 0, mScreenSize.x, mScreenSize.y);
+ // Always draw the overlay with square dimensions
+ int size = Math.max(mScreenSize.x, mScreenSize.y);
+ mOverlay.setBounds(0, 0, size, size);
mOverlay.draw(c);
mSurface.unlockCanvasAndPost(c);
}
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index a4dfd8a..a1d145c 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -475,6 +475,16 @@ final class Session extends IWindowSession.Stub
return mService.getWindowId(window);
}
+ @Override
+ public void pokeDrawLock(IBinder window) {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mService.pokeDrawLock(this, window);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
void windowAddedLocked() {
if (mSurfaceSession == null) {
if (WindowManagerService.localLOGV) Slog.v(
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index a1fe16b..0cda6fd 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -194,6 +194,7 @@ public class WindowManagerService extends IWindowManager.Stub
static final boolean DEBUG_TASK_MOVEMENT = false;
static final boolean DEBUG_STACK = false;
static final boolean DEBUG_DISPLAY = false;
+ static final boolean DEBUG_POWER = false;
static final boolean SHOW_SURFACE_ALLOC = false;
static final boolean SHOW_TRANSACTIONS = false;
static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
@@ -338,6 +339,7 @@ public class WindowManagerService extends IWindowManager.Stub
final boolean mHaveInputMethods;
final boolean mHasPermanentDpad;
+ final long mDrawLockTimeoutMillis;
final boolean mAllowBootMessages;
@@ -827,6 +829,8 @@ public class WindowManagerService extends IWindowManager.Stub
com.android.internal.R.bool.config_hasPermanentDpad);
mInTouchMode = context.getResources().getBoolean(
com.android.internal.R.bool.config_defaultInTouchMode);
+ mDrawLockTimeoutMillis = context.getResources().getInteger(
+ com.android.internal.R.integer.config_drawLockTimeoutMillis);
mInputManager = inputManager; // Must be before createDisplayContentLocked.
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
mDisplaySettings = new DisplaySettings();
@@ -2992,6 +2996,15 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
+ public void pokeDrawLock(Session session, IBinder token) {
+ synchronized (mWindowMap) {
+ WindowState window = windowForClientLocked(session, token, false);
+ if (window != null) {
+ window.pokeDrawLockLw(mDrawLockTimeoutMillis);
+ }
+ }
+ }
+
public int relayoutWindow(Session session, IWindow client, int seq,
WindowManager.LayoutParams attrs, int requestedWidth,
int requestedHeight, int viewVisibility, int flags,
@@ -4334,8 +4347,13 @@ public class WindowManagerService extends IWindowManager.Stub
+ " ShowWallpaper="
+ ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowShowWallpaper, false));
- if (ent.array.getBoolean(
- com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
+ final boolean windowIsTranslucentDefined = ent.array.hasValue(
+ com.android.internal.R.styleable.Window_windowIsTranslucent);
+ final boolean windowIsTranslucent = ent.array.getBoolean(
+ com.android.internal.R.styleable.Window_windowIsTranslucent, false);
+ final boolean windowSwipeToDismiss = ent.array.getBoolean(
+ com.android.internal.R.styleable.Window_windowSwipeToDismiss, false);
+ if (windowIsTranslucent || (!windowIsTranslucentDefined && windowSwipeToDismiss)) {
return;
}
if (ent.array.getBoolean(
@@ -5926,13 +5944,15 @@ public class WindowManagerService extends IWindowManager.Stub
if (mCircularDisplayMask == null) {
int screenOffset = mContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.circular_display_mask_offset);
+ int maskThickness = mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.circular_display_mask_thickness);
mCircularDisplayMask = new CircularDisplayMask(
getDefaultDisplayContentLocked().getDisplay(),
mFxSession,
mPolicy.windowTypeToLayerLw(
WindowManager.LayoutParams.TYPE_POINTER)
- * TYPE_LAYER_MULTIPLIER + 10, screenOffset);
+ * TYPE_LAYER_MULTIPLIER + 10, screenOffset, maskThickness);
}
mCircularDisplayMask.setVisibility(true);
} else if (mCircularDisplayMask != null) {
@@ -10110,7 +10130,9 @@ public class WindowManagerService extends IWindowManager.Stub
if (mAllowTheaterModeWakeFromLayout
|| Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.THEATER_MODE_ON, 0) == 0) {
- if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
+ if (DEBUG_VISIBILITY || DEBUG_POWER) {
+ Slog.v(TAG, "Turning screen on after layout!");
+ }
mPowerManager.wakeUp(SystemClock.uptimeMillis());
}
mTurnOnScreen = false;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 021a6e4..b621c52 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -19,9 +19,9 @@ package com.android.server.wm;
import static com.android.server.wm.WindowManagerService.DEBUG_CONFIGURATION;
import static com.android.server.wm.WindowManagerService.DEBUG_LAYOUT;
import static com.android.server.wm.WindowManagerService.DEBUG_ORIENTATION;
+import static com.android.server.wm.WindowManagerService.DEBUG_POWER;
import static com.android.server.wm.WindowManagerService.DEBUG_RESIZE;
import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
-
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
@@ -34,12 +34,15 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import android.app.AppOpsManager;
import android.os.Debug;
+import android.os.PowerManager;
import android.os.RemoteCallbackList;
import android.os.SystemClock;
+import android.os.WorkSource;
import android.util.TimeUtils;
import android.view.Display;
import android.view.IWindowFocusObserver;
import android.view.IWindowId;
+
import com.android.server.input.InputWindowHandle;
import android.content.Context;
@@ -345,6 +348,15 @@ final class WindowState implements WindowManagerPolicy.WindowState {
* the status bar */
boolean mUnderStatusBar = true;
+ /**
+ * Wake lock for drawing.
+ * Even though it's slightly more expensive to do so, we will use a separate wake lock
+ * for each app that is requesting to draw while dozing so that we can accurately track
+ * who is preventing the system from suspending.
+ * This lock is only acquired on first use.
+ */
+ PowerManager.WakeLock mDrawLock;
+
WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
WindowState attachedWindow, int appOp, int seq, WindowManager.LayoutParams a,
int viewVisibility, final DisplayContent displayContent) {
@@ -1272,6 +1284,33 @@ final class WindowState implements WindowManagerPolicy.WindowState {
}
}
+ public void pokeDrawLockLw(long timeout) {
+ if (isVisibleOrAdding()) {
+ if (mDrawLock == null) {
+ // We want the tag name to be somewhat stable so that it is easier to correlate
+ // in wake lock statistics. So in particular, we don't want to include the
+ // window's hash code as in toString().
+ CharSequence tag = mAttrs.getTitle();
+ if (tag == null) {
+ tag = mAttrs.packageName;
+ }
+ mDrawLock = mService.mPowerManager.newWakeLock(
+ PowerManager.DRAW_WAKE_LOCK, "Window:" + tag);
+ mDrawLock.setReferenceCounted(false);
+ mDrawLock.setWorkSource(new WorkSource(mOwnerUid, mAttrs.packageName));
+ }
+ // Each call to acquire resets the timeout.
+ if (DEBUG_POWER) {
+ Slog.d(TAG, "pokeDrawLock: poking draw lock on behalf of visible window owned by "
+ + mAttrs.packageName);
+ }
+ mDrawLock.acquire(timeout);
+ } else if (DEBUG_POWER) {
+ Slog.d(TAG, "pokeDrawLock: suppressed draw lock request for invisible window "
+ + "owned by " + mAttrs.packageName);
+ }
+ }
+
@Override
public boolean isAlive() {
return mClient.asBinder().isBinderAlive();
@@ -1626,6 +1665,9 @@ final class WindowState implements WindowManagerPolicy.WindowState {
pw.print(" mWallpaperDisplayOffsetY=");
pw.println(mWallpaperDisplayOffsetY);
}
+ if (mDrawLock != null) {
+ pw.println("mDrawLock=" + mDrawLock);
+ }
}
String makeInputChannelName() {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index c2d8004..4cdfc41 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -542,9 +542,9 @@ class WindowStateAnimator {
mDrawState = READY_TO_SHOW;
final AppWindowToken atoken = mWin.mAppToken;
if (atoken == null || atoken.allDrawn || mWin.mAttrs.type == TYPE_APPLICATION_STARTING) {
- performShowLocked();
+ return performShowLocked();
}
- return true;
+ return false;
}
static class SurfaceTrace extends SurfaceControl {