summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/app/Activity.java5
-rw-r--r--core/java/android/app/IActivityManager.aidl2
-rw-r--r--core/java/android/app/IActivityTaskManager.aidl2
-rw-r--r--core/java/android/app/TEST_MAPPING22
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java73
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl6
-rw-r--r--core/java/android/content/TEST_MAPPING32
-rw-r--r--core/java/android/content/om/TEST_MAPPING4
-rw-r--r--core/java/android/content/pm/IPackageInstallerSession.aidl1
-rw-r--r--core/java/android/content/pm/PackageInstaller.java12
-rw-r--r--core/java/android/content/pm/TEST_MAPPING18
-rw-r--r--core/java/android/content/res/TEST_MAPPING4
-rw-r--r--core/java/android/hardware/face/FaceManager.java49
-rw-r--r--core/java/android/hardware/face/IFaceService.aidl9
-rw-r--r--core/java/android/hardware/fingerprint/FingerprintManager.java30
-rw-r--r--core/java/android/hardware/fingerprint/IFingerprintService.aidl4
-rw-r--r--core/java/android/hardware/location/GeofenceHardwareRequestParcelable.java9
-rw-r--r--core/java/android/nfc/INfcTag.aidl3
-rw-r--r--core/java/android/nfc/Tag.java29
-rw-r--r--core/java/android/os/Parcel.java1
-rw-r--r--core/java/android/provider/DeviceConfig.java7
-rw-r--r--core/java/android/provider/Settings.java17
-rw-r--r--core/java/android/service/gatekeeper/GateKeeperResponse.java2
-rw-r--r--core/java/android/service/voice/AbstractHotwordDetector.java12
-rw-r--r--core/java/android/service/voice/AlwaysOnHotwordDetector.java7
-rw-r--r--core/java/android/service/voice/HotwordDetector.java37
-rw-r--r--core/java/android/service/voice/SoftwareHotwordDetector.java5
-rw-r--r--core/java/android/util/TimingsTraceLog.java2
-rw-r--r--core/java/android/util/apk/TEST_MAPPING18
-rw-r--r--core/java/android/view/IWindowSession.aidl2
-rw-r--r--core/java/android/view/SurfaceControl.java8
-rw-r--r--core/java/android/view/SurfaceControlViewHost.java2
-rw-r--r--core/java/android/view/ViewRootInsetsControllerHost.java5
-rw-r--r--core/java/android/view/WindowlessWindowManager.java12
-rw-r--r--core/java/android/view/contentcapture/ContentCaptureSession.java2
-rw-r--r--core/java/android/view/translation/UiTranslationManager.java8
-rw-r--r--core/java/android/widget/SelectionActionModeHelper.java10
-rw-r--r--core/java/android/widget/TextViewTranslationCallback.java18
-rw-r--r--core/java/android/window/SplashScreen.java8
-rw-r--r--core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl4
-rw-r--r--core/java/com/android/internal/infra/ServiceConnector.java13
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java25
-rw-r--r--core/java/com/android/internal/os/MobileRadioPowerCalculator.java11
-rw-r--r--core/java/com/android/internal/policy/IKeyguardStateCallback.aidl2
-rw-r--r--core/java/com/android/internal/policy/SystemBarUtils.java2
-rw-r--r--core/java/com/android/internal/widget/ConversationLayout.java32
-rw-r--r--core/java/com/android/internal/widget/MessagingGroup.java14
-rw-r--r--core/java/com/android/internal/widget/MessagingLayout.java29
-rw-r--r--core/java/com/android/internal/widget/MessagingLinearLayout.java1
-rw-r--r--core/java/com/android/internal/widget/MessagingMessage.java5
50 files changed, 451 insertions, 184 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index f453ba16043c..750e3d6f6fed 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1537,7 +1537,10 @@ public class Activity extends ContextThemeWrapper
}
private void dispatchActivityConfigurationChanged() {
- getApplication().dispatchActivityConfigurationChanged(this);
+ // In case the new config comes before mApplication is assigned.
+ if (getApplication() != null) {
+ getApplication().dispatchActivityConfigurationChanged(this);
+ }
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 64a9c441c57f..9e23b5fa692b 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -438,7 +438,7 @@ interface IActivityManager {
void requestInteractiveBugReport();
void requestFullBugReport();
- void requestRemoteBugReport();
+ void requestRemoteBugReport(long nonce);
boolean launchBugReportHandlerApp();
List<String> getBugreportWhitelistedPackages();
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index 2be78033ddf7..cfda7e284c6b 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -293,7 +293,7 @@ interface IActivityTaskManager {
* a short predefined amount of time.
*/
void registerRemoteAnimationForNextActivityStart(in String packageName,
- in RemoteAnimationAdapter adapter);
+ in RemoteAnimationAdapter adapter, in IBinder launchCookie);
/**
* Registers remote animations for a display.
diff --git a/core/java/android/app/TEST_MAPPING b/core/java/android/app/TEST_MAPPING
index 23fc6f3bc72a..31c81bef7357 100644
--- a/core/java/android/app/TEST_MAPPING
+++ b/core/java/android/app/TEST_MAPPING
@@ -115,40 +115,42 @@
"file_patterns": ["(/|^)VoiceInteract[^/]*"]
},
{
- "name": "CtsContentTestCases",
+ "name": "CtsOsTestCases",
"options": [
{
+ "include-annotation": "android.platform.test.annotations.Presubmit"
+ },
+ {
"exclude-annotation": "androidx.test.filters.FlakyTest"
},
{
"exclude-annotation": "org.junit.Ignore"
},
{
- "include-filter": "android.content.wm.cts"
+ "include-filter": "android.os.cts.StrictModeTest"
}
],
"file_patterns": ["(/|^)ContextImpl.java"]
},
{
- "name": "CtsOsTestCases",
+ "name": "FrameworksCoreTests",
"options": [
{
- "include-annotation": "android.platform.test.annotations.Presubmit"
- },
- {
"exclude-annotation": "androidx.test.filters.FlakyTest"
},
{
"exclude-annotation": "org.junit.Ignore"
},
{
- "include-filter": "android.os.cts.StrictModeTest"
+ "include-filter": "android.content.ContextTest"
}
],
"file_patterns": ["(/|^)ContextImpl.java"]
- },
+ }
+ ],
+ "presubmit-large": [
{
- "name": "FrameworksCoreTests",
+ "name": "CtsContentTestCases",
"options": [
{
"exclude-annotation": "androidx.test.filters.FlakyTest"
@@ -157,7 +159,7 @@
"exclude-annotation": "org.junit.Ignore"
},
{
- "include-filter": "android.content.ContextTest"
+ "include-filter": "android.content.wm.cts"
}
],
"file_patterns": ["(/|^)ContextImpl.java"]
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 3553748e5004..65793bee353f 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -19,6 +19,7 @@ package android.app.admin;
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
import android.Manifest.permission;
+import android.accounts.Account;
import android.annotation.CallbackExecutor;
import android.annotation.ColorInt;
import android.annotation.IntDef;
@@ -165,6 +166,27 @@ public class DevicePolicyManager {
this(context, service, false);
}
+ /**
+ * Called when a managed profile has been provisioned.
+ *
+ * @throws SecurityException if the caller does not hold
+ * {@link android.Manifest.permission#MANAGE_PROFILE_AND_DEVICE_OWNERS}.
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)
+ public void finalizeWorkProfileProvisioning(
+ @NonNull UserHandle managedProfileUser, @Nullable Account migratedAccount) {
+ Objects.requireNonNull(managedProfileUser, "managedProfileUser can't be null");
+ if (mService == null) {
+ throw new IllegalStateException("Could not find DevicePolicyManagerService");
+ }
+ try {
+ mService.finalizeWorkProfileProvisioning(managedProfileUser, migratedAccount);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
/** @hide */
@VisibleForTesting
protected DevicePolicyManager(Context context, IDevicePolicyManager service,
@@ -497,6 +519,14 @@ public class DevicePolicyManager {
"android.intent.extra.REMOTE_BUGREPORT_HASH";
/**
+ * Extra for shared bugreport's nonce in long integer type.
+ *
+ * @hide
+ */
+ public static final String EXTRA_REMOTE_BUGREPORT_NONCE =
+ "android.intent.extra.REMOTE_BUGREPORT_NONCE";
+
+ /**
* Extra for remote bugreport notification shown type.
*
* @hide
@@ -3103,11 +3133,19 @@ public class DevicePolicyManager {
}
}
- /** @hide */
- public void resetNewUserDisclaimer() {
+ /**
+ * Acknoledges that the new managed user disclaimer was viewed by the (human) user
+ * so that {@link #ACTION_SHOW_NEW_USER_DISCLAIMER broadcast} is not sent again the next time
+ * this user is switched to.
+ *
+ * @hide
+ */
+ @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS,
+ android.Manifest.permission.INTERACT_ACROSS_USERS})
+ public void acknowledgeNewUserDisclaimer() {
if (mService != null) {
try {
- mService.resetNewUserDisclaimer();
+ mService.acknowledgeNewUserDisclaimer();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -3115,6 +3153,25 @@ public class DevicePolicyManager {
}
/**
+ * Checks whether the new managed user disclaimer was viewed by the current user.
+ *
+ * @hide
+ */
+ @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS,
+ android.Manifest.permission.INTERACT_ACROSS_USERS})
+ @TestApi
+ public boolean isNewUserDisclaimerAcknowledged() {
+ if (mService != null) {
+ try {
+ return mService.isNewUserDisclaimerAcknowledged();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ return false;
+ }
+
+ /**
* Return true if the given administrator component is currently active (enabled) in the system.
*
* @param admin The administrator component to check for.
@@ -5673,7 +5730,7 @@ public class DevicePolicyManager {
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_SHOW_NEW_USER_DISCLAIMER =
- "android.app.action.ACTION_SHOW_NEW_USER_DISCLAIMER";
+ "android.app.action.SHOW_NEW_USER_DISCLAIMER";
/**
* Widgets are enabled in keyguard
@@ -6361,10 +6418,10 @@ public class DevicePolicyManager {
* management app can use {@link #ID_TYPE_BASE_INFO} to request inclusion of the general device
* information including manufacturer, model, brand, device and product in the attestation
* record.
- * Only device owner, profile owner on an organization-owned device and their delegated
- * certificate installers can use {@link #ID_TYPE_SERIAL}, {@link #ID_TYPE_IMEI} and
- * {@link #ID_TYPE_MEID} to request unique device identifiers to be attested (the serial number,
- * IMEI and MEID correspondingly), if supported by the device
+ * Only device owner, profile owner on an organization-owned device or affiliated user, and
+ * their delegated certificate installers can use {@link #ID_TYPE_SERIAL}, {@link #ID_TYPE_IMEI}
+ * and {@link #ID_TYPE_MEID} to request unique device identifiers to be attested (the serial
+ * number, IMEI and MEID correspondingly), if supported by the device
* (see {@link #isDeviceIdAttestationSupported()}).
* Additionally, device owner, profile owner on an organization-owned device and their delegated
* certificate installers can also request the attestation record to be signed using an
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 7c7478bdb41f..e2e2a353e0c6 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -17,6 +17,7 @@
package android.app.admin;
+import android.accounts.Account;
import android.app.admin.NetworkEvent;
import android.app.IApplicationThread;
import android.app.IServiceConnection;
@@ -97,6 +98,8 @@ interface IDevicePolicyManager {
int getCurrentFailedPasswordAttempts(int userHandle, boolean parent);
int getProfileWithMinimumFailedPasswordsForWipe(int userHandle, boolean parent);
+ void finalizeWorkProfileProvisioning(in UserHandle managedProfileUser, in Account migratedAccount);
+
void setMaximumFailedPasswordsForWipe(in ComponentName admin, int num, boolean parent);
int getMaximumFailedPasswordsForWipe(in ComponentName admin, int userHandle, boolean parent);
@@ -264,7 +267,8 @@ interface IDevicePolicyManager {
int getLogoutUserId();
void clearLogoutUser();
List<UserHandle> getSecondaryUsers(in ComponentName who);
- void resetNewUserDisclaimer();
+ void acknowledgeNewUserDisclaimer();
+ boolean isNewUserDisclaimerAcknowledged();
void enableSystemApp(in ComponentName admin, in String callerPackage, in String packageName);
int enableSystemAppWithIntent(in ComponentName admin, in String callerPackage, in Intent intent);
diff --git a/core/java/android/content/TEST_MAPPING b/core/java/android/content/TEST_MAPPING
index 614143e7c04d..7f1d0d1d05cf 100644
--- a/core/java/android/content/TEST_MAPPING
+++ b/core/java/android/content/TEST_MAPPING
@@ -1,21 +1,6 @@
{
"presubmit": [
{
- "name": "CtsContentTestCases",
- "options": [
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- },
- {
- "include-filter": "android.content.wm.cts"
- }
- ],
- "file_patterns": ["(/|^)Context.java", "(/|^)ContextWrapper.java"]
- },
- {
"name": "CtsOsTestCases",
"options": [
{
@@ -51,5 +36,22 @@
],
"file_patterns": ["(/|^)Context.java", "(/|^)ContextWrapper.java", "(/|^)ComponentCallbacksController.java"]
}
+ ],
+ "presubmit-large": [
+ {
+ "name": "CtsContentTestCases",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "org.junit.Ignore"
+ },
+ {
+ "include-filter": "android.content.wm.cts"
+ }
+ ],
+ "file_patterns": ["(/|^)Context.java", "(/|^)ContextWrapper.java"]
+ }
]
} \ No newline at end of file
diff --git a/core/java/android/content/om/TEST_MAPPING b/core/java/android/content/om/TEST_MAPPING
index d8f885439b34..6185cf64ad12 100644
--- a/core/java/android/content/om/TEST_MAPPING
+++ b/core/java/android/content/om/TEST_MAPPING
@@ -21,7 +21,9 @@
"include-filter": "android.appsecurity.cts.OverlayHostTest"
}
]
- },
+ }
+ ],
+ "presubmit-large": [
{
"name": "CtsContentTestCases",
"options": [
diff --git a/core/java/android/content/pm/IPackageInstallerSession.aidl b/core/java/android/content/pm/IPackageInstallerSession.aidl
index f72288c670d9..9a7a949e3cd2 100644
--- a/core/java/android/content/pm/IPackageInstallerSession.aidl
+++ b/core/java/android/content/pm/IPackageInstallerSession.aidl
@@ -55,4 +55,5 @@ interface IPackageInstallerSession {
int getParentSessionId();
boolean isStaged();
+ int getInstallFlags();
}
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 3f8aedb31ea9..4030708d6a53 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -1432,6 +1432,18 @@ public class PackageInstaller {
}
/**
+ * @return Session's {@link SessionParams#installFlags}.
+ * @hide
+ */
+ public int getInstallFlags() {
+ try {
+ return mSession.getInstallFlags();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* @return the session ID of the multi-package session that this belongs to or
* {@link SessionInfo#INVALID_ID} if it does not belong to a multi-package session.
*/
diff --git a/core/java/android/content/pm/TEST_MAPPING b/core/java/android/content/pm/TEST_MAPPING
index 8bc3734e060d..0a69413b36ea 100644
--- a/core/java/android/content/pm/TEST_MAPPING
+++ b/core/java/android/content/pm/TEST_MAPPING
@@ -19,6 +19,16 @@
"name": "CarrierAppIntegrationTestCases"
},
{
+ "name": "CtsIncrementalInstallHostTestCases",
+ "options": [
+ {
+ "include-filter": "android.incrementalinstall.cts.IncrementalFeatureTest"
+ }
+ ]
+ }
+ ],
+ "presubmit-large": [
+ {
"name": "CtsContentTestCases",
"options": [
{
@@ -31,14 +41,6 @@
"include-filter": "android.content.pm.cts"
}
]
- },
- {
- "name": "CtsIncrementalInstallHostTestCases",
- "options": [
- {
- "include-filter": "android.incrementalinstall.cts.IncrementalFeatureTest"
- }
- ]
}
],
"postsubmit": [
diff --git a/core/java/android/content/res/TEST_MAPPING b/core/java/android/content/res/TEST_MAPPING
index c02af59ab72e..535afd361f01 100644
--- a/core/java/android/content/res/TEST_MAPPING
+++ b/core/java/android/content/res/TEST_MAPPING
@@ -2,7 +2,9 @@
"presubmit": [
{
"name": "CtsResourcesLoaderTests"
- },
+ }
+ ],
+ "presubmit-large": [
{
"name": "CtsContentTestCases",
"options": [
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index 56f81423db4e..b97055976e3e 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -306,22 +306,21 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
throw new IllegalArgumentException("Must supply an enrollment callback");
}
- if (cancel != null) {
- if (cancel.isCanceled()) {
- Slog.w(TAG, "enrollment already canceled");
- return;
- } else {
- cancel.setOnCancelListener(new OnEnrollCancelListener());
- }
+ if (cancel != null && cancel.isCanceled()) {
+ Slog.w(TAG, "enrollment already canceled");
+ return;
}
if (mService != null) {
try {
mEnrollmentCallback = callback;
Trace.beginSection("FaceManager#enroll");
- mService.enroll(userId, mToken, hardwareAuthToken, mServiceReceiver,
- mContext.getOpPackageName(), disabledFeatures, previewSurface,
- debugConsent);
+ final long enrollId = mService.enroll(userId, mToken, hardwareAuthToken,
+ mServiceReceiver, mContext.getOpPackageName(), disabledFeatures,
+ previewSurface, debugConsent);
+ if (cancel != null) {
+ cancel.setOnCancelListener(new OnEnrollCancelListener(enrollId));
+ }
} catch (RemoteException e) {
Slog.w(TAG, "Remote exception in enroll: ", e);
// Though this may not be a hardware issue, it will cause apps to give up or
@@ -359,21 +358,20 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
throw new IllegalArgumentException("Must supply an enrollment callback");
}
- if (cancel != null) {
- if (cancel.isCanceled()) {
- Slog.w(TAG, "enrollRemotely is already canceled.");
- return;
- } else {
- cancel.setOnCancelListener(new OnEnrollCancelListener());
- }
+ if (cancel != null && cancel.isCanceled()) {
+ Slog.w(TAG, "enrollRemotely is already canceled.");
+ return;
}
if (mService != null) {
try {
mEnrollmentCallback = callback;
Trace.beginSection("FaceManager#enrollRemotely");
- mService.enrollRemotely(userId, mToken, hardwareAuthToken, mServiceReceiver,
- mContext.getOpPackageName(), disabledFeatures);
+ final long enrolId = mService.enrollRemotely(userId, mToken, hardwareAuthToken,
+ mServiceReceiver, mContext.getOpPackageName(), disabledFeatures);
+ if (cancel != null) {
+ cancel.setOnCancelListener(new OnEnrollCancelListener(enrolId));
+ }
} catch (RemoteException e) {
Slog.w(TAG, "Remote exception in enrollRemotely: ", e);
// Though this may not be a hardware issue, it will cause apps to give up or
@@ -713,10 +711,10 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
}
}
- private void cancelEnrollment() {
+ private void cancelEnrollment(long requestId) {
if (mService != null) {
try {
- mService.cancelEnrollment(mToken);
+ mService.cancelEnrollment(mToken, requestId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1100,9 +1098,16 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
}
private class OnEnrollCancelListener implements OnCancelListener {
+ private final long mAuthRequestId;
+
+ private OnEnrollCancelListener(long id) {
+ mAuthRequestId = id;
+ }
+
@Override
public void onCancel() {
- cancelEnrollment();
+ Slog.d(TAG, "Cancel face enrollment requested for: " + mAuthRequestId);
+ cancelEnrollment(mAuthRequestId);
}
}
diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl
index e9198246dee3..989b001ca8bf 100644
--- a/core/java/android/hardware/face/IFaceService.aidl
+++ b/core/java/android/hardware/face/IFaceService.aidl
@@ -76,15 +76,16 @@ interface IFaceService {
void cancelAuthenticationFromService(int sensorId, IBinder token, String opPackageName, long requestId);
// Start face enrollment
- void enroll(int userId, IBinder token, in byte [] hardwareAuthToken, IFaceServiceReceiver receiver,
- String opPackageName, in int [] disabledFeatures, in Surface previewSurface, boolean debugConsent);
+ long enroll(int userId, IBinder token, in byte [] hardwareAuthToken, IFaceServiceReceiver receiver,
+ String opPackageName, in int [] disabledFeatures,
+ in Surface previewSurface, boolean debugConsent);
// Start remote face enrollment
- void enrollRemotely(int userId, IBinder token, in byte [] hardwareAuthToken, IFaceServiceReceiver receiver,
+ long enrollRemotely(int userId, IBinder token, in byte [] hardwareAuthToken, IFaceServiceReceiver receiver,
String opPackageName, in int [] disabledFeatures);
// Cancel enrollment in progress
- void cancelEnrollment(IBinder token);
+ void cancelEnrollment(IBinder token, long requestId);
// Removes the specified face enrollment for the specified userId.
void remove(IBinder token, int faceId, int userId, IFaceServiceReceiver receiver,
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index fe04e5d35784..acf9427b1241 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -183,9 +183,16 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
}
private class OnEnrollCancelListener implements OnCancelListener {
+ private final long mAuthRequestId;
+
+ private OnEnrollCancelListener(long id) {
+ mAuthRequestId = id;
+ }
+
@Override
public void onCancel() {
- cancelEnrollment();
+ Slog.d(TAG, "Cancel fingerprint enrollment requested for: " + mAuthRequestId);
+ cancelEnrollment(mAuthRequestId);
}
}
@@ -646,20 +653,19 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
throw new IllegalArgumentException("Must supply an enrollment callback");
}
- if (cancel != null) {
- if (cancel.isCanceled()) {
- Slog.w(TAG, "enrollment already canceled");
- return;
- } else {
- cancel.setOnCancelListener(new OnEnrollCancelListener());
- }
+ if (cancel != null && cancel.isCanceled()) {
+ Slog.w(TAG, "enrollment already canceled");
+ return;
}
if (mService != null) {
try {
mEnrollmentCallback = callback;
- mService.enroll(mToken, hardwareAuthToken, userId, mServiceReceiver,
- mContext.getOpPackageName(), enrollReason);
+ final long enrollId = mService.enroll(mToken, hardwareAuthToken, userId,
+ mServiceReceiver, mContext.getOpPackageName(), enrollReason);
+ if (cancel != null) {
+ cancel.setOnCancelListener(new OnEnrollCancelListener(enrollId));
+ }
} catch (RemoteException e) {
Slog.w(TAG, "Remote exception in enroll: ", e);
// Though this may not be a hardware issue, it will cause apps to give up or try
@@ -1302,9 +1308,9 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
return allSensors.isEmpty() ? null : allSensors.get(0);
}
- private void cancelEnrollment() {
+ private void cancelEnrollment(long requestId) {
if (mService != null) try {
- mService.cancelEnrollment(mToken);
+ mService.cancelEnrollment(mToken, requestId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index ba1dc6da62a6..cbff8b11a72a 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -84,11 +84,11 @@ interface IFingerprintService {
void cancelAuthenticationFromService(int sensorId, IBinder token, String opPackageName, long requestId);
// Start fingerprint enrollment
- void enroll(IBinder token, in byte [] hardwareAuthToken, int userId, IFingerprintServiceReceiver receiver,
+ long enroll(IBinder token, in byte [] hardwareAuthToken, int userId, IFingerprintServiceReceiver receiver,
String opPackageName, int enrollReason);
// Cancel enrollment in progress
- void cancelEnrollment(IBinder token);
+ void cancelEnrollment(IBinder token, long requestId);
// Any errors resulting from this call will be returned to the listener
void remove(IBinder token, int fingerId, int userId, IFingerprintServiceReceiver receiver,
diff --git a/core/java/android/hardware/location/GeofenceHardwareRequestParcelable.java b/core/java/android/hardware/location/GeofenceHardwareRequestParcelable.java
index df13ade2bf5e..bd25b8f2ad88 100644
--- a/core/java/android/hardware/location/GeofenceHardwareRequestParcelable.java
+++ b/core/java/android/hardware/location/GeofenceHardwareRequestParcelable.java
@@ -16,9 +16,9 @@
package android.hardware.location;
+import android.os.BadParcelableException;
import android.os.Parcel;
import android.os.Parcelable;
-import android.util.Log;
/**
* Geofence Hardware Request used for internal location services communication.
@@ -139,11 +139,8 @@ public final class GeofenceHardwareRequestParcelable implements Parcelable {
@Override
public GeofenceHardwareRequestParcelable createFromParcel(Parcel parcel) {
int geofenceType = parcel.readInt();
- if(geofenceType != GeofenceHardwareRequest.GEOFENCE_TYPE_CIRCLE) {
- Log.e(
- "GeofenceHardwareRequest",
- String.format("Invalid Geofence type: %d", geofenceType));
- return null;
+ if (geofenceType != GeofenceHardwareRequest.GEOFENCE_TYPE_CIRCLE) {
+ throw new BadParcelableException("Invalid Geofence type: " + geofenceType);
}
GeofenceHardwareRequest request = GeofenceHardwareRequest.createCircularGeofence(
diff --git a/core/java/android/nfc/INfcTag.aidl b/core/java/android/nfc/INfcTag.aidl
index 539fd4adb0a0..e1ccc4fb740b 100644
--- a/core/java/android/nfc/INfcTag.aidl
+++ b/core/java/android/nfc/INfcTag.aidl
@@ -45,4 +45,7 @@ interface INfcTag
boolean canMakeReadOnly(int ndefType);
int getMaxTransceiveLength(int technology);
boolean getExtendedLengthApdusSupported();
+
+ void setTagUpToDate(long cookie);
+ boolean isTagUpToDate(long cookie);
}
diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java
index 398ec63a931b..731d1ba78299 100644
--- a/core/java/android/nfc/Tag.java
+++ b/core/java/android/nfc/Tag.java
@@ -34,6 +34,7 @@ import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
+import android.os.SystemClock;
import java.io.IOException;
import java.util.Arrays;
@@ -121,6 +122,7 @@ public final class Tag implements Parcelable {
final INfcTag mTagService; // interface to NFC service, will be null if mock tag
int mConnectedTechnology;
+ long mCookie;
/**
* Hidden constructor to be used by NFC service and internal classes.
@@ -140,6 +142,17 @@ public final class Tag implements Parcelable {
mTagService = tagService;
mConnectedTechnology = -1;
+ mCookie = SystemClock.elapsedRealtime();
+
+ if (tagService == null) {
+ return;
+ }
+
+ try {
+ tagService.setTagUpToDate(mCookie);
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
}
/**
@@ -361,6 +374,22 @@ public final class Tag implements Parcelable {
/** @hide */
@UnsupportedAppUsage
public INfcTag getTagService() {
+ if (mTagService == null) {
+ return null;
+ }
+
+ try {
+ if (!mTagService.isTagUpToDate(mCookie)) {
+ String id_str = "";
+ for (int i = 0; i < mId.length; i++) {
+ id_str = id_str + String.format("%02X ", mId[i]);
+ }
+ String msg = "Permission Denial: Tag ( ID: " + id_str + ") is out of date";
+ throw new SecurityException(msg);
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
return mTagService;
}
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index e06e7b6be90a..d0a77a031c99 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -474,6 +474,7 @@ public final class Parcel {
*/
public final void recycle() {
if (DEBUG_RECYCLE) mStack = null;
+ mClassCookies = null;
freeBuffer();
if (mOwnsNativeParcelObject) {
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index e58419fb688d..338ad242874f 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -513,6 +513,13 @@ public final class DeviceConfig {
public static final String NAMESPACE_WINDOW_MANAGER_NATIVE_BOOT = "window_manager_native_boot";
/**
+ * Definitions for voice interaction related functions.
+ *
+ * @hide
+ */
+ public static final String NAMESPACE_VOICE_INTERACTION = "voice_interaction";
+
+ /**
* List of namespaces which can be read without READ_DEVICE_CONFIG permission
*
* @hide
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 042445b5011f..9b51ab9e30a7 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -9675,6 +9675,13 @@ public final class Settings {
"lockscreen_use_double_line_clock";
/**
+ * Whether to show the vibrate icon in the Status Bar (default off)
+ *
+ * @hide
+ */
+ public static final String STATUS_BAR_SHOW_VIBRATE_ICON = "status_bar_show_vibrate_icon";
+
+ /**
* Specifies whether the web action API is enabled.
*
* @hide
@@ -13769,6 +13776,16 @@ public final class Settings {
public static final String EMERGENCY_AFFORDANCE_NEEDED = "emergency_affordance_needed";
/**
+ * The power button "cooldown" period in milliseconds after the Emergency gesture is
+ * triggered, during which single-key actions on the power button are suppressed. Cooldown
+ * period is disabled if set to zero.
+ *
+ * @hide
+ */
+ public static final String EMERGENCY_GESTURE_POWER_BUTTON_COOLDOWN_PERIOD_MS =
+ "emergency_gesture_power_button_cooldown_period_ms";
+
+ /**
* Whether to enable automatic system server heap dumps. This only works on userdebug or
* eng builds, not on user builds. This is set by the user and overrides the config value.
* 1 means enable, 0 means disable.
diff --git a/core/java/android/service/gatekeeper/GateKeeperResponse.java b/core/java/android/service/gatekeeper/GateKeeperResponse.java
index 7ed733cb4f4c..9d648a6995fb 100644
--- a/core/java/android/service/gatekeeper/GateKeeperResponse.java
+++ b/core/java/android/service/gatekeeper/GateKeeperResponse.java
@@ -105,7 +105,7 @@ public final class GateKeeperResponse implements Parcelable {
dest.writeInt(mTimeout);
} else if (mResponseCode == RESPONSE_OK) {
dest.writeInt(mShouldReEnroll ? 1 : 0);
- if (mPayload != null) {
+ if (mPayload != null && mPayload.length > 0) {
dest.writeInt(mPayload.length);
dest.writeByteArray(mPayload);
} else {
diff --git a/core/java/android/service/voice/AbstractHotwordDetector.java b/core/java/android/service/voice/AbstractHotwordDetector.java
index dbe108974684..192260791a8b 100644
--- a/core/java/android/service/voice/AbstractHotwordDetector.java
+++ b/core/java/android/service/voice/AbstractHotwordDetector.java
@@ -44,14 +44,17 @@ abstract class AbstractHotwordDetector implements HotwordDetector {
private final IVoiceInteractionManagerService mManagerService;
private final Handler mHandler;
private final HotwordDetector.Callback mCallback;
+ private final int mDetectorType;
AbstractHotwordDetector(
IVoiceInteractionManagerService managerService,
- HotwordDetector.Callback callback) {
+ HotwordDetector.Callback callback,
+ int detectorType) {
mManagerService = managerService;
// TODO: this needs to be supplied from above
mHandler = new Handler(Looper.getMainLooper());
mCallback = callback;
+ mDetectorType = detectorType;
}
/**
@@ -104,19 +107,20 @@ abstract class AbstractHotwordDetector implements HotwordDetector {
Slog.d(TAG, "updateState()");
}
synchronized (mLock) {
- updateStateLocked(options, sharedMemory, null /* callback */);
+ updateStateLocked(options, sharedMemory, null /* callback */, mDetectorType);
}
}
protected void updateStateLocked(@Nullable PersistableBundle options,
- @Nullable SharedMemory sharedMemory, IHotwordRecognitionStatusCallback callback) {
+ @Nullable SharedMemory sharedMemory, IHotwordRecognitionStatusCallback callback,
+ int detectorType) {
if (DEBUG) {
Slog.d(TAG, "updateStateLocked()");
}
Identity identity = new Identity();
identity.packageName = ActivityThread.currentOpPackageName();
try {
- mManagerService.updateState(identity, options, sharedMemory, callback);
+ mManagerService.updateState(identity, options, sharedMemory, callback, detectorType);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
index face870ca1b4..c9daf52b5685 100644
--- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java
+++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
@@ -578,7 +578,9 @@ public class AlwaysOnHotwordDetector extends AbstractHotwordDetector {
IVoiceInteractionManagerService modelManagementService, int targetSdkVersion,
boolean supportHotwordDetectionService, @Nullable PersistableBundle options,
@Nullable SharedMemory sharedMemory) {
- super(modelManagementService, callback);
+ super(modelManagementService, callback,
+ supportHotwordDetectionService ? DETECTOR_TYPE_TRUSTED_HOTWORD_DSP
+ : DETECTOR_TYPE_NORMAL);
mHandler = new MyHandler();
mText = text;
@@ -590,7 +592,8 @@ public class AlwaysOnHotwordDetector extends AbstractHotwordDetector {
mTargetSdkVersion = targetSdkVersion;
mSupportHotwordDetectionService = supportHotwordDetectionService;
if (mSupportHotwordDetectionService) {
- updateStateLocked(options, sharedMemory, mInternalCallback);
+ updateStateLocked(options, sharedMemory, mInternalCallback,
+ DETECTOR_TYPE_TRUSTED_HOTWORD_DSP);
}
try {
Identity identity = new Identity();
diff --git a/core/java/android/service/voice/HotwordDetector.java b/core/java/android/service/voice/HotwordDetector.java
index e2478195bdde..969ec22beb97 100644
--- a/core/java/android/service/voice/HotwordDetector.java
+++ b/core/java/android/service/voice/HotwordDetector.java
@@ -37,6 +37,27 @@ import android.os.SharedMemory;
public interface HotwordDetector {
/**
+ * Indicates that it is a non-trusted hotword detector.
+ *
+ * @hide
+ */
+ int DETECTOR_TYPE_NORMAL = 0;
+
+ /**
+ * Indicates that it is a DSP trusted hotword detector.
+ *
+ * @hide
+ */
+ int DETECTOR_TYPE_TRUSTED_HOTWORD_DSP = 1;
+
+ /**
+ * Indicates that it is a software trusted hotword detector.
+ *
+ * @hide
+ */
+ int DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE = 2;
+
+ /**
* Starts hotword recognition.
* <p>
* On calling this, the system streams audio from the device microphone to this application's
@@ -98,6 +119,22 @@ public interface HotwordDetector {
void updateState(@Nullable PersistableBundle options, @Nullable SharedMemory sharedMemory);
/**
+ * @hide
+ */
+ static String detectorTypeToString(int detectorType) {
+ switch (detectorType) {
+ case DETECTOR_TYPE_NORMAL:
+ return "normal";
+ case DETECTOR_TYPE_TRUSTED_HOTWORD_DSP:
+ return "trusted_hotword_dsp";
+ case DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE:
+ return "trusted_hotword_software";
+ default:
+ return Integer.toString(detectorType);
+ }
+ }
+
+ /**
* The callback to notify of detection events.
*/
interface Callback {
diff --git a/core/java/android/service/voice/SoftwareHotwordDetector.java b/core/java/android/service/voice/SoftwareHotwordDetector.java
index f7a3415259fd..512a654adbab 100644
--- a/core/java/android/service/voice/SoftwareHotwordDetector.java
+++ b/core/java/android/service/voice/SoftwareHotwordDetector.java
@@ -60,14 +60,15 @@ class SoftwareHotwordDetector extends AbstractHotwordDetector {
PersistableBundle options,
SharedMemory sharedMemory,
HotwordDetector.Callback callback) {
- super(managerService, callback);
+ super(managerService, callback, DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE);
mManagerService = managerService;
mAudioFormat = audioFormat;
mCallback = callback;
mHandler = new Handler(Looper.getMainLooper());
updateStateLocked(options, sharedMemory,
- new InitializationStateListener(mHandler, mCallback));
+ new InitializationStateListener(mHandler, mCallback),
+ DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE);
}
@RequiresPermission(RECORD_AUDIO)
diff --git a/core/java/android/util/TimingsTraceLog.java b/core/java/android/util/TimingsTraceLog.java
index 5370645d31bc..f3353f45d434 100644
--- a/core/java/android/util/TimingsTraceLog.java
+++ b/core/java/android/util/TimingsTraceLog.java
@@ -127,7 +127,7 @@ public class TimingsTraceLog {
* Logs a duration so it can be parsed by external tools for performance reporting.
*/
public void logDuration(String name, long timeMs) {
- Slog.d(mTag, name + " took to complete: " + timeMs + "ms");
+ Slog.v(mTag, name + " took to complete: " + timeMs + "ms");
}
/**
diff --git a/core/java/android/util/apk/TEST_MAPPING b/core/java/android/util/apk/TEST_MAPPING
index 4598b4ffe4f6..e1825210bfd9 100644
--- a/core/java/android/util/apk/TEST_MAPPING
+++ b/core/java/android/util/apk/TEST_MAPPING
@@ -1,21 +1,23 @@
{
"presubmit": [
{
- "name": "CtsContentTestCases",
+ "name": "FrameworksCoreTests",
"options": [
{
- "include-filter": "android.content.pm.cts.PackageManagerShellCommandIncrementalTest"
- },
- {
- "include-filter": "android.content.pm.cts.PackageManagerShellCommandTest"
+ "include-filter": "android.util.apk.SourceStampVerifierTest"
}
]
- },
+ }
+ ],
+ "presubmit-large": [
{
- "name": "FrameworksCoreTests",
+ "name": "CtsContentTestCases",
"options": [
{
- "include-filter": "android.util.apk.SourceStampVerifierTest"
+ "include-filter": "android.content.pm.cts.PackageManagerShellCommandIncrementalTest"
+ },
+ {
+ "include-filter": "android.content.pm.cts.PackageManagerShellCommandTest"
}
]
}
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 9da50889e43f..46ee0f839fa9 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -306,7 +306,7 @@ interface IWindowSession {
*/
void grantInputChannel(int displayId, in SurfaceControl surface, in IWindow window,
in IBinder hostInputToken, int flags, int privateFlags, int type,
- out InputChannel outInputChannel);
+ in IBinder focusGrantToken, out InputChannel outInputChannel);
/**
* Update the flags on an input channel associated with a particular surface.
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 960d23d7afb0..a686cbf257ef 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -245,6 +245,7 @@ public final class SurfaceControl implements Parcelable {
@SurfaceControl.BufferTransform int transformHint);
private static native int nativeGetTransformHint(long nativeObject);
private static native int nativeGetLayerId(long nativeObject);
+ private static native void nativeSanitize(long transactionObject);
/**
* Transforms that can be applied to buffers as they are displayed to a window.
@@ -3544,6 +3545,13 @@ public final class SurfaceControl implements Parcelable {
}
/**
+ * @hide
+ */
+ public void sanitize() {
+ nativeSanitize(mNativeObject);
+ }
+
+ /**
* Merge the other transaction into this transaction, clearing the
* other transaction as if it had been applied.
*
diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java
index a6c5042db275..a312939e6522 100644
--- a/core/java/android/view/SurfaceControlViewHost.java
+++ b/core/java/android/view/SurfaceControlViewHost.java
@@ -231,7 +231,7 @@ public class SurfaceControlViewHost {
public @Nullable SurfacePackage getSurfacePackage() {
if (mSurfaceControl != null && mAccessibilityEmbeddedConnection != null) {
return new SurfacePackage(mSurfaceControl, mAccessibilityEmbeddedConnection,
- mViewRoot.getInputToken());
+ mWm.getFocusGrantToken());
} else {
return null;
}
diff --git a/core/java/android/view/ViewRootInsetsControllerHost.java b/core/java/android/view/ViewRootInsetsControllerHost.java
index efffa2b05a1e..aba79d5b87c3 100644
--- a/core/java/android/view/ViewRootInsetsControllerHost.java
+++ b/core/java/android/view/ViewRootInsetsControllerHost.java
@@ -171,8 +171,9 @@ public class ViewRootInsetsControllerHost implements InsetsController.Host {
public void setSystemBarsAppearance(int appearance, int mask) {
mViewRoot.mWindowAttributes.privateFlags |= PRIVATE_FLAG_APPEARANCE_CONTROLLED;
final InsetsFlags insetsFlags = mViewRoot.mWindowAttributes.insetsFlags;
- if (insetsFlags.appearance != appearance) {
- insetsFlags.appearance = (insetsFlags.appearance & ~mask) | (appearance & mask);
+ final int newAppearance = (insetsFlags.appearance & ~mask) | (appearance & mask);
+ if (insetsFlags.appearance != newAppearance) {
+ insetsFlags.appearance = newAppearance;
mViewRoot.mWindowAttributesChanged = true;
mViewRoot.scheduleTraversals();
}
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index ffb7efa67243..d5cf1a360b0f 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -22,6 +22,7 @@ import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
+import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteCallback;
import android.os.RemoteException;
@@ -75,6 +76,7 @@ public class WindowlessWindowManager implements IWindowSession {
private final Configuration mConfiguration;
private final IWindowSession mRealWm;
private final IBinder mHostInputToken;
+ private final IBinder mFocusGrantToken = new Binder();
private int mForceHeight = -1;
private int mForceWidth = -1;
@@ -91,6 +93,10 @@ public class WindowlessWindowManager implements IWindowSession {
mConfiguration.setTo(configuration);
}
+ IBinder getFocusGrantToken() {
+ return mFocusGrantToken;
+ }
+
/**
* Utility API.
*/
@@ -153,10 +159,10 @@ public class WindowlessWindowManager implements IWindowSession {
mRealWm.grantInputChannel(displayId,
new SurfaceControl(sc, "WindowlessWindowManager.addToDisplay"),
window, mHostInputToken, attrs.flags, attrs.privateFlags, attrs.type,
- outInputChannel);
+ mFocusGrantToken, outInputChannel);
} else {
mRealWm.grantInputChannel(displayId, sc, window, mHostInputToken, attrs.flags,
- attrs.privateFlags, attrs.type, outInputChannel);
+ attrs.privateFlags, attrs.type, mFocusGrantToken, outInputChannel);
}
} catch (RemoteException e) {
Log.e(TAG, "Failed to grant input to surface: ", e);
@@ -464,7 +470,7 @@ public class WindowlessWindowManager implements IWindowSession {
@Override
public void grantInputChannel(int displayId, SurfaceControl surface, IWindow window,
- IBinder hostInputToken, int flags, int privateFlags, int type,
+ IBinder hostInputToken, int flags, int privateFlags, int type, IBinder focusGrantToken,
InputChannel outInputChannel) {
}
diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java
index cc47f09d4e8d..a4db84055142 100644
--- a/core/java/android/view/contentcapture/ContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/ContentCaptureSession.java
@@ -290,6 +290,8 @@ public abstract class ContentCaptureSession implements AutoCloseable {
* <p>Typically used to change the context associated with the default session from an activity.
*/
public final void setContentCaptureContext(@Nullable ContentCaptureContext context) {
+ if (!isContentCaptureEnabled()) return;
+
mClientContext = context;
updateContentCaptureContext(context);
}
diff --git a/core/java/android/view/translation/UiTranslationManager.java b/core/java/android/view/translation/UiTranslationManager.java
index 3012e9344a1b..b57134b3ec44 100644
--- a/core/java/android/view/translation/UiTranslationManager.java
+++ b/core/java/android/view/translation/UiTranslationManager.java
@@ -101,26 +101,26 @@ public final class UiTranslationManager {
public static final String LOG_TAG = "UiTranslation";
/**
- * The state caller request to disable utranslation,, it is no longer need to ui translation.
+ * The state the caller requests to enable UI translation.
*
* @hide
*/
public static final int STATE_UI_TRANSLATION_STARTED = 0;
/**
- * The state caller request to pause ui translation, it will switch back to the original text.
+ * The state caller requests to pause UI translation. It will switch back to the original text.
*
* @hide
*/
public static final int STATE_UI_TRANSLATION_PAUSED = 1;
/**
- * The state caller request to resume the paused ui translation, it will show the translated
+ * The state caller requests to resume the paused UI translation. It will show the translated
* text again if the text had been translated.
*
* @hide
*/
public static final int STATE_UI_TRANSLATION_RESUMED = 2;
/**
- * The state the caller request to enable ui translation.
+ * The state the caller requests to disable UI translation when it no longer needs translation.
*
* @hide
*/
diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java
index 2d1f17a420fa..a0ec48bc6beb 100644
--- a/core/java/android/widget/SelectionActionModeHelper.java
+++ b/core/java/android/widget/SelectionActionModeHelper.java
@@ -297,12 +297,12 @@ public final class SelectionActionModeHelper {
} else {
mTextClassification = null;
}
- final SelectionModifierCursorController controller = mEditor.getSelectionController();
- if (controller != null
- && (mTextView.isTextSelectable() || mTextView.isTextEditable())) {
- controller.show();
- }
if (mEditor.startActionModeInternal(actionMode)) {
+ final SelectionModifierCursorController controller = mEditor.getSelectionController();
+ if (controller != null
+ && (mTextView.isTextSelectable() || mTextView.isTextEditable())) {
+ controller.show();
+ }
if (result != null) {
switch (actionMode) {
case Editor.TextActionMode.SELECTION:
diff --git a/core/java/android/widget/TextViewTranslationCallback.java b/core/java/android/widget/TextViewTranslationCallback.java
index 942be21b1ade..1713d842560b 100644
--- a/core/java/android/widget/TextViewTranslationCallback.java
+++ b/core/java/android/widget/TextViewTranslationCallback.java
@@ -89,7 +89,7 @@ public class TextViewTranslationCallback implements ViewTranslationCallback {
originalTranslationMethod);
}
final TransformationMethod transformation = mTranslationTransformation;
- runWithAnimation(
+ runChangeTextWithAnimationIfNeeded(
(TextView) view,
() -> {
mIsShowingTranslation = true;
@@ -122,7 +122,7 @@ public class TextViewTranslationCallback implements ViewTranslationCallback {
if (mTranslationTransformation != null) {
final TransformationMethod transformation =
mTranslationTransformation.getOriginalTransformationMethod();
- runWithAnimation(
+ runChangeTextWithAnimationIfNeeded(
(TextView) view,
() -> {
mIsShowingTranslation = false;
@@ -232,10 +232,16 @@ public class TextViewTranslationCallback implements ViewTranslationCallback {
* Applies a simple text alpha animation when toggling between original and translated text. The
* text is fully faded out, then swapped to the new text, then the fading is reversed.
*
- * @param runnable the operation to run on the view after the text is faded out, to change to
- * displaying the original or translated text.
+ * @param changeTextRunnable the operation to run on the view after the text is faded out, to
+ * change to displaying the original or translated text.
*/
- private void runWithAnimation(TextView view, Runnable runnable) {
+ private void runChangeTextWithAnimationIfNeeded(TextView view, Runnable changeTextRunnable) {
+ boolean areAnimatorsEnabled = ValueAnimator.areAnimatorsEnabled();
+ if (!areAnimatorsEnabled) {
+ // The animation is disabled, just change display text
+ changeTextRunnable.run();
+ return;
+ }
if (mAnimator != null) {
mAnimator.end();
// Note: mAnimator is now null; do not use again here.
@@ -269,7 +275,7 @@ public class TextViewTranslationCallback implements ViewTranslationCallback {
@Override
public void onAnimationRepeat(Animator animation) {
- runnable.run();
+ changeTextRunnable.run();
}
});
mAnimator.start();
diff --git a/core/java/android/window/SplashScreen.java b/core/java/android/window/SplashScreen.java
index 090dbff488e9..251e0acb97e6 100644
--- a/core/java/android/window/SplashScreen.java
+++ b/core/java/android/window/SplashScreen.java
@@ -99,8 +99,12 @@ public interface SplashScreen {
* <p>
* To reset to the default theme, set this the themeId to {@link Resources#ID_NULL}.
* <p>
- * <b>Note:</b> The theme name must be stable across versions, otherwise it won't be found
- * after your application is updated.
+ * <b>Note:</b> Internally, the theme name is resolved and persisted. This means that the theme
+ * name must be stable across versions, otherwise it won't be found after your application is
+ * updated.
+ *
+ * @param themeId The ID of the splashscreen theme to be used in place of the one defined in
+ * the manifest.
*/
void setSplashScreenTheme(@StyleRes int themeId);
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index 998526209c72..61c9128e499e 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -242,12 +242,14 @@ interface IVoiceInteractionManagerService {
* {@link HotwordDetectionService}. Use this to provide the hotword models data or other
* such data to the trusted process.
* @param callback Use this to report {@link HotwordDetectionService} status.
+ * @param detectorType Indicate which detector is used.
*/
void updateState(
in Identity originatorIdentity,
in PersistableBundle options,
in SharedMemory sharedMemory,
- in IHotwordRecognitionStatusCallback callback);
+ in IHotwordRecognitionStatusCallback callback,
+ int detectorType);
/**
* Requests to shutdown hotword detection service.
diff --git a/core/java/com/android/internal/infra/ServiceConnector.java b/core/java/com/android/internal/infra/ServiceConnector.java
index 9ced6097804d..c379385429b5 100644
--- a/core/java/com/android/internal/infra/ServiceConnector.java
+++ b/core/java/com/android/internal/infra/ServiceConnector.java
@@ -507,10 +507,21 @@ public interface ServiceConnector<I extends IInterface> {
void unbindJobThread() {
cancelTimeout();
I service = mService;
+ // TODO(b/224695239): This is actually checking wasConnected. Rename and/or fix
+ // implementation based on what this should actually be checking. At least the first
+ // check for calling unbind is the correct behavior, though.
boolean wasBound = service != null;
+ if (wasBound || mBinding) {
+ try {
+ mContext.unbindService(mServiceConnection);
+ } catch (IllegalArgumentException e) { // TODO(b/224697137): Fix the race condition
+ // that requires catching this (crashes if
+ // service isn't currently bound).
+ Log.e(LOG_TAG, "Failed to unbind: " + e);
+ }
+ }
if (wasBound) {
onServiceConnectionStatusChanged(service, false);
- mContext.unbindService(mServiceConnection);
service.asBinder().unlinkToDeath(this, 0);
mService = null;
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 169eff009bff..988ddb28af62 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -4664,7 +4664,6 @@ public class BatteryStatsImpl extends BatteryStats {
public void noteLongPartialWakelockStart(String name, String historyName, int uid,
long elapsedRealtimeMs, long uptimeMs) {
- uid = mapUid(uid);
noteLongPartialWakeLockStartInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs);
}
@@ -4696,15 +4695,21 @@ public class BatteryStatsImpl extends BatteryStats {
private void noteLongPartialWakeLockStartInternal(String name, String historyName, int uid,
long elapsedRealtimeMs, long uptimeMs) {
+ final int mappedUid = mapUid(uid);
if (historyName == null) {
historyName = name;
}
- if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName, uid,
- 0)) {
+ if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName,
+ mappedUid, 0)) {
return;
}
addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_START,
- historyName, uid);
+ historyName, mappedUid);
+ if (mappedUid != uid) {
+ // Prevent the isolated uid mapping from being removed while the wakelock is
+ // being held.
+ incrementIsolatedUidRefCount(uid);
+ }
}
public void noteLongPartialWakelockFinish(String name, String historyName, int uid) {
@@ -4714,7 +4719,6 @@ public class BatteryStatsImpl extends BatteryStats {
public void noteLongPartialWakelockFinish(String name, String historyName, int uid,
long elapsedRealtimeMs, long uptimeMs) {
- uid = mapUid(uid);
noteLongPartialWakeLockFinishInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs);
}
@@ -4746,15 +4750,20 @@ public class BatteryStatsImpl extends BatteryStats {
private void noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid,
long elapsedRealtimeMs, long uptimeMs) {
+ final int mappedUid = mapUid(uid);
if (historyName == null) {
historyName = name;
}
- if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName, uid,
- 0)) {
+ if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName,
+ mappedUid, 0)) {
return;
}
addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH,
- historyName, uid);
+ historyName, mappedUid);
+ if (mappedUid != uid) {
+ // Decrement the ref count for the isolated uid and delete the mapping if uneeded.
+ maybeRemoveIsolatedUidLocked(uid, elapsedRealtimeMs, uptimeMs);
+ }
}
void aggregateLastWakeupUptimeLocked(long elapsedRealtimeMs, long uptimeMs) {
diff --git a/core/java/com/android/internal/os/MobileRadioPowerCalculator.java b/core/java/com/android/internal/os/MobileRadioPowerCalculator.java
index eb5993dc2d61..31b807201bb6 100644
--- a/core/java/com/android/internal/os/MobileRadioPowerCalculator.java
+++ b/core/java/com/android/internal/os/MobileRadioPowerCalculator.java
@@ -99,9 +99,9 @@ public class MobileRadioPowerCalculator extends PowerCalculator {
calculateApp(app, uid, powerPerPacketMah, total, query);
}
- final long consumptionUC = batteryStats.getMobileRadioMeasuredBatteryConsumptionUC();
- final int powerModel = getPowerModel(consumptionUC, query);
- calculateRemaining(total, powerModel, batteryStats, rawRealtimeUs, consumptionUC);
+ final long totalConsumptionUC = batteryStats.getMobileRadioMeasuredBatteryConsumptionUC();
+ final int powerModel = getPowerModel(totalConsumptionUC, query);
+ calculateRemaining(total, powerModel, batteryStats, rawRealtimeUs, totalConsumptionUC);
if (total.remainingPowerMah != 0 || total.totalAppPowerMah != 0) {
builder.getAggregateBatteryConsumerBuilder(
@@ -229,12 +229,13 @@ public class MobileRadioPowerCalculator extends PowerCalculator {
private void calculateRemaining(PowerAndDuration total,
@BatteryConsumer.PowerModel int powerModel, BatteryStats batteryStats,
- long rawRealtimeUs, long consumptionUC) {
+ long rawRealtimeUs, long totalConsumptionUC) {
long signalTimeMs = 0;
double powerMah = 0;
if (powerModel == BatteryConsumer.POWER_MODEL_MEASURED_ENERGY) {
- powerMah = uCtoMah(consumptionUC);
+ powerMah = uCtoMah(totalConsumptionUC) - total.totalAppPowerMah;
+ if (powerMah < 0) powerMah = 0;
}
for (int i = 0; i < NUM_SIGNAL_STRENGTH_LEVELS; i++) {
diff --git a/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl b/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl
index 419b1f8feac7..d69a240b140b 100644
--- a/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl
+++ b/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl
@@ -16,7 +16,7 @@
package com.android.internal.policy;
interface IKeyguardStateCallback {
- void onShowingStateChanged(boolean showing);
+ void onShowingStateChanged(boolean showing, int userId);
void onSimSecureStateChanged(boolean simSecure);
void onInputRestrictedStateChanged(boolean inputRestricted);
void onTrustedChanged(boolean trusted);
diff --git a/core/java/com/android/internal/policy/SystemBarUtils.java b/core/java/com/android/internal/policy/SystemBarUtils.java
index 6bf1333097f7..5358b96a0f97 100644
--- a/core/java/com/android/internal/policy/SystemBarUtils.java
+++ b/core/java/com/android/internal/policy/SystemBarUtils.java
@@ -43,7 +43,7 @@ public final class SystemBarUtils {
* Gets the status bar height with a specific display cutout.
*/
public static int getStatusBarHeight(Resources res, DisplayCutout cutout) {
- final int defaultSize = res.getDimensionPixelSize(R.dimen.status_bar_height);
+ final int defaultSize = res.getDimensionPixelSize(R.dimen.status_bar_height_default);
final int safeInsetTop = cutout == null ? 0 : cutout.getSafeInsetTop();
final int waterfallInsetTop = cutout == null ? 0 : cutout.getWaterfallInsets().top;
// The status bar height should be:
diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java
index e6deada45fc1..a7d78eb02ed1 100644
--- a/core/java/com/android/internal/widget/ConversationLayout.java
+++ b/core/java/com/android/internal/widget/ConversationLayout.java
@@ -66,7 +66,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
-import java.util.function.Consumer;
/**
* A custom-built layout for the Notification.MessagingStyle allows dynamic addition and removal
@@ -76,8 +75,6 @@ import java.util.function.Consumer;
public class ConversationLayout extends FrameLayout
implements ImageMessageConsumer, IMessagingLayout {
- private static final Consumer<MessagingMessage> REMOVE_MESSAGE
- = MessagingMessage::removeMessage;
public static final Interpolator LINEAR_OUT_SLOW_IN = new PathInterpolator(0f, 0f, 0.2f, 1f);
public static final Interpolator FAST_OUT_LINEAR_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
public static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
@@ -150,6 +147,7 @@ public class ConversationLayout extends FrameLayout
private Icon mShortcutIcon;
private View mAppNameDivider;
private TouchDelegateComposite mTouchDelegate = new TouchDelegateComposite(this);
+ private ArrayList<MessagingLinearLayout.MessagingChild> mToRecycle = new ArrayList<>();
public ConversationLayout(@NonNull Context context) {
super(context);
@@ -462,8 +460,12 @@ public class ConversationLayout extends FrameLayout
removeGroups(oldGroups);
// Let's remove the remaining messages
- mMessages.forEach(REMOVE_MESSAGE);
- mHistoricMessages.forEach(REMOVE_MESSAGE);
+ for (MessagingMessage message : mMessages) {
+ message.removeMessage(mToRecycle);
+ }
+ for (MessagingMessage historicMessage : mHistoricMessages) {
+ historicMessage.removeMessage(mToRecycle);
+ }
mMessages = messages;
mHistoricMessages = historicMessages;
@@ -472,6 +474,12 @@ public class ConversationLayout extends FrameLayout
updateTitleAndNamesDisplay();
updateConversationLayout();
+
+ // Recycle everything at the end of the update, now that we know it's no longer needed.
+ for (MessagingLinearLayout.MessagingChild child : mToRecycle) {
+ child.recycle();
+ }
+ mToRecycle.clear();
}
/**
@@ -745,18 +753,18 @@ public class ConversationLayout extends FrameLayout
MessagingGroup group = oldGroups.get(i);
if (!mGroups.contains(group)) {
List<MessagingMessage> messages = group.getMessages();
- Runnable endRunnable = () -> {
- mMessagingLinearLayout.removeTransientView(group);
- group.recycle();
- };
-
boolean wasShown = group.isShown();
mMessagingLinearLayout.removeView(group);
if (wasShown && !MessagingLinearLayout.isGone(group)) {
mMessagingLinearLayout.addTransientView(group, 0);
- group.removeGroupAnimated(endRunnable);
+ group.removeGroupAnimated(() -> {
+ mMessagingLinearLayout.removeTransientView(group);
+ group.recycle();
+ });
} else {
- endRunnable.run();
+ // Defer recycling until after the update is done, since we may still need the
+ // old group around to perform other updates.
+ mToRecycle.add(group);
}
mMessages.removeAll(messages);
mHistoricMessages.removeAll(messages);
diff --git a/core/java/com/android/internal/widget/MessagingGroup.java b/core/java/com/android/internal/widget/MessagingGroup.java
index f30b8442dc35..eaa9bcd72b84 100644
--- a/core/java/com/android/internal/widget/MessagingGroup.java
+++ b/core/java/com/android/internal/widget/MessagingGroup.java
@@ -263,7 +263,8 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
return createdGroup;
}
- public void removeMessage(MessagingMessage messagingMessage) {
+ public void removeMessage(MessagingMessage messagingMessage,
+ ArrayList<MessagingLinearLayout.MessagingChild> toRecycle) {
View view = messagingMessage.getView();
boolean wasShown = view.isShown();
ViewGroup messageParent = (ViewGroup) view.getParent();
@@ -271,15 +272,14 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
return;
}
messageParent.removeView(view);
- Runnable recycleRunnable = () -> {
- messageParent.removeTransientView(view);
- messagingMessage.recycle();
- };
if (wasShown && !MessagingLinearLayout.isGone(view)) {
messageParent.addTransientView(view, 0);
- performRemoveAnimation(view, recycleRunnable);
+ performRemoveAnimation(view, () -> {
+ messageParent.removeTransientView(view);
+ messagingMessage.recycle();
+ });
} else {
- recycleRunnable.run();
+ toRecycle.add(messagingMessage);
}
}
diff --git a/core/java/com/android/internal/widget/MessagingLayout.java b/core/java/com/android/internal/widget/MessagingLayout.java
index e1602a981920..914de9e5e643 100644
--- a/core/java/com/android/internal/widget/MessagingLayout.java
+++ b/core/java/com/android/internal/widget/MessagingLayout.java
@@ -51,7 +51,6 @@ import com.android.internal.util.ContrastColorUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.function.Consumer;
/**
* A custom-built layout for the Notification.MessagingStyle allows dynamic addition and removal
@@ -62,8 +61,6 @@ public class MessagingLayout extends FrameLayout
implements ImageMessageConsumer, IMessagingLayout {
private static final float COLOR_SHIFT_AMOUNT = 60;
- private static final Consumer<MessagingMessage> REMOVE_MESSAGE
- = MessagingMessage::removeMessage;
public static final Interpolator LINEAR_OUT_SLOW_IN = new PathInterpolator(0f, 0f, 0.2f, 1f);
public static final Interpolator FAST_OUT_LINEAR_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
public static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
@@ -89,6 +86,7 @@ public class MessagingLayout extends FrameLayout
private boolean mIsCollapsed;
private ImageResolver mImageResolver;
private CharSequence mConversationTitle;
+ private ArrayList<MessagingLinearLayout.MessagingChild> mToRecycle = new ArrayList<>();
public MessagingLayout(@NonNull Context context) {
super(context);
@@ -212,8 +210,12 @@ public class MessagingLayout extends FrameLayout
removeGroups(oldGroups);
// Let's remove the remaining messages
- mMessages.forEach(REMOVE_MESSAGE);
- mHistoricMessages.forEach(REMOVE_MESSAGE);
+ for (MessagingMessage message : mMessages) {
+ message.removeMessage(mToRecycle);
+ }
+ for (MessagingMessage historicMessage : mHistoricMessages) {
+ historicMessage.removeMessage(mToRecycle);
+ }
mMessages = messages;
mHistoricMessages = historicMessages;
@@ -223,6 +225,12 @@ public class MessagingLayout extends FrameLayout
// after groups are finalized, hide the first sender name if it's showing as the title
mPeopleHelper.maybeHideFirstSenderName(mGroups, mIsOneToOne, mConversationTitle);
updateImageMessages();
+
+ // Recycle everything at the end of the update, now that we know it's no longer needed.
+ for (MessagingLinearLayout.MessagingChild child : mToRecycle) {
+ child.recycle();
+ }
+ mToRecycle.clear();
}
private void updateImageMessages() {
@@ -263,18 +271,17 @@ public class MessagingLayout extends FrameLayout
MessagingGroup group = oldGroups.get(i);
if (!mGroups.contains(group)) {
List<MessagingMessage> messages = group.getMessages();
- Runnable endRunnable = () -> {
- mMessagingLinearLayout.removeTransientView(group);
- group.recycle();
- };
boolean wasShown = group.isShown();
mMessagingLinearLayout.removeView(group);
if (wasShown && !MessagingLinearLayout.isGone(group)) {
mMessagingLinearLayout.addTransientView(group, 0);
- group.removeGroupAnimated(endRunnable);
+ group.removeGroupAnimated(() -> {
+ mMessagingLinearLayout.removeTransientView(group);
+ group.recycle();
+ });
} else {
- endRunnable.run();
+ mToRecycle.add(group);
}
mMessages.removeAll(messages);
mHistoricMessages.removeAll(messages);
diff --git a/core/java/com/android/internal/widget/MessagingLinearLayout.java b/core/java/com/android/internal/widget/MessagingLinearLayout.java
index cb1d387dbd07..c06f5f75514f 100644
--- a/core/java/com/android/internal/widget/MessagingLinearLayout.java
+++ b/core/java/com/android/internal/widget/MessagingLinearLayout.java
@@ -365,6 +365,7 @@ public class MessagingLinearLayout extends ViewGroup {
default int getExtraSpacing() {
return 0;
}
+ void recycle();
}
public static class LayoutParams extends MarginLayoutParams {
diff --git a/core/java/com/android/internal/widget/MessagingMessage.java b/core/java/com/android/internal/widget/MessagingMessage.java
index 8c8437951402..2cc0d2305a78 100644
--- a/core/java/com/android/internal/widget/MessagingMessage.java
+++ b/core/java/com/android/internal/widget/MessagingMessage.java
@@ -20,6 +20,7 @@ import android.app.ActivityManager;
import android.app.Notification;
import android.view.View;
+import java.util.ArrayList;
import java.util.Objects;
/**
@@ -96,8 +97,8 @@ public interface MessagingMessage extends MessagingLinearLayout.MessagingChild {
return sameAs(message.getMessage());
}
- default void removeMessage() {
- getGroup().removeMessage(this);
+ default void removeMessage(ArrayList<MessagingLinearLayout.MessagingChild> toRecycle) {
+ getGroup().removeMessage(this, toRecycle);
}
default void setMessagingGroup(MessagingGroup group) {