Merge "Added WC#showToCurrentUser (83/n)"
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index fe4f860..ffb97c0 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -517,7 +517,9 @@
@Override
public void onCreateInlineSuggestionsRequest(ComponentName componentName,
AutofillId autofillId, IInlineSuggestionsRequestCallback cb) {
- Log.d(TAG, "InputMethodService received onCreateInlineSuggestionsRequest()");
+ if (DEBUG) {
+ Log.d(TAG, "InputMethodService received onCreateInlineSuggestionsRequest()");
+ }
handleOnCreateInlineSuggestionsRequest(componentName, autofillId, cb);
}
@@ -755,7 +757,12 @@
private void handleOnCreateInlineSuggestionsRequest(@NonNull ComponentName componentName,
@NonNull AutofillId autofillId, @NonNull IInlineSuggestionsRequestCallback callback) {
if (!mInputStarted) {
- Log.w(TAG, "onStartInput() not called yet");
+ try {
+ Log.w(TAG, "onStartInput() not called yet");
+ callback.onInlineSuggestionsUnsupported();
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to call onInlineSuggestionsUnsupported.", e);
+ }
return;
}
@@ -768,8 +775,12 @@
private void handleOnInlineSuggestionsResponse(@NonNull ComponentName componentName,
@NonNull AutofillId autofillId, @NonNull InlineSuggestionsResponse response) {
if (!mInlineSuggestionsRequestInfo.validate(componentName)) {
- Log.d(TAG, "Response component=" + componentName + " differs from request component="
- + mInlineSuggestionsRequestInfo.mComponentName + ", ignoring response");
+ if (DEBUG) {
+ Log.d(TAG,
+ "Response component=" + componentName + " differs from request component="
+ + mInlineSuggestionsRequestInfo.mComponentName
+ + ", ignoring response");
+ }
return;
}
onInlineSuggestionsResponse(response);
@@ -841,7 +852,7 @@
*/
public boolean validate(ComponentName componentName) {
final boolean result = componentName.equals(mComponentName);
- if (!result) {
+ if (DEBUG && !result) {
Log.d(TAG, "Cached request info ComponentName=" + mComponentName
+ " differs from received ComponentName=" + componentName);
}
diff --git a/core/java/android/os/incremental/IncrementalFileStorages.java b/core/java/android/os/incremental/IncrementalFileStorages.java
index 2138d553..63335a0 100644
--- a/core/java/android/os/incremental/IncrementalFileStorages.java
+++ b/core/java/android/os/incremental/IncrementalFileStorages.java
@@ -38,6 +38,7 @@
import android.content.pm.DataLoaderParams;
import android.content.pm.InstallationFile;
import android.os.IVold;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.ArraySet;
@@ -208,7 +209,8 @@
if (!hasObb()) {
return;
}
- final String mainObbDir = String.format("/storage/emulated/0/Android/obb/%s", mPackageName);
+ final String obbDir = "/storage/emulated/0/Android/obb";
+ final String packageObbDir = String.format("%s/%s", obbDir, mPackageName);
final String packageObbDirRoot =
String.format("/mnt/runtime/%s/emulated/0/Android/obb/", mPackageName);
final String[] obbDirs = {
@@ -217,12 +219,12 @@
packageObbDirRoot + "full",
packageObbDirRoot + "default",
String.format("/data/media/0/Android/obb/%s", mPackageName),
- mainObbDir,
+ packageObbDir,
};
try {
- Slog.i(TAG, "Creating obb directory '" + mainObbDir + "'");
+ Slog.i(TAG, "Creating obb directory '" + packageObbDir + "'");
final IVold vold = IVold.Stub.asInterface(ServiceManager.getServiceOrThrow("vold"));
- vold.mkdirs(mainObbDir);
+ vold.setupAppDir(packageObbDir, obbDir, Process.ROOT_UID);
for (String d : obbDirs) {
mObbStorage.bindPermanent(d);
}
@@ -230,7 +232,7 @@
Slog.e(TAG, "vold service is not found.");
cleanUp();
} catch (IOException | RemoteException ex) {
- Slog.e(TAG, "Failed to create obb dir at: " + mainObbDir, ex);
+ Slog.e(TAG, "Failed to create obb dir at: " + packageObbDir, ex);
cleanUp();
}
}
diff --git a/core/java/android/view/inputmethod/InputMethod.java b/core/java/android/view/inputmethod/InputMethod.java
index 1e5a3b0..cf494ae 100644
--- a/core/java/android/view/inputmethod/InputMethod.java
+++ b/core/java/android/view/inputmethod/InputMethod.java
@@ -63,6 +63,8 @@
* which is what clients use to communicate with the input method.
*/
public interface InputMethod {
+ /** @hide **/
+ public static final String TAG = "InputMethod";
/**
* This is the interface name that a service implementing an input
* method should say that it supports -- that is, this is the action it
@@ -111,6 +113,10 @@
/**
* Called to notify the IME that Autofill Frameworks requested an inline suggestions request.
*
+ * @param componentName {@link ComponentName} of current app/activity.
+ * @param autofillId {@link AutofillId} of currently focused field.
+ * @param cb {@link IInlineSuggestionsRequestCallback} used to pass back the request object.
+ *
* @hide
*/
default void onCreateInlineSuggestionsRequest(ComponentName componentName,
@@ -118,7 +124,7 @@
try {
cb.onInlineSuggestionsUnsupported();
} catch (RemoteException e) {
- Log.w("InputMethod", "RemoteException calling onInlineSuggestionsUnsupported: " + e);
+ Log.w(TAG, "Failed to call onInlineSuggestionsUnsupported.", e);
}
}
diff --git a/core/java/android/view/textclassifier/logging/SmartSelectionEventTracker.java b/core/java/android/view/textclassifier/logging/SmartSelectionEventTracker.java
index 7dbcbf9..28cb80d 100644
--- a/core/java/android/view/textclassifier/logging/SmartSelectionEventTracker.java
+++ b/core/java/android/view/textclassifier/logging/SmartSelectionEventTracker.java
@@ -22,6 +22,7 @@
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.metrics.LogMaker;
+import android.os.Build;
import android.util.Log;
import android.view.textclassifier.TextClassification;
import android.view.textclassifier.TextClassifier;
@@ -101,7 +102,8 @@
private boolean mSmartSelectionTriggered;
private String mModelName;
- @UnsupportedAppUsage(trackingBug = 136637107)
+ @UnsupportedAppUsage(trackingBug = 136637107, maxTargetSdk = Build.VERSION_CODES.Q,
+ publicAlternatives = "See {@link android.view.textclassifier.TextClassifier}.")
public SmartSelectionEventTracker(@NonNull Context context, @WidgetType int widgetType) {
mWidgetType = widgetType;
mWidgetVersion = null;
@@ -120,7 +122,8 @@
*
* @param event the selection event
*/
- @UnsupportedAppUsage(trackingBug = 136637107)
+ @UnsupportedAppUsage(trackingBug = 136637107, maxTargetSdk = Build.VERSION_CODES.Q,
+ publicAlternatives = "See {@link android.view.textclassifier.TextClassifier}.")
public void logEvent(@NonNull SelectionEvent event) {
Objects.requireNonNull(event);
@@ -444,7 +447,8 @@
*
* @param start the word index of the selected word
*/
- @UnsupportedAppUsage(trackingBug = 136637107)
+ @UnsupportedAppUsage(trackingBug = 136637107, maxTargetSdk = Build.VERSION_CODES.Q,
+ publicAlternatives = "See {@link android.view.textclassifier.TextClassifier}.")
public static SelectionEvent selectionStarted(int start) {
return new SelectionEvent(
start, start + 1, EventType.SELECTION_STARTED,
@@ -458,7 +462,8 @@
* @param start the start word (inclusive) index of the selection
* @param end the end word (exclusive) index of the selection
*/
- @UnsupportedAppUsage(trackingBug = 136637107)
+ @UnsupportedAppUsage(trackingBug = 136637107, maxTargetSdk = Build.VERSION_CODES.Q,
+ publicAlternatives = "See {@link android.view.textclassifier.TextClassifier}.")
public static SelectionEvent selectionModified(int start, int end) {
return new SelectionEvent(
start, end, EventType.SELECTION_MODIFIED,
@@ -474,7 +479,8 @@
* @param classification the TextClassification object returned by the TextClassifier that
* classified the selected text
*/
- @UnsupportedAppUsage(trackingBug = 136637107)
+ @UnsupportedAppUsage(trackingBug = 136637107, maxTargetSdk = Build.VERSION_CODES.Q,
+ publicAlternatives = "See {@link android.view.textclassifier.TextClassifier}.")
public static SelectionEvent selectionModified(
int start, int end, @NonNull TextClassification classification) {
final String entityType = classification.getEntityCount() > 0
@@ -494,7 +500,8 @@
* @param selection the TextSelection object returned by the TextClassifier for the
* specified selection
*/
- @UnsupportedAppUsage(trackingBug = 136637107)
+ @UnsupportedAppUsage(trackingBug = 136637107, maxTargetSdk = Build.VERSION_CODES.Q,
+ publicAlternatives = "See {@link android.view.textclassifier.TextClassifier}.")
public static SelectionEvent selectionModified(
int start, int end, @NonNull TextSelection selection) {
final boolean smartSelection = getSourceClassifier(selection.getId())
@@ -523,7 +530,8 @@
* @param end the end word (exclusive) index of the selection
* @param actionType the action that was performed on the selection
*/
- @UnsupportedAppUsage(trackingBug = 136637107)
+ @UnsupportedAppUsage(trackingBug = 136637107, maxTargetSdk = Build.VERSION_CODES.Q,
+ publicAlternatives = "See {@link android.view.textclassifier.TextClassifier}.")
public static SelectionEvent selectionAction(
int start, int end, @ActionType int actionType) {
return new SelectionEvent(
@@ -541,7 +549,8 @@
* @param classification the TextClassification object returned by the TextClassifier that
* classified the selected text
*/
- @UnsupportedAppUsage(trackingBug = 136637107)
+ @UnsupportedAppUsage(trackingBug = 136637107, maxTargetSdk = Build.VERSION_CODES.Q,
+ publicAlternatives = "See {@link android.view.textclassifier.TextClassifier}.")
public static SelectionEvent selectionAction(
int start, int end, @ActionType int actionType,
@NonNull TextClassification classification) {
diff --git a/packages/SettingsLib/res/values/arrays.xml b/packages/SettingsLib/res/values/arrays.xml
index 9b4a6d6..7b589370 100644
--- a/packages/SettingsLib/res/values/arrays.xml
+++ b/packages/SettingsLib/res/values/arrays.xml
@@ -132,6 +132,20 @@
<item>avrcp16</item>
</string-array>
+ <!-- Titles for Bluetooth MAP Versions -->
+ <string-array name="bluetooth_map_versions">
+ <item>MAP 1.2 (Default)</item>
+ <item>MAP 1.3</item>
+ <item>MAP 1.4</item>
+ </string-array>
+
+ <!-- Values for Bluetooth MAP Versions -->
+ <string-array name="bluetooth_map_version_values">
+ <item>map12</item>
+ <item>map13</item>
+ <item>map14</item>
+ </string-array>
+
<!-- Titles for Bluetooth Audio Codec selection preference. [CHAR LIMIT=50] -->
<string-array name="bluetooth_a2dp_codec_titles">
<item>Use System Selection (Default)</item>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 96f307d..a7df6db 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -606,6 +606,11 @@
<!-- UI debug setting: Select Bluetooth AVRCP Version -->
<string name="bluetooth_select_avrcp_version_dialog_title">Select Bluetooth AVRCP Version</string>
+ <!-- UI debug setting: Select Bluetooth MAP Version [CHAR LIMIT=NONE] -->
+ <string name="bluetooth_select_map_version_string">Bluetooth MAP Version</string>
+ <!-- UI debug setting: Select Bluetooth MAP Version [CHAR LIMIT=NONE] -->
+ <string name="bluetooth_select_map_version_dialog_title">Select Bluetooth MAP Version</string>
+
<!-- UI debug setting: Trigger Bluetooth Audio Codec Selection -->
<string name="bluetooth_select_a2dp_codec_type">Bluetooth Audio Codec</string>
<!-- UI debug setting: Trigger Bluetooth Audio Codec Selection -->
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 2c8bc22..3b51329 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -646,8 +646,10 @@
@Override
public void onInlineSuggestionsUnsupported() throws RemoteException {
- Log.i(TAG, "inline suggestions request unsupported, "
- + "falling back to regular autofill");
+ if (sDebug) {
+ Log.d(TAG, "inline suggestions request unsupported, "
+ + "falling back to regular autofill");
+ }
final Session session = mSession.get();
if (session != null) {
synchronized (session.mLock) {
@@ -660,8 +662,9 @@
@Override
public void onInlineSuggestionsRequest(InlineSuggestionsRequest request,
IInlineSuggestionsResponseCallback callback) throws RemoteException {
- Log.i(TAG, "onInlineSuggestionsRequest() received: "
- + request);
+ if (sDebug) {
+ Log.d(TAG, "onInlineSuggestionsRequest() received: " + request);
+ }
final Session session = mSession.get();
if (session != null) {
synchronized (session.mLock) {
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 3651a41..3bce322 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -16,8 +16,6 @@
package com.android.server.backup;
-import static com.android.internal.util.Preconditions.checkNotNull;
-
import static java.util.Collections.emptySet;
import android.Manifest;
@@ -68,6 +66,7 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
+import java.util.Objects;
import java.util.Set;
/**
@@ -124,7 +123,7 @@
static BackupManagerService sInstance;
static BackupManagerService getInstance() {
- return checkNotNull(sInstance);
+ return Objects.requireNonNull(sInstance);
}
private final Context mContext;
diff --git a/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java b/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java
index 92c2ee4..c9b09e3 100644
--- a/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java
+++ b/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java
@@ -21,7 +21,6 @@
import android.os.SELinux;
import android.util.Slog;
-import com.android.internal.util.Preconditions;
import com.android.server.backup.fullbackup.AppMetadataBackupWriter;
import com.android.server.backup.remote.ServiceBackupCallback;
import com.android.server.backup.utils.FullBackupUtils;
@@ -33,6 +32,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
+import java.util.Objects;
/**
* Used by BackupManagerService to perform adb backup for key-value packages. At the moment this
@@ -87,7 +87,7 @@
pkg + BACKUP_KEY_VALUE_NEW_STATE_FILENAME_SUFFIX);
mManifestFile = new File(mDataDir, BACKUP_MANIFEST_FILENAME);
- mAgentTimeoutParameters = Preconditions.checkNotNull(
+ mAgentTimeoutParameters = Objects.requireNonNull(
backupManagerService.getAgentTimeoutParameters(),
"Timeout parameters cannot be null");
}
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index 2799f12..064cd06 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -18,7 +18,6 @@
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND;
-import static com.android.internal.util.Preconditions.checkNotNull;
import static com.android.server.backup.BackupManagerService.DEBUG;
import static com.android.server.backup.BackupManagerService.DEBUG_SCHEDULING;
import static com.android.server.backup.BackupManagerService.MORE_DEBUG;
@@ -159,6 +158,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Queue;
import java.util.Random;
import java.util.Set;
@@ -518,7 +518,7 @@
File dataDir,
TransportManager transportManager) {
mUserId = userId;
- mContext = checkNotNull(context, "context cannot be null");
+ mContext = Objects.requireNonNull(context, "context cannot be null");
mPackageManager = context.getPackageManager();
mPackageManagerBinder = AppGlobals.getPackageManager();
mActivityManager = ActivityManager.getService();
@@ -528,14 +528,14 @@
mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mStorageManager = IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
- checkNotNull(parent, "parent cannot be null");
+ Objects.requireNonNull(parent, "parent cannot be null");
mBackupManagerBinder = BackupManagerService.asInterface(parent.asBinder());
mAgentTimeoutParameters = new
BackupAgentTimeoutParameters(Handler.getMain(), mContext.getContentResolver());
mAgentTimeoutParameters.start();
- checkNotNull(userBackupThread, "userBackupThread cannot be null");
+ Objects.requireNonNull(userBackupThread, "userBackupThread cannot be null");
mBackupHandler = new BackupHandler(this, userBackupThread);
// Set up our bookkeeping
@@ -551,7 +551,7 @@
mSetupObserver,
mUserId);
- mBaseStateDir = checkNotNull(baseStateDir, "baseStateDir cannot be null");
+ mBaseStateDir = Objects.requireNonNull(baseStateDir, "baseStateDir cannot be null");
// TODO (b/120424138): Remove once the system user is migrated to use the per-user CE
// directory. Per-user CE directories are managed by vold.
if (userId == UserHandle.USER_SYSTEM) {
@@ -563,7 +563,7 @@
// TODO (b/120424138): The system user currently uses the cache which is managed by init.rc
// Initialization and restorecon is managed by vold for per-user CE directories.
- mDataDir = checkNotNull(dataDir, "dataDir cannot be null");
+ mDataDir = Objects.requireNonNull(dataDir, "dataDir cannot be null");
mBackupPasswordManager = new BackupPasswordManager(mContext, mBaseStateDir, mRng);
// Receivers for scheduled backups and transport initialization operations.
@@ -625,7 +625,7 @@
addPackageParticipantsLocked(null);
}
- mTransportManager = checkNotNull(transportManager, "transportManager cannot be null");
+ mTransportManager = Objects.requireNonNull(transportManager, "transportManager cannot be null");
mTransportManager.setOnTransportRegisteredListener(this::onTransportRegistered);
mRegisterTransportsRequestedTime = SystemClock.elapsedRealtime();
mBackupHandler.postDelayed(
@@ -3047,9 +3047,9 @@
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.BACKUP, "updateTransportAttributes");
- Preconditions.checkNotNull(transportComponent, "transportComponent can't be null");
- Preconditions.checkNotNull(name, "name can't be null");
- Preconditions.checkNotNull(
+ Objects.requireNonNull(transportComponent, "transportComponent can't be null");
+ Objects.requireNonNull(name, "name can't be null");
+ Objects.requireNonNull(
currentDestinationString, "currentDestinationString can't be null");
Preconditions.checkArgument(
(dataManagementIntent == null) == (dataManagementLabel == null),
diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
index 7ea1892..846c6a2 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
@@ -36,7 +36,6 @@
import android.os.RemoteException;
import android.util.Slog;
-import com.android.internal.util.Preconditions;
import com.android.server.AppWidgetBackupBridge;
import com.android.server.backup.BackupAgentTimeoutParameters;
import com.android.server.backup.BackupRestoreTask;
@@ -47,6 +46,7 @@
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
+import java.util.Objects;
/**
* Core logic for performing one package's full backup, gathering the tarball from the application
@@ -201,7 +201,7 @@
mOpToken = opToken;
mTransportFlags = transportFlags;
mAgentTimeoutParameters =
- Preconditions.checkNotNull(
+ Objects.requireNonNull(
backupManagerService.getAgentTimeoutParameters(),
"Timeout parameters cannot be null");
}
diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupObbConnection.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupObbConnection.java
index e142537..aaf1f0a 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/FullBackupObbConnection.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupObbConnection.java
@@ -32,13 +32,13 @@
import android.util.Slog;
import com.android.internal.backup.IObbBackupService;
-import com.android.internal.util.Preconditions;
import com.android.server.backup.BackupAgentTimeoutParameters;
import com.android.server.backup.UserBackupManagerService;
import com.android.server.backup.utils.FullBackupUtils;
import java.io.IOException;
import java.io.OutputStream;
+import java.util.Objects;
/**
* Full backup/restore to a file/socket.
@@ -52,7 +52,7 @@
public FullBackupObbConnection(UserBackupManagerService backupManagerService) {
this.backupManagerService = backupManagerService;
mService = null;
- mAgentTimeoutParameters = Preconditions.checkNotNull(
+ mAgentTimeoutParameters = Objects.requireNonNull(
backupManagerService.getAgentTimeoutParameters(),
"Timeout parameters cannot be null");
}
diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
index 18c38dc..f7f0138 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
@@ -42,7 +42,6 @@
import android.util.Slog;
import com.android.internal.backup.IBackupTransport;
-import com.android.internal.util.Preconditions;
import com.android.server.EventLogTags;
import com.android.server.backup.BackupAgentTimeoutParameters;
import com.android.server.backup.BackupRestoreTask;
@@ -62,6 +61,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
@@ -171,7 +171,7 @@
mUserInitiated = userInitiated;
mCurrentOpToken = backupManagerService.generateRandomIntegerToken();
mBackupRunnerOpToken = backupManagerService.generateRandomIntegerToken();
- mAgentTimeoutParameters = Preconditions.checkNotNull(
+ mAgentTimeoutParameters = Objects.requireNonNull(
backupManagerService.getAgentTimeoutParameters(),
"Timeout parameters cannot be null");
mUserId = backupManagerService.getUserId();
diff --git a/services/backup/java/com/android/server/backup/internal/BackupHandler.java b/services/backup/java/com/android/server/backup/internal/BackupHandler.java
index 8c48b84..0964b31 100644
--- a/services/backup/java/com/android/server/backup/internal/BackupHandler.java
+++ b/services/backup/java/com/android/server/backup/internal/BackupHandler.java
@@ -32,7 +32,6 @@
import android.util.Slog;
import com.android.internal.backup.IBackupTransport;
-import com.android.internal.util.Preconditions;
import com.android.server.EventLogTags;
import com.android.server.backup.BackupAgentTimeoutParameters;
import com.android.server.backup.BackupRestoreTask;
@@ -58,6 +57,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
/**
* Asynchronous backup/restore handler thread.
@@ -98,7 +98,7 @@
super(backupThread.getLooper());
mBackupThread = backupThread;
this.backupManagerService = backupManagerService;
- mAgentTimeoutParameters = Preconditions.checkNotNull(
+ mAgentTimeoutParameters = Objects.requireNonNull(
backupManagerService.getAgentTimeoutParameters(),
"Timeout parameters cannot be null");
}
diff --git a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
index 9492118..bda0e3b 100644
--- a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
+++ b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
@@ -310,7 +310,7 @@
mUserInitiated = userInitiated;
mNonIncremental = nonIncremental;
mAgentTimeoutParameters =
- Preconditions.checkNotNull(
+ Objects.requireNonNull(
backupManagerService.getAgentTimeoutParameters(),
"Timeout parameters cannot be null");
mStateDirectory = new File(backupManagerService.getBaseStateDir(), transportDirName);
diff --git a/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java b/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java
index e4890e0..376b618 100644
--- a/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java
+++ b/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java
@@ -21,11 +21,11 @@
import android.util.Slog;
-import com.android.internal.util.Preconditions;
import com.android.server.backup.BackupAgentTimeoutParameters;
import com.android.server.backup.BackupRestoreTask;
import com.android.server.backup.UserBackupManagerService;
+import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -45,7 +45,7 @@
this.backupManagerService = backupManagerService;
mLatch = new CountDownLatch(1);
mCurrentOpToken = currentOpToken;
- mAgentTimeoutParameters = Preconditions.checkNotNull(
+ mAgentTimeoutParameters = Objects.requireNonNull(
backupManagerService.getAgentTimeoutParameters(),
"Timeout parameters cannot be null");
}
diff --git a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
index eba9e4a..82bed3b 100644
--- a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
+++ b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
@@ -42,7 +42,6 @@
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.Preconditions;
import com.android.server.LocalServices;
import com.android.server.backup.BackupAgentTimeoutParameters;
import com.android.server.backup.BackupRestoreTask;
@@ -62,6 +61,7 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Objects;
/**
* Full restore engine, used by both adb restore and transport-based full restore.
@@ -142,7 +142,7 @@
mOnlyPackage = onlyPackage;
mAllowApks = allowApks;
mBuffer = new byte[32 * 1024];
- mAgentTimeoutParameters = Preconditions.checkNotNull(
+ mAgentTimeoutParameters = Objects.requireNonNull(
backupManagerService.getAgentTimeoutParameters(),
"Timeout parameters cannot be null");
mIsAdbRestore = isAdbRestore;
diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
index de6a080..16484df9f 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
@@ -54,7 +54,6 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.backup.IBackupTransport;
-import com.android.internal.util.Preconditions;
import com.android.server.AppWidgetBackupBridge;
import com.android.server.EventLogTags;
import com.android.server.LocalServices;
@@ -79,6 +78,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
public class PerformUnifiedRestoreTask implements BackupRestoreTask {
@@ -208,7 +208,7 @@
mFinished = false;
mDidLaunch = false;
mListener = listener;
- mAgentTimeoutParameters = Preconditions.checkNotNull(
+ mAgentTimeoutParameters = Objects.requireNonNull(
backupManagerService.getAgentTimeoutParameters(),
"Timeout parameters cannot be null");
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index c474f47..34a8910 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -74,8 +74,6 @@
import android.os.Binder;
import android.os.DropBoxManager;
import android.os.Environment;
-import android.os.Environment.UserEnvironment;
-import android.os.FileUtils;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
@@ -183,6 +181,8 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
@@ -379,6 +379,14 @@
@GuardedBy("mAppFuseLock")
private AppFuseBridge mAppFuseBridge = null;
+ /** Matches known application dir paths. The first group contains the generic part of the path,
+ * the second group contains the user id (or null if it's a public volume without users), the
+ * third group contains the package name, and the fourth group the remainder of the path.
+ */
+ public static final Pattern KNOWN_APP_DIR_PATHS = Pattern.compile(
+ "(?i)(^/storage/[^/]+/(?:([0-9]+)/)?Android/(?:data|media|obb|sandbox)/)([^/]+)(/.*)?");
+
+
private VolumeInfo findVolumeByIdOrThrow(String id) {
synchronized (mLock) {
final VolumeInfo vol = mVolumes.get(id);
@@ -3135,7 +3143,6 @@
public void mkdirs(String callingPkg, String appPath) {
final int callingUid = Binder.getCallingUid();
final int userId = UserHandle.getUserId(callingUid);
- final UserEnvironment userEnv = new UserEnvironment(userId);
final String propertyName = "sys.user." + userId + ".ce_available";
// Ignore requests to create directories while storage is locked
@@ -3161,25 +3168,36 @@
throw new IllegalStateException("Failed to resolve " + appPath + ": " + e);
}
- // Try translating the app path into a vold path, but require that it
- // belong to the calling package.
- if (FileUtils.contains(userEnv.buildExternalStorageAppDataDirs(callingPkg), appFile) ||
- FileUtils.contains(userEnv.buildExternalStorageAppObbDirs(callingPkg), appFile) ||
- FileUtils.contains(userEnv.buildExternalStorageAppMediaDirs(callingPkg), appFile)) {
- appPath = appFile.getAbsolutePath();
- if (!appPath.endsWith("/")) {
- appPath = appPath + "/";
+ appPath = appFile.getAbsolutePath();
+ if (!appPath.endsWith("/")) {
+ appPath = appPath + "/";
+ }
+ // Ensure that the path we're asked to create is a known application directory
+ // path.
+ final Matcher matcher = KNOWN_APP_DIR_PATHS.matcher(appPath);
+ if (matcher.matches()) {
+ // And that the package dir matches the calling package
+ if (!matcher.group(3).equals(callingPkg)) {
+ throw new SecurityException("Invalid mkdirs path: " + appFile
+ + " does not contain calling package " + callingPkg);
}
-
+ // And that the user id part of the path (if any) matches the calling user id,
+ // or if for a public volume (no user id), the user matches the current user
+ if ((matcher.group(2) != null && !matcher.group(2).equals(Integer.toString(userId)))
+ || (matcher.group(2) == null && userId != mCurrentUserId)) {
+ throw new SecurityException("Invalid mkdirs path: " + appFile
+ + " does not match calling user id " + userId);
+ }
try {
- mVold.mkdirs(appPath);
- return;
- } catch (Exception e) {
+ mVold.setupAppDir(appPath, matcher.group(1), callingUid);
+ } catch (RemoteException e) {
throw new IllegalStateException("Failed to prepare " + appPath + ": " + e);
}
- }
- throw new SecurityException("Invalid mkdirs path: " + appFile);
+ return;
+ }
+ throw new SecurityException("Invalid mkdirs path: " + appFile
+ + " is not a known app path.");
}
@Override
diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
index d729a96..c58000f 100644
--- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
@@ -50,6 +50,7 @@
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
/**
* Base class for {@link SystemService SystemServices} that support multi user.
@@ -373,7 +374,7 @@
+ durationMs + "ms");
enforceCallingPermissionForManagement();
- Preconditions.checkNotNull(componentName);
+ Objects.requireNonNull(componentName);
final int maxDurationMs = getMaximumTemporaryServiceDurationMs();
if (durationMs > maxDurationMs) {
throw new IllegalArgumentException(
@@ -735,7 +736,7 @@
* @throws SecurityException when it's not...
*/
protected final void assertCalledByPackageOwner(@NonNull String packageName) {
- Preconditions.checkNotNull(packageName);
+ Objects.requireNonNull(packageName);
final int uid = Binder.getCallingUid();
final String[] packages = getContext().getPackageManager().getPackagesForUid(uid);
if (packages != null) {
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index bf73aa3..ae6d63a 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -1719,7 +1719,7 @@
// Binder call
@Override
public void setCustomPointerIcon(PointerIcon icon) {
- Preconditions.checkNotNull(icon);
+ Objects.requireNonNull(icon);
nativeSetCustomPointerIcon(mPtr, icon);
}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
index 44c8971..c40e8af 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
@@ -19,8 +19,6 @@
import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.content.ComponentName;
-import android.os.RemoteException;
-import android.util.Log;
import android.view.autofill.AutofillId;
import android.view.inputmethod.InlineSuggestionsRequest;
import android.view.inputmethod.InputMethodInfo;
@@ -99,12 +97,6 @@
@Override
public void onCreateInlineSuggestionsRequest(ComponentName componentName,
AutofillId autofillId, IInlineSuggestionsRequestCallback cb) {
- try {
- cb.onInlineSuggestionsUnsupported();
- } catch (RemoteException e) {
- Log.w("IMManagerInternal", "RemoteException calling"
- + " onInlineSuggestionsUnsupported: " + e);
- }
}
};
diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
index c13d55a..1f9379c 100644
--- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
@@ -59,7 +59,6 @@
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
-import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
import android.view.InputChannel;
@@ -198,8 +197,7 @@
//TODO(b/137800469): support multi client IMEs.
cb.onInlineSuggestionsUnsupported();
} catch (RemoteException e) {
- Log.w("MultiClientIMManager", "RemoteException calling"
- + " onInlineSuggestionsUnsupported: " + e);
+ Slog.w(TAG, "Failed to call onInlineSuggestionsUnsupported.", e);
}
}
});
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 3393cbf..b156d1b 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -4763,7 +4763,7 @@
}
// Schedule an idle timeout in case the app doesn't do it for us.
- mStackSupervisor.scheduleIdleTimeoutLocked(this);
+ mStackSupervisor.scheduleIdleTimeout(this);
mStackSupervisor.reportResumedActivityLocked(this);
@@ -4984,9 +4984,9 @@
+ "immediate=" + !idleDelayed);
}
if (!idleDelayed) {
- mStackSupervisor.scheduleIdleLocked();
+ mStackSupervisor.scheduleIdle();
} else {
- mStackSupervisor.scheduleIdleTimeoutLocked(this);
+ mStackSupervisor.scheduleIdleTimeout(this);
}
} else {
stack.checkReadyForSleep();
@@ -6102,13 +6102,13 @@
// the full stop of this activity. This is because we won't do that while they are still
// waiting for the animation to finish.
if (mAtmService.mStackSupervisor.mStoppingActivities.contains(this)) {
- mAtmService.mStackSupervisor.scheduleIdleLocked();
+ mStackSupervisor.scheduleIdle();
}
} else {
// Instead of doing the full stop routine here, let's just hide any activities
// we now can, and let them stop when the normal idle happens.
- mAtmService.mStackSupervisor.processStoppingActivitiesLocked(null /* idleActivity */,
- false /* remove */, true /* processPausingActivities */);
+ mStackSupervisor.processStoppingActivities(null /* launchedActivity */,
+ true /* onlyUpdateVisibility */, true /* unused */, null /* unused */);
}
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index b08cdc8..ef34327 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -1276,7 +1276,7 @@
// Make sure that there is no activity waiting for this to launch.
if (!mStackSupervisor.mWaitingActivityLaunched.isEmpty()) {
mStackSupervisor.removeIdleTimeoutForActivity(r);
- mStackSupervisor.scheduleIdleTimeoutLocked(r);
+ mStackSupervisor.scheduleIdleTimeout(r);
}
}
@@ -1329,7 +1329,7 @@
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to stop "
+ mStackSupervisor.mStoppingActivities.size() + " activities");
- mStackSupervisor.scheduleIdleLocked();
+ mStackSupervisor.scheduleIdle();
shouldSleep = false;
}
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 88b5cd3..ed73943 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -1301,22 +1301,14 @@
return booting;
}
- // Checked.
- @GuardedBy("mService")
- final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
+ void activityIdleInternal(ActivityRecord r, boolean fromTimeout,
boolean processPausingActivities, Configuration config) {
- if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + token);
+ if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + r);
- ArrayList<ActivityRecord> finishes = null;
- ArrayList<UserState> startingUsers = null;
- int NS = 0;
- int NF = 0;
boolean booting = false;
- boolean activityRemoved = false;
- ActivityRecord r = ActivityRecord.forTokenLocked(token);
if (r != null) {
- if (DEBUG_IDLE) Slog.d(TAG_IDLE, "activityIdleInternalLocked: Callers="
+ if (DEBUG_IDLE) Slog.d(TAG_IDLE, "activityIdleInternal: Callers="
+ Debug.getCallers(4));
mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
r.finishLaunchTickingLocked();
@@ -1369,47 +1361,14 @@
}
// Atomically retrieve all of the other things to do.
- final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(r,
- true /* remove */, processPausingActivities);
- NS = stops != null ? stops.size() : 0;
- if ((NF = mFinishingActivities.size()) > 0) {
- finishes = new ArrayList<>(mFinishingActivities);
- mFinishingActivities.clear();
- }
+ processStoppingAndFinishingActivities(r, processPausingActivities, "idle");
- if (mStartingUsers.size() > 0) {
- startingUsers = new ArrayList<>(mStartingUsers);
+ if (!mStartingUsers.isEmpty()) {
+ final ArrayList<UserState> startingUsers = new ArrayList<>(mStartingUsers);
mStartingUsers.clear();
- }
- // Stop any activities that are scheduled to do so but have been
- // waiting for the next one to start.
- for (int i = 0; i < NS; i++) {
- r = stops.get(i);
- final ActivityStack stack = r.getActivityStack();
- if (stack != null) {
- if (r.finishing) {
- // TODO(b/137329632): Wait for idle of the right activity, not just any.
- r.destroyIfPossible("activityIdleInternalLocked");
- } else {
- r.stopIfPossible();
- }
- }
- }
-
- // Finish any activities that are scheduled to do so but have been
- // waiting for the next one to start.
- for (int i = 0; i < NF; i++) {
- r = finishes.get(i);
- final ActivityStack stack = r.getActivityStack();
- if (stack != null) {
- activityRemoved |= r.destroyImmediately(true /* removeFromApp */, "finish-idle");
- }
- }
-
- if (!booting) {
- // Complete user switch
- if (startingUsers != null) {
+ if (!booting) {
+ // Complete user switch.
for (int i = 0; i < startingUsers.size(); i++) {
mService.mAmInternal.finishUserSwitch(startingUsers.get(i));
}
@@ -1417,14 +1376,6 @@
}
mService.mH.post(() -> mService.mAmInternal.trimApplications());
- //dump();
- //mWindowManager.dump();
-
- if (activityRemoved) {
- mRootWindowContainer.resumeFocusedStacksTopActivities();
- }
-
- return r;
}
/** This doesn't just find a task, it also moves the task to front. */
@@ -1765,7 +1716,7 @@
stack.mForceHidden = true;
stack.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
stack.mForceHidden = false;
- activityIdleInternalLocked(null, false /* fromTimeout */,
+ activityIdleInternal(null /* idleActivity */, false /* fromTimeout */,
true /* processPausingActivities */, null /* configuration */);
// Move all the tasks to the bottom of the fullscreen stack
@@ -2133,19 +2084,46 @@
return false;
}
- // TODO: Change method name to reflect what it actually does.
- final ArrayList<ActivityRecord> processStoppingActivitiesLocked(ActivityRecord idleActivity,
- boolean remove, boolean processPausingActivities) {
- ArrayList<ActivityRecord> stops = null;
+ /**
+ * Processes the activities to be stopped or destroyed. This should be called when the resumed
+ * activities are idle or drawn.
+ */
+ private void processStoppingAndFinishingActivities(ActivityRecord launchedActivity,
+ boolean processPausingActivities, String reason) {
+ // Stop any activities that are scheduled to do so but have been waiting for the transition
+ // animation to finish.
+ processStoppingActivities(launchedActivity, false /* onlyUpdateVisibility */,
+ processPausingActivities, reason);
+
+ final int numFinishingActivities = mFinishingActivities.size();
+ if (numFinishingActivities == 0) {
+ return;
+ }
+
+ // Finish any activities that are scheduled to do so but have been waiting for the next one
+ // to start.
+ final ArrayList<ActivityRecord> finishingActivities = new ArrayList<>(mFinishingActivities);
+ mFinishingActivities.clear();
+ for (int i = 0; i < numFinishingActivities; i++) {
+ final ActivityRecord r = finishingActivities.get(i);
+ if (r.isInHistory()) {
+ r.destroyImmediately(true /* removeFromApp */, "finish-" + reason);
+ }
+ }
+ }
+
+ /** Stop or destroy the stopping activities if they are not interactive. */
+ void processStoppingActivities(ActivityRecord launchedActivity, boolean onlyUpdateVisibility,
+ boolean processPausingActivities, String reason) {
+ final int numStoppingActivities = mStoppingActivities.size();
+ if (numStoppingActivities == 0) {
+ return;
+ }
+ ArrayList<ActivityRecord> readyToStopActivities = null;
final boolean nowVisible = mRootWindowContainer.allResumedActivitiesVisible();
- for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) {
- ActivityRecord s = mStoppingActivities.get(activityNdx);
-
- final boolean animating = s.isAnimating(TRANSITION);
-
- if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible
- + " animating=" + animating + " finishing=" + s.finishing);
+ for (int activityNdx = numStoppingActivities - 1; activityNdx >= 0; --activityNdx) {
+ final ActivityRecord s = mStoppingActivities.get(activityNdx);
if (nowVisible && s.finishing) {
// If this activity is finishing, it is sitting on top of
@@ -2156,32 +2134,49 @@
if (DEBUG_STATES) Slog.v(TAG, "Before stopping, can hide: " + s);
s.setVisibility(false);
}
- if (remove) {
- final ActivityStack stack = s.getActivityStack();
- final boolean shouldSleepOrShutDown = stack != null
- ? stack.shouldSleepOrShutDownActivities()
- : mService.isSleepingOrShuttingDownLocked();
- if (!animating || shouldSleepOrShutDown) {
- if (!processPausingActivities && s.isState(PAUSING)) {
- // Defer processing pausing activities in this iteration and reschedule
- // a delayed idle to reprocess it again
- removeIdleTimeoutForActivity(idleActivity);
- scheduleIdleTimeoutLocked(idleActivity);
- continue;
- }
+ if (onlyUpdateVisibility) {
+ continue;
+ }
- if (DEBUG_STATES) Slog.v(TAG, "Ready to stop: " + s);
- if (stops == null) {
- stops = new ArrayList<>();
- }
- stops.add(s);
+ final boolean animating = s.isAnimating(TRANSITION);
+ if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible
+ + " animating=" + animating + " finishing=" + s.finishing);
- mStoppingActivities.remove(activityNdx);
+ final ActivityStack stack = s.getActivityStack();
+ final boolean shouldSleepOrShutDown = stack != null
+ ? stack.shouldSleepOrShutDownActivities()
+ : mService.isSleepingOrShuttingDownLocked();
+ if (!animating || shouldSleepOrShutDown) {
+ if (!processPausingActivities && s.isState(PAUSING)) {
+ // Defer processing pausing activities in this iteration and reschedule
+ // a delayed idle to reprocess it again
+ removeIdleTimeoutForActivity(launchedActivity);
+ scheduleIdleTimeout(launchedActivity);
+ continue;
}
+
+ if (DEBUG_STATES) Slog.v(TAG, "Ready to stop: " + s);
+ if (readyToStopActivities == null) {
+ readyToStopActivities = new ArrayList<>();
+ }
+ readyToStopActivities.add(s);
+
+ mStoppingActivities.remove(activityNdx);
}
}
- return stops;
+ final int numReadyStops = readyToStopActivities == null ? 0 : readyToStopActivities.size();
+ for (int i = 0; i < numReadyStops; i++) {
+ final ActivityRecord r = readyToStopActivities.get(i);
+ if (r.isInHistory()) {
+ if (r.finishing) {
+ // TODO(b/137329632): Wait for idle of the right activity, not just any.
+ r.destroyIfPossible(reason);
+ } else {
+ r.stopIfPossible();
+ }
+ }
+ }
}
void removeHistoryRecords(WindowProcessController app) {
@@ -2319,14 +2314,13 @@
return printed;
}
- void scheduleIdleTimeoutLocked(ActivityRecord next) {
- if (DEBUG_IDLE) Slog.d(TAG_IDLE,
- "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
+ void scheduleIdleTimeout(ActivityRecord next) {
+ if (DEBUG_IDLE) Slog.d(TAG_IDLE, "scheduleIdleTimeout: Callers=" + Debug.getCallers(4));
Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
}
- final void scheduleIdleLocked() {
+ final void scheduleIdle() {
mHandler.sendEmptyMessage(IDLE_NOW_MSG);
}
@@ -2620,83 +2614,19 @@
private final class ActivityStackSupervisorHandler extends Handler {
- public ActivityStackSupervisorHandler(Looper looper) {
+ ActivityStackSupervisorHandler(Looper looper) {
super(looper);
}
- void activityIdleInternal(ActivityRecord r, boolean processPausingActivities) {
- synchronized (mService.mGlobalLock) {
- activityIdleInternalLocked(r != null ? r.appToken : null, true /* fromTimeout */,
- processPausingActivities, null);
- }
- }
-
@Override
public void handleMessage(Message msg) {
+ synchronized (mService.mGlobalLock) {
+ if (handleMessageInner(msg)) {
+ return;
+ }
+ }
+ // The cases that some invocations cannot be locked by WM.
switch (msg.what) {
- case REPORT_MULTI_WINDOW_MODE_CHANGED_MSG: {
- synchronized (mService.mGlobalLock) {
- for (int i = mMultiWindowModeChangedActivities.size() - 1; i >= 0; i--) {
- final ActivityRecord r = mMultiWindowModeChangedActivities.remove(i);
- r.updateMultiWindowMode();
- }
- }
- } break;
- case REPORT_PIP_MODE_CHANGED_MSG: {
- synchronized (mService.mGlobalLock) {
- for (int i = mPipModeChangedActivities.size() - 1; i >= 0; i--) {
- final ActivityRecord r = mPipModeChangedActivities.remove(i);
- r.updatePictureInPictureMode(mPipModeChangedTargetStackBounds,
- false /* forceUpdate */);
- }
- }
- } break;
- case IDLE_TIMEOUT_MSG: {
- if (DEBUG_IDLE) Slog.d(TAG_IDLE,
- "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
- // We don't at this point know if the activity is fullscreen,
- // so we need to be conservative and assume it isn't.
- activityIdleInternal((ActivityRecord) msg.obj,
- true /* processPausingActivities */);
- } break;
- case IDLE_NOW_MSG: {
- if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
- activityIdleInternal((ActivityRecord) msg.obj,
- false /* processPausingActivities */);
- } break;
- case RESUME_TOP_ACTIVITY_MSG: {
- synchronized (mService.mGlobalLock) {
- mRootWindowContainer.resumeFocusedStacksTopActivities();
- }
- } break;
- case SLEEP_TIMEOUT_MSG: {
- synchronized (mService.mGlobalLock) {
- if (mService.isSleepingOrShuttingDownLocked()) {
- Slog.w(TAG, "Sleep timeout! Sleeping now.");
- checkReadyForSleepLocked(false /* allowDelay */);
- }
- }
- } break;
- case LAUNCH_TIMEOUT_MSG: {
- synchronized (mService.mGlobalLock) {
- if (mLaunchingActivityWakeLock.isHeld()) {
- Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
- if (VALIDATE_WAKE_LOCK_CALLER
- && Binder.getCallingUid() != Process.myUid()) {
- throw new IllegalStateException("Calling must be system uid");
- }
- mLaunchingActivityWakeLock.release();
- }
- }
- } break;
- case LAUNCH_TASK_BEHIND_COMPLETE: {
- synchronized (mService.mGlobalLock) {
- ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
- if (r != null) {
- handleLaunchTaskBehindCompleteLocked(r);
- }
- }
- } break;
case RESTART_ACTIVITY_PROCESS_TIMEOUT_MSG: {
final ActivityRecord r = (ActivityRecord) msg.obj;
String processName = null;
@@ -2713,26 +2643,89 @@
"restartActivityProcessTimeout");
}
} break;
- case REPORT_HOME_CHANGED_MSG: {
- synchronized (mService.mGlobalLock) {
- mHandler.removeMessages(REPORT_HOME_CHANGED_MSG);
+ }
+ }
- // Start home activities on displays with no activities.
- mRootWindowContainer.startHomeOnEmptyDisplays("homeChanged");
+ private void activityIdleFromMessage(ActivityRecord idleActivity, boolean fromTimeout) {
+ activityIdleInternal(idleActivity, fromTimeout,
+ fromTimeout /* processPausingActivities */, null /* config */);
+ }
+
+ /**
+ * Handles the message with lock held.
+ *
+ * @return {@code true} if the message is handled.
+ */
+ private boolean handleMessageInner(Message msg) {
+ switch (msg.what) {
+ case REPORT_MULTI_WINDOW_MODE_CHANGED_MSG: {
+ for (int i = mMultiWindowModeChangedActivities.size() - 1; i >= 0; i--) {
+ final ActivityRecord r = mMultiWindowModeChangedActivities.remove(i);
+ r.updateMultiWindowMode();
}
} break;
- case TOP_RESUMED_STATE_LOSS_TIMEOUT_MSG: {
- ActivityRecord r = (ActivityRecord) msg.obj;
- Slog.w(TAG, "Activity top resumed state loss timeout for " + r);
- synchronized (mService.mGlobalLock) {
- if (r.hasProcess()) {
- mService.logAppTooSlow(r.app, r.topResumedStateLossTime,
- "top state loss for " + r);
+ case REPORT_PIP_MODE_CHANGED_MSG: {
+ for (int i = mPipModeChangedActivities.size() - 1; i >= 0; i--) {
+ final ActivityRecord r = mPipModeChangedActivities.remove(i);
+ r.updatePictureInPictureMode(mPipModeChangedTargetStackBounds,
+ false /* forceUpdate */);
+ }
+ } break;
+ case IDLE_TIMEOUT_MSG: {
+ if (DEBUG_IDLE) Slog.d(TAG_IDLE,
+ "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
+ // We don't at this point know if the activity is fullscreen, so we need to be
+ // conservative and assume it isn't.
+ activityIdleFromMessage((ActivityRecord) msg.obj, true /* fromTimeout */);
+ } break;
+ case IDLE_NOW_MSG: {
+ if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
+ activityIdleFromMessage((ActivityRecord) msg.obj, false /* fromTimeout */);
+ } break;
+ case RESUME_TOP_ACTIVITY_MSG: {
+ mRootWindowContainer.resumeFocusedStacksTopActivities();
+ } break;
+ case SLEEP_TIMEOUT_MSG: {
+ if (mService.isSleepingOrShuttingDownLocked()) {
+ Slog.w(TAG, "Sleep timeout! Sleeping now.");
+ checkReadyForSleepLocked(false /* allowDelay */);
+ }
+ } break;
+ case LAUNCH_TIMEOUT_MSG: {
+ if (mLaunchingActivityWakeLock.isHeld()) {
+ Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
+ if (VALIDATE_WAKE_LOCK_CALLER
+ && Binder.getCallingUid() != Process.myUid()) {
+ throw new IllegalStateException("Calling must be system uid");
}
+ mLaunchingActivityWakeLock.release();
+ }
+ } break;
+ case LAUNCH_TASK_BEHIND_COMPLETE: {
+ final ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
+ if (r != null) {
+ handleLaunchTaskBehindCompleteLocked(r);
+ }
+ } break;
+ case REPORT_HOME_CHANGED_MSG: {
+ mHandler.removeMessages(REPORT_HOME_CHANGED_MSG);
+
+ // Start home activities on displays with no activities.
+ mRootWindowContainer.startHomeOnEmptyDisplays("homeChanged");
+ } break;
+ case TOP_RESUMED_STATE_LOSS_TIMEOUT_MSG: {
+ final ActivityRecord r = (ActivityRecord) msg.obj;
+ Slog.w(TAG, "Activity top resumed state loss timeout for " + r);
+ if (r.hasProcess()) {
+ mService.logAppTooSlow(r.app, r.topResumedStateLossTime,
+ "top state loss for " + r);
}
handleTopResumedStateReleased(true /* timeout */);
} break;
+ default:
+ return false;
}
+ return true;
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java
index 955e581..75d87ed 100644
--- a/services/core/java/com/android/server/wm/ActivityStartController.java
+++ b/services/core/java/com/android/server/wm/ActivityStartController.java
@@ -135,7 +135,7 @@
mHandler = new StartHandler(mService.mH.getLooper());
mFactory = factory;
mFactory.setController(this);
- mPendingRemoteAnimationRegistry = new PendingRemoteAnimationRegistry(service,
+ mPendingRemoteAnimationRegistry = new PendingRemoteAnimationRegistry(service.mGlobalLock,
service.mH);
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 374af5a..76c0e4e 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -1685,20 +1685,16 @@
public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
final long origId = Binder.clearCallingIdentity();
try {
- WindowProcessController proc = null;
synchronized (mGlobalLock) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityIdle");
- ActivityStack stack = ActivityRecord.getStackLocked(token);
- if (stack == null) {
+ final ActivityRecord r = ActivityRecord.forTokenLocked(token);
+ if (r == null) {
return;
}
- final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
- false /* fromTimeout */, false /* processPausingActivities */, config);
- if (r != null) {
- proc = r.app;
- }
- if (stopProfiling && proc != null) {
- proc.clearProfilerIfNeeded();
+ mStackSupervisor.activityIdleInternal(r, false /* fromTimeout */,
+ false /* processPausingActivities */, config);
+ if (stopProfiling && r.hasProcess()) {
+ r.app.clearProfilerIfNeeded();
}
}
} finally {
@@ -6905,7 +6901,7 @@
if (mRootWindowContainer.finishDisabledPackageActivities(
packageName, disabledClasses, true, false, userId) && booted) {
mRootWindowContainer.resumeFocusedStacksTopActivities();
- mStackSupervisor.scheduleIdleLocked();
+ mStackSupervisor.scheduleIdle();
}
// Clean-up disabled tasks
@@ -6932,7 +6928,7 @@
synchronized (mGlobalLock) {
mRootWindowContainer.resumeFocusedStacksTopActivities();
if (scheduleIdle) {
- mStackSupervisor.scheduleIdleLocked();
+ mStackSupervisor.scheduleIdle();
}
}
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 896147e..67fe149 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -230,7 +230,6 @@
import com.android.internal.util.function.pooled.PooledFunction;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.internal.util.function.pooled.PooledPredicate;
-import com.android.server.AnimationThread;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.protolog.common.ProtoLog;
import com.android.server.wm.utils.DisplayRotationUtil;
@@ -977,7 +976,7 @@
AnimationHandler animationHandler = new AnimationHandler();
mBoundsAnimationController = new BoundsAnimationController(mWmService.mContext,
- mAppTransition, AnimationThread.getHandler(), animationHandler);
+ mAppTransition, mWmService.mAnimationHandler, animationHandler);
final InputChannel inputChannel = mWmService.mInputManager.monitorInput(
"PointerEventDispatcher" + mDisplayId, mDisplayId);
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index b9a9c12..a8ff500 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -47,7 +47,6 @@
import android.view.InputWindowHandle;
import android.view.SurfaceControl;
-import com.android.server.AnimationThread;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.protolog.common.ProtoLog;
@@ -157,7 +156,7 @@
mDisplayContent = mService.mRoot.getDisplayContent(displayId);
mDisplayId = displayId;
mInputTransaction = mService.mTransactionFactory.get();
- mHandler = AnimationThread.getHandler();
+ mHandler = mService.mAnimationHandler;
mUpdateInputForAllWindowsConsumer = new UpdateInputForAllWindowsConsumer();
}
diff --git a/services/core/java/com/android/server/wm/PendingRemoteAnimationRegistry.java b/services/core/java/com/android/server/wm/PendingRemoteAnimationRegistry.java
index dcb9a6a..3b8631a 100644
--- a/services/core/java/com/android/server/wm/PendingRemoteAnimationRegistry.java
+++ b/services/core/java/com/android/server/wm/PendingRemoteAnimationRegistry.java
@@ -22,12 +22,10 @@
import android.util.ArrayMap;
import android.view.RemoteAnimationAdapter;
-import com.android.server.am.ActivityManagerService;
-
/**
* Registry to keep track of remote animations to be run for activity starts from a certain package.
*
- * @see ActivityManagerService#registerRemoteAnimationForNextActivityStart
+ * @see ActivityTaskManagerService#registerRemoteAnimationForNextActivityStart
*/
class PendingRemoteAnimationRegistry {
@@ -35,10 +33,10 @@
private final ArrayMap<String, Entry> mEntries = new ArrayMap<>();
private final Handler mHandler;
- private final ActivityTaskManagerService mService;
+ private final WindowManagerGlobalLock mLock;
- PendingRemoteAnimationRegistry(ActivityTaskManagerService service, Handler handler) {
- mService = service;
+ PendingRemoteAnimationRegistry(WindowManagerGlobalLock lock, Handler handler) {
+ mLock = lock;
mHandler = handler;
}
@@ -76,7 +74,7 @@
this.packageName = packageName;
this.adapter = adapter;
mHandler.postDelayed(() -> {
- synchronized (mService.mGlobalLock) {
+ synchronized (mLock) {
final Entry entry = mEntries.get(packageName);
if (entry == this) {
mEntries.remove(packageName);
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
index bbd986f..50cea2e 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
@@ -27,6 +27,7 @@
import android.animation.ValueAnimator;
import android.annotation.Nullable;
import android.hardware.power.V1_0.PowerHint;
+import android.os.Handler;
import android.os.PowerManagerInternal;
import android.util.ArrayMap;
import android.view.Choreographer;
@@ -57,6 +58,8 @@
@VisibleForTesting
Choreographer mChoreographer;
+ private final Handler mAnimationThreadHandler = AnimationThread.getHandler();
+ private final Handler mSurfaceAnimationHandler = SurfaceAnimationThread.getHandler();
private final Runnable mApplyTransactionRunnable = this::applyTransaction;
private final AnimationHandler mAnimationHandler;
private final Transaction mFrameTransaction;
@@ -85,7 +88,7 @@
SurfaceAnimationRunner(@Nullable AnimationFrameCallbackProvider callbackProvider,
AnimatorFactory animatorFactory, Transaction frameTransaction,
PowerManagerInternal powerManagerInternal) {
- SurfaceAnimationThread.getHandler().runWithScissors(() -> mChoreographer = getSfInstance(),
+ mSurfaceAnimationHandler.runWithScissors(() -> mChoreographer = getSfInstance(),
0 /* timeout */);
mFrameTransaction = frameTransaction;
mAnimationHandler = new AnimationHandler();
@@ -152,7 +155,7 @@
synchronized (mCancelLock) {
anim.mCancelled = true;
}
- SurfaceAnimationThread.getHandler().post(() -> {
+ mSurfaceAnimationHandler.post(() -> {
anim.mAnim.cancel();
applyTransaction();
});
@@ -211,7 +214,7 @@
if (!a.mCancelled) {
// Post on other thread that we can push final state without jank.
- AnimationThread.getHandler().post(a.mFinishCallback);
+ mAnimationThreadHandler.post(a.mFinishCallback);
}
}
}
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index f7525a9..fd91bc5 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -32,7 +32,6 @@
import android.view.Choreographer;
import android.view.SurfaceControl;
-import com.android.server.AnimationThread;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.protolog.common.ProtoLog;
@@ -92,7 +91,7 @@
mContext = service.mContext;
mPolicy = service.mPolicy;
mTransaction = service.mTransactionFactory.get();
- AnimationThread.getHandler().runWithScissors(
+ service.mAnimationHandler.runWithScissors(
() -> mChoreographer = Choreographer.getSfInstance(), 0 /* timeout */);
mAnimationFrameCallback = frameTimeNs -> {
diff --git a/services/tests/wmtests/src/com/android/server/wm/AnimatingActivityRegistryTest.java b/services/tests/wmtests/src/com/android/server/wm/AnimatingActivityRegistryTest.java
index a39be56..574517a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AnimatingActivityRegistryTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AnimatingActivityRegistryTest.java
@@ -28,11 +28,11 @@
import android.platform.test.annotations.Presubmit;
-import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -44,6 +44,7 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class AnimatingActivityRegistryTest extends WindowTestsBase {
@Mock
@@ -60,7 +61,6 @@
}
@Test
- @FlakyTest(bugId = 144611135)
public void testDeferring() {
final ActivityRecord activity1 = createActivityRecord(mDisplayContent,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
@@ -83,7 +83,6 @@
}
@Test
- @FlakyTest(bugId = 131005232)
public void testContainerRemoved() {
final ActivityRecord window1 = createActivityRecord(mDisplayContent,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
diff --git a/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java b/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java
index 103c3ab..f007149 100644
--- a/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java
@@ -24,12 +24,13 @@
import android.platform.test.annotations.Presubmit;
import android.view.RemoteAnimationAdapter;
-import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
+import com.android.server.AnimationThread;
import com.android.server.testutils.OffsettableClock;
import com.android.server.testutils.TestHandler;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
@@ -41,7 +42,7 @@
*/
@SmallTest
@Presubmit
-public class PendingRemoteAnimationRegistryTest extends ActivityTestsBase {
+public class PendingRemoteAnimationRegistryTest {
@Mock RemoteAnimationAdapter mAdapter;
private PendingRemoteAnimationRegistry mRegistry;
@@ -51,10 +52,15 @@
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- mService.mH.runWithScissors(() -> {
+ AnimationThread.getHandler().runWithScissors(() -> {
mHandler = new TestHandler(null, mClock);
}, 0);
- mRegistry = new PendingRemoteAnimationRegistry(mService, mHandler);
+ mRegistry = new PendingRemoteAnimationRegistry(new WindowManagerGlobalLock(), mHandler);
+ }
+
+ @After
+ public void teadDown() {
+ AnimationThread.dispose();
}
@Test
@@ -74,7 +80,6 @@
}
@Test
- @FlakyTest(bugId = 131005232)
public void testTimeout() {
mRegistry.addPendingAnimation("com.android.test", mAdapter);
mClock.fastForward(5000);
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index e27c724..05d1c76 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -484,8 +484,8 @@
spyOn(this);
// Do not schedule idle that may touch methods outside the scope of the test.
- doNothing().when(this).scheduleIdleLocked();
- doNothing().when(this).scheduleIdleTimeoutLocked(any());
+ doNothing().when(this).scheduleIdle();
+ doNothing().when(this).scheduleIdleTimeout(any());
// unit test version does not handle launch wake lock
doNothing().when(this).acquireLaunchWakelock();
doReturn(mock(KeyguardController.class)).when(this).getKeyguardController();