diff options
Diffstat (limited to 'services/core')
7 files changed, 161 insertions, 93 deletions
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java index aa7d1f8..f69626d 100644 --- a/services/core/java/com/android/server/MountService.java +++ b/services/core/java/com/android/server/MountService.java @@ -993,6 +993,7 @@ class MountService extends IMountService.Stub private void onDiskScannedLocked(DiskInfo disk) { final Intent intent = new Intent(DiskInfo.ACTION_DISK_SCANNED); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); + intent.putExtra(DiskInfo.EXTRA_DISK_ID, disk.id); mContext.sendBroadcastAsUser(intent, UserHandle.ALL, android.Manifest.permission.WRITE_MEDIA_STORAGE); diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index cd467bd..d39b25f 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -2852,6 +2852,49 @@ public class AudioService extends IAudioService.Stub { } } + void setBtScoDeviceConnectionState(BluetoothDevice btDevice, int state) { + if (btDevice == null) { + return; + } + + String address = btDevice.getAddress(); + BluetoothClass btClass = btDevice.getBluetoothClass(); + int outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO; + int inDevice = AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET; + if (btClass != null) { + switch (btClass.getDeviceClass()) { + case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET: + case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE: + outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET; + break; + case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO: + outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT; + break; + } + } + + if (!BluetoothAdapter.checkBluetoothAddress(address)) { + address = ""; + } + + boolean connected = (state == BluetoothProfile.STATE_CONNECTED); + + String btDeviceName = btDevice.getName(); + boolean success = + handleDeviceConnection(connected, outDevice, address, btDeviceName) && + handleDeviceConnection(connected, inDevice, address, btDeviceName); + if (success) { + synchronized (mScoClients) { + if (connected) { + mBluetoothHeadsetDevice = btDevice; + } else { + mBluetoothHeadsetDevice = null; + resetBluetoothSco(); + } + } + } + } + private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener = new BluetoothProfile.ServiceListener() { public void onServiceConnected(int profile, BluetoothProfile proxy) { @@ -3002,6 +3045,10 @@ public class AudioService extends IAudioService.Stub { case BluetoothProfile.HEADSET: synchronized (mScoClients) { + if (mBluetoothHeadsetDevice != null) { + setBtScoDeviceConnectionState(mBluetoothHeadsetDevice, + BluetoothProfile.STATE_DISCONNECTED); + } mBluetoothHeadset = null; } break; @@ -4894,49 +4941,9 @@ public class AudioService extends IAudioService.Stub { } else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) { state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED); - outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO; - inDevice = AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET; - String address = null; - BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - if (btDevice == null) { - return; - } - address = btDevice.getAddress(); - BluetoothClass btClass = btDevice.getBluetoothClass(); - if (btClass != null) { - switch (btClass.getDeviceClass()) { - case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET: - case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE: - outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET; - break; - case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO: - outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT; - break; - } - } - - if (!BluetoothAdapter.checkBluetoothAddress(address)) { - address = ""; - } - - boolean connected = (state == BluetoothProfile.STATE_CONNECTED); - - String btDeviceName = btDevice.getName(); - boolean success = - handleDeviceConnection(connected, outDevice, address, btDeviceName) && - handleDeviceConnection(connected, inDevice, address, btDeviceName); - if (success) { - synchronized (mScoClients) { - if (connected) { - mBluetoothHeadsetDevice = btDevice; - } else { - mBluetoothHeadsetDevice = null; - resetBluetoothSco(); - } - } - } + setBtScoDeviceConnectionState(btDevice, state); } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) { boolean broadcast = false; int scoAudioState = AudioManager.SCO_AUDIO_STATE_ERROR; diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 7673af4..81ef4d5 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -376,8 +376,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub void updatePowerSaveTempWhitelistLocked() { try { + // Clear the states of the current whitelist + final int N = mPowerSaveTempWhitelistAppIds.size(); + for (int i = 0; i < N; i++) { + mPowerSaveTempWhitelistAppIds.setValueAt(i, false); + } + // Update the states with the new whitelist final int[] whitelist = mDeviceIdleController.getAppIdTempWhitelist(); - mPowerSaveTempWhitelistAppIds.clear(); if (whitelist != null) { for (int uid : whitelist) { mPowerSaveTempWhitelistAppIds.put(uid, true); @@ -387,6 +392,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub } } + /** + * Remove unnecessary entries in the temp whitelist + */ + void purgePowerSaveTempWhitelistLocked() { + final int N = mPowerSaveTempWhitelistAppIds.size(); + for (int i = N - 1; i >= 0; i--) { + if (mPowerSaveTempWhitelistAppIds.valueAt(i) == false) { + mPowerSaveTempWhitelistAppIds.removeAt(i); + } + } + } + public void systemReady() { if (!isBandwidthControlEnabled()) { Slog.w(TAG, "bandwidth controls disabled, unable to enforce policy"); @@ -521,6 +538,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub } else { updatePowerSaveTempWhitelistLocked(); updateRulesForTempWhitelistChangeLocked(); + purgePowerSaveTempWhitelistLocked(); } } } diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java index 7e66cd1..7b1ac5c 100644 --- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java +++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java @@ -16,6 +16,7 @@ package com.android.server.pm; +import android.app.AlarmManager; import android.app.job.JobInfo; import android.app.job.JobParameters; import android.app.job.JobScheduler; @@ -34,6 +35,8 @@ import java.util.concurrent.atomic.AtomicBoolean; public class BackgroundDexOptService extends JobService { static final String TAG = "BackgroundDexOptService"; + static final long RETRY_LATENCY = 4 * AlarmManager.INTERVAL_HOUR; + static final int BACKGROUND_DEXOPT_JOB = 800; private static ComponentName sDexoptServiceName = new ComponentName( "android", @@ -46,11 +49,12 @@ public class BackgroundDexOptService extends JobService { final AtomicBoolean mIdleTime = new AtomicBoolean(false); - public static void schedule(Context context) { + public static void schedule(Context context, long minLatency) { JobScheduler js = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); JobInfo job = new JobInfo.Builder(BACKGROUND_DEXOPT_JOB, sDexoptServiceName) .setRequiresDeviceIdle(true) .setRequiresCharging(true) + .setMinimumLatency(minLatency) .build(); js.schedule(job); } @@ -62,6 +66,7 @@ public class BackgroundDexOptService extends JobService { (PackageManagerService)ServiceManager.getService("package"); if (pm.isStorageLow()) { + schedule(BackgroundDexOptService.this, RETRY_LATENCY); return false; } final ArraySet<String> pkgs = pm.getPackagesThatNeedDexOpt(); @@ -77,7 +82,7 @@ public class BackgroundDexOptService extends JobService { for (String pkg : pkgs) { if (!mIdleTime.get()) { // stopped while still working, so we need to reschedule - schedule(BackgroundDexOptService.this); + schedule(BackgroundDexOptService.this, 0); return; } if (sFailedPackageNames.contains(pkg)) { diff --git a/services/core/java/com/android/server/pm/KeySetManagerService.java b/services/core/java/com/android/server/pm/KeySetManagerService.java index 7531403..1ee07a5 100644 --- a/services/core/java/com/android/server/pm/KeySetManagerService.java +++ b/services/core/java/com/android/server/pm/KeySetManagerService.java @@ -277,6 +277,11 @@ public class KeySetManagerService { return mKeySets.get(keySetId); } + /* Checks if an identifier refers to a known keyset */ + public boolean isIdValidKeySetId(long id) { + return mKeySets.get(id) != null; + } + /** * Fetches the {@link PublicKey public keys} which belong to the specified * KeySet id. diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 6c9fd3f..99b24ed 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -6157,7 +6157,24 @@ public class PackageManagerService extends IPackageManager.Stub { pkg.applicationInfo.uid = pkgSetting.appId; pkg.mExtras = pkgSetting; - if (!pkgSetting.keySetData.isUsingUpgradeKeySets() || pkgSetting.sharedUser != null) { + if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) { + if (checkUpgradeKeySetLP(pkgSetting, pkg)) { + // We just determined the app is signed correctly, so bring + // over the latest parsed certs. + pkgSetting.signatures.mSignatures = pkg.mSignatures; + } else { + if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { + throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, + "Package " + pkg.packageName + " upgrade keys do not match the " + + "previously installed version"); + } else { + pkgSetting.signatures.mSignatures = pkg.mSignatures; + String msg = "System package " + pkg.packageName + + " signature changed; retaining data."; + reportSettingsProblem(Log.WARN, msg); + } + } + } else { try { verifySignaturesLP(pkgSetting, pkg); // We just determined the app is signed correctly, so bring @@ -6189,23 +6206,6 @@ public class PackageManagerService extends IPackageManager.Stub { + " signature changed; retaining data."; reportSettingsProblem(Log.WARN, msg); } - } else { - if (!checkUpgradeKeySetLP(pkgSetting, pkg)) { - if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { - throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, - "Package " + pkg.packageName + " upgrade keys do not match the " - + "previously installed version"); - } else { - pkgSetting.signatures.mSignatures = pkg.mSignatures; - String msg = "System package " + pkg.packageName - + " signature changed; retaining data."; - reportSettingsProblem(Log.WARN, msg); - } - } else { - // We just determined the app is signed correctly, so bring - // over the latest parsed certs. - pkgSetting.signatures.mSignatures = pkg.mSignatures; - } } // Verify that this new package doesn't have any content providers // that conflict with existing packages. Only do this if the @@ -11161,6 +11161,28 @@ public class PackageManagerService extends IPackageManager.Stub { } } + private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) { + // Can't rotate keys during boot or if sharedUser. + if (oldPs == null || (scanFlags&SCAN_BOOTING) != 0 || oldPs.sharedUser != null + || !oldPs.keySetData.isUsingUpgradeKeySets()) { + return false; + } + // app is using upgradeKeySets; make sure all are valid + KeySetManagerService ksms = mSettings.mKeySetManagerService; + long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets(); + for (int i = 0; i < upgradeKeySets.length; i++) { + if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) { + Slog.wtf(TAG, "Package " + + (oldPs.name != null ? oldPs.name : "<null>") + + " contains upgrade-key-set reference to unknown key-set: " + + upgradeKeySets[i] + + " reverting to signatures check."); + return false; + } + } + return true; + } + private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) { // Upgrade keysets are being used. Determine if new package has a superset of the // required keys. @@ -11189,19 +11211,19 @@ public class PackageManagerService extends IPackageManager.Stub { oldPackage = mPackages.get(pkgName); if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); final PackageSetting ps = mSettings.mPackages.get(pkgName); - if (ps == null || !ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) { - // default to original signature matching - if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) - != PackageManager.SIGNATURE_MATCH) { + if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { + if(!checkUpgradeKeySetLP(ps, pkg)) { res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, - "New package has a different signature: " + pkgName); + "New package not signed by keys specified by upgrade-keysets: " + + pkgName); return; } } else { - if(!checkUpgradeKeySetLP(ps, pkg)) { + // default to original signature matching + if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) + != PackageManager.SIGNATURE_MATCH) { res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, - "New package not signed by keys specified by upgrade-keysets: " - + pkgName); + "New package has a different signature: " + pkgName); return; } } @@ -11633,20 +11655,20 @@ public class PackageManagerService extends IPackageManager.Stub { // Quick sanity check that we're signed correctly if updating; // we'll check this again later when scanning, but we want to // bail early here before tripping over redefined permissions. - if (!ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) { - try { - verifySignaturesLP(ps, pkg); - } catch (PackageManagerException e) { - res.setError(e.error, e.getMessage()); - return; - } - } else { + if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { if (!checkUpgradeKeySetLP(ps, pkg)) { res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " + pkg.packageName + " upgrade keys do not match the " + "previously installed version"); return; } + } else { + try { + verifySignaturesLP(ps, pkg); + } catch (PackageManagerException e) { + res.setError(e.error, e.getMessage()); + return; + } } oldCodePath = mSettings.mPackages.get(pkgName).codePathString; @@ -11667,14 +11689,14 @@ public class PackageManagerService extends IPackageManager.Stub { // also includes the "updating the same package" case, of course. // "updating same package" could also involve key-rotation. final boolean sigsOk; - if (!bp.sourcePackage.equals(pkg.packageName) - || !(bp.packageSetting instanceof PackageSetting) - || !bp.packageSetting.keySetData.isUsingUpgradeKeySets() - || ((PackageSetting) bp.packageSetting).sharedUser != null) { + if (bp.sourcePackage.equals(pkg.packageName) + && (bp.packageSetting instanceof PackageSetting) + && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting, + scanFlags))) { + sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg); + } else { sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures, pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; - } else { - sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg); } if (!sigsOk) { // If the owning package is the system itself, we log but allow diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 25ca167..dbcfa19 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -243,7 +243,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } /** Amount of time (in milliseconds) to wait for windows drawn before powering on. */ - static final int WAITING_FOR_DRAWN_TIMEOUT = 1000; + static final int WAITING_FOR_DRAWN_TIMEOUT = 500; /** * Lock protecting internal state. Must not call out into window @@ -836,13 +836,18 @@ public class PhoneWindowManager implements WindowManagerPolicy { // If sensor is turned off or nonexistent for some reason return; } - //Could have been invoked due to screen turning on or off or - //change of the currently visible window's orientation + // Could have been invoked due to screen turning on or off or + // change of the currently visible window's orientation. if (localLOGV) Slog.v(TAG, "mScreenOnEarly=" + mScreenOnEarly + ", mAwake=" + mAwake + ", mCurrentAppOrientation=" + mCurrentAppOrientation - + ", mOrientationSensorEnabled=" + mOrientationSensorEnabled); + + ", mOrientationSensorEnabled=" + mOrientationSensorEnabled + + ", mKeyguardDrawComplete=" + mKeyguardDrawComplete + + ", mWindowManagerDrawComplete=" + mWindowManagerDrawComplete); boolean disable = true; - if (mScreenOnEarly && mAwake) { + // Note: We postpone the rotating of the screen until the keyguard as well as the + // window manager have reported a draw complete. + if (mScreenOnEarly && mAwake && + mKeyguardDrawComplete && mWindowManagerDrawComplete) { if (needSensorRunningLp()) { disable = false; //enable listener if not already enabled @@ -5369,7 +5374,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { private void finishKeyguardDrawn() { synchronized (mLock) { if (!mAwake || mKeyguardDrawComplete) { - return; // spurious + return; // We are not awake yet or we have already informed of this event. } mKeyguardDrawComplete = true; @@ -5407,18 +5412,18 @@ public class PhoneWindowManager implements WindowManagerPolicy { mScreenOnFully = false; mWindowManagerDrawComplete = false; mScreenOnListener = screenOnListener; - updateOrientationListenerLp(); } mWindowManagerInternal.waitForAllWindowsDrawn(mWindowManagerDrawCallback, WAITING_FOR_DRAWN_TIMEOUT); - // ... eventually calls finishWindowsDrawn + // ... eventually calls finishWindowsDrawn which will finalize our screen turn on + // as well as enabling the orientation change logic/sensor. } private void finishWindowsDrawn() { synchronized (mLock) { if (!mScreenOnEarly || mWindowManagerDrawComplete) { - return; // spurious + return; // Screen is not turned on or we did already handle this case earlier. } mWindowManagerDrawComplete = true; @@ -5428,6 +5433,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { } private void finishScreenTurningOn() { + synchronized (mLock) { + // We have just finished drawing screen content. Since the orientation listener + // gets only installed when all windows are drawn, we try to install it again. + updateOrientationListenerLp(); + } final ScreenOnListener listener; final boolean enableScreen; synchronized (mLock) { |