summaryrefslogtreecommitdiffstats
path: root/services/core/java
diff options
context:
space:
mode:
authorKevin F. Haggerty <haggertk@lineageos.org>2020-06-06 10:12:07 -0600
committerKevin F. Haggerty <haggertk@lineageos.org>2020-06-06 10:12:07 -0600
commitf67897bc05520f743974fc397aa96e4049a057b3 (patch)
tree1f6e15e69b9c76b427f2c92555f0047cd527445f /services/core/java
parent63fc6d8c0acb37835336862674206cf001753667 (diff)
parent81ee10241fc143ed576734268708c9943217ff8b (diff)
downloadframeworks_base-f67897bc05520f743974fc397aa96e4049a057b3.tar.gz
frameworks_base-f67897bc05520f743974fc397aa96e4049a057b3.tar.bz2
frameworks_base-f67897bc05520f743974fc397aa96e4049a057b3.zip
Merge tag 'android-10.0.0_r37' into staging/lineage-17.1_merge-android-10.0.0_r37
Android 10.0.0 Release 37 (QQ3A.200605.001) * tag 'android-10.0.0_r37': DO NOT MERGE Fix ImageWallpaper memory regression Import translations. DO NOT MERGE Import translations. DO NOT MERGE Don't crash if NSSL gets incomplete gesture Import translations. DO NOT MERGE Import translations. DO NOT MERGE Import translations. DO NOT MERGE Import translations. DO NOT MERGE Import translations. DO NOT MERGE Import translations. DO NOT MERGE Import translations. DO NOT MERGE Fix order of uid/pid in LocationAccessPolicy RESTRICT AUTOMERGE RESTRICT AUTOMERGE Verify all possible hosts that match web nav Verify all possible hosts that match web nav Verify all possible hosts that match web nav Verify all possible hosts that match web nav Verify all possible hosts that match web nav RESTRICT AUTOMERGE RESTRICT AUTOMERGE Revert "Revoke 'always' web handler status when not autoverifying" Revert "Revoke 'always' web handler status when not autoverifying" Revert "Revoke 'always' web handler status when not autoverifying" Fix Battery optimization takes long time Import translations. DO NOT MERGE Check DUMP permission before dumping in RollbackManagerService. Check permissions in INetworkManagementService#setIPv6AddrGenMode Require a more specific intent Fix command injection on screencap Failed UiModeManagerServiceTest Revert "Revoke 'always' web handler status when not autoverifying" Import translations. DO NOT MERGE Force update uid state when pending uid state is applied Notify all packages is uid-mode is changed Import translations. DO NOT MERGE Disable deep press when long press is long Import translations. DO NOT MERGE Revert "Revoke 'always' web handler status when not autoverifying" DO NOT MERGE Institute limit on PhoneStateListener Fix broken link DO NOT MERGE use left/right insets instead of cutout DO NOT MERGE: Add blacklist for camera protection 5G Q backport Import translations. DO NOT MERGE Import translations. DO NOT MERGE Import translations. DO NOT MERGE Import translations. DO NOT MERGE Import translations. DO NOT MERGE Import translations. DO NOT MERGE Create different KeyId for saved and suggestion network String change for ConnectionFailureNotifier Do not allow division by 0 Move filterMobileSubscriptionInSameGroup into KeyguardUpdateMonitor. DO NOT MERGE: Use status_bar_padding_top RESTRICT AUTOMERGE Prevent accessing companion records from arbitrary uids RESTRICT AUTOMERGE Prevent accessing companion records from arbitrary uids Import translations. DO NOT MERGE RESTRICT AUTOMERGE Prevent accessing companion records from arbitrary uids Camera: Clarify CAMERA_OPEN_CLOSE_LISTENER description Import translations. DO NOT MERGE DO NOT MERGE Optimizing ScreenDecorations performance [RESTRICT AUTOMERGE] Allow bar to be transparent during animating. Fix race condition while WallpaperMS rebinding service. Either reuse sensor values or don't dim down at all RESTRICT AUTOMERGE Use consistent calling uid and package in navigateUpTo DO NOT MERGE: Allow corner UI to decouple from rounded_corner_radius DO NOT MERGE - Kill apps outright for API contract violations Properly rotate cutout protection rect [DO NOT MERGE] Allows the Assistant to request suppression of fling Camera: Add new hidden API for camera open/close callback Allow two finger swipes down. RESTRICT AUTOMERGE Create separated tasks for different apps from startActivities DO NOT MERGE Add null check for status bar transitions DO NOT MERGE Ignore insets on status_bar_container RESTRICT AUTOMERGE Block TYPE_PRESENTATION windows on default display RESTRICT AUTOMERGE Block TYPE_PRESENTATION windows on default display Fix bluetooth can't turn off during network reset (2/3) DO NOT MERGE: Resolve mBehindAlpha with mCurrentBehindAlpha Do not accept NaN as scrim values Reset protection path on rotation Revert "[automerger skipped] Merge "DO NOT MERGE - Kill apps out..." Animate cuttout protection DO NOT MERGE Set the sensor threshold only if sensor exists RESTRICT AUTOMERGE Block TYPE_PRESENTATION windows on default display RESTRICT AUTOMERGE Block TYPE_PRESENTATION windows on default display RESTRICT AUTOMERGE Use consistent calling uid and package in navigateUpTo RESTRICT AUTOMERGE Use consistent calling uid and package in navigateUpTo Frameworks/base: Support dex2oat cpu-set system property Create different KeyId for saved and suggestion network Add EAP methods in wifi.proto Remove Dependency.staticOnConfigurationChanged RESTRICT AUTOMERGE Use consistent calling uid and package in navigateUpTo Set/get allowed capture policy via AudioService. RESTRICT AUTOMERGE Use consistent calling uid and package in navigateUpTo DO NOT MERGE: Revert Move startInput for WINDOW_FOCUS_GAIN to background thread DO NOT MERGE: Revert: Freeup lock when IME is set inactive and unbound Updated wakeLock permission descriptions. CP ag/9571636 from master to qt-qpr1-dev Bug: 143299398 Fix carrier config string typo. DO NOT MERGE Add toast message when bluetooth connects to voice recognition. AudioService - remove sendBroadcastToAll() from setMasterMuteInternalNoCallerCheck() Allow settingIgnored for DBH request if inEmergency Use status_bar_padding_top in QS system icons Resolve trust agents on USER_STARTED in addition to USER_ADDED. DO NOT MERGE: Add SystemUI support for front-facing camera protection RESTRICT AUTOMERGE Create separated tasks for different apps from startActivities RESTRICT AUTOMERGE Create separated tasks for different apps from startActivities DO NOT MERGE Fix Autohide functionality DO NOT MERGE Respect rounded.xml size in ScreenDecorations DO NOT MERGE Set background drawable on status_bar_container Add DEBUG flag for rounded corner and display cutout path RESTRICT AUTOMERGE Use Alternative Prox Sensor for Falsing DO NOT MERGE Have volume UI dismiss on home button press. RESTRICT AUTOMERGE Update keyguard locked state from TrustManagerService Back porting Dark theme bug fixes from R DO NOT MERGE Hold onto NotificationListener when reconnecting notifications UI. Add carrier config to skip validation if recently validate. DO NOT MERGE Dismiss system dialog DO NOT MERGE Reflect the selection state that reflects the current task stack upon restarting the Navigation Bar. Add cutout support in QSDetail Add vertical type check to prevent non-Automotive Androids from force displaying system bars. Fix potential NPE while releasing worker thread of ImageWallpaper DO NOT MERGE Adjust NotificationView bottom margin based on whether Keyboard is shown. Add null check for voiceInteractorComponentName. CountryDetector: Enable detector class override for automotive DO NOT MERGE - Added system user packages blacklist / whitelist to dump() DO NOT MERGE - Add flag to turn on/off the headless user specific blacklist/whitelist DO NOT MERGE - Enable blacklist for headless system user Fix flaky sysui crash in devicehealthchecks test. Disabled some DEBUG constants. Fix security issue in DynamicRefTable::load. Use the main thread to update alignment indication DO NOT MERGE - Kill apps outright for API contract violations Remove hidden shared account methods from AccountManager.java Add null check for handler on Clock view Make switching dialog full screen and change "Loading" text color. DO NOT MERGE - Kill apps outright for API contract violations Parcel only the canonical Uri.Part representation, not both. DO NOT MERGE - Use TimingsTraceLog on SystemServiceManager and VoiceInteractionManagerService. Call getPackageInfo() with cleared calling identity in ensureSystemPackageName(). Add SafetyNet logging for package names read from config. DO NOT MERGE - Kill apps outright for API contract violations Force update uid state when pending uid state is applied Notify all packages is uid-mode is changed DO NOT MERGE Ensure package names read from config are system packages. DO NOT MERGE Ensure package names read from config are system packages. Call getPackageInfo() with cleared calling identity in ensureSystemPackageName(). Re-activate backup service after cleaning a profile owner [DO NOT MERGE] Fix AoD front scrim being opaque at DOZE_PULSING resolve merge conflicts of 01f94b7cc053049a472481f457593d895ad9eca0 to qt-qpr1-dev Set a shorter timeout for logging a warn on slow IUserSwitchObservers. Added log statements to some user-switching tasks. Change coverage dump to specify the output file instead of directory. Add JVMTI agent to dump/reset JaCoCo coverage information Don't crash system process on empty onTuneFailed Update redaction upon profile changes Fixed NPE in package installer session. [framework] Remove boot complete marker DO NOT MERGE Unregister notification listener before creating a new one to avoid duplicate Heads Up notifications. Separate icon sizes for sharesheet and resolver list. DO NOT MERGE Ensure package names read from config are system packages. RESTRICT AUTOMERGE Update keyguard locked state from TrustManagerService Fix serialization issue of ExternalVibration GraphicsEnv: refactor to unify the debuggable logic DO NOT MERGE Only set the LAYOUT flags if the window is fullscreen Only suspend package from system or shell Adding option in global setting to control the display message during user switch Update mOnDissmissRunnable when Notification gets updated. Ensure adb key store is instantiated before revoking grants Do not destroy CustomTile when in QSCustomizer Handle ParcelableException instead of crashing system server Import translations. DO NOT MERGE Import translations. DO NOT MERGE Fix potential double destroy of AssetManager Change permissionLevel of ACCESS_SHORTCUTS and UNLIMITED_SHORTCUTS_API_CALLS Fix potential double destroy of AssetManager DO NOT MERGE Fix AppOpsServiceTest DO NOT MERGE: Use a copy of bt device profile list when updating Fix IsolatedUidAllocator for non-primary users. DO NOT MERGE Don't throw exception in AppOpsManager.checkOp DO NOT MERGE Remove unnecessary internal APIs. Prevent sending early termination of appop use DO NOT MERGE SetMode: Don't call into PM with AppOps lock held Import translations. DO NOT MERGE Import translations. DO NOT MERGE Import translations. DO NOT MERGE Fix ModuleInfoProviderTest by passing correct flag Refactor CountryDetectorService Revoke 'always' web handler status when not autoverifying Revoke 'always' web handler status when not autoverifying Supplementary Services(SS) gray out when airplane mode on in Call Settings menu. Revoke 'always' web handler status when not autoverifying Revoke 'always' web handler status when not autoverifying Revoke 'always' web handler status when not autoverifying [DO NOT MERGE] Add a configuration to allow disabling auto-suspend DO NOT MERGE: Adds artificial package handler latency Concurrent collections for Bluetooth callbacks. FocusRequester: fix NPE Conflicts: core/res/res/values/config.xml core/res/res/values/symbols.xml packages/SystemUI/res/layout/system_icons.xml packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java services/core/java/com/android/server/BluetoothManagerService.java services/core/java/com/android/server/NetworkManagementService.java services/core/java/com/android/server/input/InputManagerService.java services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java Change-Id: I9bcfb8567a49063d8427986f7fc2fba8e19b241e
Diffstat (limited to 'services/core/java')
-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 "