diff options
Diffstat (limited to 'services/core/java/com/android')
23 files changed, 613 insertions, 129 deletions
diff --git a/services/core/java/com/android/server/AnyMotionDetector.java b/services/core/java/com/android/server/AnyMotionDetector.java index 6a67316..a0b5c15 100644 --- a/services/core/java/com/android/server/AnyMotionDetector.java +++ b/services/core/java/com/android/server/AnyMotionDetector.java @@ -58,9 +58,6 @@ public class AnyMotionDetector { /** Current measurement state. */ private int mState; - /** Threshold angle in degrees beyond which the device is considered moving. */ - private final float THRESHOLD_ANGLE = 2f; - /** Threshold energy above which the device is considered moving. */ private final float THRESHOLD_ENERGY = 5f; @@ -88,6 +85,9 @@ public class AnyMotionDetector { private SensorManager mSensorManager; private PowerManager.WakeLock mWakeLock; + /** Threshold angle in degrees beyond which the device is considered moving. */ + private final float mThresholdAngle; + /** The minimum number of samples required to detect AnyMotion. */ private int mNumSufficientSamples; @@ -106,7 +106,7 @@ public class AnyMotionDetector { private DeviceIdleCallback mCallback = null; public AnyMotionDetector(PowerManager pm, Handler handler, SensorManager sm, - DeviceIdleCallback callback) { + DeviceIdleCallback callback, float thresholdAngle) { if (DEBUG) Slog.d(TAG, "AnyMotionDetector instantiated."); mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); mWakeLock.setReferenceCounted(false); @@ -116,6 +116,7 @@ public class AnyMotionDetector { mMeasurementInProgress = false; mState = STATE_INACTIVE; mCallback = callback; + mThresholdAngle = thresholdAngle; mRunningStats = new RunningSignalStats(); mNumSufficientSamples = (int) Math.ceil( ((double)ORIENTATION_MEASUREMENT_DURATION_MILLIS / SAMPLING_INTERVAL_MILLIS)); @@ -224,8 +225,9 @@ public class AnyMotionDetector { Vector3 previousGravityVectorNormalized = mPreviousGravityVector.normalized(); Vector3 currentGravityVectorNormalized = mCurrentGravityVector.normalized(); float angle = previousGravityVectorNormalized.angleBetween(currentGravityVectorNormalized); - if (DEBUG) Slog.d(TAG, "getStationaryStatus: angle = " + angle); - if ((angle < THRESHOLD_ANGLE) && (mRunningStats.getEnergy() < THRESHOLD_ENERGY)) { + if (DEBUG) Slog.d(TAG, "getStationaryStatus: angle = " + angle + + " energy = " + mRunningStats.getEnergy()); + if ((angle < mThresholdAngle) && (mRunningStats.getEnergy() < THRESHOLD_ENERGY)) { return RESULT_STATIONARY; } else if (Float.isNaN(angle)) { /** diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java index 6067bd2..5a76227 100644 --- a/services/core/java/com/android/server/BluetoothManagerService.java +++ b/services/core/java/com/android/server/BluetoothManagerService.java @@ -266,7 +266,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { sysUiUid = mContext.getPackageManager().getPackageUid("com.android.systemui", UserHandle.USER_OWNER); } catch (PackageManager.NameNotFoundException e) { - Log.wtf(TAG, "Unable to resolve SystemUI's UID.", e); + // Some platforms, such as wearables do not have a system ui. + Log.w(TAG, "Unable to resolve SystemUI's UID.", e); } mSystemUiUid = sysUiUid; } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index b053c3a..2a47460 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -171,6 +171,7 @@ public class ConnectivityService extends IConnectivityManager.Stub private static final boolean VDBG = false; private static final boolean LOGD_RULES = false; + private static final boolean LOGD_BLOCKED_NETWORKINFO = true; // TODO: create better separation between radio types and network types @@ -964,6 +965,21 @@ public class ConnectivityService extends IConnectivityManager.Stub } } + private void maybeLogBlockedNetworkInfo(NetworkInfo ni, int uid) { + if (ni == null || !LOGD_BLOCKED_NETWORKINFO) return; + boolean removed = false; + boolean added = false; + synchronized (mBlockedAppUids) { + if (ni.getDetailedState() == DetailedState.BLOCKED && mBlockedAppUids.add(uid)) { + added = true; + } else if (ni.isConnected() && mBlockedAppUids.remove(uid)) { + removed = true; + } + } + if (added) log("Returning blocked NetworkInfo to uid=" + uid); + else if (removed) log("Returning unblocked NetworkInfo to uid=" + uid); + } + /** * Return a filtered {@link NetworkInfo}, potentially marked * {@link DetailedState#BLOCKED} based on @@ -974,10 +990,6 @@ public class ConnectivityService extends IConnectivityManager.Stub // network is blocked; clone and override state info = new NetworkInfo(info); info.setDetailedState(DetailedState.BLOCKED, null, null); - if (VDBG) { - log("returning Blocked NetworkInfo for ifname=" + - lp.getInterfaceName() + ", uid=" + uid); - } } if (info != null && mLockdownTracker != null) { info = mLockdownTracker.augmentNetworkInfo(info); @@ -998,7 +1010,9 @@ public class ConnectivityService extends IConnectivityManager.Stub enforceAccessPermission(); final int uid = Binder.getCallingUid(); NetworkState state = getUnfilteredActiveNetworkState(uid); - return getFilteredNetworkInfo(state.networkInfo, state.linkProperties, uid); + NetworkInfo ni = getFilteredNetworkInfo(state.networkInfo, state.linkProperties, uid); + maybeLogBlockedNetworkInfo(ni, uid); + return ni; } @Override @@ -3927,6 +3941,9 @@ public class ConnectivityService extends IConnectivityManager.Stub private final HashMap<Messenger, NetworkAgentInfo> mNetworkAgentInfos = new HashMap<Messenger, NetworkAgentInfo>(); + @GuardedBy("mBlockedAppUids") + private final HashSet<Integer> mBlockedAppUids = new HashSet(); + // Note: if mDefaultRequest is changed, NetworkMonitor needs to be updated. private final NetworkRequest mDefaultRequest; diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java index abe8f5c..71650c3 100644 --- a/services/core/java/com/android/server/DeviceIdleController.java +++ b/services/core/java/com/android/server/DeviceIdleController.java @@ -31,6 +31,8 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.database.ContentObserver; import android.hardware.Sensor; import android.hardware.SensorManager; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; import android.hardware.TriggerEvent; import android.hardware.TriggerEventListener; import android.hardware.display.DisplayManager; @@ -111,7 +113,7 @@ public class DeviceIdleController extends SystemService private INetworkPolicyManager mNetworkPolicyManager; private DisplayManager mDisplayManager; private SensorManager mSensorManager; - private Sensor mSigMotionSensor; + private Sensor mMotionSensor; private LocationManager mLocationManager; private LocationRequest mLocationRequest; private PendingIntent mSensingAlarmIntent; @@ -123,12 +125,12 @@ public class DeviceIdleController extends SystemService private boolean mForceIdle; private boolean mScreenOn; private boolean mCharging; - private boolean mSigMotionActive; private boolean mSensing; private boolean mNotMoving; private boolean mLocating; private boolean mLocated; - private boolean mHaveGps; + private boolean mHasGps; + private boolean mHasNetworkLocation; private Location mLastGenericLocation; private Location mLastGpsLocation; @@ -275,13 +277,57 @@ public class DeviceIdleController extends SystemService } }; - private final TriggerEventListener mSigMotionListener = new TriggerEventListener() { - @Override public void onTrigger(TriggerEvent event) { + private final class MotionListener extends TriggerEventListener + implements SensorEventListener { + + boolean active = false; + + @Override + public void onTrigger(TriggerEvent event) { synchronized (DeviceIdleController.this) { - significantMotionLocked(); + active = false; + motionLocked(); } } - }; + + @Override + public void onSensorChanged(SensorEvent event) { + synchronized (DeviceIdleController.this) { + mSensorManager.unregisterListener(this, mMotionSensor); + active = false; + motionLocked(); + } + } + + @Override + public void onAccuracyChanged(Sensor sensor, int accuracy) {} + + public boolean registerLocked() { + boolean success = false; + if (mMotionSensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) { + success = mSensorManager.requestTriggerSensor(mMotionListener, mMotionSensor); + } else { + success = mSensorManager.registerListener( + mMotionListener, mMotionSensor, SensorManager.SENSOR_DELAY_NORMAL); + } + if (success) { + active = true; + } else { + Slog.e(TAG, "Unable to register for " + mMotionSensor); + } + return success; + } + + public void unregisterLocked() { + if (mMotionSensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) { + mSensorManager.cancelTriggerSensor(mMotionListener, mMotionSensor); + } else { + mSensorManager.unregisterListener(mMotionListener); + } + active = false; + } + } + private final MotionListener mMotionListener = new MotionListener(); private final LocationListener mGenericLocationListener = new LocationListener() { @Override @@ -356,7 +402,7 @@ public class DeviceIdleController extends SystemService * This is the time, after becoming inactive, at which we start looking at the * motion sensor to determine if the device is being left alone. We don't do this * immediately after going inactive just because we don't want to be continually running - * the significant motion sensor whenever the screen is off. + * the motion sensor whenever the screen is off. * @see Settings.Global#DEVICE_IDLE_CONSTANTS * @see #KEY_INACTIVE_TIMEOUT */ @@ -399,7 +445,7 @@ public class DeviceIdleController extends SystemService /** * This is the time, after the inactive timeout elapses, that we will wait looking - * for significant motion until we truly consider the device to be idle. + * for motion until we truly consider the device to be idle. * @see Settings.Global#DEVICE_IDLE_CONSTANTS * @see #KEY_IDLE_AFTER_INACTIVE_TIMEOUT */ @@ -896,17 +942,38 @@ public class DeviceIdleController extends SystemService mDisplayManager = (DisplayManager) getContext().getSystemService( Context.DISPLAY_SERVICE); mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE); - mSigMotionSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION); - mLocationManager = (LocationManager) getContext().getSystemService( - Context.LOCATION_SERVICE); - mLocationRequest = new LocationRequest() - .setQuality(LocationRequest.ACCURACY_FINE) - .setInterval(0) - .setFastestInterval(0) - .setNumUpdates(1); + int sigMotionSensorId = getContext().getResources().getInteger( + com.android.internal.R.integer.config_autoPowerModeAnyMotionSensor); + if (sigMotionSensorId > 0) { + mMotionSensor = mSensorManager.getDefaultSensor(sigMotionSensorId, true); + } + if (mMotionSensor == null && getContext().getResources().getBoolean( + com.android.internal.R.bool.config_autoPowerModePreferWristTilt)) { + mMotionSensor = mSensorManager.getDefaultSensor( + Sensor.TYPE_WRIST_TILT_GESTURE, true); + } + if (mMotionSensor == null) { + // As a last ditch, fall back to SMD. + mMotionSensor = mSensorManager.getDefaultSensor( + Sensor.TYPE_SIGNIFICANT_MOTION, true); + } + + if (getContext().getResources().getBoolean( + com.android.internal.R.bool.config_autoPowerModePrefetchLocation)) { + mLocationManager = (LocationManager) getContext().getSystemService( + Context.LOCATION_SERVICE); + mLocationRequest = new LocationRequest() + .setQuality(LocationRequest.ACCURACY_FINE) + .setInterval(0) + .setFastestInterval(0) + .setNumUpdates(1); + } + + float angleThreshold = getContext().getResources().getInteger( + com.android.internal.R.integer.config_autoPowerModeThresholdAngle) / 100f; mAnyMotionDetector = new AnyMotionDetector( (PowerManager) getContext().getSystemService(Context.POWER_SERVICE), - mHandler, mSensorManager, this); + mHandler, mSensorManager, this, angleThreshold); Intent intent = new Intent(ACTION_STEP_IDLE_STATE) .setPackage("android") @@ -1242,7 +1309,7 @@ public class DeviceIdleController extends SystemService cancelAlarmLocked(); cancelSensingAlarmLocked(); cancelLocatingLocked(); - stopMonitoringSignificantMotion(); + stopMonitoringMotionLocked(); mAnyMotionDetector.stop(); } @@ -1271,8 +1338,8 @@ public class DeviceIdleController extends SystemService switch (mState) { case STATE_INACTIVE: // We have now been inactive long enough, it is time to start looking - // for significant motion and sleep some more while doing so. - startMonitoringSignificantMotion(); + // for motion and sleep some more while doing so. + startMonitoringMotionLocked(); scheduleAlarmLocked(mConstants.IDLE_AFTER_INACTIVE_TIMEOUT, false); // Reset the upcoming idle delays. mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT; @@ -1298,17 +1365,30 @@ public class DeviceIdleController extends SystemService if (DEBUG) Slog.d(TAG, "Moved from STATE_SENSING to STATE_LOCATING."); EventLogTags.writeDeviceIdle(mState, "step"); scheduleSensingAlarmLocked(mConstants.LOCATING_TIMEOUT); - mLocating = true; - mLocationManager.requestLocationUpdates(mLocationRequest, mGenericLocationListener, - mHandler.getLooper()); - if (mLocationManager.getProvider(LocationManager.GPS_PROVIDER) != null) { - mHaveGps = true; + if (mLocationManager != null + && mLocationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) { + mLocationManager.requestLocationUpdates(mLocationRequest, + mGenericLocationListener, mHandler.getLooper()); + mLocating = true; + } else { + mHasNetworkLocation = false; + } + if (mLocationManager != null + && mLocationManager.getProvider(LocationManager.GPS_PROVIDER) != null) { + mHasGps = true; mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5, mGpsLocationListener, mHandler.getLooper()); + mLocating = true; } else { - mHaveGps = false; + mHasGps = false; } - break; + // If we have a location provider, we're all set, the listeners will move state + // forward. + if (mLocating) { + break; + } + + // Otherwise, we have to move from locating into idle maintenance. case STATE_LOCATING: cancelSensingAlarmLocked(); cancelLocatingLocked(); @@ -1338,17 +1418,16 @@ public class DeviceIdleController extends SystemService } } - void significantMotionLocked() { - if (DEBUG) Slog.d(TAG, "significantMotionLocked()"); - // When the sensor goes off, its trigger is automatically removed. - mSigMotionActive = false; + void motionLocked() { + if (DEBUG) Slog.d(TAG, "motionLocked()"); + // The motion sensor will have been disabled at this point handleMotionDetectedLocked(mConstants.MOTION_INACTIVE_TIMEOUT, "motion"); } void handleMotionDetectedLocked(long timeout, String type) { // The device is not yet active, so we want to go back to the pending idle - // state to wait again for no motion. Note that we only monitor for significant - // motion after moving out of the inactive state, so no need to worry about that. + // state to wait again for no motion. Note that we only monitor for motion + // after moving out of the inactive state, so no need to worry about that. if (mState != STATE_ACTIVE) { scheduleReportActiveLocked(type, Process.myUid()); mState = STATE_ACTIVE; @@ -1366,7 +1445,7 @@ public class DeviceIdleController extends SystemService } if (DEBUG) Slog.d(TAG, "Generic location: " + location); mLastGenericLocation = new Location(location); - if (location.getAccuracy() > mConstants.LOCATION_ACCURACY && mHaveGps) { + if (location.getAccuracy() > mConstants.LOCATION_ACCURACY && mHasGps) { return; } mLocated = true; @@ -1391,19 +1470,17 @@ public class DeviceIdleController extends SystemService } } - void startMonitoringSignificantMotion() { - if (DEBUG) Slog.d(TAG, "startMonitoringSignificantMotion()"); - if (mSigMotionSensor != null && !mSigMotionActive) { - mSensorManager.requestTriggerSensor(mSigMotionListener, mSigMotionSensor); - mSigMotionActive = true; + void startMonitoringMotionLocked() { + if (DEBUG) Slog.d(TAG, "startMonitoringMotionLocked()"); + if (mMotionSensor != null && !mMotionListener.active) { + mMotionListener.registerLocked(); } } - void stopMonitoringSignificantMotion() { - if (DEBUG) Slog.d(TAG, "stopMonitoringSignificantMotion()"); - if (mSigMotionActive) { - mSensorManager.cancelTriggerSensor(mSigMotionListener, mSigMotionSensor); - mSigMotionActive = false; + void stopMonitoringMotionLocked() { + if (DEBUG) Slog.d(TAG, "stopMonitoringMotionLocked()"); + if (mMotionSensor != null && mMotionListener.active) { + mMotionListener.unregisterLocked(); } } @@ -1432,10 +1509,10 @@ public class DeviceIdleController extends SystemService void scheduleAlarmLocked(long delay, boolean idleUntil) { if (DEBUG) Slog.d(TAG, "scheduleAlarmLocked(" + delay + ", " + idleUntil + ")"); - if (mSigMotionSensor == null) { - // If there is no significant motion sensor on this device, then we won't schedule + if (mMotionSensor == null) { + // If there is no motion sensor on this device, then we won't schedule // alarms, because we can't determine if the device is not moving. This effectively - // turns off normal exeuction of device idling, although it is still possible to + // turns off normal execution of device idling, although it is still possible to // manually poke it by pretending like the alarm is going off. return; } @@ -1917,15 +1994,16 @@ public class DeviceIdleController extends SystemService pw.print(" mEnabled="); pw.println(mEnabled); pw.print(" mForceIdle="); pw.println(mForceIdle); - pw.print(" mSigMotionSensor="); pw.println(mSigMotionSensor); + pw.print(" mMotionSensor="); pw.println(mMotionSensor); pw.print(" mCurDisplay="); pw.println(mCurDisplay); pw.print(" mScreenOn="); pw.println(mScreenOn); pw.print(" mCharging="); pw.println(mCharging); - pw.print(" mSigMotionActive="); pw.println(mSigMotionActive); + pw.print(" mMotionActive="); pw.println(mMotionListener.active); pw.print(" mSensing="); pw.print(mSensing); pw.print(" mNotMoving="); pw.println(mNotMoving); - pw.print(" mLocating="); pw.print(mLocating); pw.print(" mHaveGps="); - pw.print(mHaveGps); pw.print(" mLocated="); pw.println(mLocated); + pw.print(" mLocating="); pw.print(mLocating); pw.print(" mHasGps="); + pw.print(mHasGps); pw.print(" mHasNetwork="); + pw.print(mHasNetworkLocation); pw.print(" mLocated="); pw.println(mLocated); if (mLastGenericLocation != null) { pw.print(" mLastGenericLocation="); pw.println(mLastGenericLocation); } diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags index cfc123b..8bb158e 100644 --- a/services/core/java/com/android/server/EventLogTags.logtags +++ b/services/core/java/com/android/server/EventLogTags.logtags @@ -33,6 +33,9 @@ option java_package com.android.server # This is logged when the partial wake lock (keeping the device awake # regardless of whether the screen is off) is acquired or released. 2729 power_partial_wake_state (releasedorAcquired|1|5),(tag|3) +# The device is being asked to go into a soft sleep (typically by the ungaze gesture). +# It logs the time remaining before the device would've normally gone to sleep without the request. +2731 power_soft_sleep_requested (savedwaketimems|2) # # Leave IDs through 2739 for more power logs (2730 used by battery_discharge and diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java index 55a9ff5..274adf8 100644 --- a/services/core/java/com/android/server/LockSettingsService.java +++ b/services/core/java/com/android/server/LockSettingsService.java @@ -358,6 +358,10 @@ public class LockSettingsService extends ILockSettings.Stub { } } + if (LockPatternUtils.LEGACY_LOCK_PATTERN_ENABLED.equals(key)) { + key = Settings.Secure.LOCK_PATTERN_ENABLED; + } + return mStorage.readKeyValue(key, defaultValue, userId); } diff --git a/services/core/java/com/android/server/ThermalObserver.java b/services/core/java/com/android/server/ThermalObserver.java new file mode 100644 index 0000000..aee28fb --- /dev/null +++ b/services/core/java/com/android/server/ThermalObserver.java @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2015 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.server; + +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.os.Binder; +import android.os.Handler; +import android.os.Message; +import android.os.PowerManager; +import android.os.UEventObserver; +import android.os.UserHandle; + +import java.io.FileDescriptor; +import java.io.PrintWriter; + +/** + * ThermalObserver for monitoring temperature changes. + */ +public class ThermalObserver extends SystemService { + private static final String TAG = "ThermalObserver"; + + private static final String CALLSTATE_UEVENT_MATCH = + "DEVPATH=/devices/virtual/switch/thermalstate"; + + private static final int MSG_THERMAL_STATE_CHANGED = 0; + + private static final int SWITCH_STATE_NORMAL = 0; + private static final int SWITCH_STATE_WARNING = 1; + private static final int SWITCH_STATE_EXCEEDED = 2; + + private final PowerManager mPowerManager; + private final PowerManager.WakeLock mWakeLock; + + private final Object mLock = new Object(); + private Integer mLastState; + + private final UEventObserver mThermalWarningObserver = new UEventObserver() { + @Override + public void onUEvent(UEventObserver.UEvent event) { + updateLocked(Integer.parseInt(event.get("SWITCH_STATE"))); + } + }; + + private final Handler mHandler = new Handler(true /*async*/) { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_THERMAL_STATE_CHANGED: + handleThermalStateChange(msg.arg1); + mWakeLock.release(); + break; + } + } + }; + + public ThermalObserver(Context context) { + super(context); + mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE); + mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); + + mThermalWarningObserver.startObserving(CALLSTATE_UEVENT_MATCH); + } + + private void updateLocked(int state) { + Message message = new Message(); + message.what = MSG_THERMAL_STATE_CHANGED; + message.arg1 = state; + + mWakeLock.acquire(); + mHandler.sendMessage(message); + } + + private void handleThermalStateChange(int state) { + synchronized (mLock) { + mLastState = state; + Intent intent = new Intent(Intent.ACTION_THERMAL_EVENT); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); + + final int thermalState; + + switch (state) { + case SWITCH_STATE_WARNING: + thermalState = Intent.EXTRA_THERMAL_STATE_WARNING; + break; + case SWITCH_STATE_EXCEEDED: + thermalState = Intent.EXTRA_THERMAL_STATE_EXCEEDED; + break; + case SWITCH_STATE_NORMAL: + default: + thermalState = Intent.EXTRA_THERMAL_STATE_NORMAL; + break; + } + + intent.putExtra(Intent.EXTRA_THERMAL_STATE, thermalState); + + getContext().sendBroadcastAsUser(intent, UserHandle.ALL); + } + } + + @Override + public void onStart() { + publishBinderService(TAG, new BinderService()); + } + + private final class BinderService extends Binder { + @Override + protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP) + != PackageManager.PERMISSION_GRANTED) { + pw.println("Permission Denial: can't dump thermal observer service from from pid=" + + Binder.getCallingPid() + + ", uid=" + Binder.getCallingUid()); + return; + } + + final long ident = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + if (args == null || args.length == 0 || "-a".equals(args[0])) { + pw.println("Current Thermal Observer Service state:"); + pw.println(" last state change: " + + (mLastState != null ? mLastState : "none")); + } + } + } finally { + Binder.restoreCallingIdentity(ident); + } + } + } +} diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index ed7c3a8..1014395 100755 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -334,6 +334,11 @@ public final class ActivityManagerService extends ActivityManagerNative // before we decide it must be hung. static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000; + // How long we will retain processes hosting content providers in the "last activity" + // state before allowing them to drop down to the regular cached LRU list. This is + // to avoid thrashing of provider processes under low memory situations. + static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000; + // How long we wait for a launched process to attach to the activity manager // before we decide it's never going to come up for real, when the process was // started with a wrapper for instrumentation (such as Valgrind) because it @@ -9709,6 +9714,14 @@ public final class ActivityManagerService extends ActivityManagerNative if (conn.stableCount == 0 && conn.unstableCount == 0) { cpr.connections.remove(conn); conn.client.conProviders.remove(conn); + if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { + // The client is more important than last activity -- note the time this + // is happening, so we keep the old provider process around a bit as last + // activity to avoid thrashing it. + if (cpr.proc != null) { + cpr.proc.lastProviderTime = SystemClock.uptimeMillis(); + } + } stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name); return true; } @@ -15398,6 +15411,10 @@ public final class ActivityManagerService extends ActivityManagerNative pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); + } else { + pw.print("lostram,"); pw.println(memInfo.getTotalSizeKb() + - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() + - memInfo.getKernelUsedSizeKb()); } if (!brief) { if (memInfo.getZramTotalSizeKb() != 0) { @@ -18555,6 +18572,18 @@ public final class ActivityManagerService extends ActivityManagerNative } } + if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) { + if (adj > ProcessList.PREVIOUS_APP_ADJ) { + adj = ProcessList.PREVIOUS_APP_ADJ; + schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; + app.cached = false; + app.adjType = "provider"; + } + if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { + procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; + } + } + if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { // A client of one of our services or providers is in the top state. We // *may* want to be in the top state, but not if we are already running in diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index 9cab95b..33f1a1c 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -136,6 +136,7 @@ final class ProcessRecord { long curCpuTime; // How long proc has run CPU most recently long lastRequestedGc; // When we last asked the app to do a gc long lastLowMemory; // When we last told the app that memory is low + long lastProviderTime; // The last time someone else was using a provider in this process. boolean reportLowMemory; // Set to true when waiting to report low mem boolean empty; // Is this an empty background process? boolean cached; // Is this a cached process? @@ -317,6 +318,11 @@ final class ProcessRecord { pw.print(" foregroundActivities="); pw.print(foregroundActivities); pw.print(" (rep="); pw.print(repForegroundActivities); pw.println(")"); } + if (lastProviderTime > 0) { + pw.print(prefix); pw.print("lastProviderTime="); + TimeUtils.formatDuration(lastProviderTime, now, pw); + pw.println(); + } if (hasStartedServices) { pw.print(prefix); pw.print("hasStartedServices="); pw.println(hasStartedServices); } diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index 3ec0bee..ef086da 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -2604,32 +2604,17 @@ public class SyncManager { } continue; } - if (!isOperationValidLocked(op)) { - operationIterator.remove(); - mSyncStorageEngine.deleteFromPending(op.pendingOperation); - continue; - } - // If the next run time is in the future, even given the flexible scheduling, - // return the time. - if (op.effectiveRunTime - op.flexTime > now) { - if (nextReadyToRunTime > op.effectiveRunTime) { - nextReadyToRunTime = op.effectiveRunTime; - } - if (isLoggable) { - Log.v(TAG, " Not running sync operation: Sync too far in future." - + "effective: " + op.effectiveRunTime + " flex: " + op.flexTime - + " now: " + now); - } - continue; - } String packageName = getPackageName(op.target); ApplicationInfo ai = null; if (packageName != null) { try { ai = mContext.getPackageManager().getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES - | PackageManager.GET_DISABLED_COMPONENTS); + | PackageManager.GET_DISABLED_COMPONENTS); } catch (NameNotFoundException e) { + operationIterator.remove(); + mSyncStorageEngine.deleteFromPending(op.pendingOperation); + continue; } } // If app is considered idle, then skip for now and backoff @@ -2644,6 +2629,24 @@ public class SyncManager { } else { op.appIdle = false; } + if (!isOperationValidLocked(op)) { + operationIterator.remove(); + mSyncStorageEngine.deleteFromPending(op.pendingOperation); + continue; + } + // If the next run time is in the future, even given the flexible scheduling, + // return the time. + if (op.effectiveRunTime - op.flexTime > now) { + if (nextReadyToRunTime > op.effectiveRunTime) { + nextReadyToRunTime = op.effectiveRunTime; + } + if (isLoggable) { + Log.v(TAG, " Not running sync operation: Sync too far in future." + + "effective: " + op.effectiveRunTime + " flex: " + op.flexTime + + " now: " + now); + } + continue; + } // Add this sync to be run. operations.add(op); } diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java index 11de1a2..bdb77db 100644 --- a/services/core/java/com/android/server/location/GpsLocationProvider.java +++ b/services/core/java/com/android/server/location/GpsLocationProvider.java @@ -781,6 +781,10 @@ public class GpsLocationProvider implements LocationProviderInterface { && mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) { if (mNetworkAvailable) { String apnName = info.getExtraInfo(); + // APN wasn't found in the intent, try to get it from the content provider. + if (apnName == null) { + apnName = getSelectedApn(); + } if (apnName == null) { /* Assign a dummy value in the case of C2K as otherwise we will have a runtime exception in the following call to native_agps_data_conn_open*/ diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index f1d1c35..da62313 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -203,6 +203,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private static final int VERSION_LATEST = VERSION_SWITCH_UID; @VisibleForTesting + public static final int TYPE_NONE = 0; + @VisibleForTesting public static final int TYPE_WARNING = 0x1; @VisibleForTesting public static final int TYPE_LIMIT = 0x2; @@ -263,6 +265,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private PowerManagerInternal mPowerManagerInternal; private IDeviceIdleController mDeviceIdleController; + private final ComponentName mNotificationComponent; + private int mNotificationSequenceNumber; + final Object mRulesLock = new Object(); volatile boolean mSystemReady; @@ -364,6 +369,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml")); mAppOps = context.getSystemService(AppOpsManager.class); + + final String notificationComponent = context.getString( + R.string.config_networkPolicyNotificationComponent); + mNotificationComponent = notificationComponent != null + ? ComponentName.unflattenFromString(notificationComponent) : null; } public void bindConnectivityManager(IConnectivityManager connManager) { @@ -776,6 +786,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final ArraySet<String> beforeNotifs = new ArraySet<String>(mActiveNotifs); mActiveNotifs.clear(); + // increment the sequence number so custom components know + // this update is new + mNotificationSequenceNumber++; + boolean hasNotifications = false; + // TODO: when switching to kernel notifications, compute next future // cycle boundary to recompute notifications. @@ -792,6 +807,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final long totalBytes = getTotalBytes(policy.template, start, end); if (policy.isOverLimit(totalBytes)) { + hasNotifications = true; if (policy.lastLimitSnooze >= start) { enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes); } else { @@ -805,10 +821,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { if (policy.isOverWarning(totalBytes) && policy.lastWarningSnooze < start && policy.limitBytes != LIMIT_DISABLED) { enqueueNotification(policy, TYPE_WARNING, totalBytes); + hasNotifications = true; } } } + // right now we don't care about restricted background notifications + // in the custom notification component, so trigger an update now + // if we didn't update anything this pass + if (!hasNotifications) { + sendNotificationToCustomComponent(null, TYPE_NONE, 0); + } + // ongoing notification when restricting background data if (mRestrictBackground) { enqueueRestrictedNotification(TAG_ALLOW_BACKGROUND); @@ -855,6 +879,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { * {@link NetworkPolicy#limitBytes}, potentially showing dialog to user. */ private void notifyOverLimitLocked(NetworkTemplate template) { + if (mNotificationComponent != null) { + // It is the job of the notification component to handle UI, + // so we do nothing here + return; + } + if (!mOverLimitNotified.contains(template)) { mContext.startActivity(buildNetworkOverLimitIntent(template)); mOverLimitNotified.add(template); @@ -873,11 +903,55 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { return TAG + ":" + policy.template.hashCode() + ":" + type; } + private boolean sendNotificationToCustomComponent( + NetworkPolicy policy, + int type, + long totalBytes) { + if (mNotificationComponent == null) { + return false; + } + + Intent intent = new Intent(); + intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND); + intent.setComponent(mNotificationComponent); + + int notificationType = NetworkPolicyManager.NOTIFICATION_TYPE_NONE; + switch (type) { + case TYPE_WARNING: + notificationType = NetworkPolicyManager.NOTIFICATION_TYPE_USAGE_WARNING; + break; + case TYPE_LIMIT: + notificationType = NetworkPolicyManager.NOTIFICATION_TYPE_USAGE_REACHED_LIMIT; + break; + case TYPE_LIMIT_SNOOZED: + notificationType = NetworkPolicyManager.NOTIFICATION_TYPE_USAGE_EXCEEDED_LIMIT; + break; + } + + intent.setAction(NetworkPolicyManager.ACTION_SHOW_NETWORK_POLICY_NOTIFICATION); + intent.putExtra(NetworkPolicyManager.EXTRA_NOTIFICATION_TYPE, notificationType); + intent.putExtra( + NetworkPolicyManager.EXTRA_NOTIFICATION_SEQUENCE_NUMBER, + mNotificationSequenceNumber); + + if (notificationType != NetworkPolicyManager.NOTIFICATION_TYPE_NONE) { + intent.putExtra(NetworkPolicyManager.EXTRA_NETWORK_POLICY, policy); + intent.putExtra(NetworkPolicyManager.EXTRA_BYTES_USED, totalBytes); + } + + mContext.sendBroadcast(intent); + return true; + } + /** * Show notification for combined {@link NetworkPolicy} and specific type, * like {@link #TYPE_LIMIT}. Okay to call multiple times. */ private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes) { + if (sendNotificationToCustomComponent(policy, type, totalBytes)) { + return; + } + final String tag = buildNotificationTag(policy, type); final Notification.Builder builder = new Notification.Builder(mContext); builder.setOnlyAlertOnce(true); @@ -1737,6 +1811,19 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } + @Override + public void snoozeWarning(NetworkTemplate template) { + mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); + + final long token = Binder.clearCallingIdentity(); + try { + // TODO: this seems like a race condition? (along with snoozeLimit above) + performSnooze(template, TYPE_WARNING); + } finally { + Binder.restoreCallingIdentity(token); + } + } + void performSnooze(NetworkTemplate template, int type) { maybeRefreshTrustedTime(); final long currentTime = currentTimeMillis(); diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 12190be..36818b5 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -1596,10 +1596,11 @@ public class NotificationManagerService extends SystemService { Binder.getCallingUid(), incomingUserId, true, false, "getAppActiveNotifications", pkg); - final int N = mNotificationList.size(); - final ArrayList<StatusBarNotification> list = new ArrayList<StatusBarNotification>(N); + final ArrayList<StatusBarNotification> list + = new ArrayList<StatusBarNotification>(mNotificationList.size()); synchronized (mNotificationList) { + final int N = mNotificationList.size(); for (int i = 0; i < N; i++) { final StatusBarNotification sbn = mNotificationList.get(i).sbn; if (sbn.getPackageName().equals(pkg) && sbn.getUserId() == userId) { diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index 3fbd626..468ef8d 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -436,8 +436,7 @@ public class ZenModeHelper { applyRestrictions(muteNotifications, USAGE_NOTIFICATION); // call restrictions - final boolean muteCalls = zen && !mConfig.allowCalls && !mConfig.allowRepeatCallers - || mEffectsSuppressed; + final boolean muteCalls = zen && !mConfig.allowCalls && !mConfig.allowRepeatCallers; applyRestrictions(muteCalls, USAGE_NOTIFICATION_RINGTONE); // alarm restrictions diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java index df023fd..29e9fa6 100644 --- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java +++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java @@ -572,6 +572,26 @@ final class DefaultPermissionGrantPolicy { grantRuntimePermissionsLPw(musicPackage, STORAGE_PERMISSIONS, userId); } + // Android Wear Home + if (mService.hasSystemFeature(PackageManager.FEATURE_WATCH)) { + Intent homeIntent = new Intent(Intent.ACTION_MAIN); + homeIntent.addCategory(Intent.CATEGORY_HOME_MAIN); + + PackageParser.Package wearHomePackage = getDefaultSystemHandlerActivityPackageLPr( + homeIntent, userId); + + if (wearHomePackage != null + && doesPackageSupportRuntimePermissions(wearHomePackage)) { + grantRuntimePermissionsLPw(wearHomePackage, CONTACTS_PERMISSIONS, false, + userId); + grantRuntimePermissionsLPw(wearHomePackage, PHONE_PERMISSIONS, true, userId); + grantRuntimePermissionsLPw(wearHomePackage, MICROPHONE_PERMISSIONS, false, + userId); + grantRuntimePermissionsLPw(wearHomePackage, LOCATION_PERMISSIONS, false, + userId); + } + } + mService.mSettings.onDefaultRuntimePermissionsGrantedLPr(userId); } } @@ -579,7 +599,10 @@ final class DefaultPermissionGrantPolicy { private void grantDefaultPermissionsToDefaultSystemDialerAppLPr( PackageParser.Package dialerPackage, int userId) { if (doesPackageSupportRuntimePermissions(dialerPackage)) { - grantRuntimePermissionsLPw(dialerPackage, PHONE_PERMISSIONS, userId); + boolean isPhonePermFixed = + mService.hasSystemFeature(PackageManager.FEATURE_WATCH); + grantRuntimePermissionsLPw( + dialerPackage, PHONE_PERMISSIONS, isPhonePermFixed, userId); grantRuntimePermissionsLPw(dialerPackage, CONTACTS_PERMISSIONS, userId); grantRuntimePermissionsLPw(dialerPackage, SMS_PERMISSIONS, userId); grantRuntimePermissionsLPw(dialerPackage, MICROPHONE_PERMISSIONS, userId); diff --git a/services/core/java/com/android/server/policy/BurnInProtectionHelper.java b/services/core/java/com/android/server/policy/BurnInProtectionHelper.java index fef1e57..e6ec6a6 100644 --- a/services/core/java/com/android/server/policy/BurnInProtectionHelper.java +++ b/services/core/java/com/android/server/policy/BurnInProtectionHelper.java @@ -72,6 +72,9 @@ public class BurnInProtectionHelper implements DisplayManager.DisplayListener, /* 1 means increasing, -1 means decreasing */ private int mYOffsetDirection = 1; + private int mAppliedBurnInXOffset = 0; + private int mAppliedBurnInYOffset = 0; + private final AlarmManager mAlarmManager; private final PendingIntent mBurnInProtectionIntent; private final DisplayManagerInternal mDisplayManagerInternal; @@ -139,6 +142,8 @@ public class BurnInProtectionHelper implements DisplayManager.DisplayListener, mFirstUpdate = false; } else { adjustOffsets(); + mAppliedBurnInXOffset = mLastBurnInXOffset; + mAppliedBurnInYOffset = mLastBurnInYOffset; mDisplayManagerInternal.setDisplayOffsets(mDisplay.getDisplayId(), mLastBurnInXOffset, mLastBurnInYOffset); } @@ -258,6 +263,8 @@ public class BurnInProtectionHelper implements DisplayManager.DisplayListener, @Override public void onAnimationEnd(Animator animator) { if (animator == mCenteringAnimator && !mBurnInProtectionActive) { + mAppliedBurnInXOffset = 0; + mAppliedBurnInYOffset = 0; // No matter how the animation finishes, we want to zero the offsets. mDisplayManagerInternal.setDisplayOffsets(mDisplay.getDisplayId(), 0, 0); } @@ -276,7 +283,7 @@ public class BurnInProtectionHelper implements DisplayManager.DisplayListener, if (!mBurnInProtectionActive) { final float value = (Float) valueAnimator.getAnimatedValue(); mDisplayManagerInternal.setDisplayOffsets(mDisplay.getDisplayId(), - (int) (mLastBurnInXOffset * value), (int) (mLastBurnInYOffset * value)); + (int) (mAppliedBurnInXOffset * value), (int) (mAppliedBurnInYOffset * value)); } } } diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 70d40d7..cd99038 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -1567,6 +1567,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class); mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); + mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); // Init display burn-in protection boolean burnInProtectionEnabled = context.getResources().getBoolean( @@ -5829,6 +5830,15 @@ public class PhoneWindowManager implements WindowManagerPolicy { break; } + case KeyEvent.KEYCODE_SOFT_SLEEP: { + result &= ~ACTION_PASS_TO_USER; + isWakeKey = false; + if (!down) { + mPowerManagerInternal.setUserInactiveOverrideFromWindowManager(); + } + break; + } + case KeyEvent.KEYCODE_WAKEUP: { result &= ~ACTION_PASS_TO_USER; isWakeKey = true; @@ -6041,11 +6051,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { } private boolean shouldDispatchInputWhenNonInteractive() { - if (mDisplay == null || mDisplay.getState() == Display.STATE_OFF) { - return false; - } - // Send events to keyguard while the screen is on and it's showing. - if (isKeyguardShowingAndNotOccluded()) { + // Send events to keyguard while the screen is on. + if (isKeyguardShowingAndNotOccluded() && mDisplay != null + && mDisplay.getState() != Display.STATE_OFF) { return true; } diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 05ab6b6..70fdfff 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -434,6 +434,14 @@ public final class PowerManagerService extends SystemService // Use -1 to disable. private int mButtonBrightnessOverrideFromWindowManager = -1; + // The window manager has determined the user to be inactive via other means. + // Set this to false to disable. + private boolean mUserInactiveOverrideFromWindowManager; + + // The next possible user activity timeout after being explicitly told the user is inactive. + // Set to -1 when not told the user is inactive since the last period spent dozing or asleep. + private long mOverriddenTimeout = -1; + // The user activity timeout override from the window manager // to allow the current foreground activity to override the user activity timeout. // Use -1 to disable. @@ -1151,6 +1159,11 @@ public final class PowerManagerService extends SystemService mNotifier.onUserActivity(event, uid); + if (mUserInactiveOverrideFromWindowManager) { + mUserInactiveOverrideFromWindowManager = false; + mOverriddenTimeout = -1; + } + if (mWakefulness == WAKEFULNESS_ASLEEP || mWakefulness == WAKEFULNESS_DOZING || (flags & PowerManager.USER_ACTIVITY_FLAG_INDIRECT) != 0) { @@ -1366,12 +1379,28 @@ public final class PowerManagerService extends SystemService } } + /** + * Logs the time the device would have spent awake before user activity timeout, + * had the system not been told the user was inactive. + */ + private void logSleepTimeoutRecapturedLocked() { + final long now = SystemClock.uptimeMillis(); + final long savedWakeTimeMs = mOverriddenTimeout - now; + if (savedWakeTimeMs >= 0) { + EventLog.writeEvent(EventLogTags.POWER_SOFT_SLEEP_REQUESTED, savedWakeTimeMs); + mOverriddenTimeout = -1; + } + } + private void finishWakefulnessChangeIfNeededLocked() { if (mWakefulnessChanging && mDisplayReady) { if (mWakefulness == WAKEFULNESS_DOZING && (mWakeLockSummary & WAKE_LOCK_DOZE) == 0) { return; // wait until dream has enabled dozing } + if (mWakefulness == WAKEFULNESS_DOZING || mWakefulness == WAKEFULNESS_ASLEEP) { + logSleepTimeoutRecapturedLocked(); + } mWakefulnessChanging = false; mNotifier.onWakefulnessChangeFinished(); } @@ -1657,6 +1686,7 @@ public final class PowerManagerService extends SystemService final int sleepTimeout = getSleepTimeoutLocked(); final int screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout); final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout); + final boolean userInactiveOverride = mUserInactiveOverrideFromWindowManager; mUserActivitySummary = 0; if (mLastUserActivityTime >= mLastWakeTime) { @@ -1710,6 +1740,7 @@ public final class PowerManagerService extends SystemService } } } + if (mUserActivitySummary == 0) { if (sleepTimeout >= 0) { final long anyUserActivity = Math.max(mLastUserActivityTime, @@ -1725,6 +1756,20 @@ public final class PowerManagerService extends SystemService nextTimeout = -1; } } + + if (mUserActivitySummary != USER_ACTIVITY_SCREEN_DREAM && userInactiveOverride) { + if ((mUserActivitySummary & + (USER_ACTIVITY_SCREEN_BRIGHT | USER_ACTIVITY_SCREEN_DIM)) != 0) { + // Device is being kept awake by recent user activity + if (nextTimeout >= now && mOverriddenTimeout == -1) { + // Save when the next timeout would have occurred + mOverriddenTimeout = nextTimeout; + } + } + mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM; + nextTimeout = -1; + } + if (mUserActivitySummary != 0 && nextTimeout >= 0) { Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT); msg.setAsynchronous(true); @@ -2654,6 +2699,14 @@ public final class PowerManagerService extends SystemService } } + private void setUserInactiveOverrideFromWindowManagerInternal() { + synchronized (mLock) { + mUserInactiveOverrideFromWindowManager = true; + mDirty |= DIRTY_USER_ACTIVITY; + updatePowerStateLocked(); + } + } + private void setUserActivityTimeoutOverrideFromWindowManagerInternal(long timeoutMillis) { synchronized (mLock) { if (mUserActivityTimeoutOverrideFromWindowManager != timeoutMillis) { @@ -2843,6 +2896,8 @@ public final class PowerManagerService extends SystemService + mScreenBrightnessOverrideFromWindowManager); pw.println(" mUserActivityTimeoutOverrideFromWindowManager=" + mUserActivityTimeoutOverrideFromWindowManager); + pw.println(" mUserInactiveOverrideFromWindowManager=" + + mUserInactiveOverrideFromWindowManager); pw.println(" mTemporaryScreenBrightnessSettingOverride=" + mTemporaryScreenBrightnessSettingOverride); pw.println(" mTemporaryScreenAutoBrightnessAdjustmentSettingOverride=" @@ -3839,6 +3894,11 @@ public final class PowerManagerService extends SystemService } @Override + public void setUserInactiveOverrideFromWindowManager() { + setUserInactiveOverrideFromWindowManagerInternal(); + } + + @Override public void setUserActivityTimeoutOverrideFromWindowManager(long timeoutMillis) { setUserActivityTimeoutOverrideFromWindowManagerInternal(timeoutMillis); } diff --git a/services/core/java/com/android/server/wm/CircularDisplayMask.java b/services/core/java/com/android/server/wm/CircularDisplayMask.java index 7c2da2d..be3e922 100644 --- a/services/core/java/com/android/server/wm/CircularDisplayMask.java +++ b/services/core/java/com/android/server/wm/CircularDisplayMask.java @@ -56,7 +56,7 @@ class CircularDisplayMask { int screenOffset, int maskThickness) { mScreenSize = new Point(); display.getSize(mScreenSize); - if (mScreenSize.x != mScreenSize.y) { + if (mScreenSize.x != mScreenSize.y + screenOffset) { Slog.w(TAG, "Screen dimensions of displayId = " + display.getDisplayId() + "are not equal, circularMask will not be drawn."); mDimensionsUnequal = true; diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 331ddbf..2edf552 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -116,6 +116,7 @@ class DisplayContent { display.getDisplayInfo(mDisplayInfo); isDefaultDisplay = mDisplayId == Display.DEFAULT_DISPLAY; mService = service; + initializeDisplayBaseInfo(); } int getDisplayId() { @@ -176,6 +177,21 @@ class DisplayContent { } } + void initializeDisplayBaseInfo() { + synchronized(mDisplaySizeLock) { + // Bootstrap the default logical display from the display manager. + final DisplayInfo newDisplayInfo = + mService.mDisplayManagerInternal.getDisplayInfo(mDisplayId); + if (newDisplayInfo != null) { + mDisplayInfo.copyFrom(newDisplayInfo); + } + mBaseDisplayWidth = mInitialDisplayWidth = mDisplayInfo.logicalWidth; + mBaseDisplayHeight = mInitialDisplayHeight = mDisplayInfo.logicalHeight; + mBaseDisplayDensity = mInitialDisplayDensity = mDisplayInfo.logicalDensityDpi; + mBaseDisplayRect.set(0, 0, mBaseDisplayWidth, mBaseDisplayHeight); + } + } + void getLogicalDisplayRect(Rect out) { // Uses same calculation as in LogicalDisplay#configureDisplayInTransactionLocked. final int orientation = mDisplayInfo.rotation; diff --git a/services/core/java/com/android/server/wm/DisplaySettings.java b/services/core/java/com/android/server/wm/DisplaySettings.java index 01f878c..80526f2 100644 --- a/services/core/java/com/android/server/wm/DisplaySettings.java +++ b/services/core/java/com/android/server/wm/DisplaySettings.java @@ -79,17 +79,20 @@ public class DisplaySettings { } } - public void setOverscanLocked(String name, int left, int top, int right, int bottom) { + public void setOverscanLocked(String uniqueId, String name, int left, int top, int right, + int bottom) { if (left == 0 && top == 0 && right == 0 && bottom == 0) { // Right now all we are storing is overscan; if there is no overscan, // we have no need for the entry. + mEntries.remove(uniqueId); + // Legacy name might have been in used, so we need to clear it. mEntries.remove(name); return; } - Entry entry = mEntries.get(name); + Entry entry = mEntries.get(uniqueId); if (entry == null) { - entry = new Entry(name); - mEntries.put(name, entry); + entry = new Entry(uniqueId); + mEntries.put(uniqueId, entry); } entry.overscanLeft = left; entry.overscanTop = top; diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index 480da44..7e437c7 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -399,7 +399,9 @@ public class TaskStack { void resetAnimationBackgroundAnimator() { mAnimationBackgroundAnimator = null; - mAnimationBackgroundSurface.hide(); + if (mAnimationBackgroundSurface != null) { + mAnimationBackgroundSurface.hide(); + } } private long getBlurBehindFadeDuration(long duration) { @@ -468,11 +470,14 @@ public class TaskStack { } boolean isDimming() { + if (mDimLayer == null) { + return false; + } return mDimLayer.isDimming(); } boolean isDimming(WindowStateAnimator winAnimator) { - return mDimWinAnimator == winAnimator && mDimLayer.isDimming(); + return mDimWinAnimator == winAnimator && isDimming(); } void startDimmingIfNeeded(WindowStateAnimator newWinAnimator) { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 1d5f64c..dcb1e18 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1015,7 +1015,6 @@ public class WindowManagerService extends IWindowManager.Stub // Load hardware rotation from prop mSfHwRotation = android.os.SystemProperties.getInt("ro.sf.hwrotation",0) / 90; - updateCircularDisplayMaskIfNeeded(); showEmulatorDisplayOverlayIfNeeded(); } @@ -4490,13 +4489,8 @@ public class WindowManagerService extends IWindowManager.Stub + " ShowWallpaper=" + ent.array.getBoolean( com.android.internal.R.styleable.Window_windowShowWallpaper, 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)) { + if (ent.array.getBoolean( + com.android.internal.R.styleable.Window_windowIsTranslucent, false)) { return; } if (ent.array.getBoolean( @@ -6003,7 +5997,7 @@ public class WindowManagerService extends IWindowManager.Stub } } - public void updateCircularDisplayMaskIfNeeded() { + private void updateCircularDisplayMaskIfNeeded() { // we're fullscreen and not hosted in an ActivityView if (mContext.getResources().getConfiguration().isScreenRound() && mContext.getResources().getBoolean( @@ -6043,8 +6037,8 @@ public class WindowManagerService extends IWindowManager.Stub if (visible) { // TODO(multi-display): support multiple displays if (mCircularDisplayMask == null) { - int screenOffset = mContext.getResources().getDimensionPixelSize( - com.android.internal.R.dimen.circular_display_mask_offset); + int screenOffset = mContext.getResources().getInteger( + com.android.internal.R.integer.config_windowOutsetBottom); int maskThickness = mContext.getResources().getDimensionPixelSize( com.android.internal.R.dimen.circular_display_mask_thickness); @@ -7726,6 +7720,8 @@ public class WindowManagerService extends IWindowManager.Stub mActivityManager.updateConfiguration(null); } catch (RemoteException e) { } + + updateCircularDisplayMaskIfNeeded(); } private void displayReady(int displayId) { @@ -7733,22 +7729,7 @@ public class WindowManagerService extends IWindowManager.Stub final DisplayContent displayContent = getDisplayContentLocked(displayId); if (displayContent != null) { mAnimator.addDisplayLocked(displayId); - synchronized(displayContent.mDisplaySizeLock) { - // Bootstrap the default logical display from the display manager. - final DisplayInfo displayInfo = displayContent.getDisplayInfo(); - DisplayInfo newDisplayInfo = mDisplayManagerInternal.getDisplayInfo(displayId); - if (newDisplayInfo != null) { - displayInfo.copyFrom(newDisplayInfo); - } - displayContent.mInitialDisplayWidth = displayInfo.logicalWidth; - displayContent.mInitialDisplayHeight = displayInfo.logicalHeight; - displayContent.mInitialDisplayDensity = displayInfo.logicalDensityDpi; - displayContent.mBaseDisplayWidth = displayContent.mInitialDisplayWidth; - displayContent.mBaseDisplayHeight = displayContent.mInitialDisplayHeight; - displayContent.mBaseDisplayDensity = displayContent.mInitialDisplayDensity; - displayContent.mBaseDisplayRect.set(0, 0, - displayContent.mBaseDisplayWidth, displayContent.mBaseDisplayHeight); - } + displayContent.initializeDisplayBaseInfo(); } } } @@ -8787,7 +8768,8 @@ public class WindowManagerService extends IWindowManager.Stub displayInfo.overscanBottom = bottom; } - mDisplaySettings.setOverscanLocked(displayInfo.uniqueId, left, top, right, bottom); + mDisplaySettings.setOverscanLocked(displayInfo.uniqueId, displayInfo.name, left, top, + right, bottom); mDisplaySettings.writeSettingsLocked(); reconfigureDisplayLocked(displayContent); |