diff options
Diffstat (limited to 'services')
14 files changed, 425 insertions, 111 deletions
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java index 83b953e..8d9c965 100644 --- a/services/backup/java/com/android/server/backup/BackupManagerService.java +++ b/services/backup/java/com/android/server/backup/BackupManagerService.java @@ -7848,8 +7848,12 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF // If we get this far, the callback or timeout will schedule the // next restore state, so we're done } catch (Exception e) { - Slog.e(TAG, "Unable to finalize restore of " + mCurrentPackage.packageName); - executeNextState(UnifiedRestoreState.FINAL); + final String packageName = mCurrentPackage.packageName; + Slog.e(TAG, "Unable to finalize restore of " + packageName); + EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, + packageName, e.toString()); + keyValueAgentErrorCleanup(); + executeNextState(UnifiedRestoreState.RUNNING_QUEUE); } } diff --git a/services/core/java/com/android/server/AnyMotionDetector.java b/services/core/java/com/android/server/AnyMotionDetector.java index 6390bcd..6a67316 100644 --- a/services/core/java/com/android/server/AnyMotionDetector.java +++ b/services/core/java/com/android/server/AnyMotionDetector.java @@ -16,9 +16,6 @@ package com.android.server; -import android.app.AlarmManager; -import android.content.BroadcastReceiver; -import android.content.Intent; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; @@ -85,17 +82,12 @@ public class AnyMotionDetector { /** The accelerometer sampling interval. */ private static final int SAMPLING_INTERVAL_MILLIS = 40; - private AlarmManager mAlarmManager; private final Handler mHandler; - private Intent mAlarmIntent; private final Object mLock = new Object(); private Sensor mAccelSensor; private SensorManager mSensorManager; private PowerManager.WakeLock mWakeLock; - /** The time when detection was last performed. */ - private long mDetectionStartTime; - /** The minimum number of samples required to detect AnyMotion. */ private int mNumSufficientSamples; @@ -113,11 +105,11 @@ public class AnyMotionDetector { private DeviceIdleCallback mCallback = null; - public AnyMotionDetector(AlarmManager am, PowerManager pm, Handler handler, SensorManager sm, + public AnyMotionDetector(PowerManager pm, Handler handler, SensorManager sm, DeviceIdleCallback callback) { if (DEBUG) Slog.d(TAG, "AnyMotionDetector instantiated."); - mAlarmManager = am; mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); + mWakeLock.setReferenceCounted(false); mHandler = handler; mSensorManager = sm; mAccelSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); @@ -144,6 +136,22 @@ public class AnyMotionDetector { } } + public void stop() { + if (mState == STATE_ACTIVE) { + mState = STATE_INACTIVE; + if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE."); + if (mMeasurementInProgress) { + mMeasurementInProgress = false; + mSensorManager.unregisterListener(mListener); + } + mHandler.removeCallbacks(mMeasurementTimeout); + mHandler.removeCallbacks(mSensorRestart); + mWakeLock.release(); + mCurrentGravityVector = null; + mPreviousGravityVector = null; + } + } + private void startOrientationMeasurement() { if (DEBUG) Slog.d(TAG, "startOrientationMeasurement: mMeasurementInProgress=" + mMeasurementInProgress + ", (mAccelSensor != null)=" + (mAccelSensor != null)); @@ -153,7 +161,6 @@ public class AnyMotionDetector { SAMPLING_INTERVAL_MILLIS * 1000)) { mWakeLock.acquire(); mMeasurementInProgress = true; - mDetectionStartTime = SystemClock.elapsedRealtime(); mRunningStats.reset(); } @@ -170,9 +177,7 @@ public class AnyMotionDetector { if (mMeasurementInProgress) { mSensorManager.unregisterListener(mListener); mHandler.removeCallbacks(mMeasurementTimeout); - if (mWakeLock.isHeld()) { - mWakeLock.release(); - } + mWakeLock.release(); long detectionEndTime = SystemClock.elapsedRealtime(); mMeasurementInProgress = false; mPreviousGravityVector = mCurrentGravityVector; diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java index e678bbc..80fd441 100644 --- a/services/core/java/com/android/server/DeviceIdleController.java +++ b/services/core/java/com/android/server/DeviceIdleController.java @@ -34,10 +34,15 @@ import android.hardware.SensorManager; import android.hardware.TriggerEvent; import android.hardware.TriggerEventListener; import android.hardware.display.DisplayManager; +import android.location.LocationRequest; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; import android.net.INetworkPolicyManager; import android.net.Uri; import android.os.BatteryStats; import android.os.Binder; +import android.os.Bundle; import android.os.Environment; import android.os.FileUtils; import android.os.Handler; @@ -107,6 +112,8 @@ public class DeviceIdleController extends SystemService private DisplayManager mDisplayManager; private SensorManager mSensorManager; private Sensor mSigMotionSensor; + private LocationManager mLocationManager; + private LocationRequest mLocationRequest; private PendingIntent mSensingAlarmIntent; private PendingIntent mAlarmIntent; private Intent mIdleIntent; @@ -117,6 +124,13 @@ public class DeviceIdleController extends SystemService 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 Location mLastGenericLocation; + private Location mLastGpsLocation; /** Device is currently active. */ private static final int STATE_ACTIVE = 0; @@ -126,16 +140,19 @@ public class DeviceIdleController extends SystemService private static final int STATE_IDLE_PENDING = 2; /** Device is currently sensing motion. */ private static final int STATE_SENSING = 3; + /** Device is currently finding location (and may still be sensing). */ + private static final int STATE_LOCATING = 4; /** Device is in the idle state, trying to stay asleep as much as possible. */ - private static final int STATE_IDLE = 4; + private static final int STATE_IDLE = 5; /** Device is in the idle state, but temporarily out of idle to do regular maintenance. */ - private static final int STATE_IDLE_MAINTENANCE = 5; + private static final int STATE_IDLE_MAINTENANCE = 6; private static String stateToString(int state) { switch (state) { case STATE_ACTIVE: return "ACTIVE"; case STATE_INACTIVE: return "INACTIVE"; case STATE_IDLE_PENDING: return "IDLE_PENDING"; case STATE_SENSING: return "SENSING"; + case STATE_LOCATING: return "LOCATING"; case STATE_IDLE: return "IDLE"; case STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE"; default: return Integer.toString(state); @@ -258,6 +275,48 @@ public class DeviceIdleController extends SystemService } }; + private final LocationListener mGenericLocationListener = new LocationListener() { + @Override + public void onLocationChanged(Location location) { + synchronized (DeviceIdleController.this) { + receivedGenericLocationLocked(location); + } + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + } + + @Override + public void onProviderEnabled(String provider) { + } + + @Override + public void onProviderDisabled(String provider) { + } + }; + + private final LocationListener mGpsLocationListener = new LocationListener() { + @Override + public void onLocationChanged(Location location) { + synchronized (DeviceIdleController.this) { + receivedGpsLocationLocked(location); + } + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + } + + @Override + public void onProviderEnabled(String provider) { + } + + @Override + public void onProviderDisabled(String provider) { + } + }; + /** * All times are in milliseconds. These constants are kept synchronized with the system * global Settings. Any access to this class or its fields should be done while @@ -267,6 +326,8 @@ public class DeviceIdleController extends SystemService // Key names stored in the settings value. private static final String KEY_INACTIVE_TIMEOUT = "inactive_to"; private static final String KEY_SENSING_TIMEOUT = "sensing_to"; + private static final String KEY_LOCATING_TIMEOUT = "locating_to"; + private static final String KEY_LOCATION_ACCURACY = "location_accuracy"; private static final String KEY_MOTION_INACTIVE_TIMEOUT = "motion_inactive_to"; private static final String KEY_IDLE_AFTER_INACTIVE_TIMEOUT = "idle_after_inactive_to"; private static final String KEY_IDLE_PENDING_TIMEOUT = "idle_pending_to"; @@ -294,7 +355,8 @@ public class DeviceIdleController extends SystemService public long INACTIVE_TIMEOUT; /** - * If we don't receive a callback from AnyMotion in this amount of time, we will change from + * If we don't receive a callback from AnyMotion in this amount of time + + * {@link #LOCATING_TIMEOUT}, we will change from * STATE_SENSING to STATE_INACTIVE, and any AnyMotion callbacks while not in STATE_SENSING * will be ignored. * @see Settings.Global#DEVICE_IDLE_CONSTANTS @@ -303,6 +365,23 @@ public class DeviceIdleController extends SystemService public long SENSING_TIMEOUT; /** + * This is how long we will wait to try to get a good location fix before going in to + * idle mode. + * @see Settings.Global#DEVICE_IDLE_CONSTANTS + * @see #KEY_LOCATING_TIMEOUT + */ + public long LOCATING_TIMEOUT; + + /** + * The desired maximum accuracy (in meters) we consider the location to be good enough to go + * on to idle. We will be trying to get an accuracy fix at least this good or until + * {@link #LOCATING_TIMEOUT} expires. + * @see Settings.Global#DEVICE_IDLE_CONSTANTS + * @see #KEY_LOCATION_ACCURACY + */ + public float LOCATION_ACCURACY; + + /** * This is the time, after seeing motion, that we wait after becoming inactive from * that until we start looking for motion again. * @see Settings.Global#DEVICE_IDLE_CONSTANTS @@ -423,7 +502,10 @@ public class DeviceIdleController extends SystemService INACTIVE_TIMEOUT = mParser.getLong(KEY_INACTIVE_TIMEOUT, !COMPRESS_TIME ? 30 * 60 * 1000L : 3 * 60 * 1000L); SENSING_TIMEOUT = mParser.getLong(KEY_SENSING_TIMEOUT, - !DEBUG ? 5 * 60 * 1000L : 60 * 1000L); + !DEBUG ? 4 * 60 * 1000L : 60 * 1000L); + LOCATING_TIMEOUT = mParser.getLong(KEY_LOCATING_TIMEOUT, + !DEBUG ? 30 * 1000L : 15 * 1000L); + LOCATION_ACCURACY = mParser.getFloat(KEY_LOCATION_ACCURACY, 20); MOTION_INACTIVE_TIMEOUT = mParser.getLong(KEY_MOTION_INACTIVE_TIMEOUT, !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L); IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getLong(KEY_IDLE_AFTER_INACTIVE_TIMEOUT, @@ -462,6 +544,14 @@ public class DeviceIdleController extends SystemService TimeUtils.formatDuration(SENSING_TIMEOUT, pw); pw.println(); + pw.print(" "); pw.print(KEY_LOCATING_TIMEOUT); pw.print("="); + TimeUtils.formatDuration(LOCATING_TIMEOUT, pw); + pw.println(); + + pw.print(" "); pw.print(KEY_LOCATION_ACCURACY); pw.print("="); + pw.print(LOCATION_ACCURACY); pw.print("m"); + pw.println(); + pw.print(" "); pw.print(KEY_MOTION_INACTIVE_TIMEOUT); pw.print("="); TimeUtils.formatDuration(MOTION_INACTIVE_TIMEOUT, pw); pw.println(); @@ -515,17 +605,27 @@ public class DeviceIdleController extends SystemService @Override public void onAnyMotionResult(int result) { if (DEBUG) Slog.d(TAG, "onAnyMotionResult(" + result + ")"); - if (mState == STATE_SENSING) { - if (result == AnyMotionDetector.RESULT_STATIONARY) { - if (DEBUG) Slog.d(TAG, "RESULT_STATIONARY received."); + if (result == AnyMotionDetector.RESULT_MOVED) { + if (DEBUG) Slog.d(TAG, "RESULT_MOVED received."); + synchronized (this) { + handleMotionDetectedLocked(mConstants.INACTIVE_TIMEOUT, "sense_motion"); + } + } else if (result == AnyMotionDetector.RESULT_STATIONARY) { + if (DEBUG) Slog.d(TAG, "RESULT_STATIONARY received."); + if (mState == STATE_SENSING) { + // If we are currently sensing, it is time to move to locating. synchronized (this) { + mNotMoving = true; stepIdleStateLocked(); } - } else if (result == AnyMotionDetector.RESULT_MOVED) { - if (DEBUG) Slog.d(TAG, "RESULT_MOVED received."); + } else if (mState == STATE_LOCATING) { + // If we are currently locating, note that we are not moving and step + // if we have located the position. synchronized (this) { - EventLogTags.writeDeviceIdle(mState, "sense_moved"); - enterInactiveStateLocked(); + mNotMoving = true; + if (mLocated) { + stepIdleStateLocked(); + } } } } @@ -778,13 +878,19 @@ public class DeviceIdleController extends SystemService mBatteryStats = BatteryStatsService.getService(); mLocalPowerManager = getLocalService(PowerManagerInternal.class); mNetworkPolicyManager = INetworkPolicyManager.Stub.asInterface( - ServiceManager.getService(Context.NETWORK_POLICY_SERVICE)); + ServiceManager.getService(Context.NETWORK_POLICY_SERVICE)); 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); mAnyMotionDetector = new AnyMotionDetector( - mAlarmManager, (PowerManager) getContext().getSystemService(Context.POWER_SERVICE), mHandler, mSensorManager, this); @@ -1049,7 +1155,7 @@ public class DeviceIdleController extends SystemService // We consider any situation where the display is showing something to be it on, // because if there is anything shown we are going to be updating it at some // frequency so can't be allowed to go into deep sleeps. - boolean screenOn = mCurDisplay.getState() != Display.STATE_OFF;; + boolean screenOn = mCurDisplay.getState() == Display.STATE_ON; if (DEBUG) Slog.d(TAG, "updateDisplayLocked: screenOn=" + screenOn); if (!screenOn && mScreenOn) { mScreenOn = false; @@ -1092,10 +1198,7 @@ public class DeviceIdleController extends SystemService scheduleReportActiveLocked(activeReason, activeUid); mState = STATE_ACTIVE; mInactiveTimeout = mConstants.INACTIVE_TIMEOUT; - mNextIdlePendingDelay = 0; - mNextIdleDelay = 0; - cancelAlarmLocked(); - stopMonitoringSignificantMotion(); + resetIdleManagementLocked(); } } @@ -1106,20 +1209,20 @@ public class DeviceIdleController extends SystemService // waiting to see if we will ultimately go idle. mState = STATE_INACTIVE; if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE"); - mNextIdlePendingDelay = 0; - mNextIdleDelay = 0; + resetIdleManagementLocked(); scheduleAlarmLocked(mInactiveTimeout, false); EventLogTags.writeDeviceIdle(mState, "no activity"); } } - /** - * This is called when we've failed to receive a callback from AnyMotionDetector - * within the DEFAULT_SENSING_TIMEOUT, to return to STATE_INACTIVE. - */ - void enterInactiveStateLocked() { - mInactiveTimeout = mConstants.INACTIVE_TIMEOUT; - becomeInactiveIfAppropriateLocked(); + void resetIdleManagementLocked() { + mNextIdlePendingDelay = 0; + mNextIdleDelay = 0; + cancelAlarmLocked(); + cancelSensingAlarmLocked(); + cancelLocatingLocked(); + stopMonitoringSignificantMotion(); + mAnyMotionDetector.stop(); } void exitForceIdleLocked() { @@ -1160,11 +1263,37 @@ public class DeviceIdleController extends SystemService case STATE_IDLE_PENDING: mState = STATE_SENSING; if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE_PENDING to STATE_SENSING."); + EventLogTags.writeDeviceIdle(mState, "step"); scheduleSensingAlarmLocked(mConstants.SENSING_TIMEOUT); + cancelSensingAlarmLocked(); + cancelLocatingLocked(); mAnyMotionDetector.checkForAnyMotion(); + mNotMoving = false; + mLocated = false; + mLastGenericLocation = null; + mLastGpsLocation = null; break; case STATE_SENSING: + mState = STATE_LOCATING; + if (DEBUG) Slog.d(TAG, "Moved from STATE_SENSING to STATE_LOCATING."); + EventLogTags.writeDeviceIdle(mState, "step"); + cancelSensingAlarmLocked(); + scheduleSensingAlarmLocked(mConstants.LOCATING_TIMEOUT); + mLocating = true; + mLocationManager.requestLocationUpdates(mLocationRequest, mGenericLocationListener, + mHandler.getLooper()); + if (mLocationManager.getProvider(LocationManager.GPS_PROVIDER) != null) { + mHaveGps = true; + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5, + mGpsLocationListener, mHandler.getLooper()); + } else { + mHaveGps = false; + } + break; + case STATE_LOCATING: cancelSensingAlarmLocked(); + cancelLocatingLocked(); + mAnyMotionDetector.stop(); case STATE_IDLE_MAINTENANCE: scheduleAlarmLocked(mNextIdleDelay, true); if (DEBUG) Slog.d(TAG, "Moved to STATE_IDLE. Next alarm in " + mNextIdleDelay + @@ -1173,6 +1302,7 @@ public class DeviceIdleController extends SystemService if (DEBUG) Slog.d(TAG, "Setting mNextIdleDelay = " + mNextIdleDelay); mNextIdleDelay = Math.min(mNextIdleDelay, mConstants.MAX_IDLE_TIMEOUT); mState = STATE_IDLE; + EventLogTags.writeDeviceIdle(mState, "step"); mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON); break; case STATE_IDLE: @@ -1193,18 +1323,54 @@ public class DeviceIdleController extends SystemService if (DEBUG) Slog.d(TAG, "significantMotionLocked()"); // When the sensor goes off, its trigger is automatically removed. mSigMotionActive = false; + 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. if (mState != STATE_ACTIVE) { - scheduleReportActiveLocked("motion", Process.myUid()); + scheduleReportActiveLocked(type, Process.myUid()); mState = STATE_ACTIVE; - mInactiveTimeout = mConstants.MOTION_INACTIVE_TIMEOUT; - EventLogTags.writeDeviceIdle(mState, "motion"); + mInactiveTimeout = timeout; + EventLogTags.writeDeviceIdle(mState, type); becomeInactiveIfAppropriateLocked(); } } + void receivedGenericLocationLocked(Location location) { + if (mState != STATE_LOCATING) { + cancelLocatingLocked(); + return; + } + if (DEBUG) Slog.d(TAG, "Generic location: " + location); + mLastGenericLocation = new Location(location); + if (location.getAccuracy() > mConstants.LOCATION_ACCURACY && mHaveGps) { + return; + } + mLocated = true; + if (mNotMoving) { + stepIdleStateLocked(); + } + } + + void receivedGpsLocationLocked(Location location) { + if (mState != STATE_LOCATING) { + cancelLocatingLocked(); + return; + } + if (DEBUG) Slog.d(TAG, "GPS location: " + location); + mLastGpsLocation = new Location(location); + if (location.getAccuracy() > mConstants.LOCATION_ACCURACY) { + return; + } + mLocated = true; + if (mNotMoving) { + stepIdleStateLocked(); + } + } + void startMonitoringSignificantMotion() { if (DEBUG) Slog.d(TAG, "startMonitoringSignificantMotion()"); if (mSigMotionSensor != null && !mSigMotionActive) { @@ -1229,8 +1395,19 @@ public class DeviceIdleController extends SystemService } void cancelSensingAlarmLocked() { - if (DEBUG) Slog.d(TAG, "cancelSensingAlarmLocked()"); - mAlarmManager.cancel(mSensingAlarmIntent); + if (mSensing) { + if (DEBUG) Slog.d(TAG, "cancelSensingAlarmLocked()"); + mAlarmManager.cancel(mSensingAlarmIntent); + mSensing = false; + } + } + + void cancelLocatingLocked() { + if (mLocating) { + mLocationManager.removeUpdates(mGenericLocationListener); + mLocationManager.removeUpdates(mGpsLocationListener); + mLocating = false; + } } void scheduleAlarmLocked(long delay, boolean idleUntil) { @@ -1253,10 +1430,12 @@ public class DeviceIdleController extends SystemService } void scheduleSensingAlarmLocked(long delay) { - if (DEBUG) Slog.d(TAG, "scheduleSensingAlarmLocked(" + delay + ")"); - mNextAlarmTime = SystemClock.elapsedRealtime() + delay; - mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, - mNextAlarmTime, mSensingAlarmIntent); + if (DEBUG) Slog.d(TAG, "scheduleSensingAlarmLocked(" + delay + ")"); + cancelSensingAlarmLocked(); + mNextAlarmTime = SystemClock.elapsedRealtime() + delay; + mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, + mNextAlarmTime, mSensingAlarmIntent); + mSensing = true; } private static int[] buildAppIdArray(ArrayMap<String, Integer> systemApps, @@ -1721,6 +1900,16 @@ public class DeviceIdleController extends SystemService pw.print(" mScreenOn="); pw.println(mScreenOn); pw.print(" mCharging="); pw.println(mCharging); pw.print(" mSigMotionActive="); pw.println(mSigMotionActive); + 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); + if (mLastGenericLocation != null) { + pw.print(" mLastGenericLocation="); pw.println(mLastGenericLocation); + } + if (mLastGpsLocation != null) { + pw.print(" mLastGpsLocation="); pw.println(mLastGpsLocation); + } pw.print(" mState="); pw.println(stateToString(mState)); pw.print(" mInactiveTimeout="); TimeUtils.formatDuration(mInactiveTimeout, pw); pw.println(); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 3d523d9..113c9b6 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -12850,6 +12850,7 @@ public final class ActivityManagerService extends ActivityManagerNative pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); pw.println(" o[om]: out of memory management"); + pw.println(" perm[issions]: URI permission grant state"); pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); pw.println(" provider [COMP_SPEC]: provider client-side state"); pw.println(" s[ervices] [COMP_SPEC ...]: service state"); @@ -12940,6 +12941,10 @@ public final class ActivityManagerService extends ActivityManagerNative synchronized (this) { dumpOomLocked(fd, pw, args, opti, true); } + } else if ("permissions".equals(cmd) || "perm".equals(cmd)) { + synchronized (this) { + dumpPermissionsLocked(fd, pw, args, opti, true, null); + } } else if ("provider".equals(cmd)) { String[] newArgs; String name; @@ -13055,6 +13060,11 @@ public final class ActivityManagerService extends ActivityManagerNative if (dumpAll) { pw.println("-------------------------------------------------------------------------------"); } + dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage); + pw.println(); + if (dumpAll) { + pw.println("-------------------------------------------------------------------------------"); + } mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); pw.println(); if (dumpAll) { @@ -14075,6 +14085,18 @@ public final class ActivityManagerService extends ActivityManagerNative } } + if (!printedAnything) { + pw.println(" (nothing)"); + } + } + + void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args, + int opti, boolean dumpAll, String dumpPackage) { + boolean needSep = false; + boolean printedAnything = false; + + pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)"); + if (mGrantedUriPermissions.size() > 0) { boolean printed = false; int dumpUid = -2; diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 7c79661..6d91309 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -1687,16 +1687,16 @@ public final class ActivityStackSupervisor implements DisplayListener { private int getComponentRestrictionForCallingPackage(ActivityInfo activityInfo, String callingPackage, int callingPid, int callingUid, boolean ignoreTargetSecurity) { - if (activityInfo.permission == null) { - return ACTIVITY_RESTRICTION_NONE; - } - if (!ignoreTargetSecurity && mService.checkComponentPermission(activityInfo.permission, callingPid, callingUid, activityInfo.applicationInfo.uid, activityInfo.exported) == PackageManager.PERMISSION_DENIED) { return ACTIVITY_RESTRICTION_PERMISSION; } + if (activityInfo.permission == null) { + return ACTIVITY_RESTRICTION_NONE; + } + final int opCode = AppOpsManager.permissionToOpCode(activityInfo.permission); if (opCode == AppOpsManager.OP_NONE) { return ACTIVITY_RESTRICTION_NONE; diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java index c13401f..b766894 100644 --- a/services/core/java/com/android/server/content/ContentService.java +++ b/services/core/java/com/android/server/content/ContentService.java @@ -157,7 +157,7 @@ public final class ContentService extends IContentService.Stub { mFactoryTest = factoryTest; // Let the package manager query for the sync adapters for a given authority - // as we grant default permissions to sync adapters for specifix authorities. + // as we grant default permissions to sync adapters for specific authorities. PackageManagerInternal packageManagerInternal = LocalServices.getService( PackageManagerInternal.class); packageManagerInternal.setSyncAdapterPackagesprovider( diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 9426b76..4351798 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -3615,22 +3615,28 @@ public class NotificationManagerService extends SystemService { public ArraySet<String> getGrantedPackages() { final ArraySet<String> pkgs = new ArraySet<>(); - final String setting = Settings.Secure.getStringForUser( - getContext().getContentResolver(), - Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES, - ActivityManager.getCurrentUser()); - if (setting != null) { - final String[] tokens = setting.split(SEPARATOR); - for (int i = 0; i < tokens.length; i++) { - String token = tokens[i]; - if (token != null) { - token.trim(); - } - if (TextUtils.isEmpty(token)) { - continue; + + long identity = Binder.clearCallingIdentity(); + try { + final String setting = Settings.Secure.getStringForUser( + getContext().getContentResolver(), + Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES, + ActivityManager.getCurrentUser()); + if (setting != null) { + final String[] tokens = setting.split(SEPARATOR); + for (int i = 0; i < tokens.length; i++) { + String token = tokens[i]; + if (token != null) { + token.trim(); + } + if (TextUtils.isEmpty(token)) { + continue; + } + pkgs.add(token); } - pkgs.add(token); } + } finally { + Binder.restoreCallingIdentity(identity); } return pkgs; } diff --git a/services/core/java/com/android/server/pm/BasePermission.java b/services/core/java/com/android/server/pm/BasePermission.java index 18407c9..52d0928 100644 --- a/services/core/java/com/android/server/pm/BasePermission.java +++ b/services/core/java/com/android/server/pm/BasePermission.java @@ -88,4 +88,10 @@ final class BasePermission { return (protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) == PermissionInfo.PROTECTION_DANGEROUS; } + + public boolean isDevelopment() { + return (protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) + == PermissionInfo.PROTECTION_SIGNATURE + && (protectionLevel & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0; + } } diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java index 71a2d59..96a5e00 100644 --- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java +++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java @@ -296,7 +296,7 @@ final class DefaultPermissionGrantPolicy { PackageParser.Package storagePackage = getDefaultProviderAuthorityPackageLPr( "com.android.externalstorage.documents", userId); if (storagePackage != null) { - grantRuntimePermissionsLPw(storagePackage, STORAGE_PERMISSIONS, userId); + grantRuntimePermissionsLPw(storagePackage, STORAGE_PERMISSIONS, true, userId); } // CertInstaller @@ -360,7 +360,15 @@ final class DefaultPermissionGrantPolicy { PackageParser.Package cbrPackage = getDefaultSystemHandlerActivityPackageLPr(cbrIntent, userId); if (cbrPackage != null && doesPackageSupportRuntimePermissions(cbrPackage)) { - grantRuntimePermissionsLPw(cbrPackage, SMS_PERMISSIONS, false, userId); + grantRuntimePermissionsLPw(cbrPackage, SMS_PERMISSIONS, userId); + } + + // Carrier Provisioning Service + Intent carrierProvIntent = new Intent(Intents.SMS_CARRIER_PROVISION_ACTION); + PackageParser.Package carrierProvPackage = + getDefaultSystemHandlerServicePackageLPr(carrierProvIntent, userId); + if (carrierProvPackage != null && doesPackageSupportRuntimePermissions(carrierProvPackage)) { + grantRuntimePermissionsLPw(carrierProvPackage, SMS_PERMISSIONS, false, userId); } // Calendar diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 21e256e..f67f3f3 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -56,6 +56,7 @@ import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATIO import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; +import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK; import static android.content.pm.PackageManager.MATCH_ALL; import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST; import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR; @@ -3432,14 +3433,14 @@ public class PackageManagerService extends IPackageManager.Stub { } } - private static void enforceDeclaredAsUsedAndRuntimePermission(PackageParser.Package pkg, + private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg, BasePermission bp) { int index = pkg.requestedPermissions.indexOf(bp.name); if (index == -1) { throw new SecurityException("Package " + pkg.packageName + " has not requested permission " + bp.name); } - if (!bp.isRuntime()) { + if (!bp.isRuntime() && !bp.isDevelopment()) { throw new SecurityException("Permission " + bp.name + " is not a changeable permission type"); } @@ -3473,7 +3474,7 @@ public class PackageManagerService extends IPackageManager.Stub { throw new IllegalArgumentException("Unknown permission: " + name); } - enforceDeclaredAsUsedAndRuntimePermission(pkg, bp); + enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); uid = UserHandle.getUid(userId, pkg.applicationInfo.uid); sb = (SettingBase) pkg.mExtras; @@ -3489,6 +3490,16 @@ public class PackageManagerService extends IPackageManager.Stub { + name + " for package: " + packageName); } + if (bp.isDevelopment()) { + // Development permissions must be handled specially, since they are not + // normal runtime permissions. For now they apply to all users. + if (permissionsState.grantInstallPermission(bp) != + PermissionsState.PERMISSION_OPERATION_FAILURE) { + scheduleWriteSettingsLocked(); + } + return; + } + final int result = permissionsState.grantRuntimePermission(bp, userId); switch (result) { case PermissionsState.PERMISSION_OPERATION_FAILURE: { @@ -3557,7 +3568,7 @@ public class PackageManagerService extends IPackageManager.Stub { throw new IllegalArgumentException("Unknown permission: " + name); } - enforceDeclaredAsUsedAndRuntimePermission(pkg, bp); + enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); SettingBase sb = (SettingBase) pkg.mExtras; if (sb == null) { @@ -3572,6 +3583,16 @@ public class PackageManagerService extends IPackageManager.Stub { + name + " for package: " + packageName); } + if (bp.isDevelopment()) { + // Development permissions must be handled specially, since they are not + // normal runtime permissions. For now they apply to all users. + if (permissionsState.revokeInstallPermission(bp) != + PermissionsState.PERMISSION_OPERATION_FAILURE) { + scheduleWriteSettingsLocked(); + } + return; + } + if (permissionsState.revokeRuntimePermission(bp, userId) == PermissionsState.PERMISSION_OPERATION_FAILURE) { return; @@ -3799,21 +3820,6 @@ public class PackageManagerService extends IPackageManager.Stub { return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0; } - void grantInstallPermissionLPw(String permission, PackageParser.Package pkg) { - BasePermission bp = mSettings.mPermissions.get(permission); - if (bp == null) { - throw new SecurityException("Missing " + permission + " permission"); - } - - SettingBase sb = (SettingBase) pkg.mExtras; - PermissionsState permissionsState = sb.getPermissionsState(); - - if (permissionsState.grantInstallPermission(bp) != - PermissionsState.PERMISSION_OPERATION_FAILURE) { - scheduleWriteSettingsLocked(); - } - } - @Override public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { mContext.enforceCallingOrSelfPermission( @@ -4701,6 +4707,7 @@ public class PackageManagerService extends IPackageManager.Stub { ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>(); ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>(); ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>(); + ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>(); ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>(); ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>(); @@ -4737,6 +4744,11 @@ public class PackageManagerService extends IPackageManager.Stub { Slog.i(TAG, " + never: " + info.activityInfo.packageName); } neverList.add(info); + } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, " + always-ask: " + info.activityInfo.packageName); + } + alwaysAskList.add(info); } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) { if (DEBUG_DOMAIN_VERIFICATION) { @@ -4746,6 +4758,10 @@ public class PackageManagerService extends IPackageManager.Stub { } } } + + // We'll want to include browser possibilities in a few cases + boolean includeBrowser = false; + // First try to add the "always" resolution(s) for the current user, if any if (alwaysList.size() > 0) { result.addAll(alwaysList); @@ -4754,7 +4770,7 @@ public class PackageManagerService extends IPackageManager.Stub { == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { result.add(xpDomainInfo.resolveInfo); } else { - // Add all undefined Apps as we want them to appear in the Disambiguation dialog. + // Add all undefined apps as we want them to appear in the disambiguation dialog. result.addAll(undefinedList); if (xpDomainInfo != null && ( xpDomainInfo.bestDomainVerificationStatus @@ -4763,7 +4779,25 @@ public class PackageManagerService extends IPackageManager.Stub { == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK)) { result.add(xpDomainInfo.resolveInfo); } - // Also add Browsers (all of them or only the default one) + includeBrowser = true; + } + + // The presence of any 'always ask' alternatives means we'll also offer browsers. + // If there were 'always' entries their preferred order has been set, so we also + // back that off to make the alternatives equivalent + if (alwaysAskList.size() > 0) { + for (ResolveInfo i : result) { + i.preferredOrder = 0; + } + result.addAll(alwaysAskList); + includeBrowser = true; + } + + if (includeBrowser) { + // Also add browsers (all of them or only the default one) + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.v(TAG, " ...including browsers in candidate set"); + } if ((matchFlags & MATCH_ALL) != 0) { result.addAll(matchAllList); } else { @@ -14764,6 +14798,7 @@ public class PackageManagerService extends IPackageManager.Stub { pw.println(" version: print database version info"); pw.println(" write: write current settings now"); pw.println(" installs: details about install sessions"); + pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?"); pw.println(" <package.name>: info about given package"); return; } else if ("--checkin".equals(opt)) { @@ -14785,6 +14820,31 @@ public class PackageManagerService extends IPackageManager.Stub { // When dumping a single package, we always dump all of its // filter information since the amount of data will be reasonable. dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); + } else if ("check-permission".equals(cmd)) { + if (opti >= args.length) { + pw.println("Error: check-permission missing permission argument"); + return; + } + String perm = args[opti]; + opti++; + if (opti >= args.length) { + pw.println("Error: check-permission missing package argument"); + return; + } + String pkg = args[opti]; + opti++; + int user = UserHandle.getUserId(Binder.getCallingUid()); + if (opti < args.length) { + try { + user = Integer.parseInt(args[opti]); + } catch (NumberFormatException e) { + pw.println("Error: check-permission user argument is not a number: " + + args[opti]); + return; + } + } + pw.println(checkPermission(perm, pkg, user)); + return; } else if ("l".equals(cmd) || "libraries".equals(cmd)) { dumpState.setDump(DumpState.DUMP_LIBS); } else if ("f".equals(cmd) || "features".equals(cmd)) { diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 00d0fe1..a762014 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -3949,7 +3949,7 @@ final class Settings { void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag, ArraySet<String> permissionNames, PackageSetting ps, SimpleDateFormat sdf, - Date date, List<UserInfo> users) { + Date date, List<UserInfo> users, boolean dumpAll) { if (checkinTag != null) { pw.print(checkinTag); pw.print(","); @@ -4151,7 +4151,7 @@ final class Settings { pw.print(", COSTS_MONEY"); } if ((perm.info.flags&PermissionInfo.FLAG_HIDDEN) != 0) { - pw.print(", COSTS_HIDDEN"); + pw.print(", HIDDEN"); } if ((perm.info.flags&PermissionInfo.FLAG_INSTALLED) != 0) { pw.print(", INSTALLED"); @@ -4160,7 +4160,21 @@ final class Settings { } } - if (ps.sharedUser == null || permissionNames != null) { + if ((permissionNames != null || dumpAll) && ps.pkg.requestedPermissions != null + && ps.pkg.requestedPermissions.size() > 0) { + final ArrayList<String> perms = ps.pkg.requestedPermissions; + pw.print(prefix); pw.println(" requested permissions:"); + for (int i=0; i<perms.size(); i++) { + String perm = perms.get(i); + if (permissionNames != null + && !permissionNames.contains(perm)) { + continue; + } + pw.print(prefix); pw.print(" "); pw.println(perm); + } + } + + if (ps.sharedUser == null || permissionNames != null || dumpAll) { PermissionsState permissionsState = ps.getPermissionsState(); dumpInstallPermissionsLPr(pw, prefix + " ", permissionNames, permissionsState); } @@ -4187,7 +4201,7 @@ final class Settings { PermissionsState permissionsState = ps.getPermissionsState(); dumpGidsLPr(pw, prefix + " ", permissionsState.computeGids(user.id)); dumpRuntimePermissionsLPr(pw, prefix + " ", permissionNames, permissionsState - .getRuntimePermissionStates(user.id)); + .getRuntimePermissionStates(user.id), dumpAll); } if (permissionNames == null) { @@ -4235,11 +4249,12 @@ final class Settings { pw.println("Packages:"); printedSomething = true; } - dumpPackageLPr(pw, " ", checkin ? "pkg" : null, permissionNames, ps, sdf, date, users); + dumpPackageLPr(pw, " ", checkin ? "pkg" : null, permissionNames, ps, sdf, date, users, + packageName != null); } printedSomething = false; - if (!checkin && mRenamedPackages.size() > 0 && permissionNames == null) { + if (mRenamedPackages.size() > 0 && permissionNames == null) { for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) { if (packageName != null && !packageName.equals(e.getKey()) && !packageName.equals(e.getValue())) { @@ -4276,7 +4291,7 @@ final class Settings { printedSomething = true; } dumpPackageLPr(pw, " ", checkin ? "dis" : null, permissionNames, ps, sdf, date, - users); + users, packageName != null); } } } @@ -4361,7 +4376,8 @@ final class Settings { if (!ArrayUtils.isEmpty(gids) || !permissions.isEmpty()) { pw.print(prefix); pw.print("User "); pw.print(userId); pw.println(": "); dumpGidsLPr(pw, prefix + " ", gids); - dumpRuntimePermissionsLPr(pw, prefix + " ", permissionNames, permissions); + dumpRuntimePermissionsLPr(pw, prefix + " ", permissionNames, permissions, + packageName != null); } } } else { @@ -4407,8 +4423,8 @@ final class Settings { } void dumpRuntimePermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames, - List<PermissionState> permissionStates) { - if (!permissionStates.isEmpty()) { + List<PermissionState> permissionStates, boolean dumpAll) { + if (!permissionStates.isEmpty() || dumpAll) { pw.print(prefix); pw.println("runtime permissions:"); for (PermissionState permissionState : permissionStates) { if (permissionNames != null diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index 174bf16..15da829 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -579,14 +579,8 @@ public class TrustManagerService extends SystemService { private void clearUserHasAuthenticated(int userId) { if (userId == UserHandle.USER_ALL) { mUserHasAuthenticated.clear(); - synchronized (mUserHasAuthenticatedSinceBoot) { - mUserHasAuthenticatedSinceBoot.clear(); - } } else { mUserHasAuthenticated.put(userId, false); - synchronized (mUserHasAuthenticatedSinceBoot) { - mUserHasAuthenticatedSinceBoot.put(userId, false); - } } } diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 3ac6bba..ab56d5e 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -40,7 +40,6 @@ import android.graphics.RectF; import android.graphics.Region; import android.os.Debug; import android.os.RemoteException; -import android.os.UserHandle; import android.util.Slog; import android.view.Display; import android.view.DisplayInfo; @@ -837,6 +836,8 @@ class WindowStateAnimator { mSurfaceX = 0; mSurfaceY = 0; w.mLastSystemDecorRect.set(0, 0, 0, 0); + mHasClipRect = false; + mClipRect.set(0, 0, 0, 0); mLastClipRect.set(0, 0, 0, 0); // Set up surface control with initial size. diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index 85f0665..4146c1c 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -848,6 +848,9 @@ public class UsageStatsService extends SystemService implements try { ParceledListSlice<ApplicationInfo> slice = AppGlobals.getPackageManager().getInstalledApplications(0, userId); + if (slice == null) { + return new int[0]; + } apps = slice.getList(); } catch (RemoteException e) { return new int[0]; |