diff options
19 files changed, 176 insertions, 82 deletions
diff --git a/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java b/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java index 73bff08c626d..af0237491639 100644 --- a/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java +++ b/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java @@ -20,6 +20,7 @@ import android.app.Activity; import android.app.Instrumentation; import android.os.Bundle; import android.os.Debug; +import android.os.Trace; import android.util.Log; import androidx.test.InstrumentationRegistry; @@ -129,17 +130,23 @@ public final class BenchmarkState { } private void beginWarmup() { + Trace.beginSection("Warmup"); mStartTimeNs = System.nanoTime(); mIteration = 0; mState = WARMUP; } + private void endWarmup() { + Trace.endSection(); + } + private void beginBenchmark(long warmupDuration, int iterations) { if (ENABLE_PROFILING) { File f = new File(InstrumentationRegistry.getContext().getDataDir(), "benchprof"); Log.d(TAG, "Tracing to: " + f.getAbsolutePath()); Debug.startMethodTracingSampling(f.getAbsolutePath(), 16 * 1024 * 1024, 100); } + Trace.beginSection("Benchmark"); mMaxIterations = (int) (TARGET_TEST_DURATION_NS / (warmupDuration / iterations)); mMaxIterations = Math.min(MAX_TEST_ITERATIONS, Math.max(mMaxIterations, MIN_TEST_ITERATIONS)); @@ -150,6 +157,10 @@ public final class BenchmarkState { mStartTimeNs = System.nanoTime(); } + private void endBenchmark() { + Trace.endSection(); + } + private boolean startNextTestRun() { final long currentTime = System.nanoTime(); mResults.add((currentTime - mStartTimeNs - mPausedDurationNs) / mMaxIterations); @@ -165,6 +176,7 @@ public final class BenchmarkState { return true; } mState = FINISHED; + endBenchmark(); return false; } mPausedDurationNs = 0; @@ -189,6 +201,7 @@ public final class BenchmarkState { // don't yet have a target iteration count. final long duration = System.nanoTime() - mStartTimeNs; if (mIteration >= WARMUP_MIN_ITERATIONS && duration >= WARMUP_DURATION_NS) { + endWarmup(); beginBenchmark(duration, mIteration); } return true; @@ -208,6 +221,7 @@ public final class BenchmarkState { mCustomizedIterations++; if (mCustomizedIterations >= mMaxCustomizedIterations) { mState = FINISHED; + endBenchmark(); return false; } mCustomizedIterationListener.onStart(mCustomizedIterations); diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 59327c8afecc..7862a361997b 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -2385,6 +2385,12 @@ package android.os { method @NonNull public static byte[] digest(@NonNull java.io.InputStream, @NonNull String) throws java.io.IOException, java.security.NoSuchAlgorithmException; } + public class Handler { + method @FlaggedApi("android.os.mainline_vcn_platform_api") public final boolean hasMessagesOrCallbacks(); + method @FlaggedApi("android.os.mainline_vcn_platform_api") public final void removeCallbacksAndEqualMessages(@Nullable Object); + method @FlaggedApi("android.os.mainline_vcn_platform_api") public final void removeEqualMessages(int, @Nullable Object); + } + public class IpcDataCache<Query, Result> extends android.app.PropertyInvalidatedCache<Query,Result> { ctor public IpcDataCache(int, @NonNull String, @NonNull String, @NonNull String, @NonNull android.os.IpcDataCache.QueryHandler<Query,Result>); method public static void disableForCurrentProcess(@NonNull String); diff --git a/core/java/android/net/flags.aconfig b/core/java/android/net/flags.aconfig index f7dc7906d50d..a30cd5cfe23a 100644 --- a/core/java/android/net/flags.aconfig +++ b/core/java/android/net/flags.aconfig @@ -28,3 +28,11 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "mdns_improvement_for_25q2" + is_exported: true + namespace: "android_core_networking" + description: "Flag for MDNS quality, reliability and performance improvement in 25Q2" + bug: "373270045" +} diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java index d0828c384664..eaecd34b9d75 100644 --- a/core/java/android/os/Handler.java +++ b/core/java/android/os/Handler.java @@ -20,6 +20,7 @@ import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.util.Log; import android.util.Printer; @@ -839,6 +840,7 @@ public class Handler { *@hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + @TestApi @FlaggedApi(android.os.Flags.FLAG_MAINLINE_VCN_PLATFORM_API) public final void removeEqualMessages(int what, @Nullable Object object) { mQueue.removeEqualMessages(this, what, disallowNullArgumentIfShared(object)); @@ -872,6 +874,7 @@ public class Handler { *@hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + @TestApi @FlaggedApi(android.os.Flags.FLAG_MAINLINE_VCN_PLATFORM_API) public final void removeCallbacksAndEqualMessages(@Nullable Object token) { mQueue.removeCallbacksAndEqualMessages(this, disallowNullArgumentIfShared(token)); @@ -889,6 +892,7 @@ public class Handler { * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + @TestApi @FlaggedApi(android.os.Flags.FLAG_MAINLINE_VCN_PLATFORM_API) public final boolean hasMessagesOrCallbacks() { return mQueue.hasMessages(this); diff --git a/framework-jarjar-rules.txt b/framework-jarjar-rules.txt index 087378bef6a1..3da69e854b63 100644 --- a/framework-jarjar-rules.txt +++ b/framework-jarjar-rules.txt @@ -10,3 +10,6 @@ rule com.android.modules.utils.build.** android.internal.modules.utils.build.@1 # For Perfetto proto dependencies rule perfetto.protos.** android.internal.perfetto.protos.@1 + +# For aconfig storage classes +rule android.aconfig.storage.** android.internal.aconfig.storage.@1 diff --git a/nfc/Android.bp b/nfc/Android.bp index b82dec88993d..c33665aef41d 100644 --- a/nfc/Android.bp +++ b/nfc/Android.bp @@ -56,7 +56,7 @@ java_sdk_library { ], defaults: ["framework-module-defaults"], sdk_version: "module_current", - min_sdk_version: "current", + min_sdk_version: "35", // Make it 36 once available. installable: true, optimize: { enabled: false, diff --git a/nfc/api/current.txt b/nfc/api/current.txt index 0ee81cbb7a73..c8c479a4d2ad 100644 --- a/nfc/api/current.txt +++ b/nfc/api/current.txt @@ -211,7 +211,7 @@ package android.nfc.cardemulation { method public boolean isDefaultServiceForCategory(android.content.ComponentName, String); method @FlaggedApi("android.nfc.enable_card_emulation_euicc") public boolean isEuiccSupported(); method public boolean registerAidsForService(android.content.ComponentName, String, java.util.List<java.lang.String>); - method @FlaggedApi("android.nfc.nfc_event_listener") public void registerNfcEventListener(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.cardemulation.CardEmulation.NfcEventListener); + method @FlaggedApi("android.nfc.nfc_event_listener") public void registerNfcEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.cardemulation.CardEmulation.NfcEventCallback); method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean registerPollingLoopFilterForService(@NonNull android.content.ComponentName, @NonNull String, boolean); method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean registerPollingLoopPatternFilterForService(@NonNull android.content.ComponentName, @NonNull String, boolean); method public boolean removeAidsForService(android.content.ComponentName, String); @@ -221,7 +221,7 @@ package android.nfc.cardemulation { method public boolean setPreferredService(android.app.Activity, android.content.ComponentName); method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean setShouldDefaultToObserveModeForService(@NonNull android.content.ComponentName, boolean); method public boolean supportsAidPrefixRegistration(); - method @FlaggedApi("android.nfc.nfc_event_listener") public void unregisterNfcEventListener(@NonNull android.nfc.cardemulation.CardEmulation.NfcEventListener); + method @FlaggedApi("android.nfc.nfc_event_listener") public void unregisterNfcEventCallback(@NonNull android.nfc.cardemulation.CardEmulation.NfcEventCallback); method @NonNull @RequiresPermission(android.Manifest.permission.NFC) public boolean unsetOffHostForService(@NonNull android.content.ComponentName); method public boolean unsetPreferredService(android.app.Activity); field @Deprecated public static final String ACTION_CHANGE_DEFAULT = "android.nfc.cardemulation.action.ACTION_CHANGE_DEFAULT"; @@ -244,7 +244,7 @@ package android.nfc.cardemulation { field public static final int SELECTION_MODE_PREFER_DEFAULT = 0; // 0x0 } - @FlaggedApi("android.nfc.nfc_event_listener") public static interface CardEmulation.NfcEventListener { + @FlaggedApi("android.nfc.nfc_event_listener") public static interface CardEmulation.NfcEventCallback { method @FlaggedApi("android.nfc.nfc_event_listener") public default void onAidConflictOccurred(@NonNull String); method @FlaggedApi("android.nfc.nfc_event_listener") public default void onAidNotRouted(@NonNull String); method @FlaggedApi("android.nfc.nfc_event_listener") public default void onInternalErrorReported(int); diff --git a/nfc/java/android/nfc/INfcCardEmulation.aidl b/nfc/java/android/nfc/INfcCardEmulation.aidl index bb9fe959dc06..00ceaa9801d8 100644 --- a/nfc/java/android/nfc/INfcCardEmulation.aidl +++ b/nfc/java/android/nfc/INfcCardEmulation.aidl @@ -17,7 +17,7 @@ package android.nfc; import android.content.ComponentName; -import android.nfc.INfcEventListener; +import android.nfc.INfcEventCallback; import android.nfc.cardemulation.AidGroup; import android.nfc.cardemulation.ApduServiceInfo; @@ -60,6 +60,6 @@ interface INfcCardEmulation List<String> getRoutingStatus(); void overwriteRoutingTable(int userHandle, String emptyAid, String protocol, String tech, String sc); - void registerNfcEventListener(in INfcEventListener listener); - void unregisterNfcEventListener(in INfcEventListener listener); + void registerNfcEventCallback(in INfcEventCallback listener); + void unregisterNfcEventCallback(in INfcEventCallback listener); } diff --git a/nfc/java/android/nfc/INfcEventListener.aidl b/nfc/java/android/nfc/INfcEventCallback.aidl index 774d8f875192..af1fa2fb2456 100644 --- a/nfc/java/android/nfc/INfcEventListener.aidl +++ b/nfc/java/android/nfc/INfcEventCallback.aidl @@ -5,7 +5,7 @@ import android.nfc.ComponentNameAndUser; /** * @hide */ -oneway interface INfcEventListener { +oneway interface INfcEventCallback { void onPreferredServiceChanged(in ComponentNameAndUser ComponentNameAndUser); void onObserveModeStateChanged(boolean isEnabled); void onAidConflictOccurred(in String aid); diff --git a/nfc/java/android/nfc/cardemulation/CardEmulation.java b/nfc/java/android/nfc/cardemulation/CardEmulation.java index e0bc15fe6e94..fee9c5bfa328 100644 --- a/nfc/java/android/nfc/cardemulation/CardEmulation.java +++ b/nfc/java/android/nfc/cardemulation/CardEmulation.java @@ -39,7 +39,7 @@ import android.nfc.ComponentNameAndUser; import android.nfc.Constants; import android.nfc.Flags; import android.nfc.INfcCardEmulation; -import android.nfc.INfcEventListener; +import android.nfc.INfcEventCallback; import android.nfc.NfcAdapter; import android.os.Build; import android.os.RemoteException; @@ -1304,7 +1304,7 @@ public final class CardEmulation { /** Listener for preferred service state changes. */ @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) - public interface NfcEventListener { + public interface NfcEventCallback { /** * This method is called when this package gains or loses preferred Nfc service status, * either the Default Wallet Role holder (see {@link @@ -1327,7 +1327,10 @@ public final class CardEmulation { /** * This method is called when an AID conflict is detected during an NFC transaction. This - * can happen when multiple services are registered for the same AID. + * can happen when multiple services are registered for the same AID. If your service is + * registered for this AID you may want to instruct users to bring your app to the + * foreground and ensure you call {@link #setPreferredService(Activity, ComponentName)} + * to ensure the transaction is routed to your service. * * @param aid The AID that is in conflict */ @@ -1377,10 +1380,10 @@ public final class CardEmulation { default void onInternalErrorReported(@NfcInternalErrorType int errorType) {} } - private final ArrayMap<NfcEventListener, Executor> mNfcEventListeners = new ArrayMap<>(); + private final ArrayMap<NfcEventCallback, Executor> mNfcEventCallbacks = new ArrayMap<>(); - final INfcEventListener mINfcEventListener = - new INfcEventListener.Stub() { + final INfcEventCallback mINfcEventCallback = + new INfcEventCallback.Stub() { public void onPreferredServiceChanged(ComponentNameAndUser componentNameAndUser) { if (!android.nfc.Flags.nfcEventListener()) { return; @@ -1440,12 +1443,12 @@ public final class CardEmulation { } interface ListenerCall { - void invoke(NfcEventListener listener); + void invoke(NfcEventCallback listener); } private void callListeners(ListenerCall listenerCall) { - synchronized (mNfcEventListeners) { - mNfcEventListeners.forEach( + synchronized (mNfcEventCallbacks) { + mNfcEventCallbacks.forEach( (listener, executor) -> { executor.execute(() -> listenerCall.invoke(listener)); }); @@ -1460,34 +1463,34 @@ public final class CardEmulation { * @param listener The listener to register */ @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) - public void registerNfcEventListener( - @NonNull @CallbackExecutor Executor executor, @NonNull NfcEventListener listener) { + public void registerNfcEventCallback( + @NonNull @CallbackExecutor Executor executor, @NonNull NfcEventCallback listener) { if (!android.nfc.Flags.nfcEventListener()) { return; } - synchronized (mNfcEventListeners) { - mNfcEventListeners.put(listener, executor); - if (mNfcEventListeners.size() == 1) { - callService(() -> sService.registerNfcEventListener(mINfcEventListener)); + synchronized (mNfcEventCallbacks) { + mNfcEventCallbacks.put(listener, executor); + if (mNfcEventCallbacks.size() == 1) { + callService(() -> sService.registerNfcEventCallback(mINfcEventCallback)); } } } /** * Unregister a preferred service listener that was previously registered with {@link - * #registerNfcEventListener(Executor, NfcEventListener)} + * #registerNfcEventCallback(Executor, NfcEventCallback)} * * @param listener The previously registered listener to unregister */ @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) - public void unregisterNfcEventListener(@NonNull NfcEventListener listener) { + public void unregisterNfcEventCallback(@NonNull NfcEventCallback listener) { if (!android.nfc.Flags.nfcEventListener()) { return; } - synchronized (mNfcEventListeners) { - mNfcEventListeners.remove(listener); - if (mNfcEventListeners.size() == 0) { - callService(() -> sService.unregisterNfcEventListener(mINfcEventListener)); + synchronized (mNfcEventCallbacks) { + mNfcEventCallbacks.remove(listener); + if (mNfcEventCallbacks.size() == 0) { + callService(() -> sService.unregisterNfcEventCallback(mINfcEventCallback)); } } } diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java index bcfd8f620f9c..75156bac3dc4 100644 --- a/packages/Shell/src/com/android/shell/BugreportProgressService.java +++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java @@ -236,6 +236,9 @@ public class BugreportProgressService extends Service { /** Always keep remote bugreport files created in the last day. */ private static final long REMOTE_MIN_KEEP_AGE = DateUtils.DAY_IN_MILLIS; + /** Minimum delay for sending last update notification */ + private static final int DELAY_NOTIFICATION_MS = 250; + private final Object mLock = new Object(); /** Managed bugreport info (keyed by id) */ @@ -849,6 +852,7 @@ public class BugreportProgressService extends Service { Log.d(TAG, "Progress #" + info.id + ": " + percentageText); } info.lastProgress.set(progress); + info.lastUpdate.set(System.currentTimeMillis()); sendForegroundabledNotification(info.id, builder.build()); } @@ -1368,6 +1372,16 @@ public class BugreportProgressService extends Service { */ private void sendBugreportNotification(BugreportInfo info, boolean takingScreenshot) { + final long lastUpdate = System.currentTimeMillis() - info.lastUpdate.longValue(); + if (lastUpdate < DELAY_NOTIFICATION_MS) { + Log.d(TAG, "Delaying final notification for " + + (DELAY_NOTIFICATION_MS - lastUpdate) + " ms "); + mMainThreadHandler.postDelayed(() -> { + sendBugreportNotification(info, takingScreenshot); + }, DELAY_NOTIFICATION_MS - lastUpdate); + return; + } + // Since adding the details can take a while, do it before notifying user. addDetailsToZipFile(info); @@ -1388,6 +1402,7 @@ public class BugreportProgressService extends Service { final Notification.Builder builder = newBaseNotification(mContext) .setContentTitle(title) .setTicker(title) + .setProgress(100 /* max value of progress percentage */, 100, false) .setOnlyAlertOnce(false) .setContentText(content); @@ -2426,7 +2441,6 @@ public class BugreportProgressService extends Service { } } info.progress.set(progress); - info.lastUpdate.set(System.currentTimeMillis()); updateProgress(info); } diff --git a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java index 050a3704df1f..7bda2ea790b0 100644 --- a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java +++ b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java @@ -193,7 +193,7 @@ public class BugreportReceiverTest { mService.mScreenshotDelaySec = SCREENSHOT_DELAY_SECONDS; // Dup the fds which are passing to startBugreport function. Mockito.doAnswer(invocation -> { - final boolean isScreenshotRequested = invocation.getArgument(6); + final boolean isScreenshotRequested = invocation.getArgument(7); if (isScreenshotRequested) { mScreenshotFd = ParcelFileDescriptor.dup(invocation.getArgument(3)); } @@ -250,7 +250,22 @@ public class BugreportReceiverTest { mIDumpstateListener.onProgress(300); assertProgressNotification(mProgressTitle, 99); - Bundle extras = sendBugreportFinishedAndGetSharedIntent(mBugreportId); + Bundle extras = sendBugreportFinishedAndGetSharedIntent(mBugreportId, 1); + assertActionSendMultiple(extras); + + assertServiceNotRunning(); + } + + @Test + public void testStressProgress() throws Exception { + sendBugreportStarted(); + waitForScreenshotButtonEnabled(true); + + for (int i = 0; i <= 1000; i++) { + mIDumpstateListener.onProgress(i); + } + sendBugreportFinished(); + Bundle extras = acceptBugreportAndGetSharedIntent(mBugreportId, 1); assertActionSendMultiple(extras); assertServiceNotRunning(); @@ -277,7 +292,7 @@ public class BugreportReceiverTest { assertScreenshotButtonEnabled(false); waitForScreenshotButtonEnabled(true); - Bundle extras = sendBugreportFinishedAndGetSharedIntent(mBugreportId); + Bundle extras = sendBugreportFinishedAndGetSharedIntent(mBugreportId, 2); assertActionSendMultiple(extras, NO_NAME, NO_TITLE, NO_DESCRIPTION, 1); assertServiceNotRunning(); @@ -294,7 +309,7 @@ public class BugreportReceiverTest { // There's no indication in the UI about the screenshot finish, so just sleep like a baby... sleep(SAFE_SCREENSHOT_DELAY * DateUtils.SECOND_IN_MILLIS); - Bundle extras = acceptBugreportAndGetSharedIntent(mBugreportId); + Bundle extras = acceptBugreportAndGetSharedIntent(mBugreportId, 2); assertActionSendMultiple(extras, NO_NAME, NO_TITLE, NO_DESCRIPTION, 1); assertServiceNotRunning(); @@ -328,7 +343,7 @@ public class BugreportReceiverTest { assertProgressNotification(NEW_NAME, 00.00f); - Bundle extras = sendBugreportFinishedAndGetSharedIntent(TITLE); + Bundle extras = sendBugreportFinishedAndGetSharedIntent(TITLE, 1); assertActionSendMultiple(extras, NEW_NAME, TITLE, mDescription, 0); assertServiceNotRunning(); @@ -363,7 +378,7 @@ public class BugreportReceiverTest { assertProgressNotification(NEW_NAME, 00.00f); - Bundle extras = sendBugreportFinishedAndGetSharedIntent(TITLE); + Bundle extras = sendBugreportFinishedAndGetSharedIntent(TITLE, 1); assertActionSendMultiple(extras, NEW_NAME, TITLE, mDescription, 0); assertServiceNotRunning(); @@ -390,7 +405,7 @@ public class BugreportReceiverTest { detailsUi.descField.setText(mDescription); detailsUi.clickOk(); - Bundle extras = sendBugreportFinishedAndGetSharedIntent(mBugreportId); + Bundle extras = sendBugreportFinishedAndGetSharedIntent(mBugreportId, 1); assertActionSendMultiple(extras, NO_NAME, NO_TITLE, mDescription, 0); assertServiceNotRunning(); @@ -441,7 +456,7 @@ public class BugreportReceiverTest { detailsUi.clickOk(); // Finally, share bugreport. - Bundle extras = acceptBugreportAndGetSharedIntent(mBugreportId); + Bundle extras = acceptBugreportAndGetSharedIntent(mBugreportId, 1); assertActionSendMultiple(extras, NO_NAME, TITLE, mDescription, 0); assertServiceNotRunning(); @@ -504,7 +519,7 @@ public class BugreportReceiverTest { mUiBot.click(ok, "ok"); // Share the bugreport. - mUiBot.chooseActivity(UI_NAME); + mUiBot.chooseActivity(UI_NAME, mContext, 1); Bundle extras = mListener.getExtras(); assertActionSendMultiple(extras); @@ -531,7 +546,7 @@ public class BugreportReceiverTest { sendBugreportFinished(); killService(); assertServiceNotRunning(); - Bundle extras = acceptBugreportAndGetSharedIntent(mBugreportId); + Bundle extras = acceptBugreportAndGetSharedIntent(mBugreportId, 1); assertActionSendMultiple(extras); } @@ -618,45 +633,49 @@ public class BugreportReceiverTest { * Sends a "bugreport finished" event and waits for the result. * * @param id The bugreport id for finished notification string title substitution. + * @param count Number of files to be shared * @return extras sent in the shared intent. */ - private Bundle sendBugreportFinishedAndGetSharedIntent(int id) throws Exception { + private Bundle sendBugreportFinishedAndGetSharedIntent(int id, int count) throws Exception { sendBugreportFinished(); - return acceptBugreportAndGetSharedIntent(id); + return acceptBugreportAndGetSharedIntent(id, count); } /** * Sends a "bugreport finished" event and waits for the result. * * @param notificationTitle The title of finished notification. + * @param count Number of files to be shared * @return extras sent in the shared intent. */ - private Bundle sendBugreportFinishedAndGetSharedIntent(String notificationTitle) + private Bundle sendBugreportFinishedAndGetSharedIntent(String notificationTitle, int count) throws Exception { sendBugreportFinished(); - return acceptBugreportAndGetSharedIntent(notificationTitle); + return acceptBugreportAndGetSharedIntent(notificationTitle, count); } /** * Accepts the notification to share the finished bugreport and waits for the result. * * @param id The bugreport id for finished notification string title substitution. + * @param count Number of files to be shared * @return extras sent in the shared intent. */ - private Bundle acceptBugreportAndGetSharedIntent(int id) { + private Bundle acceptBugreportAndGetSharedIntent(int id, int count) { final String notificationTitle = mContext.getString(R.string.bugreport_finished_title, id); - return acceptBugreportAndGetSharedIntent(notificationTitle); + return acceptBugreportAndGetSharedIntent(notificationTitle, count); } /** * Accepts the notification to share the finished bugreport and waits for the result. * * @param notificationTitle The title of finished notification. + * @param count Number of files to be shared * @return extras sent in the shared intent. */ - private Bundle acceptBugreportAndGetSharedIntent(String notificationTitle) { + private Bundle acceptBugreportAndGetSharedIntent(String notificationTitle, int count) { mUiBot.clickOnNotification(notificationTitle); - mUiBot.chooseActivity(UI_NAME); + mUiBot.chooseActivity(UI_NAME, mContext, count); return mListener.getExtras(); } diff --git a/packages/Shell/tests/src/com/android/shell/UiBot.java b/packages/Shell/tests/src/com/android/shell/UiBot.java index ce9f70d8b977..60008a353d81 100644 --- a/packages/Shell/tests/src/com/android/shell/UiBot.java +++ b/packages/Shell/tests/src/com/android/shell/UiBot.java @@ -18,9 +18,12 @@ package com.android.shell; import android.app.Instrumentation; import android.app.StatusBarManager; +import android.content.Context; +import android.content.res.Resources; import android.os.SystemClock; import android.text.format.DateUtils; import android.util.Log; +import android.util.PluralsMessageFormatter; import androidx.test.uiautomator.By; import androidx.test.uiautomator.UiDevice; @@ -34,7 +37,9 @@ import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertTrue; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * A helper class for UI-related testing tasks. @@ -206,11 +211,26 @@ final class UiBot { * * @param name name of the activity as displayed in the UI (typically the value set by * {@code android:label} in the manifest). + * @param context Context of the target application + * @param count Number of files to be shared */ - public void chooseActivity(String name) { + public void chooseActivity(String name, Context context, int count) { // It uses an intent chooser now, so just getting the activity by text is enough... - final String share = mInstrumentation.getContext().getString( - com.android.internal.R.string.share); + Resources res = null; + try { + res = context.getPackageManager() + .getResourcesForApplication("com.android.intentresolver"); + } catch (Exception e) { + assertNotNull("could not get resources for com.android.intentresolver", res); + } + /* Resource read is defined as a string which contains a plural + * which needs some formatting */ + Map<String, Object> arguments = new HashMap<>(); + arguments.put("count", count); + final String share = PluralsMessageFormatter.format( + res, + arguments, + res.getIdentifier("sharing_files", "string", "com.android.intentresolver")); boolean gotIt = mDevice.wait(Until.hasObject(By.text(share)), mTimeout); assertTrue("could not get share activity (" + share + ")", gotIt); swipeUp(); diff --git a/services/art-wear-profile b/services/art-wear-profile index 47bdb1385137..42c4a01c5c2f 100644 --- a/services/art-wear-profile +++ b/services/art-wear-profile @@ -7419,7 +7419,7 @@ PLcom/android/server/app/GameManagerService;->sendUserMessage(IILjava/lang/Strin PLcom/android/server/app/GameManagerService;->updateConfigsForUser(IZ[Ljava/lang/String;)V PLcom/android/server/app/GameManagerService;->writeGameModeInterventionsToFile(I)V PLcom/android/server/app/GameManagerSettings;-><init>(Ljava/io/File;)V -HPLcom/android/server/app/GameManagerSettings;->getConfigOverride(Ljava/lang/String;)Lcom/android/server/app/GameManagerService$GamePackageConfiguration; +HPLcom/android/server/app/GameManagerSettings;->getConfigOverrideLocked(Ljava/lang/String;)Lcom/android/server/app/GameManagerService$GamePackageConfiguration; HPLcom/android/server/app/GameManagerSettings;->getGameModeLocked(Ljava/lang/String;)I PLcom/android/server/app/GameManagerSettings;->readPersistentDataLocked()Z PLcom/android/server/appbinding/AppBindingConstants;-><init>(Ljava/lang/String;)V diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java index 5f637a39674d..58ef814b67df 100644 --- a/services/core/java/com/android/server/app/GameManagerService.java +++ b/services/core/java/com/android/server/app/GameManagerService.java @@ -1422,10 +1422,10 @@ public final class GameManagerService extends IGameManagerService.Stub { } final GameManagerSettings settings = mSettings.get(userId); // look for the existing GamePackageConfiguration override - configOverride = settings.getConfigOverride(packageName); + configOverride = settings.getConfigOverrideLocked(packageName); if (configOverride == null) { configOverride = new GamePackageConfiguration(packageName); - settings.setConfigOverride(packageName, configOverride); + settings.setConfigOverrideLocked(packageName, configOverride); } } GamePackageConfiguration.GameModeConfiguration internalConfig = @@ -1758,10 +1758,10 @@ public final class GameManagerService extends IGameManagerService.Stub { } final GameManagerSettings settings = mSettings.get(userId); // look for the existing GamePackageConfiguration override - configOverride = settings.getConfigOverride(packageName); + configOverride = settings.getConfigOverrideLocked(packageName); if (configOverride == null) { configOverride = new GamePackageConfiguration(packageName); - settings.setConfigOverride(packageName, configOverride); + settings.setConfigOverrideLocked(packageName, configOverride); } } // modify GameModeConfiguration intervention settings @@ -1800,7 +1800,7 @@ public final class GameManagerService extends IGameManagerService.Stub { } final GameManagerSettings settings = mSettings.get(userId); if (gameModeToReset != -1) { - final GamePackageConfiguration configOverride = settings.getConfigOverride( + final GamePackageConfiguration configOverride = settings.getConfigOverrideLocked( packageName); if (configOverride == null) { return; @@ -1811,10 +1811,10 @@ public final class GameManagerService extends IGameManagerService.Stub { } configOverride.removeModeConfig(gameModeToReset); if (!configOverride.hasActiveGameModeConfig()) { - settings.removeConfigOverride(packageName); + settings.removeConfigOverrideLocked(packageName); } } else { - settings.removeConfigOverride(packageName); + settings.removeConfigOverrideLocked(packageName); } } @@ -2029,7 +2029,7 @@ public final class GameManagerService extends IGameManagerService.Stub { synchronized (mLock) { if (mSettings.containsKey(userId)) { - overrideConfig = mSettings.get(userId).getConfigOverride(packageName); + overrideConfig = mSettings.get(userId).getConfigOverrideLocked(packageName); } } if (overrideConfig == null || config == null) { @@ -2074,7 +2074,7 @@ public final class GameManagerService extends IGameManagerService.Stub { } synchronized (mLock) { if (mSettings.containsKey(userId)) { - mSettings.get(userId).removeGame(packageName); + mSettings.get(userId).removeGameLocked(packageName); } sendUserMessage(userId, WRITE_SETTINGS, Intent.ACTION_PACKAGE_REMOVED, WRITE_DELAY_MILLIS); diff --git a/services/core/java/com/android/server/app/GameManagerSettings.java b/services/core/java/com/android/server/app/GameManagerSettings.java index b084cf3c3b12..c57a1f73d7d7 100644 --- a/services/core/java/com/android/server/app/GameManagerSettings.java +++ b/services/core/java/com/android/server/app/GameManagerSettings.java @@ -116,7 +116,7 @@ public class GameManagerSettings { * Removes all game settings of a given package. * This operation must be synced with an external lock. */ - void removeGame(String packageName) { + void removeGameLocked(String packageName) { mGameModes.remove(packageName); mConfigOverrides.remove(packageName); } @@ -125,7 +125,7 @@ public class GameManagerSettings { * Returns the game config override of a given package or null if absent. * This operation must be synced with an external lock. */ - GamePackageConfiguration getConfigOverride(String packageName) { + GamePackageConfiguration getConfigOverrideLocked(String packageName) { return mConfigOverrides.get(packageName); } @@ -133,7 +133,7 @@ public class GameManagerSettings { * Sets the game config override of a given package. * This operation must be synced with an external lock. */ - void setConfigOverride(String packageName, GamePackageConfiguration configOverride) { + void setConfigOverrideLocked(String packageName, GamePackageConfiguration configOverride) { mConfigOverrides.put(packageName, configOverride); } @@ -141,7 +141,7 @@ public class GameManagerSettings { * Removes the game mode config override of a given package. * This operation must be synced with an external lock. */ - void removeConfigOverride(String packageName) { + void removeConfigOverrideLocked(String packageName) { mConfigOverrides.remove(packageName); } diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java index ecffd382f542..3f9144f0d980 100644 --- a/services/core/java/com/android/server/policy/AppOpsPolicy.java +++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java @@ -136,7 +136,8 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat final LocationManagerInternal locationManagerInternal = LocalServices.getService( LocationManagerInternal.class); - locationManagerInternal.setLocationPackageTagsListener( + if (locationManagerInternal != null) { + locationManagerInternal.setLocationPackageTagsListener( (uid, packageTagsList) -> { synchronized (mLock) { if (packageTagsList.isEmpty()) { @@ -158,6 +159,7 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat mLocationTags); } }); + } final IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 673d82d4d35f..fcb603628240 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -3254,7 +3254,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // just kill it. And if it is a window of foreground activity, the activity can be // restarted automatically if needed. Slog.w(TAG, "Exception thrown during dispatchAppVisibility " + this, e); - if (android.os.Process.getUidForPid(mSession.mPid) == mSession.mUid) { + if (android.os.Process.getUidForPid(mSession.mPid) == mSession.mUid + && android.os.Process.getThreadGroupLeader(mSession.mPid) == mSession.mPid) { android.os.Process.killProcess(mSession.mPid); } } diff --git a/services/tests/servicestests/src/com/android/server/app/GameManagerServiceSettingsTests.java b/services/tests/servicestests/src/com/android/server/app/GameManagerServiceSettingsTests.java index fde3422b1ff3..17f5ebb3b02a 100644 --- a/services/tests/servicestests/src/com/android/server/app/GameManagerServiceSettingsTests.java +++ b/services/tests/servicestests/src/com/android/server/app/GameManagerServiceSettingsTests.java @@ -130,9 +130,9 @@ public class GameManagerServiceSettingsTests { assertEquals(GameManager.GAME_MODE_STANDARD, settings.getGameModeLocked(PACKAGE_NAME_4)); // test game mode configs - assertNull(settings.getConfigOverride(PACKAGE_NAME_1)); - assertNull(settings.getConfigOverride(PACKAGE_NAME_3)); - GamePackageConfiguration config = settings.getConfigOverride(PACKAGE_NAME_2); + assertNull(settings.getConfigOverrideLocked(PACKAGE_NAME_1)); + assertNull(settings.getConfigOverrideLocked(PACKAGE_NAME_3)); + GamePackageConfiguration config = settings.getConfigOverrideLocked(PACKAGE_NAME_2); assertNotNull(config); assertNull(config.getGameModeConfiguration(GameManager.GAME_MODE_STANDARD)); @@ -152,7 +152,7 @@ public class GameManagerServiceSettingsTests { assertEquals(batteryConfig.getFpsStr(), GameModeConfiguration.DEFAULT_FPS); assertFalse(batteryConfig.getUseAngle()); - config = settings.getConfigOverride(PACKAGE_NAME_4); + config = settings.getConfigOverrideLocked(PACKAGE_NAME_4); assertNotNull(config); GameModeConfiguration customConfig = config.getGameModeConfiguration( GameManager.GAME_MODE_CUSTOM); @@ -177,7 +177,7 @@ public class GameManagerServiceSettingsTests { GameManagerSettings settings = new GameManagerSettings(context.getFilesDir()); assertTrue(settings.readPersistentDataLocked()); - final GamePackageConfiguration config = settings.getConfigOverride(PACKAGE_NAME_1); + final GamePackageConfiguration config = settings.getConfigOverrideLocked(PACKAGE_NAME_1); assertNotNull(config); final GameModeConfiguration batteryConfig = config.getGameModeConfiguration( GameManager.GAME_MODE_BATTERY); @@ -218,7 +218,7 @@ public class GameManagerServiceSettingsTests { assertEquals(2, settings.getGameModeLocked(PACKAGE_NAME_2)); assertEquals(3, settings.getGameModeLocked(PACKAGE_NAME_3)); - final GamePackageConfiguration config = settings.getConfigOverride(PACKAGE_NAME_2); + final GamePackageConfiguration config = settings.getConfigOverrideLocked(PACKAGE_NAME_2); assertNotNull(config); final GameModeConfiguration batteryConfig = config.getGameModeConfiguration( GameManager.GAME_MODE_BATTERY); @@ -248,7 +248,7 @@ public class GameManagerServiceSettingsTests { GameModeConfiguration batteryConfig = config.getOrAddDefaultGameModeConfiguration( GameManager.GAME_MODE_BATTERY); batteryConfig.setScaling(0.77f); - settings.setConfigOverride(PACKAGE_NAME_2, config); + settings.setConfigOverrideLocked(PACKAGE_NAME_2, config); // set config for app4 config = new GamePackageConfiguration(PACKAGE_NAME_4); @@ -256,15 +256,15 @@ public class GameManagerServiceSettingsTests { GameManager.GAME_MODE_CUSTOM); customConfig.setScaling(0.4f); customConfig.setFpsStr("30"); - settings.setConfigOverride(PACKAGE_NAME_4, config); + settings.setConfigOverrideLocked(PACKAGE_NAME_4, config); settings.writePersistentDataLocked(); // clear the settings in memory - settings.removeGame(PACKAGE_NAME_1); - settings.removeGame(PACKAGE_NAME_2); - settings.removeGame(PACKAGE_NAME_3); - settings.removeGame(PACKAGE_NAME_4); + settings.removeGameLocked(PACKAGE_NAME_1); + settings.removeGameLocked(PACKAGE_NAME_2); + settings.removeGameLocked(PACKAGE_NAME_3); + settings.removeGameLocked(PACKAGE_NAME_4); // read back in and verify assertTrue(settings.readPersistentDataLocked()); @@ -273,9 +273,9 @@ public class GameManagerServiceSettingsTests { assertEquals(1, settings.getGameModeLocked(PACKAGE_NAME_3)); assertEquals(1, settings.getGameModeLocked(PACKAGE_NAME_4)); - config = settings.getConfigOverride(PACKAGE_NAME_1); + config = settings.getConfigOverrideLocked(PACKAGE_NAME_1); assertNull(config); - config = settings.getConfigOverride(PACKAGE_NAME_2); + config = settings.getConfigOverrideLocked(PACKAGE_NAME_2); assertNotNull(config); batteryConfig = config.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY); assertNotNull(batteryConfig); @@ -292,7 +292,7 @@ public class GameManagerServiceSettingsTests { assertEquals(performanceConfig.getFpsStr(), "60"); assertTrue(performanceConfig.getUseAngle()); - config = settings.getConfigOverride(PACKAGE_NAME_4); + config = settings.getConfigOverrideLocked(PACKAGE_NAME_4); assertNotNull(config); customConfig = config.getGameModeConfiguration(GameManager.GAME_MODE_CUSTOM); assertNotNull(customConfig); |