summaryrefslogtreecommitdiffstats
path: root/services/core
diff options
context:
space:
mode:
Diffstat (limited to 'services/core')
-rw-r--r--services/core/java/com/android/server/MountService.java1
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java89
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java20
-rw-r--r--services/core/java/com/android/server/pm/BackgroundDexOptService.java9
-rw-r--r--services/core/java/com/android/server/pm/KeySetManagerService.java5
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java102
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java28
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) {