summaryrefslogtreecommitdiffstats
path: root/services/core/java/com
diff options
context:
space:
mode:
Diffstat (limited to 'services/core/java/com')
-rw-r--r--services/core/java/com/android/server/BluetoothManagerService.java114
-rw-r--r--services/core/java/com/android/server/CountryDetectorService.java122
-rw-r--r--services/core/java/com/android/server/NetworkManagementService.java2
-rw-r--r--services/core/java/com/android/server/SystemServiceManager.java41
-rw-r--r--services/core/java/com/android/server/TelephonyRegistry.java30
-rw-r--r--services/core/java/com/android/server/UiModeManagerService.java128
-rw-r--r--services/core/java/com/android/server/accounts/AccountManagerService.java3
-rw-r--r--services/core/java/com/android/server/adb/AdbDebuggingManager.java5
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java7
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java45
-rw-r--r--services/core/java/com/android/server/am/CarUserSwitchingDialog.java19
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java4
-rw-r--r--services/core/java/com/android/server/am/UserController.java18
-rw-r--r--services/core/java/com/android/server/appop/AppOpsService.java352
-rw-r--r--services/core/java/com/android/server/appop/TEST_MAPPING8
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java62
-rw-r--r--services/core/java/com/android/server/audio/FocusRequester.java11
-rw-r--r--services/core/java/com/android/server/audio/PlaybackActivityMonitor.java82
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal2/Convert.java16
-rw-r--r--services/core/java/com/android/server/input/InputManagerService.java42
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java69
-rw-r--r--services/core/java/com/android/server/pm/Installer.java10
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java9
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java117
-rw-r--r--services/core/java/com/android/server/pm/StagingManager.java25
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java25
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java9
-rw-r--r--services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java3
-rw-r--r--services/core/java/com/android/server/trust/TrustManagerService.java4
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperManagerService.java8
-rw-r--r--services/core/java/com/android/server/wm/BarController.java3
-rw-r--r--services/core/java/com/android/server/wm/PolicyControl.java10
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java6
33 files changed, 1024 insertions, 385 deletions
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 9931651081d..9bcded3e1e1 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -74,11 +74,14 @@ import com.android.server.pm.UserRestrictionsUtils;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Map;
import java.util.NoSuchElementException;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -261,6 +264,47 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
};
+ public boolean onFactoryReset() {
+ // Wait for stable state if bluetooth is temporary state.
+ int state = getState();
+ if (state == BluetoothAdapter.STATE_BLE_TURNING_ON
+ || state == BluetoothAdapter.STATE_TURNING_ON
+ || state == BluetoothAdapter.STATE_TURNING_OFF) {
+ if (!waitForState(new HashSet<Integer>(Arrays.asList(BluetoothAdapter.STATE_BLE_ON,
+ BluetoothAdapter.STATE_ON)))) {
+ return false;
+ }
+ }
+
+ // Clear registered LE apps to force shut-off Bluetooth
+ clearBleApps();
+ state = getState();
+ try {
+ mBluetoothLock.readLock().lock();
+ if (mBluetooth == null) {
+ return false;
+ }
+ if (state == BluetoothAdapter.STATE_BLE_ON) {
+ addActiveLog(
+ BluetoothProtoEnums.ENABLE_DISABLE_REASON_FACTORY_RESET,
+ mContext.getPackageName(), false);
+ mBluetooth.onBrEdrDown();
+ return true;
+ } else if (state == BluetoothAdapter.STATE_ON) {
+ addActiveLog(
+ BluetoothProtoEnums.ENABLE_DISABLE_REASON_FACTORY_RESET,
+ mContext.getPackageName(), false);
+ mBluetooth.disable();
+ return true;
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Unable to shutdown Bluetooth", e);
+ } finally {
+ mBluetoothLock.readLock().unlock();
+ }
+ return false;
+ }
+
public void onAirplaneModeChanged() {
synchronized (this) {
if (isBluetoothPersistedStateOn()) {
@@ -1644,7 +1688,9 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
// the previous Bluetooth process has exited. The
// waiting period has three components:
// (a) Wait until the local state is STATE_OFF. This
- // is accomplished by "waitForOnOff(false, true)".
+ // is accomplished by
+ // "waitForState(new HashSet<Integer>(
+ // Arrays.asList(BluetoothAdapter.STATE_OFF)))".
// (b) Wait until the STATE_OFF state is updated to
// all components.
// (c) Wait until the Bluetooth process exits, and
@@ -1654,7 +1700,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
// message. The delay time is backed off if Bluetooth
// continuously failed to turn on itself.
//
- waitForOnOff(false, true);
+ waitForState(new HashSet<Integer>(Arrays.asList(
+ BluetoothAdapter.STATE_OFF)));
Message restartMsg =
mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs());
@@ -1667,10 +1714,16 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
if (mEnable && mBluetooth != null) {
- waitForOnOff(true, false);
+ waitForState(new HashSet<Integer>(Arrays.asList(
+ BluetoothAdapter.STATE_ON)));
mEnable = false;
handleDisable();
- waitForOnOff(false, false);
+ waitForState(new HashSet<Integer>(Arrays.asList(BluetoothAdapter.STATE_OFF,
+ BluetoothAdapter.STATE_TURNING_ON,
+ BluetoothAdapter.STATE_TURNING_OFF,
+ BluetoothAdapter.STATE_BLE_TURNING_ON,
+ BluetoothAdapter.STATE_BLE_ON,
+ BluetoothAdapter.STATE_BLE_TURNING_OFF)));
} else {
mEnable = false;
handleDisable();
@@ -1799,9 +1852,15 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
if (!mEnable) {
- waitForOnOff(true, false);
+ waitForState(new HashSet<Integer>(Arrays.asList(
+ BluetoothAdapter.STATE_ON)));
handleDisable();
- waitForOnOff(false, false);
+ waitForState(new HashSet<Integer>(Arrays.asList(BluetoothAdapter.STATE_OFF,
+ BluetoothAdapter.STATE_TURNING_ON,
+ BluetoothAdapter.STATE_TURNING_OFF,
+ BluetoothAdapter.STATE_BLE_TURNING_ON,
+ BluetoothAdapter.STATE_BLE_ON,
+ BluetoothAdapter.STATE_BLE_TURNING_OFF)));
}
break;
}
@@ -1833,7 +1892,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
== BluetoothAdapter.STATE_OFF)) {
if (mEnable) {
Slog.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting.");
- waitForOnOff(false, true);
+ waitForState(new HashSet<Integer>(Arrays.asList(
+ BluetoothAdapter.STATE_OFF)));
Message restartMsg =
mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs());
@@ -1962,7 +2022,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
mState = BluetoothAdapter.STATE_TURNING_ON;
}
- waitForOnOff(true, false);
+ waitForState(new HashSet<Integer>(Arrays.asList(
+ BluetoothAdapter.STATE_ON)));
if (mState == BluetoothAdapter.STATE_TURNING_ON) {
bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_ON);
@@ -1977,7 +2038,9 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
BluetoothAdapter.STATE_TURNING_OFF);
- boolean didDisableTimeout = !waitForOnOff(false, true);
+ boolean didDisableTimeout =
+ !waitForState(new HashSet<Integer>(Arrays.asList(
+ BluetoothAdapter.STATE_OFF)));
bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
BluetoothAdapter.STATE_OFF);
@@ -2229,12 +2292,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
}
- /**
- * if on is true, wait for state become ON
- * if off is true, wait for state become OFF
- * if both on and off are false, wait for state not ON
- */
- private boolean waitForOnOff(boolean on, boolean off) {
+ private boolean waitForState(Set<Integer> states) {
int i = 0;
while (i < 10) {
try {
@@ -2242,18 +2300,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
if (mBluetooth == null) {
break;
}
- if (on) {
- if (mBluetooth.getState() == BluetoothAdapter.STATE_ON) {
- return true;
- }
- } else if (off) {
- if (mBluetooth.getState() == BluetoothAdapter.STATE_OFF) {
- return true;
- }
- } else {
- if (mBluetooth.getState() != BluetoothAdapter.STATE_ON) {
- return true;
- }
+ if (states.contains(mBluetooth.getState())) {
+ return true;
}
} catch (RemoteException e) {
Slog.e(TAG, "getState()", e);
@@ -2261,14 +2309,10 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
} finally {
mBluetoothLock.readLock().unlock();
}
- if (on || off) {
- SystemClock.sleep(300);
- } else {
- SystemClock.sleep(50);
- }
+ SystemClock.sleep(300);
i++;
}
- Slog.e(TAG, "waitForOnOff time out");
+ Slog.e(TAG, "waitForState " + states + " time out");
return false;
}
@@ -2329,7 +2373,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
mContext.getPackageName(), false);
handleDisable();
- waitForOnOff(false, true);
+ waitForState(new HashSet<Integer>(Arrays.asList(BluetoothAdapter.STATE_OFF)));
sendBluetoothServiceDownCallback();
@@ -2491,6 +2535,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
return "USER_SWITCH";
case BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING:
return "RESTORE_USER_SETTING";
+ case BluetoothProtoEnums.ENABLE_DISABLE_REASON_FACTORY_RESET:
+ return "FACTORY_RESET";
case BluetoothProtoEnums.ENABLE_DISABLE_REASON_UNSPECIFIED:
default: return "UNKNOWN[" + reason + "]";
}
diff --git a/services/core/java/com/android/server/CountryDetectorService.java b/services/core/java/com/android/server/CountryDetectorService.java
index d8a2fe35c7e..b0132d35fa3 100644
--- a/services/core/java/com/android/server/CountryDetectorService.java
+++ b/services/core/java/com/android/server/CountryDetectorService.java
@@ -16,14 +16,6 @@
package com.android.server;
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.HashMap;
-
-import com.android.internal.os.BackgroundThread;
-import com.android.internal.util.DumpUtils;
-import com.android.server.location.ComprehensiveCountryDetector;
-
import android.content.Context;
import android.location.Country;
import android.location.CountryListener;
@@ -32,21 +24,37 @@ import android.location.ICountryListener;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
+import android.text.TextUtils;
import android.util.PrintWriterPrinter;
import android.util.Printer;
import android.util.Slog;
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.DumpUtils;
+import com.android.server.location.ComprehensiveCountryDetector;
+import com.android.server.location.CountryDetectorBase;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+
/**
- * This class detects the country that the user is in through
- * {@link ComprehensiveCountryDetector}.
+ * This class detects the country that the user is in. The default country detection is made through
+ * {@link com.android.server.location.ComprehensiveCountryDetector}. It is possible to overlay the
+ * detection algorithm by overlaying the attribute R.string.config_customCountryDetector with the
+ * custom class name to use instead. The custom class must extend
+ * {@link com.android.server.location.CountryDetectorBase}
*
* @hide
*/
-public class CountryDetectorService extends ICountryDetector.Stub implements Runnable {
+public class CountryDetectorService extends ICountryDetector.Stub {
/**
- * The class represents the remote listener, it will also removes itself
- * from listener list when the remote process was died.
+ * The class represents the remote listener, it will also removes itself from listener list when
+ * the remote process was died.
*/
private final class Receiver implements IBinder.DeathRecipient {
private final ICountryListener mListener;
@@ -79,28 +87,36 @@ public class CountryDetectorService extends ICountryDetector.Stub implements Run
}
}
- private final static String TAG = "CountryDetector";
+ private static final String TAG = "CountryDetector";
- /** Whether to dump the state of the country detector service to bugreports */
+ /**
+ * Whether to dump the state of the country detector service to bugreports
+ */
private static final boolean DEBUG = false;
private final HashMap<IBinder, Receiver> mReceivers;
private final Context mContext;
- private ComprehensiveCountryDetector mCountryDetector;
+ private CountryDetectorBase mCountryDetector;
private boolean mSystemReady;
private Handler mHandler;
private CountryListener mLocationBasedDetectorListener;
public CountryDetectorService(Context context) {
+ this(context, BackgroundThread.getHandler());
+ }
+
+ @VisibleForTesting
+ CountryDetectorService(Context context, Handler handler) {
super();
- mReceivers = new HashMap<IBinder, Receiver>();
+ mReceivers = new HashMap<>();
mContext = context;
+ mHandler = handler;
}
@Override
public Country detectCountry() {
if (!mSystemReady) {
- return null; // server not yet active
+ return null; // server not yet active
} else {
return mCountryDetector.detectCountry();
}
@@ -154,9 +170,8 @@ public class CountryDetectorService extends ICountryDetector.Stub implements Run
}
}
-
protected void notifyReceivers(Country country) {
- synchronized(mReceivers) {
+ synchronized (mReceivers) {
for (Receiver receiver : mReceivers.values()) {
try {
receiver.getListener().onCountryDetected(country);
@@ -170,42 +185,58 @@ public class CountryDetectorService extends ICountryDetector.Stub implements Run
void systemRunning() {
// Shall we wait for the initialization finish.
- BackgroundThread.getHandler().post(this);
- }
-
- private void initialize() {
- mCountryDetector = new ComprehensiveCountryDetector(mContext);
- mLocationBasedDetectorListener = new CountryListener() {
- public void onCountryDetected(final Country country) {
- mHandler.post(new Runnable() {
- public void run() {
- notifyReceivers(country);
- }
+ mHandler.post(
+ () -> {
+ initialize();
+ mSystemReady = true;
});
- }
- };
}
- public void run() {
- mHandler = new Handler();
- initialize();
- mSystemReady = true;
+ @VisibleForTesting
+ void initialize() {
+ final String customCountryClass = mContext.getString(R.string.config_customCountryDetector);
+ if (!TextUtils.isEmpty(customCountryClass)) {
+ mCountryDetector = loadCustomCountryDetectorIfAvailable(customCountryClass);
+ }
+
+ if (mCountryDetector == null) {
+ Slog.d(TAG, "Using default country detector");
+ mCountryDetector = new ComprehensiveCountryDetector(mContext);
+ }
+ mLocationBasedDetectorListener = country -> mHandler.post(() -> notifyReceivers(country));
}
protected void setCountryListener(final CountryListener listener) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mCountryDetector.setCountryListener(listener);
- }
- });
+ mHandler.post(() -> mCountryDetector.setCountryListener(listener));
+ }
+
+ @VisibleForTesting
+ CountryDetectorBase getCountryDetector() {
+ return mCountryDetector;
}
- // For testing
+ @VisibleForTesting
boolean isSystemReady() {
return mSystemReady;
}
+ private CountryDetectorBase loadCustomCountryDetectorIfAvailable(
+ final String customCountryClass) {
+ CountryDetectorBase customCountryDetector = null;
+
+ Slog.d(TAG, "Using custom country detector class: " + customCountryClass);
+ try {
+ customCountryDetector = Class.forName(customCountryClass).asSubclass(
+ CountryDetectorBase.class).getConstructor(Context.class).newInstance(
+ mContext);
+ } catch (ClassNotFoundException | InstantiationException | IllegalAccessException
+ | NoSuchMethodException | InvocationTargetException e) {
+ Slog.e(TAG, "Could not instantiate the custom country detector class");
+ }
+
+ return customCountryDetector;
+ }
+
@SuppressWarnings("unused")
@Override
protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
@@ -214,9 +245,10 @@ public class CountryDetectorService extends ICountryDetector.Stub implements Run
try {
final Printer p = new PrintWriterPrinter(fout);
p.println("CountryDetectorService state:");
+ p.println("Country detector class=" + mCountryDetector.getClass().getName());
p.println(" Number of listeners=" + mReceivers.keySet().size());
if (mCountryDetector == null) {
- p.println(" ComprehensiveCountryDetector not initialized");
+ p.println(" CountryDetector not initialized");
} else {
p.println(" " + mCountryDetector.toString());
}
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 3dee9f06eaf..417992cc888 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -59,6 +59,7 @@ import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkPolicyManager;
import android.net.NetworkRequest;
+import android.net.NetworkStack;
import android.net.NetworkStats;
import android.net.NetworkUtils;
import android.net.RouteInfo;
@@ -986,6 +987,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
@Override
public void setIPv6AddrGenMode(String iface, int mode) throws ServiceSpecificException {
+ NetworkStack.checkNetworkStackPermission(mContext);
try {
mNetdService.setIPv6AddrGenMode(iface, mode);
} catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/SystemServiceManager.java b/services/core/java/com/android/server/SystemServiceManager.java
index c5b4966ddcf..3df585e4b86 100644
--- a/services/core/java/com/android/server/SystemServiceManager.java
+++ b/services/core/java/com/android/server/SystemServiceManager.java
@@ -22,6 +22,7 @@ import android.os.Environment;
import android.os.SystemClock;
import android.os.Trace;
import android.util.Slog;
+import android.util.TimingsTraceLog;
import java.io.File;
import java.lang.reflect.Constructor;
@@ -178,12 +179,13 @@ public class SystemServiceManager {
}
public void startUser(final int userHandle) {
+ final TimingsTraceLog t = new TimingsTraceLog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
+ t.traceBegin("ssm.startUser-" + userHandle);
Slog.i(TAG, "Calling onStartUser u" + userHandle);
final int serviceLen = mServices.size();
for (int i = 0; i < serviceLen; i++) {
final SystemService service = mServices.get(i);
- Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onStartUser "
- + service.getClass().getName());
+ t.traceBegin("onStartUser-" + userHandle + " " + service.getClass().getName());
long time = SystemClock.elapsedRealtime();
try {
service.onStartUser(userHandle);
@@ -192,17 +194,19 @@ public class SystemServiceManager {
+ " to service " + service.getClass().getName(), ex);
}
warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStartUser ");
- Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+ t.traceEnd();
}
+ t.traceEnd();
}
public void unlockUser(final int userHandle) {
+ final TimingsTraceLog t = new TimingsTraceLog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
+ t.traceBegin("ssm.unlockUser-" + userHandle);
Slog.i(TAG, "Calling onUnlockUser u" + userHandle);
final int serviceLen = mServices.size();
for (int i = 0; i < serviceLen; i++) {
final SystemService service = mServices.get(i);
- Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onUnlockUser "
- + service.getClass().getName());
+ t.traceBegin("onUnlockUser-" + userHandle + " " + service.getClass().getName());
long time = SystemClock.elapsedRealtime();
try {
service.onUnlockUser(userHandle);
@@ -211,17 +215,19 @@ public class SystemServiceManager {
+ " to service " + service.getClass().getName(), ex);
}
warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onUnlockUser ");
- Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+ t.traceEnd();
}
+ t.traceEnd();
}
public void switchUser(final int userHandle) {
+ final TimingsTraceLog t = new TimingsTraceLog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
+ t.traceBegin("ssm.switchUser-" + userHandle);
Slog.i(TAG, "Calling switchUser u" + userHandle);
final int serviceLen = mServices.size();
for (int i = 0; i < serviceLen; i++) {
final SystemService service = mServices.get(i);
- Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onSwitchUser "
- + service.getClass().getName());
+ t.traceBegin("onSwitchUser-" + userHandle + " " + service.getClass().getName());
long time = SystemClock.elapsedRealtime();
try {
service.onSwitchUser(userHandle);
@@ -230,17 +236,19 @@ public class SystemServiceManager {
+ " to service " + service.getClass().getName(), ex);
}
warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onSwitchUser");
- Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+ t.traceEnd();
}
+ t.traceEnd();
}
public void stopUser(final int userHandle) {
+ final TimingsTraceLog t = new TimingsTraceLog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
+ t.traceBegin("ssm.stopUser-" + userHandle);
Slog.i(TAG, "Calling onStopUser u" + userHandle);
final int serviceLen = mServices.size();
for (int i = 0; i < serviceLen; i++) {
final SystemService service = mServices.get(i);
- Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onStopUser "
- + service.getClass().getName());
+ t.traceBegin("onStopUser-" + userHandle + " " + service.getClass().getName());
long time = SystemClock.elapsedRealtime();
try {
service.onStopUser(userHandle);
@@ -249,17 +257,19 @@ public class SystemServiceManager {
+ " to service " + service.getClass().getName(), ex);
}
warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStopUser");
- Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+ t.traceEnd();
}
+ t.traceEnd();
}
public void cleanupUser(final int userHandle) {
+ final TimingsTraceLog t = new TimingsTraceLog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
+ t.traceBegin("ssm.cleanupUser-" + userHandle);
Slog.i(TAG, "Calling onCleanupUser u" + userHandle);
final int serviceLen = mServices.size();
for (int i = 0; i < serviceLen; i++) {
final SystemService service = mServices.get(i);
- Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onCleanupUser "
- + service.getClass().getName());
+ t.traceBegin("onCleanupUser-" + userHandle + " " + service.getClass().getName());
long time = SystemClock.elapsedRealtime();
try {
service.onCleanupUser(userHandle);
@@ -268,8 +278,9 @@ public class SystemServiceManager {
+ " to service " + service.getClass().getName(), ex);
}
warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onCleanupUser");
- Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+ t.traceEnd();
}
+ t.traceEnd();
}
/** Sets the safe mode flag for services to query. */
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index f7e825eecc1..84c43591dcd 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -31,6 +31,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
+import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.telephony.CallAttributes;
@@ -469,7 +470,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
synchronized (mRecords) {
// register
IBinder b = callback.asBinder();
- Record r = add(b);
+ Record r = add(b, Binder.getCallingPid(), false);
if (r == null) {
return;
@@ -522,7 +523,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
synchronized (mRecords) {
// register
IBinder b = callback.asBinder();
- Record r = add(b);
+ Record r = add(b, Binder.getCallingPid(), false);
if (r == null) {
return;
@@ -643,7 +644,11 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
synchronized (mRecords) {
// register
IBinder b = callback.asBinder();
- Record r = add(b);
+ boolean shouldEnforceListenerLimit =
+ Binder.getCallingUid() != Process.SYSTEM_UID
+ && Binder.getCallingUid() != Process.PHONE_UID
+ && Binder.getCallingUid() != Process.myUid();
+ Record r = add(b, Binder.getCallingPid(), shouldEnforceListenerLimit);
if (r == null) {
return;
@@ -893,18 +898,35 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
return record.canReadCallLog() ? mCallIncomingNumber[phoneId] : "";
}
- private Record add(IBinder binder) {
+ private Record add(IBinder binder, int callingPid, boolean enforceLimit) {
Record r;
synchronized (mRecords) {
final int N = mRecords.size();
+ // While iterating through the records, keep track of how many we have from this pid.
+ int numRecordsForPid = 0;
for (int i = 0; i < N; i++) {
r = mRecords.get(i);
if (binder == r.binder) {
// Already existed.
return r;
}
+ if (r.callerPid == callingPid) {
+ numRecordsForPid++;
+ }
+ }
+ // If we've exceeded the limit for registrations, log a warning and quit.
+ if (enforceLimit && numRecordsForPid >= PhoneStateListener.PER_PID_REGISTRATION_LIMIT) {
+ String errorMsg = "Pid " + callingPid + " has exceeded the number of permissible"
+ + "registered listeners. Ignoring request to add.";
+ loge(errorMsg);
+ throw new IllegalStateException(errorMsg);
+ } else if (enforceLimit
+ && numRecordsForPid >= PhoneStateListener.PER_PID_REGISTRATION_LIMIT / 2) {
+ Rlog.w(TAG, "Pid " + callingPid + " has exceeded half the number of permissible"
+ + "registered listeners. Now at " + numRecordsForPid);
}
+
r = new Record();
r.binder = binder;
r.deathRecipient = new TelephonyRegistryDeathRecipient(binder);
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 978cc577f1e..17742b7f634 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -16,6 +16,7 @@
package com.android.server;
+import android.annotation.IntRange;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityManager;
@@ -41,6 +42,7 @@ import android.os.Handler;
import android.os.PowerManager;
import android.os.PowerManager.ServiceType;
import android.os.PowerManagerInternal;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
@@ -67,6 +69,10 @@ import com.android.server.wm.WindowManagerInternal;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.Map;
+
+import static android.app.UiModeManager.MODE_NIGHT_AUTO;
+import static android.app.UiModeManager.MODE_NIGHT_YES;
final class UiModeManagerService extends SystemService {
private static final String TAG = UiModeManager.class.getSimpleName();
@@ -124,6 +130,7 @@ final class UiModeManagerService extends SystemService {
private NotificationManager mNotificationManager;
private StatusBarManager mStatusBarManager;
private WindowManagerInternal mWindowManager;
+ private PowerManager mPowerManager;
private PowerManager.WakeLock mWakeLock;
@@ -136,11 +143,12 @@ final class UiModeManagerService extends SystemService {
@VisibleForTesting
protected UiModeManagerService(Context context, WindowManagerInternal wm,
PowerManager.WakeLock wl, TwilightManager tm,
- boolean setupWizardComplete) {
+ PowerManager pm, boolean setupWizardComplete) {
super(context);
mWindowManager = wm;
mWakeLock = wl;
mTwilightManager = tm;
+ mPowerManager = pm;
mSetupWizardComplete = setupWizardComplete;
}
@@ -261,14 +269,19 @@ final class UiModeManagerService extends SystemService {
private final ContentObserver mDarkThemeObserver = new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange, Uri uri) {
- int mode = Secure.getIntForUser(getContext().getContentResolver(), Secure.UI_NIGHT_MODE,
- mNightMode, 0);
- mode = mode == UiModeManager.MODE_NIGHT_AUTO
- ? UiModeManager.MODE_NIGHT_YES : mode;
- SystemProperties.set(SYSTEM_PROPERTY_DEVICE_THEME, Integer.toString(mode));
+ updateSystemProperties();
}
};
+ private void updateSystemProperties() {
+ int mode = Secure.getIntForUser(getContext().getContentResolver(), Secure.UI_NIGHT_MODE,
+ mNightMode, 0);
+ if (mode == MODE_NIGHT_AUTO) {
+ mode = MODE_NIGHT_YES;
+ }
+ SystemProperties.set(SYSTEM_PROPERTY_DEVICE_THEME, Integer.toString(mode));
+ }
+
@Override
public void onSwitchUser(int userHandle) {
super.onSwitchUser(userHandle);
@@ -280,9 +293,9 @@ final class UiModeManagerService extends SystemService {
public void onStart() {
final Context context = getContext();
- final PowerManager powerManager =
+ mPowerManager =
(PowerManager) context.getSystemService(Context.POWER_SERVICE);
- mWakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG);
+ mWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG);
mWindowManager = LocalServices.getService(WindowManagerInternal.class);
// If setup isn't complete for this user listen for completion so we can unblock
@@ -349,6 +362,7 @@ final class UiModeManagerService extends SystemService {
context.getContentResolver().registerContentObserver(Secure.getUriFor(Secure.UI_NIGHT_MODE),
false, mDarkThemeObserver, 0);
+ mHandler.post(() -> updateSystemProperties());
}
@VisibleForTesting
@@ -406,6 +420,7 @@ final class UiModeManagerService extends SystemService {
}
private void registerScreenOffEvent() {
+ if (mPowerSave) return;
mWaitForScreenOff = true;
final IntentFilter intentFilter =
new IntentFilter(Intent.ACTION_SCREEN_OFF);
@@ -510,7 +525,9 @@ final class UiModeManagerService extends SystemService {
persistNightMode(user);
}
// on screen off will update configuration instead
- if (mNightMode != UiModeManager.MODE_NIGHT_AUTO || mCar) {
+ if ((mNightMode != MODE_NIGHT_AUTO)
+ || shouldApplyAutomaticChangesImmediately()) {
+ unregisterScreenOffEvent();
updateLocked(0, 0);
} else {
registerScreenOffEvent();
@@ -587,19 +604,20 @@ final class UiModeManagerService extends SystemService {
synchronized (mLock) {
pw.println("Current UI Mode Service state:");
pw.print(" mDockState="); pw.print(mDockState);
- pw.print(" mLastBroadcastState="); pw.println(mLastBroadcastState);
+ pw.print(" mLastBroadcastState="); pw.println(mLastBroadcastState);
pw.print(" mNightMode="); pw.print(mNightMode); pw.print(" (");
- pw.print(Shell.nightModeToStr(mNightMode)); pw.print(") ");
- pw.print(" mNightModeLocked="); pw.print(mNightModeLocked);
- pw.print(" mCarModeEnabled="); pw.print(mCarModeEnabled);
- pw.print(" mComputedNightMode="); pw.print(mComputedNightMode);
- pw.print(" mCarModeEnableFlags="); pw.print(mCarModeEnableFlags);
- pw.print(" mEnableCarDockLaunch="); pw.println(mEnableCarDockLaunch);
+ pw.print(Shell.nightModeToStr(mNightMode)); pw.print(") ");
+ pw.print(" mNightModeLocked="); pw.print(mNightModeLocked);
+ pw.print(" mCarModeEnabled="); pw.print(mCarModeEnabled);
+ pw.print(" mComputedNightMode="); pw.print(mComputedNightMode);
+ pw.print(" mCarModeEnableFlags="); pw.print(mCarModeEnableFlags);
+ pw.print(" mEnableCarDockLaunch="); pw.println(mEnableCarDockLaunch);
pw.print(" mCurUiMode=0x"); pw.print(Integer.toHexString(mCurUiMode));
- pw.print(" mUiModeLocked="); pw.print(mUiModeLocked);
- pw.print(" mSetUiMode=0x"); pw.println(Integer.toHexString(mSetUiMode));
+ pw.print(" mUiModeLocked="); pw.print(mUiModeLocked);
+ pw.print(" mSetUiMode=0x"); pw.println(Integer.toHexString(mSetUiMode));
pw.print(" mHoldingConfiguration="); pw.print(mHoldingConfiguration);
- pw.print(" mSystemReady="); pw.println(mSystemReady);
+ pw.print(" mSystemReady="); pw.println(mSystemReady);
+
if (mTwilightManager != null) {
// We may not have a TwilightManager.
pw.print(" mTwilightService.getLastTwilightState()=");
@@ -615,7 +633,6 @@ final class UiModeManagerService extends SystemService {
mTwilightManager = getLocalService(TwilightManager.class);
mSystemReady = true;
mCarModeEnabled = mDockState == Intent.EXTRA_DOCK_STATE_CAR;
- updateComputedNightModeLocked();
registerVrStateListener();
updateLocked(0, 0);
}
@@ -683,40 +700,56 @@ final class UiModeManagerService extends SystemService {
uiMode = Configuration.UI_MODE_TYPE_VR_HEADSET;
}
- if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
+ if (mNightMode == MODE_NIGHT_YES || mNightMode == UiModeManager.MODE_NIGHT_NO) {
+ mComputedNightMode = mNightMode == MODE_NIGHT_YES;
+ }
+
+ if (mNightMode == MODE_NIGHT_AUTO) {
+ boolean activateNightMode = mComputedNightMode;
if (mTwilightManager != null) {
mTwilightManager.registerListener(mTwilightListener, mHandler);
+ final TwilightState lastState = mTwilightManager.getLastTwilightState();
+ activateNightMode = lastState == null ? mComputedNightMode : lastState.isNight();
}
- updateComputedNightModeLocked();
- uiMode |= mComputedNightMode ? Configuration.UI_MODE_NIGHT_YES
- : Configuration.UI_MODE_NIGHT_NO;
+
+ updateComputedNightModeLocked(activateNightMode);
} else {
if (mTwilightManager != null) {
mTwilightManager.unregisterListener(mTwilightListener);
}
- uiMode |= mNightMode << 4;
}
// Override night mode in power save mode if not in car mode
if (mPowerSave && !mCarModeEnabled) {
uiMode &= ~Configuration.UI_MODE_NIGHT_NO;
uiMode |= Configuration.UI_MODE_NIGHT_YES;
+ } else {
+ uiMode = getComputedUiModeConfiguration(uiMode);
}
if (LOG) {
Slog.d(TAG,
- "updateConfigurationLocked: mDockState=" + mDockState
+ "updateConfigurationLocked: mDockState=" + mDockState
+ "; mCarMode=" + mCarModeEnabled
+ "; mNightMode=" + mNightMode
+ "; uiMode=" + uiMode);
}
mCurUiMode = uiMode;
- if (!mHoldingConfiguration || !mWaitForScreenOff) {
+ if (!mHoldingConfiguration && (!mWaitForScreenOff || mPowerSave)) {
mConfiguration.uiMode = uiMode;
}
}
+ @UiModeManager.NightMode
+ private int getComputedUiModeConfiguration(@UiModeManager.NightMode int uiMode) {
+ uiMode |= mComputedNightMode ? Configuration.UI_MODE_NIGHT_YES
+ : Configuration.UI_MODE_NIGHT_NO;
+ uiMode &= mComputedNightMode ? ~Configuration.UI_MODE_NIGHT_NO
+ : ~Configuration.UI_MODE_NIGHT_YES;
+ return uiMode;
+ }
+
private void applyConfigurationExternallyLocked() {
if (mSetUiMode != mConfiguration.uiMode) {
mSetUiMode = mConfiguration.uiMode;
@@ -724,10 +757,16 @@ final class UiModeManagerService extends SystemService {
ActivityTaskManager.getService().updateConfiguration(mConfiguration);
} catch (RemoteException e) {
Slog.w(TAG, "Failure communicating with activity manager", e);
+ } catch (SecurityException e) {
+ Slog.e(TAG, "Activity does not have the ", e);
}
}
}
+ private boolean shouldApplyAutomaticChangesImmediately() {
+ return mCar || !mPowerManager.isInteractive();
+ }
+
void updateLocked(int enableFlags, int disableFlags) {
String action = null;
String oldAction = null;
@@ -958,26 +997,21 @@ final class UiModeManagerService extends SystemService {
}
}
- private void updateComputedNightModeLocked() {
- if (mTwilightManager != null) {
- TwilightState state = mTwilightManager.getLastTwilightState();
- if (state != null) {
- mComputedNightMode = state.isNight();
- }
- if (mNightModeOverride == UiModeManager.MODE_NIGHT_YES && !mComputedNightMode) {
- mComputedNightMode = true;
- return;
- }
- if (mNightModeOverride == UiModeManager.MODE_NIGHT_NO && mComputedNightMode) {
- mComputedNightMode = false;
- return;
- }
-
- mNightModeOverride = mNightMode;
- final int user = UserHandle.getCallingUserId();
- Secure.putIntForUser(getContext().getContentResolver(),
- OVERRIDE_NIGHT_MODE, mNightModeOverride, user);
+ private void updateComputedNightModeLocked(boolean activate) {
+ mComputedNightMode = activate;
+ if (mNightModeOverride == UiModeManager.MODE_NIGHT_YES && !mComputedNightMode) {
+ mComputedNightMode = true;
+ return;
+ }
+ if (mNightModeOverride == UiModeManager.MODE_NIGHT_NO && mComputedNightMode) {
+ mComputedNightMode = false;
+ return;
}
+
+ mNightModeOverride = mNightMode;
+ final int user = UserHandle.getCallingUserId();
+ Secure.putIntForUser(getContext().getContentResolver(),
+ OVERRIDE_NIGHT_MODE, mNightModeOverride, user);
}
private void registerVrStateListener() {
@@ -1098,7 +1132,7 @@ final class UiModeManagerService extends SystemService {
final boolean isIt = (mConfiguration.uiMode & Configuration.UI_MODE_NIGHT_YES) != 0;
if (LOG) {
Slog.d(TAG,
- "LocalService.isNightMode(): mNightMode=" + mNightMode
+ "LocalService.isNightMode(): mNightMode=" + mNightMode
+ "; mComputedNightMode=" + mComputedNightMode
+ "; uiMode=" + mConfiguration.uiMode
+ "; isIt=" + isIt);
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 0d2882216f0..c732521bb7c 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -4404,7 +4404,6 @@ public class AccountManagerService
return true;
}
- @Override
public boolean renameSharedAccountAsUser(Account account, String newName, int userId) {
userId = handleIncomingUser(userId);
UserAccounts accounts = getUserAccounts(userId);
@@ -4420,7 +4419,6 @@ public class AccountManagerService
return r > 0;
}
- @Override
public boolean removeSharedAccountAsUser(Account account, int userId) {
return removeSharedAccountAsUser(account, userId, getCallingUid());
}
@@ -4438,7 +4436,6 @@ public class AccountManagerService
return deleted;
}
- @Override
public Account[] getSharedAccountsAsUser(int userId) {
userId = handleIncomingUser(userId);
UserAccounts accounts = getUserAccounts(userId);
diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java
index 4b48ef91774..143474bd5c9 100644
--- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java
+++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java
@@ -413,6 +413,11 @@ public class AdbDebuggingManager {
case MESSAGE_ADB_CLEAR: {
Slog.d(TAG, "Received a request to clear the adb authorizations");
mConnectedKeys.clear();
+ // If the key store has not yet been instantiated then do so now; this avoids
+ // the unnecessary creation of the key store when adb is not enabled.
+ if (mAdbKeyStore == null) {
+ mAdbKeyStore = new AdbKeyStore();
+ }
mAdbKeyStore.deleteKeyStore();
cancelJobToUpdateAdbKeyStore();
break;
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 8373994b4c4..1a01a4b0dd4 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -3174,8 +3174,11 @@ public final class ActiveServices {
}
}
- // If unbound while waiting to start, remove the pending service
- mPendingServices.remove(s);
+ // If unbound while waiting to start and there is no connection left in this service,
+ // remove the pending service
+ if (s.getConnections().isEmpty()) {
+ mPendingServices.remove(s);
+ }
if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
boolean hasAutoCreate = s.hasAutoCreateConnections();
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 20253be76c6..0d9b907cddf 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -271,8 +271,8 @@ import android.os.WorkSource;
import android.os.storage.IStorageManager;
import android.os.storage.StorageManager;
import android.provider.DeviceConfig;
-import android.provider.Settings;
import android.provider.DeviceConfig.Properties;
+import android.provider.Settings;
import android.server.ServerProtoEnums;
import android.sysprop.VoldProperties;
import android.text.TextUtils;
@@ -352,7 +352,6 @@ import com.android.server.contentcapture.ContentCaptureManagerInternal;
import com.android.server.firewall.IntentFirewall;
import com.android.server.job.JobSchedulerInternal;
import com.android.server.pm.Installer;
-import com.android.server.pm.Installer.InstallerException;
import com.android.server.uri.GrantUri;
import com.android.server.uri.UriGrantsManagerInternal;
import com.android.server.utils.PriorityDump;
@@ -364,8 +363,6 @@ import com.android.server.wm.ActivityTaskManagerService;
import com.android.server.wm.WindowManagerService;
import com.android.server.wm.WindowProcessController;
-import dalvik.system.VMRuntime;
-
import libcore.util.EmptyArray;
import java.io.File;
@@ -5205,26 +5202,6 @@ public class ActivityManagerService extends IActivityManager.Stub
mCallFinishBooting = false;
}
- ArraySet<String> completedIsas = new ArraySet<String>();
- for (String abi : Build.SUPPORTED_ABIS) {
- ZYGOTE_PROCESS.establishZygoteConnectionForAbi(abi);
- final String instructionSet = VMRuntime.getInstructionSet(abi);
- if (!completedIsas.contains(instructionSet)) {
- try {
- mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
- } catch (InstallerException e) {
- if (!VMRuntime.didPruneDalvikCache()) {
- // This is technically not the right filter, as different zygotes may
- // have made different pruning decisions. But the log is best effort,
- // anyways.
- Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
- e.getMessage() +")");
- }
- }
- completedIsas.add(instructionSet);
- }
- }
-
IntentFilter pkgFilter = new IntentFilter();
pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
pkgFilter.addDataScheme("package");
@@ -8263,6 +8240,21 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
+ private boolean isActiveInstrumentation(int uid) {
+ synchronized (ActivityManagerService.this) {
+ for (int i = mActiveInstrumentation.size() - 1; i >= 0; i--) {
+ final ActiveInstrumentation instrumentation = mActiveInstrumentation.get(i);
+ for (int j = instrumentation.mRunningProcesses.size() - 1; j >= 0; j--) {
+ final ProcessRecord process = instrumentation.mRunningProcesses.get(j);
+ if (process.uid == uid) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
@Override
public int getUidProcessState(int uid, String callingPackage) {
if (!hasUsageStatsPermission(callingPackage)) {
@@ -18507,6 +18499,11 @@ public class ActivityManagerService extends IActivityManager.Stub
public void unregisterProcessObserver(IProcessObserver processObserver) {
ActivityManagerService.this.unregisterProcessObserver(processObserver);
}
+
+ @Override
+ public boolean isActiveInstrumentation(int uid) {
+ return ActivityManagerService.this.isActiveInstrumentation(uid);
+ }
}
long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
diff --git a/services/core/java/com/android/server/am/CarUserSwitchingDialog.java b/services/core/java/com/android/server/am/CarUserSwitchingDialog.java
index ebfc2a011e8..a6811e3070b 100644
--- a/services/core/java/com/android/server/am/CarUserSwitchingDialog.java
+++ b/services/core/java/com/android/server/am/CarUserSwitchingDialog.java
@@ -30,9 +30,9 @@ import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
-import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.UserManager;
+import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
@@ -56,8 +56,6 @@ final class CarUserSwitchingDialog extends UserSwitchingDialog {
String switchingToSystemUserMessage) {
super(service, context, oldUser, newUser, aboveSystem, switchingFromSystemUserMessage,
switchingToSystemUserMessage);
-
- getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
@Override
@@ -81,8 +79,19 @@ final class CarUserSwitchingDialog extends UserSwitchingDialog {
.setImageDrawable(drawable);
}
- ((TextView) view.findViewById(R.id.user_loading))
- .setText(res.getString(R.string.car_loading_profile));
+ TextView msgView = view.findViewById(R.id.user_loading);
+
+ // TODO(b/145132885): use constant from CarSettings
+ boolean showInfo = "true".equals(Settings.Global.getString(
+ getContext().getContentResolver(),
+ "android.car.ENABLE_USER_SWITCH_DEVELOPER_MESSAGE"));
+
+ if (showInfo) {
+ msgView.setText(res.getString(R.string.car_loading_profile) + " user\n(from "
+ + mOldUser.id + " to " + mNewUser.id + ")");
+ } else {
+ msgView.setText(res.getString(R.string.car_loading_profile));
+ }
setView(view);
}
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index fe29a36ec45..278163b9dfe 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -422,9 +422,7 @@ public final class ProcessList {
@GuardedBy("ProcessList.this.mService")
void freeIsolatedUidLocked(int uid) {
- // Strip out userId
- final int appId = UserHandle.getAppId(uid);
- mUidUsed.delete(appId);
+ mUidUsed.delete(uid);
}
};
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index f6b49bc9a25..07b5c5fccca 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -129,6 +129,10 @@ class UserController implements Handler.Callback {
// giving up on them and unfreezing the screen.
static final int USER_SWITCH_TIMEOUT_MS = 3 * 1000;
+ // Amount of time we wait for observers to handle a user switch before we log a warning.
+ // Must be smaller than USER_SWITCH_TIMEOUT_MS.
+ private static final int USER_SWITCH_WARNING_TIMEOUT_MS = 500;
+
// ActivityManager thread message constants
static final int REPORT_USER_SWITCH_MSG = 10;
static final int CONTINUE_USER_SWITCH_MSG = 20;
@@ -408,6 +412,7 @@ class UserController implements Handler.Callback {
*/
private boolean finishUserUnlocking(final UserState uss) {
final int userId = uss.mHandle.getIdentifier();
+ Slog.d(TAG, "UserController event: finishUserUnlocking(" + userId + ")");
// Only keep marching forward if user is actually unlocked
if (!StorageManager.isUserKeyUnlocked(userId)) return false;
synchronized (mLock) {
@@ -452,6 +457,7 @@ class UserController implements Handler.Callback {
*/
void finishUserUnlocked(final UserState uss) {
final int userId = uss.mHandle.getIdentifier();
+ Slog.d(TAG, "UserController event: finishUserUnlocked(" + userId + ")");
// Only keep marching forward if user is actually unlocked
if (!StorageManager.isUserKeyUnlocked(userId)) return;
synchronized (mLock) {
@@ -522,6 +528,7 @@ class UserController implements Handler.Callback {
private void finishUserUnlockedCompleted(UserState uss) {
final int userId = uss.mHandle.getIdentifier();
+ Slog.d(TAG, "UserController event: finishUserUnlockedCompleted(" + userId + ")");
synchronized (mLock) {
// Bail if we ended up with a stale user
if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
@@ -739,6 +746,7 @@ class UserController implements Handler.Callback {
}
void finishUserStopping(final int userId, final UserState uss) {
+ Slog.d(TAG, "UserController event: finishUserStopping(" + userId + ")");
// On to the next.
final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
// This is the result receiver for the final shutdown broadcast.
@@ -778,6 +786,7 @@ class UserController implements Handler.Callback {
void finishUserStopped(UserState uss) {
final int userId = uss.mHandle.getIdentifier();
+ Slog.d(TAG, "UserController event: finishUserStopped(" + userId + ")");
final boolean stopped;
boolean lockUser = true;
final ArrayList<IStopUserCallback> stopCallbacks;
@@ -1259,7 +1268,7 @@ class UserController implements Handler.Callback {
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
-
+ Slog.i(TAG, "unlocking user " + userId);
final long binderToken = Binder.clearCallingIdentity();
try {
return unlockUserCleared(userId, token, secret, listener);
@@ -1344,6 +1353,7 @@ class UserController implements Handler.Callback {
boolean switchUser(final int targetUserId) {
enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
+ Slog.i(TAG, "switching to user " + targetUserId);
int currentUserId = getCurrentUserId();
UserInfo targetUserInfo = getUserInfo(targetUserId);
if (targetUserId == currentUserId) {
@@ -1486,9 +1496,13 @@ class UserController implements Handler.Callback {
synchronized (mLock) {
long delay = SystemClock.elapsedRealtime() - dispatchStartedTime;
if (delay > USER_SWITCH_TIMEOUT_MS) {
- Slog.e(TAG, "User switch timeout: observer " + name
+ Slog.e(TAG, "User switch timeout: observer " + name
+ " sent result after " + delay + " ms");
+ } else if (delay > USER_SWITCH_WARNING_TIMEOUT_MS) {
+ Slog.w(TAG, "User switch slowed down by observer " + name
+ + ": result sent after " + delay + " ms");
}
+
curWaitingUserSwitchCallbacks.remove(name);
// Continue switching if all callbacks have been notified and
// user switching session is still valid
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 314e04c8da3..687ca192788 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -31,10 +31,13 @@ import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE_LOCATION;
import static android.app.AppOpsManager.UID_STATE_MAX_LAST_NON_RESTRICTED;
import static android.app.AppOpsManager.UID_STATE_PERSISTENT;
import static android.app.AppOpsManager.UID_STATE_TOP;
+import static android.app.AppOpsManager.WATCH_FOREGROUND_CHANGES;
import static android.app.AppOpsManager.modeToName;
import static android.app.AppOpsManager.opToName;
import static android.app.AppOpsManager.resolveFirstUnrestrictedUidState;
+import static java.lang.Long.max;
+
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -938,6 +941,19 @@ public class AppOpsService extends IAppOpsService.Stub {
}
}
+ /**
+ * Update the pending state for the uid
+ *
+ * @param currentTime The current elapsed real time
+ * @param uid The uid that has a pending state
+ */
+ private void updatePendingState(long currentTime, int uid) {
+ synchronized (this) {
+ mLastRealtime = max(currentTime, mLastRealtime);
+ updatePendingStateIfNeededLocked(mUidStates.get(uid));
+ }
+ }
+
public void updateUidProcState(int uid, int procState) {
synchronized (this) {
final UidState uidState = getUidStateLocked(uid, true);
@@ -963,7 +979,12 @@ public class AppOpsService extends IAppOpsService.Stub {
} else {
settleTime = mConstants.BG_STATE_SETTLE_TIME;
}
- uidState.pendingStateCommitTime = SystemClock.elapsedRealtime() + settleTime;
+ final long commitTime = SystemClock.elapsedRealtime() + settleTime;
+ uidState.pendingStateCommitTime = commitTime;
+
+ mHandler.sendMessageDelayed(
+ PooledLambda.obtainMessage(AppOpsService::updatePendingState, this,
+ commitTime + 1, uid), settleTime + 1);
}
if (uidState.startNesting != 0) {
// There is some actively running operation... need to find it
@@ -1110,8 +1131,8 @@ public class AppOpsService extends IAppOpsService.Stub {
return Collections.emptyList();
}
synchronized (this) {
- Ops pkgOps = getOpsRawLocked(uid, resolvedPackageName, false /* edit */,
- false /* uidMismatchExpected */);
+ Ops pkgOps = getOpsRawLocked(uid, resolvedPackageName, false /* isPrivileged */,
+ false /* edit */);
if (pkgOps == null) {
return null;
}
@@ -1208,8 +1229,7 @@ public class AppOpsService extends IAppOpsService.Stub {
private void pruneOp(Op op, int uid, String packageName) {
if (!op.hasAnyTime()) {
- Ops ops = getOpsRawLocked(uid, packageName, false /* edit */,
- false /* uidMismatchExpected */);
+ Ops ops = getOpsRawLocked(uid, packageName, false /* isPrivileged */, false /* edit */);
if (ops != null) {
ops.remove(op.op);
if (ops.size() <= 0) {
@@ -1294,6 +1314,18 @@ public class AppOpsService extends IAppOpsService.Stub {
uidState.evalForegroundOps(mOpModeWatchers);
}
+ notifyOpChangedForAllPkgsInUid(code, uid, false);
+ notifyOpChangedSync(code, uid, null, mode);
+ }
+
+ /**
+ * Notify that an op changed for all packages in an uid.
+ *
+ * @param code The op that changed
+ * @param uid The uid the op was changed for
+ * @param onlyForeground Only notify watchers that watch for foreground changes
+ */
+ private void notifyOpChangedForAllPkgsInUid(int code, int uid, boolean onlyForeground) {
String[] uidPackageNames = getPackagesForUid(uid);
ArrayMap<ModeCallback, ArraySet<String>> callbackSpecs = null;
@@ -1303,6 +1335,10 @@ public class AppOpsService extends IAppOpsService.Stub {
final int callbackCount = callbacks.size();
for (int i = 0; i < callbackCount; i++) {
ModeCallback callback = callbacks.valueAt(i);
+ if (onlyForeground && (callback.mFlags & WATCH_FOREGROUND_CHANGES) == 0) {
+ continue;
+ }
+
ArraySet<String> changedPackages = new ArraySet<>();
Collections.addAll(changedPackages, uidPackageNames);
if (callbackSpecs == null) {
@@ -1321,6 +1357,10 @@ public class AppOpsService extends IAppOpsService.Stub {
final int callbackCount = callbacks.size();
for (int i = 0; i < callbackCount; i++) {
ModeCallback callback = callbacks.valueAt(i);
+ if (onlyForeground && (callback.mFlags & WATCH_FOREGROUND_CHANGES) == 0) {
+ continue;
+ }
+
ArraySet<String> changedPackages = callbackSpecs.get(callback);
if (changedPackages == null) {
changedPackages = new ArraySet<>();
@@ -1333,7 +1373,6 @@ public class AppOpsService extends IAppOpsService.Stub {
}
if (callbackSpecs == null) {
- notifyOpChangedSync(code, uid, null, mode);
return;
}
@@ -1355,8 +1394,6 @@ public class AppOpsService extends IAppOpsService.Stub {
}
}
}
-
- notifyOpChangedSync(code, uid, null, mode);
}
private void notifyOpChangedSync(int code, int uid, @NonNull String packageName, int mode) {
@@ -1409,11 +1446,6 @@ public class AppOpsService extends IAppOpsService.Stub {
}
}
- @Override
- public void setMode(int code, int uid, String packageName, int mode) {
- setMode(code, uid, packageName, mode, true, false);
- }
-
/**
* Sets the mode for a certain op and uid.
*
@@ -1421,19 +1453,25 @@ public class AppOpsService extends IAppOpsService.Stub {
* @param uid The UID for which to set
* @param packageName The package for which to set
* @param mode The new mode to set
- * @param verifyUid Iff {@code true}, check that the package name belongs to the uid
- * @param isPrivileged Whether the package is privileged. (Only used if {@code verifyUid ==
- * false})
*/
- private void setMode(int code, int uid, @NonNull String packageName, int mode,
- boolean verifyUid, boolean isPrivileged) {
+ @Override
+ public void setMode(int code, int uid, @NonNull String packageName, int mode) {
enforceManageAppOpsModes(Binder.getCallingPid(), Binder.getCallingUid(), uid);
verifyIncomingOp(code);
ArraySet<ModeCallback> repCbs = null;
code = AppOpsManager.opToSwitch(code);
+
+ boolean isPrivileged;
+ try {
+ isPrivileged = verifyAndGetIsPrivileged(uid, packageName);
+ } catch (SecurityException e) {
+ Slog.e(TAG, "Cannot setMode", e);
+ return;
+ }
+
synchronized (this) {
UidState uidState = getUidStateLocked(uid, false);
- Op op = getOpLocked(code, uid, packageName, true, verifyUid, isPrivileged);
+ Op op = getOpLocked(code, uid, packageName, isPrivileged, true);
if (op != null) {
if (op.mode != mode) {
op.mode = mode;
@@ -1799,34 +1837,32 @@ public class AppOpsService extends IAppOpsService.Stub {
}
/**
- * @see #checkOperationUnchecked(int, int, String, boolean, boolean)
- */
- private @Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName,
- boolean raw) {
- return checkOperationUnchecked(code, uid, packageName, raw, true);
- }
-
- /**
* Get the mode of an app-op.
*
* @param code The code of the op
* @param uid The uid of the package the op belongs to
* @param packageName The package the op belongs to
* @param raw If the raw state of eval-ed state should be checked.
- * @param verify If the code should check the package belongs to the uid
*
* @return The mode of the op
*/
private @Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName,
- boolean raw, boolean verify) {
+ boolean raw) {
if (isOpRestrictedDueToSuspend(code, packageName, uid)) {
return AppOpsManager.MODE_IGNORED;
}
+
+ boolean isPrivileged;
+
+ try {
+ isPrivileged = verifyAndGetIsPrivileged(uid, packageName);
+ } catch (SecurityException e) {
+ Slog.e(TAG, "checkOperation", e);
+ return AppOpsManager.opToDefaultMode(code);
+ }
+
synchronized (this) {
- if (verify) {
- checkPackage(uid, packageName);
- }
- if (isOpRestrictedLocked(uid, code, packageName)) {
+ if (isOpRestrictedLocked(uid, code, packageName, isPrivileged)) {
return AppOpsManager.MODE_IGNORED;
}
code = AppOpsManager.opToSwitch(code);
@@ -1836,7 +1872,7 @@ public class AppOpsService extends IAppOpsService.Stub {
final int rawMode = uidState.opModes.get(code);
return raw ? rawMode : uidState.evalMode(code, rawMode);
}
- Op op = getOpLocked(code, uid, packageName, false, verify, false);
+ Op op = getOpLocked(code, uid, packageName, false, false);
if (op == null) {
return AppOpsManager.opToDefaultMode(code);
}
@@ -1941,14 +1977,12 @@ public class AppOpsService extends IAppOpsService.Stub {
@Override
public int checkPackage(int uid, String packageName) {
Preconditions.checkNotNull(packageName);
- synchronized (this) {
- Ops ops = getOpsRawLocked(uid, packageName, true /* edit */,
- true /* uidMismatchExpected */);
- if (ops != null) {
- return AppOpsManager.MODE_ALLOWED;
- } else {
- return AppOpsManager.MODE_ERRORED;
- }
+ try {
+ verifyAndGetIsPrivileged(uid, packageName);
+
+ return AppOpsManager.MODE_ALLOWED;
+ } catch (SecurityException ignored) {
+ return AppOpsManager.MODE_ERRORED;
}
}
@@ -2011,9 +2045,16 @@ public class AppOpsService extends IAppOpsService.Stub {
private int noteOperationUnchecked(int code, int uid, String packageName,
int proxyUid, String proxyPackageName, @OpFlags int flags) {
+ boolean isPrivileged;
+ try {
+ isPrivileged = verifyAndGetIsPrivileged(uid, packageName);
+ } catch (SecurityException e) {
+ Slog.e(TAG, "noteOperation", e);
+ return AppOpsManager.MODE_ERRORED;
+ }
+
synchronized (this) {
- final Ops ops = getOpsRawLocked(uid, packageName, true /* edit */,
- false /* uidMismatchExpected */);
+ final Ops ops = getOpsRawLocked(uid, packageName, isPrivileged, true /* edit */);
if (ops == null) {
scheduleOpNotedIfNeededLocked(code, uid, packageName,
AppOpsManager.MODE_IGNORED);
@@ -2022,7 +2063,7 @@ public class AppOpsService extends IAppOpsService.Stub {
return AppOpsManager.MODE_ERRORED;
}
final Op op = getOpLocked(ops, code, true);
- if (isOpRestrictedLocked(uid, code, packageName)) {
+ if (isOpRestrictedLocked(uid, code, packageName, isPrivileged)) {
scheduleOpNotedIfNeededLocked(code, uid, packageName,
AppOpsManager.MODE_IGNORED);
return AppOpsManager.MODE_IGNORED;
@@ -2181,16 +2222,25 @@ public class AppOpsService extends IAppOpsService.Stub {
return AppOpsManager.MODE_IGNORED;
}
ClientState client = (ClientState)token;
+
+ boolean isPrivileged;
+ try {
+ isPrivileged = verifyAndGetIsPrivileged(uid, packageName);
+ } catch (SecurityException e) {
+ Slog.e(TAG, "startOperation", e);
+ return AppOpsManager.MODE_ERRORED;
+ }
+
synchronized (this) {
- final Ops ops = getOpsRawLocked(uid, resolvedPackageName, true /* edit */,
- false /* uidMismatchExpected */);
+ final Ops ops = getOpsRawLocked(uid, resolvedPackageName, isPrivileged,
+ true /* edit */);
if (ops == null) {
if (DEBUG) Slog.d(TAG, "startOperation: no op for code " + code + " uid " + uid
+ " package " + resolvedPackageName);
return AppOpsManager.MODE_ERRORED;
}
final Op op = getOpLocked(ops, code, true);
- if (isOpRestrictedLocked(uid, code, resolvedPackageName)) {
+ if (isOpRestrictedLocked(uid, code, resolvedPackageName, isPrivileged)) {
return AppOpsManager.MODE_IGNORED;
}
final int switchCode = AppOpsManager.opToSwitch(code);
@@ -2262,8 +2312,17 @@ public class AppOpsService extends IAppOpsService.Stub {
return;
}
ClientState client = (ClientState) token;
+
+ boolean isPrivileged;
+ try {
+ isPrivileged = verifyAndGetIsPrivileged(uid, packageName);
+ } catch (SecurityException e) {
+ Slog.e(TAG, "Cannot finishOperation", e);
+ return;
+ }
+
synchronized (this) {
- Op op = getOpLocked(code, uid, resolvedPackageName, true, true, false);
+ Op op = getOpLocked(code, uid, resolvedPackageName, isPrivileged, true);
if (op == null) {
return;
}
@@ -2451,6 +2510,18 @@ public class AppOpsService extends IAppOpsService.Stub {
uidState = new UidState(uid);
mUidStates.put(uid, uidState);
} else {
+ updatePendingStateIfNeededLocked(uidState);
+ }
+ return uidState;
+ }
+
+ /**
+ * Check if the pending state should be updated and do so if needed
+ *
+ * @param uidState The uidState that might have a pending state
+ */
+ private void updatePendingStateIfNeededLocked(@NonNull UidState uidState) {
+ if (uidState != null) {
if (uidState.pendingStateCommitTime != 0) {
if (uidState.pendingStateCommitTime < mLastRealtime) {
commitUidPendingStateLocked(uidState);
@@ -2462,7 +2533,6 @@ public class AppOpsService extends IAppOpsService.Stub {
}
}
}
- return uidState;
}
private void commitUidPendingStateLocked(UidState uidState) {
@@ -2480,24 +2550,28 @@ public class AppOpsService extends IAppOpsService.Stub {
if (resolvedLastFg == resolvedNowFg) {
continue;
}
- final ArraySet<ModeCallback> callbacks = mOpModeWatchers.get(code);
- if (callbacks != null) {
- for (int cbi = callbacks.size() - 1; cbi >= 0; cbi--) {
- final ModeCallback callback = callbacks.valueAt(cbi);
- if ((callback.mFlags & AppOpsManager.WATCH_FOREGROUND_CHANGES) == 0
- || !callback.isWatchingUid(uidState.uid)) {
- continue;
- }
- boolean doAllPackages = uidState.opModes != null
- && uidState.opModes.indexOfKey(code) >= 0
- && uidState.opModes.get(code) == AppOpsManager.MODE_FOREGROUND;
- if (uidState.pkgOps != null) {
+
+ if (uidState.opModes != null
+ && uidState.opModes.indexOfKey(code) >= 0
+ && uidState.opModes.get(code) == AppOpsManager.MODE_FOREGROUND) {
+ mHandler.sendMessage(PooledLambda.obtainMessage(
+ AppOpsService::notifyOpChangedForAllPkgsInUid,
+ this, code, uidState.uid, true));
+ } else {
+ final ArraySet<ModeCallback> callbacks = mOpModeWatchers.get(code);
+ if (callbacks != null) {
+ for (int cbi = callbacks.size() - 1; cbi >= 0; cbi--) {
+ final ModeCallback callback = callbacks.valueAt(cbi);
+ if ((callback.mFlags & AppOpsManager.WATCH_FOREGROUND_CHANGES) == 0
+ || !callback.isWatchingUid(uidState.uid)) {
+ continue;
+ }
for (int pkgi = uidState.pkgOps.size() - 1; pkgi >= 0; pkgi--) {
final Op op = uidState.pkgOps.valueAt(pkgi).get(code);
if (op == null) {
continue;
}
- if (doAllPackages || op.mode == AppOpsManager.MODE_FOREGROUND) {
+ if (op.mode == AppOpsManager.MODE_FOREGROUND) {
mHandler.sendMessage(PooledLambda.obtainMessage(
AppOpsService::notifyOpChanged,
this, callback, code, uidState.uid,
@@ -2513,8 +2587,76 @@ public class AppOpsService extends IAppOpsService.Stub {
uidState.pendingStateCommitTime = 0;
}
- private Ops getOpsRawLocked(int uid, String packageName, boolean edit,
- boolean uidMismatchExpected) {
+ /**
+ * Verify that package belongs to uid and return whether the package is privileged.
+ *
+ * @param uid The uid the package belongs to
+ * @param packageName The package the might belong to the uid
+ *
+ * @return {@code true} iff the package is privileged
+ */
+ private boolean verifyAndGetIsPrivileged(int uid, String packageName) {
+ if (uid == Process.ROOT_UID) {
+ // For backwards compatibility, don't check package name for root UID.
+ return false;
+ }
+
+ // Do not check if uid/packageName is already known
+ synchronized (this) {
+ UidState uidState = mUidStates.get(uid);
+ if (uidState != null && uidState.pkgOps != null) {
+ Ops ops = uidState.pkgOps.get(packageName);
+
+ if (ops != null) {
+ return ops.isPrivileged;
+ }
+ }
+ }
+
+ boolean isPrivileged = false;
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ int pkgUid;
+
+ ApplicationInfo appInfo = LocalServices.getService(PackageManagerInternal.class)
+ .getApplicationInfo(packageName, PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
+ | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS
+ | PackageManager.MATCH_UNINSTALLED_PACKAGES
+ | PackageManager.MATCH_INSTANT,
+ Process.SYSTEM_UID, UserHandle.getUserId(uid));
+ if (appInfo != null) {
+ pkgUid = appInfo.uid;
+ isPrivileged = (appInfo.privateFlags
+ & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
+ } else {
+ pkgUid = resolveUid(packageName);
+ if (pkgUid >= 0) {
+ isPrivileged = false;
+ }
+ }
+ if (pkgUid != uid) {
+ throw new SecurityException("Specified package " + packageName + " under uid " + uid
+ + " but it is really " + pkgUid);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+
+ return isPrivileged;
+ }
+
+ /**
+ * Get (and potentially create) ops.
+ *
+ * @param uid The uid the package belongs to
+ * @param packageName The name of the package
+ * @param isPrivileged If the package is privilidged (ignored if {@code edit} is false)
+ * @param edit If an ops does not exist, create the ops?
+
+ * @return
+ */
+ private Ops getOpsRawLocked(int uid, String packageName, boolean isPrivileged, boolean edit) {
UidState uidState = getUidStateLocked(uid, edit);
if (uidState == null) {
return null;
@@ -2532,47 +2674,6 @@ public class AppOpsService extends IAppOpsService.Stub {
if (!edit) {
return null;
}
- boolean isPrivileged = false;
- // This is the first time we have seen this package name under this uid,
- // so let's make sure it is valid.
- if (uid != 0) {
- final long ident = Binder.clearCallingIdentity();
- try {
- int pkgUid = -1;
- try {
- ApplicationInfo appInfo = ActivityThread.getPackageManager()
- .getApplicationInfo(packageName,
- PackageManager.MATCH_DIRECT_BOOT_AWARE
- | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
- UserHandle.getUserId(uid));
- if (appInfo != null) {
- pkgUid = appInfo.uid;
- isPrivileged = (appInfo.privateFlags
- & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
- } else {
- pkgUid = resolveUid(packageName);
- if (pkgUid >= 0) {
- isPrivileged = false;
- }
- }
- } catch (RemoteException e) {
- Slog.w(TAG, "Could not contact PackageManager", e);
- }
- if (pkgUid != uid) {
- // Oops! The package name is not valid for the uid they are calling
- // under. Abort.
- if (!uidMismatchExpected) {
- RuntimeException ex = new RuntimeException("here");
- ex.fillInStackTrace();
- Slog.w(TAG, "Bad call: specified package " + packageName
- + " under uid " + uid + " but it is really " + pkgUid, ex);
- }
- return null;
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
ops = new Ops(packageName, uidState, isPrivileged);
uidState.pkgOps.put(packageName, ops);
}
@@ -2580,7 +2681,7 @@ public class AppOpsService extends IAppOpsService.Stub {
}
/**
- * Get the state of all ops for a package, <b>don't verify that package belongs to uid</b>.
+ * Get the state of all ops for a package.
*
* <p>Usually callers should use {@link #getOpLocked} and not call this directly.
*
@@ -2638,23 +2739,15 @@ public class AppOpsService extends IAppOpsService.Stub {
* @param code The code of the op
* @param uid The uid the of the package
* @param packageName The package name for which to get the state for
+ * @param isPrivileged Whether the package is privileged or not (only used if {@code edit
+ * == true})
* @param edit Iff {@code true} create the {@link Op} object if not yet created
- * @param verifyUid Iff {@code true} check that the package belongs to the uid
- * @param isPrivileged Whether the package is privileged or not (only used if {@code verifyUid
- * == false})
*
* @return The {@link Op state} of the op
*/
- private @Nullable Op getOpLocked(int code, int uid, @NonNull String packageName, boolean edit,
- boolean verifyUid, boolean isPrivileged) {
- Ops ops;
-
- if (verifyUid) {
- ops = getOpsRawLocked(uid, packageName, edit, false /* uidMismatchExpected */);
- } else {
- ops = getOpsRawNoVerifyLocked(uid, packageName, edit, isPrivileged);
- }
-
+ private @Nullable Op getOpLocked(int code, int uid, @NonNull String packageName,
+ boolean isPrivileged, boolean edit) {
+ Ops ops = getOpsRawNoVerifyLocked(uid, packageName, edit, isPrivileged);
if (ops == null) {
return null;
}
@@ -2684,7 +2777,8 @@ public class AppOpsService extends IAppOpsService.Stub {
return pmi.isPackageSuspended(packageName, UserHandle.getUserId(uid));
}
- private boolean isOpRestrictedLocked(int uid, int code, String packageName) {
+ private boolean isOpRestrictedLocked(int uid, int code, String packageName,
+ boolean isPrivileged) {
int userHandle = UserHandle.getUserId(uid);
final int restrictionSetCount = mOpUserRestrictions.size();
@@ -2696,8 +2790,8 @@ public class AppOpsService extends IAppOpsService.Stub {
if (AppOpsManager.opAllowSystemBypassRestriction(code)) {
// If we are the system, bypass user restrictions for certain codes
synchronized (this) {
- Ops ops = getOpsRawLocked(uid, packageName, true /* edit */,
- false /* uidMismatchExpected */);
+ Ops ops = getOpsRawLocked(uid, packageName, isPrivileged,
+ true /* edit */);
if ((ops != null) && ops.isPrivileged) {
return false;
}
@@ -3068,7 +3162,7 @@ public class AppOpsService extends IAppOpsService.Stub {
out.attribute(null, "n", Integer.toString(pkg.getUid()));
synchronized (this) {
Ops ops = getOpsRawLocked(pkg.getUid(), pkg.getPackageName(),
- false /* edit */, false /* uidMismatchExpected */);
+ false /* isPrivileged */, false /* edit */);
// Should always be present as the list of PackageOps is generated
// from Ops.
if (ops != null) {
@@ -4647,18 +4741,8 @@ public class AppOpsService extends IAppOpsService.Stub {
}
@Override
- public void setUidMode(int code, int uid, int mode) {
- AppOpsService.this.setUidMode(code, uid, mode);
- }
-
- @Override
public void setAllPkgModesToDefault(int code, int uid) {
AppOpsService.this.setAllPkgModesToDefault(code, uid);
}
-
- @Override
- public @Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName) {
- return AppOpsService.this.checkOperationUnchecked(code, uid, packageName, true, false);
- }
}
}
diff --git a/services/core/java/com/android/server/appop/TEST_MAPPING b/services/core/java/com/android/server/appop/TEST_MAPPING
index a53797dfa9e..1a5dac50346 100644
--- a/services/core/java/com/android/server/appop/TEST_MAPPING
+++ b/services/core/java/com/android/server/appop/TEST_MAPPING
@@ -10,6 +10,14 @@
"include-filter": "com.android.server.appop"
}
]
+ },
+ {
+ "name": "FrameworksMockingServicesTests",
+ "options": [
+ {
+ "include-filter": "com.android.server.appop"
+ }
+ ]
}
]
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 8274b8fac30..eaf51ab2954 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -1057,6 +1057,27 @@ public class AudioService extends IAudioService.Stub
}
}
+ // Restore capture policies
+ synchronized (mPlaybackMonitor) {
+ HashMap<Integer, Integer> allowedCapturePolicies =
+ mPlaybackMonitor.getAllAllowedCapturePolicies();
+ for (HashMap.Entry<Integer, Integer> entry : allowedCapturePolicies.entrySet()) {
+ int result = AudioSystem.setAllowedCapturePolicy(
+ entry.getKey(),
+ AudioAttributes.capturePolicyToFlags(entry.getValue(), 0x0));
+ if (result != AudioSystem.AUDIO_STATUS_OK) {
+ Log.e(TAG, "Failed to restore capture policy, uid: "
+ + entry.getKey() + ", capture policy: " + entry.getValue()
+ + ", result: " + result);
+ // When restoring capture policy failed, set the capture policy as
+ // ALLOW_CAPTURE_BY_ALL, which will result in removing the cached
+ // capture policy in PlaybackActivityMonitor.
+ mPlaybackMonitor.setAllowedCapturePolicy(
+ entry.getKey(), AudioAttributes.ALLOW_CAPTURE_BY_ALL);
+ }
+ }
+ }
+
onIndicateSystemReady();
// indicate the end of reconfiguration phase to audio HAL
AudioSystem.setParameters("restarting=false");
@@ -2804,10 +2825,6 @@ public class AudioService extends IAudioService.Stub
setSystemAudioMute(mute);
AudioSystem.setMasterMute(mute);
sendMasterMuteUpdate(mute, flags);
-
- Intent intent = new Intent(AudioManager.MASTER_MUTE_CHANGED_ACTION);
- intent.putExtra(AudioManager.EXTRA_MASTER_VOLUME_MUTED, mute);
- sendBroadcastToAll(intent);
}
}
}
@@ -7304,6 +7321,43 @@ public class AudioService extends IAudioService.Stub
mPlaybackMonitor.releasePlayer(piid, Binder.getCallingUid());
}
+ /**
+ * Specifies whether the audio played by this app may or may not be captured by other apps or
+ * the system.
+ *
+ * @param capturePolicy one of
+ * {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL},
+ * {@link AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM},
+ * {@link AudioAttributes#ALLOW_CAPTURE_BY_NONE}.
+ * @return AudioSystem.AUDIO_STATUS_OK if set allowed capture policy succeed.
+ * @throws IllegalArgumentException if the argument is not a valid value.
+ */
+ public int setAllowedCapturePolicy(int capturePolicy) {
+ int callingUid = Binder.getCallingUid();
+ int flags = AudioAttributes.capturePolicyToFlags(capturePolicy, 0x0);
+ final long identity = Binder.clearCallingIdentity();
+ synchronized (mPlaybackMonitor) {
+ int result = AudioSystem.setAllowedCapturePolicy(callingUid, flags);
+ if (result == AudioSystem.AUDIO_STATUS_OK) {
+ mPlaybackMonitor.setAllowedCapturePolicy(callingUid, capturePolicy);
+ }
+ Binder.restoreCallingIdentity(identity);
+ return result;
+ }
+ }
+
+ /**
+ * Return the capture policy.
+ * @return the cached capture policy for the calling uid.
+ */
+ public int getAllowedCapturePolicy() {
+ int callingUid = Binder.getCallingUid();
+ final long identity = Binder.clearCallingIdentity();
+ int capturePolicy = mPlaybackMonitor.getAllowedCapturePolicy(callingUid);
+ Binder.restoreCallingIdentity(identity);
+ return capturePolicy;
+ }
+
//======================
// Audio device management
//======================
diff --git a/services/core/java/com/android/server/audio/FocusRequester.java b/services/core/java/com/android/server/audio/FocusRequester.java
index db55138e446..7578948adb1 100644
--- a/services/core/java/com/android/server/audio/FocusRequester.java
+++ b/services/core/java/com/android/server/audio/FocusRequester.java
@@ -416,7 +416,8 @@ public class FocusRequester {
}
int dispatchFocusChange(int focusChange) {
- if (mFocusDispatcher == null) {
+ final IAudioFocusDispatcher fd = mFocusDispatcher;
+ if (fd == null) {
if (MediaFocusControl.DEBUG) { Log.e(TAG, "dispatchFocusChange: no focus dispatcher"); }
return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
}
@@ -436,7 +437,7 @@ public class FocusRequester {
mFocusLossReceived = focusChange;
}
try {
- mFocusDispatcher.dispatchAudioFocusChange(focusChange, mClientId);
+ fd.dispatchAudioFocusChange(focusChange, mClientId);
} catch (android.os.RemoteException e) {
Log.e(TAG, "dispatchFocusChange: error talking to focus listener " + mClientId, e);
return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
@@ -445,16 +446,18 @@ public class FocusRequester {
}
void dispatchFocusResultFromExtPolicy(int requestResult) {
- if (mFocusDispatcher == null) {
+ final IAudioFocusDispatcher fd = mFocusDispatcher;
+ if (fd == null) {
if (MediaFocusControl.DEBUG) {
Log.e(TAG, "dispatchFocusResultFromExtPolicy: no focus dispatcher");
}
+ return;
}
if (DEBUG) {
Log.v(TAG, "dispatching result" + requestResult + " to " + mClientId);
}
try {
- mFocusDispatcher.dispatchFocusResultFromExtPolicy(requestResult, mClientId);
+ fd.dispatchFocusResultFromExtPolicy(requestResult, mClientId);
} catch (android.os.RemoteException e) {
Log.e(TAG, "dispatchFocusResultFromExtPolicy: error talking to focus listener"
+ mClientId, e);
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index 3a25d980e97..93ffe835338 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -160,6 +160,12 @@ public final class PlaybackActivityMonitor
new AudioPlaybackConfiguration(pic, newPiid,
Binder.getCallingUid(), Binder.getCallingPid());
apc.init();
+ synchronized (mAllowedCapturePolicies) {
+ int uid = apc.getClientUid();
+ if (mAllowedCapturePolicies.containsKey(uid)) {
+ updateAllowedCapturePolicy(apc, mAllowedCapturePolicies.get(uid));
+ }
+ }
sEventLogger.log(new NewPlayerEvent(apc));
synchronized(mPlayerLock) {
mPlayers.put(newPiid, apc);
@@ -169,6 +175,13 @@ public final class PlaybackActivityMonitor
public void playerAttributes(int piid, @NonNull AudioAttributes attr, int binderUid) {
final boolean change;
+ synchronized (mAllowedCapturePolicies) {
+ if (mAllowedCapturePolicies.containsKey(binderUid)
+ && attr.getAllowedCapturePolicy() < mAllowedCapturePolicies.get(binderUid)) {
+ attr = new AudioAttributes.Builder(attr)
+ .setAllowedCapturePolicy(mAllowedCapturePolicies.get(binderUid)).build();
+ }
+ }
synchronized(mPlayerLock) {
final AudioPlaybackConfiguration apc = mPlayers.get(new Integer(piid));
if (checkConfigurationCaller(piid, apc, binderUid)) {
@@ -284,6 +297,69 @@ public final class PlaybackActivityMonitor
}
}
+ /**
+ * A map of uid to capture policy.
+ */
+ private final HashMap<Integer, Integer> mAllowedCapturePolicies =
+ new HashMap<Integer, Integer>();
+
+ /**
+ * Cache allowed capture policy, which specifies whether the audio played by the app may or may
+ * not be captured by other apps or the system.
+ *
+ * @param uid the uid of requested app
+ * @param capturePolicy one of
+ * {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL},
+ * {@link AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM},
+ * {@link AudioAttributes#ALLOW_CAPTURE_BY_NONE}.
+ */
+ public void setAllowedCapturePolicy(int uid, int capturePolicy) {
+ synchronized (mAllowedCapturePolicies) {
+ if (capturePolicy == AudioAttributes.ALLOW_CAPTURE_BY_ALL) {
+ // When the capture policy is ALLOW_CAPTURE_BY_ALL, it is okay to
+ // remove it from cached capture policy as it is the default value.
+ mAllowedCapturePolicies.remove(uid);
+ return;
+ } else {
+ mAllowedCapturePolicies.put(uid, capturePolicy);
+ }
+ }
+ synchronized (mPlayerLock) {
+ for (AudioPlaybackConfiguration apc : mPlayers.values()) {
+ if (apc.getClientUid() == uid) {
+ updateAllowedCapturePolicy(apc, capturePolicy);
+ }
+ }
+ }
+ }
+
+ /**
+ * Return the capture policy for given uid.
+ * @param uid the uid to query its cached capture policy.
+ * @return cached capture policy for given uid or AudioAttributes.ALLOW_CAPTURE_BY_ALL
+ * if there is not cached capture policy.
+ */
+ public int getAllowedCapturePolicy(int uid) {
+ return mAllowedCapturePolicies.getOrDefault(uid, AudioAttributes.ALLOW_CAPTURE_BY_ALL);
+ }
+
+ /**
+ * Return all cached capture policies.
+ */
+ public HashMap<Integer, Integer> getAllAllowedCapturePolicies() {
+ return mAllowedCapturePolicies;
+ }
+
+ private void updateAllowedCapturePolicy(AudioPlaybackConfiguration apc, int capturePolicy) {
+ AudioAttributes attr = apc.getAudioAttributes();
+ if (attr.getAllowedCapturePolicy() >= capturePolicy) {
+ return;
+ }
+ apc.handleAudioAttributesEvent(
+ new AudioAttributes.Builder(apc.getAudioAttributes())
+ .setAllowedCapturePolicy(capturePolicy).build());
+ }
+
// Implementation of AudioPlaybackConfiguration.PlayerDeathMonitor
@Override
public void playerDeath(int piid) {
@@ -331,6 +407,12 @@ public final class PlaybackActivityMonitor
// log
sEventLogger.dump(pw);
}
+ synchronized (mAllowedCapturePolicies) {
+ pw.println("\n allowed capture policies:");
+ for (HashMap.Entry<Integer, Integer> entry : mAllowedCapturePolicies.entrySet()) {
+ pw.println(" uid: " + entry.getKey() + " policy: " + entry.getValue());
+ }
+ }
}
/**
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/Convert.java b/services/core/java/com/android/server/broadcastradio/hal2/Convert.java
index 9730c9a1a38..ab5bef8b80a 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/Convert.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/Convert.java
@@ -275,8 +275,18 @@ class Convert {
return hwSel;
}
- static @NonNull ProgramSelector programSelectorFromHal(
+ private static boolean isEmpty(
@NonNull android.hardware.broadcastradio.V2_0.ProgramSelector sel) {
+ if (sel.primaryId.type != 0) return false;
+ if (sel.primaryId.value != 0) return false;
+ if (sel.secondaryIds.size() != 0) return false;
+ return true;
+ }
+
+ static @Nullable ProgramSelector programSelectorFromHal(
+ @NonNull android.hardware.broadcastradio.V2_0.ProgramSelector sel) {
+ if (isEmpty(sel)) return null;
+
ProgramSelector.Identifier[] secondaryIds = sel.secondaryIds.stream().
map(Convert::programIdentifierFromHal).map(Objects::requireNonNull).
toArray(ProgramSelector.Identifier[]::new);
@@ -364,7 +374,7 @@ class Convert {
collect(Collectors.toList());
return new RadioManager.ProgramInfo(
- programSelectorFromHal(info.selector),
+ Objects.requireNonNull(programSelectorFromHal(info.selector)),
programIdentifierFromHal(info.logicallyTunedTo),
programIdentifierFromHal(info.physicallyTunedTo),
relatedContent,
@@ -402,7 +412,7 @@ class Convert {
public static @NonNull android.hardware.radio.Announcement announcementFromHal(
@NonNull Announcement hwAnnouncement) {
return new android.hardware.radio.Announcement(
- programSelectorFromHal(hwAnnouncement.selector),
+ Objects.requireNonNull(programSelectorFromHal(hwAnnouncement.selector)),
hwAnnouncement.type,
vendorInfoFromHal(hwAnnouncement.vendorInfo)
);
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 722a696c172..fc01a1e2993 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -59,6 +59,7 @@ import android.os.MessageQueue;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.provider.DeviceConfig;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.text.TextUtils;
@@ -128,6 +129,9 @@ public class InputManagerService extends IInputManager.Stub
private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml";
private static final String PORT_ASSOCIATIONS_PATH = "etc/input-port-associations.xml";
+ // Feature flag name for the deep press feature
+ private static final String DEEP_PRESS_ENABLED = "deep_press_enabled";
+
private static final int MSG_DELIVER_INPUT_DEVICES_CHANGED = 1;
private static final int MSG_SWITCH_KEYBOARD_LAYOUT = 2;
private static final int MSG_RELOAD_KEYBOARD_LAYOUTS = 3;
@@ -244,6 +248,7 @@ public class InputManagerService extends IInputManager.Stub
private static native void nativeSetCustomPointerIcon(long ptr, PointerIcon icon);
private static native void nativeSetPointerCapture(long ptr, boolean detached);
private static native boolean nativeCanDispatchToDisplay(long ptr, int deviceId, int displayId);
+ private static native void nativeSetMotionClassifierEnabled(long ptr, boolean enabled);
// Input event injection constants defined in InputDispatcher.h.
private static final int INPUT_EVENT_INJECTION_SUCCEEDED = 0;
@@ -349,6 +354,7 @@ public class InputManagerService extends IInputManager.Stub
registerPointerSpeedSettingObserver();
registerShowTouchesSettingObserver();
registerAccessibilityLargePointerSettingObserver();
+ registerLongPressTimeoutObserver();
registerVolumeKeysRotationSettingObserver();
mContext.registerReceiver(new BroadcastReceiver() {
@@ -357,6 +363,7 @@ public class InputManagerService extends IInputManager.Stub
updatePointerSpeedFromSettings();
updateShowTouchesFromSettings();
updateAccessibilityLargePointerFromSettings();
+ updateDeepPressStatusFromSettings("user switched");
updateVolumeKeysRotationFromSettings();
}
}, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler);
@@ -364,6 +371,7 @@ public class InputManagerService extends IInputManager.Stub
updatePointerSpeedFromSettings();
updateShowTouchesFromSettings();
updateAccessibilityLargePointerFromSettings();
+ updateDeepPressStatusFromSettings("just booted");
updateVolumeKeysRotationFromSettings();
}
@@ -1578,7 +1586,7 @@ public class InputManagerService extends IInputManager.Stub
setPointerSpeedUnchecked(speed);
}
- public void updatePointerSpeedFromSettings() {
+ private void updatePointerSpeedFromSettings() {
int speed = getPointerSpeedSetting();
setPointerSpeedUnchecked(speed);
}
@@ -1610,7 +1618,7 @@ public class InputManagerService extends IInputManager.Stub
return speed;
}
- public void updateShowTouchesFromSettings() {
+ private void updateShowTouchesFromSettings() {
int setting = getShowTouchesSetting(0);
nativeSetShowTouches(mPtr, setting != 0);
}
@@ -1626,7 +1634,7 @@ public class InputManagerService extends IInputManager.Stub
}, UserHandle.USER_ALL);
}
- public void updateAccessibilityLargePointerFromSettings() {
+ private void updateAccessibilityLargePointerFromSettings() {
final int accessibilityConfig = Settings.Secure.getIntForUser(
mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON,
0, UserHandle.USER_CURRENT);
@@ -1645,6 +1653,34 @@ public class InputManagerService extends IInputManager.Stub
}, UserHandle.USER_ALL);
}
+ private void updateDeepPressStatusFromSettings(String reason) {
+ // Not using ViewConfiguration.getLongPressTimeout here because it may return a stale value
+ final int timeout = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.LONG_PRESS_TIMEOUT, ViewConfiguration.DEFAULT_LONG_PRESS_TIMEOUT,
+ UserHandle.USER_CURRENT);
+ final boolean featureEnabledFlag =
+ DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_INPUT_NATIVE_BOOT,
+ DEEP_PRESS_ENABLED, true /* default */);
+ final boolean enabled =
+ featureEnabledFlag && timeout <= ViewConfiguration.DEFAULT_LONG_PRESS_TIMEOUT;
+ Log.i(TAG,
+ (enabled ? "Enabling" : "Disabling") + " motion classifier because " + reason
+ + ": feature " + (featureEnabledFlag ? "enabled" : "disabled")
+ + ", long press timeout = " + timeout);
+ nativeSetMotionClassifierEnabled(mPtr, enabled);
+ }
+
+ private void registerLongPressTimeoutObserver() {
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.LONG_PRESS_TIMEOUT), true,
+ new ContentObserver(mHandler) {
+ @Override
+ public void onChange(boolean selfChange) {
+ updateDeepPressStatusFromSettings("timeout changed");
+ }
+ }, UserHandle.USER_ALL);
+ }
+
private int getShowTouchesSetting(int defaultValue) {
int result = defaultValue;
try {
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 19b62685dfa..01d8a303719 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -388,6 +388,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private static final int MSG_SUBSCRIPTION_OVERRIDE = 16;
private static final int MSG_METERED_RESTRICTED_PACKAGES_CHANGED = 17;
private static final int MSG_SET_NETWORK_TEMPLATE_ENABLED = 18;
+ private static final int MSG_SUBSCRIPTION_PLANS_CHANGED = 19;
private static final int UID_MSG_STATE_CHANGED = 100;
private static final int UID_MSG_GONE = 101;
@@ -3067,6 +3068,34 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mContext.enforceCallingOrSelfPermission(MANAGE_SUBSCRIPTION_PLANS, TAG);
}
+ private void enforceSubscriptionPlanValidity(SubscriptionPlan[] plans) {
+ // nothing to check if no plans
+ if (plans.length == 0) {
+ return;
+ }
+
+ long applicableNetworkTypes = 0;
+ boolean allNetworks = false;
+ for (SubscriptionPlan plan : plans) {
+ if (plan.getNetworkTypes() == null) {
+ allNetworks = true;
+ } else {
+ if ((applicableNetworkTypes & plan.getNetworkTypesBitMask()) != 0) {
+ throw new IllegalArgumentException(
+ "Multiple subscription plans defined for a single network type.");
+ } else {
+ applicableNetworkTypes |= plan.getNetworkTypesBitMask();
+ }
+ }
+ }
+
+ // ensure at least one plan applies for every network type
+ if (!allNetworks) {
+ throw new IllegalArgumentException(
+ "No generic subscription plan that applies to all network types.");
+ }
+ }
+
@Override
public SubscriptionPlan[] getSubscriptionPlans(int subId, String callingPackage) {
enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage);
@@ -3231,9 +3260,26 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
@Override
public void setSubscriptionPlans(int subId, SubscriptionPlan[] plans, String callingPackage) {
enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage);
+ enforceSubscriptionPlanValidity(plans);
+ int count5GPlans = 0;
+ SubscriptionPlan plan5G = null;
for (SubscriptionPlan plan : plans) {
Preconditions.checkNotNull(plan);
+ // temporary workaround to allow 5G unmetered for March QPR
+ // TODO: remove once SubscriptionPlan.Builder#setNetworkTypes(int[]) is public in R
+ if (plan.getTitle() != null && plan.getTitle().toString().contains("NR 5G unmetered")
+ && plan.getDataLimitBytes() == SubscriptionPlan.BYTES_UNLIMITED
+ && (plan.getDataLimitBehavior() == SubscriptionPlan.LIMIT_BEHAVIOR_UNKNOWN
+ || plan.getDataLimitBehavior() == SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)) {
+ count5GPlans++;
+ plan5G = plan;
+ }
+ }
+
+ // TODO: remove once SubscriptionPlan.Builder#setNetworkTypes(int[]) is public in R
+ if (count5GPlans == 1 && plans.length > 1) {
+ plan5G.setNetworkTypes(new int[] {TelephonyManager.NETWORK_TYPE_NR});
}
final long token = Binder.clearCallingIdentity();
@@ -3259,6 +3305,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId);
mContext.sendBroadcast(intent, android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS);
+ mHandler.sendMessage(
+ mHandler.obtainMessage(MSG_SUBSCRIPTION_PLANS_CHANGED, subId, 0, plans));
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -4463,6 +4511,16 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
}
+ private void dispatchSubscriptionPlansChanged(INetworkPolicyListener listener, int subId,
+ SubscriptionPlan[] plans) {
+ if (listener != null) {
+ try {
+ listener.onSubscriptionPlansChanged(subId, plans);
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
+
private final Handler.Callback mHandlerCallback = new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
@@ -4581,6 +4639,17 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
setNetworkTemplateEnabledInner(template, enabled);
return true;
}
+ case MSG_SUBSCRIPTION_PLANS_CHANGED: {
+ final SubscriptionPlan[] plans = (SubscriptionPlan[]) msg.obj;
+ final int subId = msg.arg1;
+ final int length = mListeners.beginBroadcast();
+ for (int i = 0; i < length; i++) {
+ final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
+ dispatchSubscriptionPlansChanged(listener, subId, plans);
+ }
+ mListeners.finishBroadcast();
+ return true;
+ }
default: {
return false;
}
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index b3b0029326d..56910ddbbb7 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -434,16 +434,6 @@ public class Installer extends SystemService {
}
}
- public void markBootComplete(String instructionSet) throws InstallerException {
- assertValidInstructionSet(instructionSet);
- if (!checkBeforeRemote()) return;
- try {
- mInstalld.markBootComplete(instructionSet);
- } catch (Exception e) {
- throw InstallerException.from(e);
- }
- }
-
public void freeCache(String uuid, long targetFreeBytes, long cacheReservedBytes, int flags)
throws InstallerException {
if (!checkBeforeRemote()) return;
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index fd8db4b99be..d17365db77d 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -258,12 +258,15 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
}
// Don't hold mSessions lock when calling restoreSession, since it might trigger an APK
// atomic install which needs to query sessions, which requires lock on mSessions.
+ boolean isDeviceUpgrading = mPm.isDeviceUpgrading();
for (PackageInstallerSession session : stagedSessionsToRestore) {
- if (mPm.isDeviceUpgrading() && !session.isStagedAndInTerminalState()) {
+ if (!session.isStagedAndInTerminalState() && session.hasParentSessionId()
+ && getSession(session.getParentSessionId()) == null) {
session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED,
- "Build fingerprint has changed");
+ "An orphan staged session " + session.sessionId + " is found, "
+ + "parent " + session.getParentSessionId() + " is missing");
}
- mStagingManager.restoreSession(session);
+ mStagingManager.restoreSession(session, isDeviceUpgrading);
}
// Broadcasts are not sent while we restore sessions on boot, since no processes would be
// ready to listen to them. From now on, we greedily assume that broadcasts requests are
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index c153a452cbe..179abe958b1 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -209,6 +209,7 @@ import android.os.AsyncTask;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
+import android.os.ConditionVariable;
import android.os.Debug;
import android.os.Environment;
import android.os.FileUtils;
@@ -980,6 +981,8 @@ public class PackageManagerService extends IPackageManager.Stub
private Future<?> mPrepareAppDataFuture;
+ private final ConditionVariable mBlockDeleteOnUserRemoveForTest = new ConditionVariable(true);
+
private static class IFVerificationParams {
PackageParser.Package pkg;
boolean replacing;
@@ -2321,33 +2324,59 @@ public class PackageManagerService extends IPackageManager.Stub
return m;
}
+ private boolean isSystemUserPackagesBlacklistSupported() {
+ return Resources.getSystem().getBoolean(
+ R.bool.config_systemUserPackagesBlacklistSupported);
+ }
+
private void enableSystemUserPackages() {
- if (!UserManager.isSplitSystemUser()) {
+ if (!isSystemUserPackagesBlacklistSupported()) {
+ Log.i(TAG, "Skipping system user blacklist since "
+ + "config_systemUserPackagesBlacklistSupported is false");
return;
}
- // For system user, enable apps based on the following conditions:
- // - app is whitelisted or belong to one of these groups:
- // -- system app which has no launcher icons
- // -- system app which has INTERACT_ACROSS_USERS permission
- // -- system IME app
- // - app is not in the blacklist
- AppsQueryHelper queryHelper = new AppsQueryHelper(this);
+
+ boolean isHeadlessSystemUserMode = UserManager.isHeadlessSystemUserMode();
+ if (!isHeadlessSystemUserMode && !UserManager.isSplitSystemUser()) {
+ Log.i(TAG, "Skipping system user blacklist on 'regular' device type");
+ return;
+ }
+
+ Log.i(TAG, "blacklisting packages for system user");
+
Set<String> enableApps = new ArraySet<>();
- enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
- | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
- | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
- ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
- enableApps.addAll(wlApps);
- enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
- /* systemAppsOnly */ false, UserHandle.SYSTEM));
- ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
- enableApps.removeAll(blApps);
- Log.i(TAG, "Applications installed for system user: " + enableApps);
+ AppsQueryHelper queryHelper = new AppsQueryHelper(this);
List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
UserHandle.SYSTEM);
+
+ if (isHeadlessSystemUserMode) {
+ enableApps.addAll(allAps);
+ } else {
+ // For split system user, select apps based on the following conditions:
+ // -- system app which has no launcher icons
+ // -- system app which has INTERACT_ACROSS_USERS permission
+ // -- system IME app
+ enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
+ | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
+ | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
+ enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
+ /* systemAppsOnly */ false, UserHandle.SYSTEM));
+
+ // Apply whitelist for split system user
+ ArraySet<String> whitelistedSystemUserApps = SystemConfig.getInstance()
+ .getSystemUserWhitelistedApps();
+ enableApps.addAll(whitelistedSystemUserApps);
+ Log.i(TAG, "Whitelisted packages: " + whitelistedSystemUserApps);
+ }
+ // Apply blacklist for split system user/headless system user
+ ArraySet<String> blacklistedSystemUserApps = SystemConfig.getInstance()
+ .getSystemUserBlacklistedApps();
+ enableApps.removeAll(blacklistedSystemUserApps);
+ Log.i(TAG, "Blacklisted packages: " + blacklistedSystemUserApps);
+
final int allAppsSize = allAps.size();
synchronized (mPackages) {
- for (int i = 0; i < allAppsSize; i++) {
+ for (int i = 0; i < allAppsSize; i++) {
String pName = allAps.get(i);
PackageSetting pkgSetting = mSettings.mPackages.get(pName);
// Should not happen, but we shouldn't be failing if it does
@@ -18209,7 +18238,9 @@ public class PackageManagerService extends IPackageManager.Stub
final int verificationId = mIntentFilterVerificationToken++;
for (PackageParser.Activity a : pkg.activities) {
for (ActivityIntentInfo filter : a.intents) {
- if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
+ // Run verification against hosts mentioned in any web-nav intent filter,
+ // even if the filter matches non-web schemes as well
+ if (filter.handlesWebUris(false) && needsNetworkVerificationLPr(filter)) {
if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
"Verification needed for IntentFilter:" + filter.toString());
mIntentFilterVerifier.addOneIntentFilterVerification(
@@ -22365,6 +22396,18 @@ public class PackageManagerService extends IPackageManager.Stub
if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
+
+ boolean systemUserPackagesBlacklistSupported =
+ isSystemUserPackagesBlacklistSupported();
+ pw.println("isSystemUserPackagesBlacklistSupported: "
+ + systemUserPackagesBlacklistSupported);
+ if (systemUserPackagesBlacklistSupported) {
+ SystemConfig sysconfig = SystemConfig.getInstance();
+ dumpPackagesList(pw, " ", "whitelist",
+ sysconfig.getSystemUserWhitelistedApps());
+ dumpPackagesList(pw, " ", "blacklist",
+ sysconfig.getSystemUserBlacklistedApps());
+ }
}
if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
@@ -22474,6 +22517,21 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
+ private void dumpPackagesList(PrintWriter pw, String prefix, String name,
+ ArraySet<String> list) {
+ pw.print(prefix); pw.print(name); pw.print(": ");
+ int size = list.size();
+ if (size == 0) {
+ pw.println("empty");
+ return;
+ }
+ pw.print(size); pw.println(" packages");
+ String prefix2 = prefix + " ";
+ for (int i = 0; i < size; i++) {
+ pw.print(prefix2); pw.println(list.valueAt(i));
+ }
+ }
+
//TODO: b/111402650
private void disableSkuSpecificApps() {
String apkList[] = mContext.getResources().getStringArray(
@@ -23816,8 +23874,13 @@ public class PackageManagerService extends IPackageManager.Stub
Slog.i(TAG, " Removing package " + packageName);
}
//end run
- mHandler.post(() -> deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
- userHandle, 0));
+ mHandler.post(() -> {
+ if (!mBlockDeleteOnUserRemoveForTest.block(30000 /* 30 seconds*/)) {
+ mBlockDeleteOnUserRemoveForTest.open();
+ }
+ deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
+ userHandle, 0);
+ });
}
}
}
@@ -25179,6 +25242,16 @@ public class PackageManagerService extends IPackageManager.Stub
Slog.wtf(TAG, e);
}
}
+
+ @Override
+ public void notifyingOnNextUserRemovalForTest() {
+ mBlockDeleteOnUserRemoveForTest.close();
+ }
+
+ @Override
+ public void userRemovedForTest() {
+ mBlockDeleteOnUserRemoveForTest.open();
+ }
}
@GuardedBy("mPackages")
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 9c87c748f86..895d2c5d00b 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -40,6 +40,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
+import android.os.ParcelableException;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -403,29 +404,28 @@ public class StagingManager {
} else {
params.installFlags |= PackageManager.INSTALL_DISABLE_VERIFICATION;
}
- int apkSessionId = mPi.createSession(
- params, originalSession.getInstallerPackageName(),
- 0 /* UserHandle.SYSTEM */);
- PackageInstallerSession apkSession = mPi.getSession(apkSessionId);
-
try {
+ int apkSessionId = mPi.createSession(
+ params, originalSession.getInstallerPackageName(),
+ 0 /* UserHandle.SYSTEM */);
+ PackageInstallerSession apkSession = mPi.getSession(apkSessionId);
apkSession.open();
for (String apkFilePath : apkFilePaths) {
File apkFile = new File(apkFilePath);
ParcelFileDescriptor pfd = ParcelFileDescriptor.open(apkFile,
ParcelFileDescriptor.MODE_READ_ONLY);
- long sizeBytes = pfd.getStatSize();
+ long sizeBytes = (pfd == null) ? -1 : pfd.getStatSize();
if (sizeBytes < 0) {
Slog.e(TAG, "Unable to get size of: " + apkFilePath);
return null;
}
apkSession.write(apkFile.getName(), 0, sizeBytes, pfd);
}
- } catch (IOException e) {
+ return apkSession;
+ } catch (IOException | ParcelableException e) {
Slog.e(TAG, "Failure to install APK staged session " + originalSession.sessionId, e);
return null;
}
- return apkSession;
}
private boolean commitApkSession(@NonNull PackageInstallerSession apkSession,
@@ -619,7 +619,7 @@ public class StagingManager {
return false;
}
- void restoreSession(@NonNull PackageInstallerSession session) {
+ void restoreSession(@NonNull PackageInstallerSession session, boolean isDeviceUpgrading) {
PackageInstallerSession sessionToResume = session;
synchronized (mStagedSessions) {
mStagedSessions.append(session.sessionId, session);
@@ -636,6 +636,13 @@ public class StagingManager {
}
}
}
+ // The preconditions used during pre-reboot verification might have changed when device
+ // is upgrading. Updated staged sessions to activation failed before we resume the session.
+ if (isDeviceUpgrading && !sessionToResume.isStagedAndInTerminalState()) {
+ sessionToResume.setStagedSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED,
+ "Build fingerprint has changed");
+ return;
+ }
checkStateAndResume(sessionToResume);
}
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 6fcb4b6e47f..82bc41fcdcd 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -16,6 +16,7 @@
package com.android.server.pm;
+import static android.Manifest.permission.INJECT_EVENTS;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
@@ -39,6 +40,7 @@ import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.PackageManagerInternal;
import android.content.pm.ShortcutServiceInternal;
import android.content.pm.UserInfo;
import android.content.pm.UserInfo.UserInfoFlag;
@@ -127,6 +129,7 @@ import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
+import java.util.concurrent.atomic.AtomicBoolean;
/**
* Service for {@link UserManager}.
@@ -250,6 +253,7 @@ public class UserManagerService extends IUserManager.Stub {
private final File mUserListFile;
private static final IBinder mUserRestriconToken = new Binder();
+ private final AtomicBoolean mNotifyPackageManagerOnUserRemoval = new AtomicBoolean(false);
/**
* Internal non-parcelable wrapper for UserInfo that is not exposed to other system apps.
@@ -3352,6 +3356,11 @@ public class UserManagerService extends IUserManager.Stub {
mRemovingUserIds.delete(userHandle);
}
}
+ if (mNotifyPackageManagerOnUserRemoval.getAndSet(false)) {
+ final PackageManagerInternal pmInternal =
+ LocalServices.getService(PackageManagerInternal.class);
+ pmInternal.userRemovedForTest();
+ }
}
private void sendProfileRemovedBroadcast(int parentUserId, int removedUserId) {
@@ -4493,4 +4502,20 @@ public class UserManagerService extends IUserManager.Stub {
+ " does not match the calling uid " + callingUid);
}
}
+
+ @Override
+ public void notifyOnNextUserRemoveForTest() {
+ mContext.enforceCallingOrSelfPermission(INJECT_EVENTS, "notifyOnNextUserRemoveForTest");
+ final ActivityManagerInternal amInternal =
+ LocalServices.getService(ActivityManagerInternal.class);
+ if (!amInternal.isActiveInstrumentation(Binder.getCallingUid())) {
+ return;
+ }
+
+ this.mNotifyPackageManagerOnUserRemoval.set(true);
+
+ final PackageManagerInternal pmInternal =
+ LocalServices.getService(PackageManagerInternal.class);
+ pmInternal.notifyingOnNextUserRemovalForTest();
+ }
}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index cff13229c93..6066cdf7fec 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -446,6 +446,8 @@ public final class PowerManagerService extends SystemService
// True if doze should not be started until after the screen off transition.
private boolean mDozeAfterScreenOff;
+ private boolean mEnableAutoSuspendConfig;
+
// The minimum screen off timeout, in milliseconds.
private long mMinimumScreenOffTimeoutConfig;
@@ -1023,6 +1025,8 @@ public final class PowerManagerService extends SystemService
com.android.internal.R.bool.config_powerDecoupleAutoSuspendModeFromDisplay);
mDecoupleHalInteractiveModeFromDisplayConfig = resources.getBoolean(
com.android.internal.R.bool.config_powerDecoupleInteractiveModeFromDisplay);
+ mEnableAutoSuspendConfig = resources.getBoolean(
+ com.android.internal.R.bool.config_enableAutoSuspend);
mWakeUpWhenPluggedOrUnpluggedConfig = resources.getBoolean(
com.android.internal.R.bool.config_unplugTurnsOnScreen);
mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig = resources.getBoolean(
@@ -2770,7 +2774,8 @@ public final class PowerManagerService extends SystemService
if (!mDecoupleHalInteractiveModeFromDisplayConfig) {
setHalInteractiveModeLocked(false);
}
- if (!mDecoupleHalAutoSuspendModeFromDisplayConfig) {
+ if (mEnableAutoSuspendConfig
+ && !mDecoupleHalAutoSuspendModeFromDisplayConfig) {
setHalAutoSuspendModeLocked(true);
}
} else {
@@ -2815,7 +2820,7 @@ public final class PowerManagerService extends SystemService
private void updateSuspendBlockerLocked() {
final boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0);
final boolean needDisplaySuspendBlocker = needDisplaySuspendBlockerLocked();
- final boolean autoSuspend = !needDisplaySuspendBlocker;
+ final boolean autoSuspend = mEnableAutoSuspendConfig && !needDisplaySuspendBlocker;
final boolean interactive = mDisplayPowerRequest.isBrightOrDim();
// Disable auto-suspend if needed.
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index 08c1bb53621..1f75294de8e 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -58,6 +58,7 @@ import android.util.SparseLongArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.LocalServices;
import com.android.server.Watchdog;
@@ -1479,6 +1480,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
+
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
synchronized (mLock) {
for (RollbackData data : mRollbacks) {
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 5f5cd3c4611..2394bafc09d 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -1437,7 +1437,8 @@ public class TrustManagerService extends SystemService {
if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
refreshAgentList(getSendingUserId());
updateDevicePolicyFeatures();
- } else if (Intent.ACTION_USER_ADDED.equals(action)) {
+ } else if (Intent.ACTION_USER_ADDED.equals(action) || Intent.ACTION_USER_STARTED.equals(
+ action)) {
int userId = getUserId(intent);
if (userId > 0) {
maybeEnableFactoryTrustAgents(mLockPatternUtils, userId);
@@ -1478,6 +1479,7 @@ public class TrustManagerService extends SystemService {
filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
filter.addAction(Intent.ACTION_USER_ADDED);
filter.addAction(Intent.ACTION_USER_REMOVED);
+ filter.addAction(Intent.ACTION_USER_STARTED);
context.registerReceiverAsUser(this,
UserHandle.ALL,
filter,
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 4e136af0fdc..0e2f0ce991c 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -1180,6 +1180,10 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
};
+ private Runnable mTryToRebindRunnable = () -> {
+ tryToRebind();
+ };
+
WallpaperConnection(WallpaperInfo info, WallpaperData wallpaper, int clientUid) {
mInfo = info;
mWallpaper = wallpaper;
@@ -1286,7 +1290,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
saveSettingsLocked(mWallpaper.userId);
}
FgThread.getHandler().removeCallbacks(mResetRunnable);
- mContext.getMainThreadHandler().removeCallbacks(this::tryToRebind);
+ mContext.getMainThreadHandler().removeCallbacks(mTryToRebindRunnable);
}
}
}
@@ -1344,7 +1348,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
< WALLPAPER_RECONNECT_TIMEOUT_MS) {
// Bind fail without timeout, schedule rebind
Slog.w(TAG, "Rebind fail! Try again later");
- mContext.getMainThreadHandler().postDelayed(this::tryToRebind, 1000);
+ mContext.getMainThreadHandler().postDelayed(mTryToRebindRunnable, 1000);
} else {
// Timeout
Slog.w(TAG, "Reverting to built-in wallpaper!");
diff --git a/services/core/java/com/android/server/wm/BarController.java b/services/core/java/com/android/server/wm/BarController.java
index 90bb494232c..338df39a162 100644
--- a/services/core/java/com/android/server/wm/BarController.java
+++ b/services/core/java/com/android/server/wm/BarController.java
@@ -164,7 +164,8 @@ public class BarController {
}
boolean isTransparentAllowed(WindowState win) {
- return win == null || !win.isLetterboxedOverlappingWith(mContentFrame);
+ return win == null || mState == StatusBarManager.WINDOW_STATE_HIDING
+ || !win.isLetterboxedOverlappingWith(mContentFrame);
}
boolean setBarShowingLw(final boolean show) {
diff --git a/services/core/java/com/android/server/wm/PolicyControl.java b/services/core/java/com/android/server/wm/PolicyControl.java
index 4c8ce9ebb72..87c34908d04 100644
--- a/services/core/java/com/android/server/wm/PolicyControl.java
+++ b/services/core/java/com/android/server/wm/PolicyControl.java
@@ -67,15 +67,19 @@ class PolicyControl {
: (attrs.systemUiVisibility | attrs.subtreeSystemUiVisibility);
if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(attrs)) {
vis |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
- | View.SYSTEM_UI_FLAG_FULLSCREEN
- | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+ | View.SYSTEM_UI_FLAG_FULLSCREEN;
+ if (attrs.isFullscreen()) {
+ vis |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+ }
vis &= ~(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.STATUS_BAR_TRANSLUCENT);
}
if (sImmersiveNavigationFilter != null && sImmersiveNavigationFilter.matches(attrs)) {
vis |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
- | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+ if (attrs.isFullscreen()) {
+ vis |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
+ }
vis &= ~(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.NAVIGATION_BAR_TRANSLUCENT);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 2e0f263b593..7cf245e0bd0 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -5710,6 +5710,12 @@ public class WindowManagerService extends IWindowManager.Stub
@Override
public void setForceShowSystemBars(boolean show) {
+ boolean isAutomotive = mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_AUTOMOTIVE);
+ if (!isAutomotive) {
+ throw new UnsupportedOperationException("Force showing system bars is only supported"
+ + "for Automotive use cases.");
+ }
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Caller does not hold permission "