Merge "Honor retry timer from setup data call response for emergency request" into udc-qpr-dev
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 66d04a3..42e0e2d 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -5717,6 +5717,25 @@
}
/**
+ * Used by ThemeOverlayController to notify when color
+ * palette is ready.
+ *
+ * @param userId The ID of the user where ThemeOverlayController is ready.
+ *
+ * @throws RemoteException
+ *
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.SET_THEME_OVERLAY_CONTROLLER_READY)
+ public void setThemeOverlayReady(@UserIdInt int userId) {
+ try {
+ getService().setThemeOverlayReady(userId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Resets the state of the {@link com.android.server.am.AppErrors} instance.
* This is intended for use with CTS only.
* @hide
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 32c40df..384d7db 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -1234,4 +1234,11 @@
*/
public abstract boolean clearApplicationUserData(String packageName, boolean keepState,
boolean isRestore, IPackageDataObserver observer, int userId);
+
+ /**
+ * Returns current state of {@link com.android.systemui.theme.ThemeOverlayController} color
+ * palette readiness.
+ * @hide
+ */
+ public abstract boolean isThemeOverlayReady(int userId);
}
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 37616e7..30dd374 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -550,6 +550,17 @@
@UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
boolean isTopOfTask(in IBinder token);
void bootAnimationComplete();
+
+ /**
+ * Used by {@link com.android.systemui.theme.ThemeOverlayController} to notify when color
+ * palette is ready.
+ *
+ * @param userId The ID of the user where ThemeOverlayController is ready.
+ *
+ * @throws RemoteException
+ */
+ void setThemeOverlayReady(int userId);
+
@UnsupportedAppUsage
void registerTaskStackListener(in ITaskStackListener listener);
void unregisterTaskStackListener(in ITaskStackListener listener);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index cbb6e74..fbe678f 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -7302,6 +7302,11 @@
<permission android:name="android.permission.RESET_APP_ERRORS"
android:protectionLevel="signature" />
+ <!-- @hide Allows ThemeOverlayController to delay launch of Home / SetupWizard on boot, ensuring
+ Theme Palettes and Colors are ready -->
+ <permission android:name="android.permission.SET_THEME_OVERLAY_CONTROLLER_READY"
+ android:protectionLevel="signature|setup" />
+
<!-- @hide Allows an application to create/destroy input consumer. -->
<permission android:name="android.permission.INPUT_CONSUMER"
android:protectionLevel="signature" />
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 430492b..b89085b 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1731,7 +1731,7 @@
<string name="user_switched" msgid="7249833311585228097">"Τρέχων χρήστης <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Εναλλαγή σε <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Αποσύνδεση <xliff:g id="NAME">%1$s</xliff:g>…"</string>
- <string name="owner_name" msgid="8713560351570795743">"Κάτοχος"</string>
+ <string name="owner_name" msgid="8713560351570795743">"Κάτοχο"</string>
<string name="guest_name" msgid="8502103277839834324">"Επισκέπτης"</string>
<string name="error_message_title" msgid="4082495589294631966">"Σφάλμα"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Αυτή η αλλαγή δεν επιτρέπεται από το διαχειριστή σας"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index c165650..8b00431 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -499,8 +499,8 @@
<string name="permdesc_backgroundCamera" msgid="1615291686191138250">"แอปนี้ถ่ายภาพและวิดีโอด้วยกล้องได้ทุกเมื่อ"</string>
<string name="permlab_systemCamera" msgid="3642917457796210580">"อนุญาตให้แอปพลิเคชันหรือบริการเข้าถึงกล้องของระบบเพื่อถ่ายภาพและวิดีโอ"</string>
<string name="permdesc_systemCamera" msgid="5938360914419175986">"แอปของระบบหรือที่ได้รับสิทธิ์นี้จะถ่ายภาพและบันทึกวิดีโอโดยใช้กล้องของระบบได้ทุกเมื่อ แอปต้องมีสิทธิ์ android.permission.CAMERA ด้วย"</string>
- <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"อนุญาตให้แอปพลิเคชันหรือบริการได้รับโค้ดเรียกกลับเมื่อมีการเปิดหรือปิดอุปกรณ์กล้อง"</string>
- <string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"แอปนี้จะได้รับโค้ดเรียกกลับเมื่อมีการปิดหรือเปิดอุปกรณ์กล้อง (โดยแอปพลิเคชันที่เปิด)"</string>
+ <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"อนุญาตให้แอปพลิเคชันหรือบริการได้รับ Callback เมื่อมีการเปิดหรือปิดอุปกรณ์กล้อง"</string>
+ <string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"แอปนี้จะได้รับ Callback เมื่อมีการปิดหรือเปิดอุปกรณ์กล้อง (โดยแอปพลิเคชันที่เปิด)"</string>
<string name="permlab_vibrate" msgid="8596800035791962017">"ควบคุมการสั่นเตือน"</string>
<string name="permdesc_vibrate" msgid="8733343234582083721">"อนุญาตให้แอปพลิเคชันควบคุมการสั่นเตือน"</string>
<string name="permdesc_vibrator_state" msgid="7050024956594170724">"อนุญาตให้แอปเข้าถึงสถานะการสั่น"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 6ac22b2..0eebc05 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -186,7 +186,7 @@
<string name="tts_play_example_title" msgid="1599468547216481684">"Kuuntele esimerkki"</string>
<string name="tts_play_example_summary" msgid="634044730710636383">"Toista lyhyt esittely puhesynteesistä"</string>
<string name="tts_install_data_title" msgid="1829942496472751703">"Asenna äänidata"</string>
- <string name="tts_install_data_summary" msgid="3608874324992243851">"Asenna puhesynteesiin tarvittavat äänitiedot"</string>
+ <string name="tts_install_data_summary" msgid="3608874324992243851">"Asenna puhesynteesiin tarvittava äänidata"</string>
<string name="tts_engine_security_warning" msgid="3372432853837988146">"Tämä puhesynteesimoottori saattaa kerätä kaiken puhutun tekstin, mukaan lukien henkilökohtaiset tiedot kuten salasanat ja luottokorttinumerot. Se on lähtöisin moottorista <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>. Haluatko ottaa tämän puhesynteesimoottorin käyttöön?"</string>
<string name="tts_engine_network_required" msgid="8722087649733906851">"Tämä kieli vaatii verkkoyhteyden, jotta tekstistä puheeksi muuntaminen toimii."</string>
<string name="tts_default_sample_string" msgid="6388016028292967973">"Tämä on esimerkki puhesynteesistä."</string>
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 4fd4723..2d9b1ee 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -256,6 +256,9 @@
<uses-permission android:name="android.permission.MODIFY_THEME_OVERLAY" />
+ <!-- Activity Manager -->
+ <uses-permission android:name="android.permission.SET_THEME_OVERLAY_CONTROLLER_READY" />
+
<!-- accessibility -->
<uses-permission android:name="android.permission.MODIFY_ACCESSIBILITY_DATA" />
<uses-permission android:name="android.permission.MANAGE_ACCESSIBILITY" />
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 1b9c117..f14827c 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -266,7 +266,7 @@
<string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"אין רשתות זמינות"</string>
<string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"אין רשתות Wi-Fi זמינות"</string>
<string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"בתהליך הפעלה…"</string>
- <string name="quick_settings_cast_title" msgid="2279220930629235211">"העברת מסך"</string>
+ <string name="quick_settings_cast_title" msgid="2279220930629235211">"הפעלת Cast למסך"</string>
<string name="quick_settings_casting" msgid="1435880708719268055">"מתבצעת העברה (cast)"</string>
<string name="quick_settings_cast_device_default_name" msgid="6988469571141331700">"מכשיר ללא שם"</string>
<string name="quick_settings_cast_detail_empty_text" msgid="2846282280014617785">"אין מכשירים זמינים"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 883302e..8d3caae 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -274,7 +274,7 @@
<string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Luminozitate"</string>
<string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inversarea culorilor"</string>
<string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Corecția culorii"</string>
- <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Dimensiunea fontului"</string>
+ <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Mărimea fontului"</string>
<string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Gestionează"</string>
<string name="quick_settings_done" msgid="2163641301648855793">"Terminat"</string>
<string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Închide"</string>
@@ -850,7 +850,7 @@
<string name="privacy_type_media_projection" msgid="8136723828804251547">"înregistrare de ecran"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Fără titlu"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string>
- <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Dimensiunea fontului"</string>
+ <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Mărimea fontului"</string>
<string name="font_scaling_smaller" msgid="1012032217622008232">"Micșorează"</string>
<string name="font_scaling_larger" msgid="5476242157436806760">"Mărește"</string>
<string name="magnification_window_title" msgid="4863914360847258333">"Fereastra de mărire"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 5eb80fc..00912d9 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -893,7 +893,7 @@
<string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Erişilebilirlik özelliklerini açmak için dokunun. Bu düğmeyi Ayarlar\'dan özelleştirin veya değiştirin.\n\n"<annotation id="link">"Ayarları göster"</annotation></string>
<string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Düğmeyi geçici olarak gizlemek için kenara taşıyın"</string>
<string name="accessibility_floating_button_undo" msgid="511112888715708241">"Geri al"</string>
- <string name="accessibility_floating_button_undo_message_label_text" msgid="9017658016426242640">"<xliff:g id="FEATURE_NAME">%s</xliff:g> kısayol kaldırıldı"</string>
+ <string name="accessibility_floating_button_undo_message_label_text" msgid="9017658016426242640">"<xliff:g id="FEATURE_NAME">%s</xliff:g> kısayolu kaldırıldı"</string>
<string name="accessibility_floating_button_undo_message_number_text" msgid="4909270290725226075">"{count,plural, =1{# kısayol kaldırıldı}other{# kısayol kaldırıldı}}"</string>
<string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"Sol üste taşı"</string>
<string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"Sağ üste taşı"</string>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButton.java b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButton.java
index 5d036fb..b44bf39 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButton.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButton.java
@@ -71,7 +71,6 @@
private AnimatedVectorDrawable mAnimatedDrawable;
private boolean mIsShowing;
- private boolean mCanShow = true;
private int mDisplayRotation;
private boolean mIsTaskbarVisible = false;
@@ -150,7 +149,7 @@
@Override
public boolean show() {
- if (!mCanShow || mIsShowing) {
+ if (mIsShowing) {
return false;
}
@@ -222,14 +221,6 @@
}
@Override
- public void setCanShowRotationButton(boolean canShow) {
- mCanShow = canShow;
- if (!mCanShow) {
- hide();
- }
- }
-
- @Override
public void onTaskbarStateChanged(boolean taskbarVisible, boolean taskbarStashed) {
mIsTaskbarVisible = taskbarVisible;
mIsTaskbarStashed = taskbarStashed;
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButton.java b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButton.java
index 89f71eb..42dda0a 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButton.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButton.java
@@ -36,7 +36,6 @@
default boolean isVisible() {
return false;
}
- default void setCanShowRotationButton(boolean canShow) {}
default void onTaskbarStateChanged(boolean taskbarVisible, boolean taskbarStashed) {}
default void updateIcon(int lightIconColor, int darkIconColor) { }
default void setOnClickListener(View.OnClickListener onClickListener) { }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
index 79e7b71..4bb39d0 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
@@ -584,7 +584,6 @@
if (!visible) {
mTransitionListener.onBackAltCleared();
}
- mRotationButtonController.getRotationButton().setCanShowRotationButton(!visible);
}
void setDisabledFlags(int disabledFlags, SysUiState sysUiState) {
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java
index 3376e23..91df866 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java
@@ -32,6 +32,7 @@
import com.android.systemui.Dumpable;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.google.android.collect.Lists;
@@ -142,6 +143,7 @@
private final Map<String, String> mCategoryToTargetPackage = new ArrayMap<>();
private final OverlayManager mOverlayManager;
private final Executor mBgExecutor;
+ private final Executor mMainExecutor;
private final String mLauncherPackage;
private final String mThemePickerPackage;
@@ -150,9 +152,11 @@
@Background Executor bgExecutor,
@Named(ThemeModule.LAUNCHER_PACKAGE) String launcherPackage,
@Named(ThemeModule.THEME_PICKER_PACKAGE) String themePickerPackage,
- DumpManager dumpManager) {
+ DumpManager dumpManager,
+ @Main Executor mainExecutor) {
mOverlayManager = overlayManager;
mBgExecutor = bgExecutor;
+ mMainExecutor = mainExecutor;
mLauncherPackage = launcherPackage;
mThemePickerPackage = themePickerPackage;
mTargetPackageToCategories.put(ANDROID_PACKAGE, Sets.newHashSet(
@@ -184,12 +188,21 @@
/**
* Apply the set of overlay packages to the set of {@code UserHandle}s provided. Overlays that
* affect sysui will also be applied to the system user.
+ *
+ * @param categoryToPackage Overlay packages to be applied
+ * @param pendingCreation Overlays yet to be created
+ * @param currentUser Current User ID
+ * @param managedProfiles Profiles get overlays
+ * @param onComplete Callback for when resources are ready. Runs in the main thread.
*/
public void applyCurrentUserOverlays(
Map<String, OverlayIdentifier> categoryToPackage,
FabricatedOverlay[] pendingCreation,
int currentUser,
- Set<UserHandle> managedProfiles) {
+ Set<UserHandle> managedProfiles,
+ Runnable onComplete
+ ) {
+
mBgExecutor.execute(() -> {
// Disable all overlays that have not been specified in the user setting.
@@ -236,6 +249,10 @@
try {
mOverlayManager.commit(transaction.build());
+ if (onComplete != null) {
+ Log.d(TAG, "Executing onComplete runnable");
+ mMainExecutor.execute(onComplete);
+ }
} catch (SecurityException | IllegalStateException e) {
Log.e(TAG, "setEnabled failed", e);
}
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index 5a9f5d5..8e69499 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -30,6 +30,7 @@
import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_COLOR_SOURCE;
import static com.android.systemui.theme.ThemeOverlayApplier.TIMESTAMP_FIELD;
+import android.app.ActivityManager;
import android.app.UiModeManager;
import android.app.WallpaperColors;
import android.app.WallpaperManager;
@@ -137,6 +138,7 @@
// Current wallpaper colors associated to a user.
private final SparseArray<WallpaperColors> mCurrentColors = new SparseArray<>();
private final WallpaperManager mWallpaperManager;
+ private final ActivityManager mActivityManager;
@VisibleForTesting
protected ColorScheme mColorScheme;
// If fabricated overlays were already created for the current theme.
@@ -395,7 +397,8 @@
FeatureFlags featureFlags,
@Main Resources resources,
WakefulnessLifecycle wakefulnessLifecycle,
- UiModeManager uiModeManager) {
+ UiModeManager uiModeManager,
+ ActivityManager activityManager) {
mContext = context;
mIsMonochromaticEnabled = featureFlags.isEnabled(Flags.MONOCHROMATIC_THEME);
mIsMonetEnabled = featureFlags.isEnabled(Flags.MONET);
@@ -413,6 +416,7 @@
mResources = resources;
mWakefulnessLifecycle = wakefulnessLifecycle;
mUiModeManager = uiModeManager;
+ mActivityManager = activityManager;
dumpManager.registerDumpable(TAG, this);
}
@@ -764,8 +768,14 @@
}
}
+ final Runnable onCompleteCallback = () -> {
+ Log.d(TAG, "ThemeHomeDelay: ThemeOverlayController ready");
+ mActivityManager.setThemeOverlayReady(currentUser);
+ };
+
if (colorSchemeIsApplied(managedProfiles)) {
Log.d(TAG, "Skipping overlay creation. Theme was already: " + mColorScheme);
+ onCompleteCallback.run();
return;
}
@@ -774,16 +784,20 @@
.map(key -> key + " -> " + categoryToPackage.get(key)).collect(
Collectors.joining(", ")));
}
+
+ FabricatedOverlay[] fOverlays = null;
+
if (mNeedsOverlayCreation) {
mNeedsOverlayCreation = false;
- mThemeManager.applyCurrentUserOverlays(categoryToPackage, new FabricatedOverlay[]{
+ fOverlays = new FabricatedOverlay[]{
mSecondaryOverlay, mNeutralOverlay, mDynamicOverlay
- }, currentUser, managedProfiles);
- } else {
- mThemeManager.applyCurrentUserOverlays(categoryToPackage, null, currentUser,
- managedProfiles);
+ };
}
- }
+
+ mThemeManager.applyCurrentUserOverlays(categoryToPackage, fOverlays, currentUser,
+ managedProfiles, onCompleteCallback);
+
+ }
private Style fetchThemeStyleFromSetting() {
// Allow-list of Style objects that can be created from a setting string, i.e. can be
diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayApplierTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayApplierTest.java
index 83439f0..8f4cbaf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayApplierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayApplierTest.java
@@ -104,9 +104,9 @@
@Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
- mManager = new ThemeOverlayApplier(mOverlayManager,
- MoreExecutors.directExecutor(),
- LAUNCHER_PACKAGE, THEMEPICKER_PACKAGE, mDumpManager) {
+ mManager = new ThemeOverlayApplier(mOverlayManager, MoreExecutors.directExecutor(),
+ LAUNCHER_PACKAGE, THEMEPICKER_PACKAGE, mDumpManager,
+ MoreExecutors.directExecutor()) {
@Override
protected OverlayManagerTransaction.Builder getTransactionBuilder() {
return mTransactionBuilder;
@@ -179,7 +179,7 @@
@Test
public void allCategoriesSpecified_allEnabledExclusively() {
mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, null, TEST_USER.getIdentifier(),
- TEST_USER_HANDLES);
+ TEST_USER_HANDLES, null);
verify(mOverlayManager).commit(any());
for (OverlayIdentifier overlayPackage : ALL_CATEGORIES_MAP.values()) {
@@ -191,7 +191,7 @@
@Test
public void allCategoriesSpecified_sysuiCategoriesAlsoAppliedToSysuiUser() {
mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, null, TEST_USER.getIdentifier(),
- TEST_USER_HANDLES);
+ TEST_USER_HANDLES, null);
for (Map.Entry<String, OverlayIdentifier> entry : ALL_CATEGORIES_MAP.entrySet()) {
if (SYSTEM_USER_CATEGORIES.contains(entry.getKey())) {
@@ -208,7 +208,7 @@
public void allCategoriesSpecified_enabledForAllUserHandles() {
Set<UserHandle> userHandles = Sets.newHashSet(TEST_USER_HANDLES);
mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, null, TEST_USER.getIdentifier(),
- userHandles);
+ userHandles, null);
for (OverlayIdentifier overlayPackage : ALL_CATEGORIES_MAP.values()) {
verify(mTransactionBuilder).setEnabled(eq(overlayPackage), eq(true),
@@ -225,7 +225,7 @@
Set<UserHandle> userHandles = Sets.newHashSet(TEST_USER_HANDLES);
mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, null, TEST_USER.getIdentifier(),
- userHandles);
+ userHandles, null);
for (OverlayIdentifier overlayPackage : ALL_CATEGORIES_MAP.values()) {
verify(mTransactionBuilder, never()).setEnabled(eq(overlayPackage), eq(true),
@@ -239,7 +239,7 @@
mock(FabricatedOverlay.class)
};
mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, pendingCreation,
- TEST_USER.getIdentifier(), TEST_USER_HANDLES);
+ TEST_USER.getIdentifier(), TEST_USER_HANDLES, null);
for (FabricatedOverlay overlay : pendingCreation) {
verify(mTransactionBuilder).registerFabricatedOverlay(eq(overlay));
@@ -253,7 +253,7 @@
categoryToPackage.remove(OVERLAY_CATEGORY_ICON_ANDROID);
mManager.applyCurrentUserOverlays(categoryToPackage, null, TEST_USER.getIdentifier(),
- TEST_USER_HANDLES);
+ TEST_USER_HANDLES, null);
for (OverlayIdentifier overlayPackage : categoryToPackage.values()) {
verify(mTransactionBuilder).setEnabled(eq(overlayPackage), eq(true),
@@ -270,7 +270,7 @@
@Test
public void zeroCategoriesSpecified_allDisabled() {
mManager.applyCurrentUserOverlays(Maps.newArrayMap(), null, TEST_USER.getIdentifier(),
- TEST_USER_HANDLES);
+ TEST_USER_HANDLES, null);
for (String category : THEME_CATEGORIES) {
verify(mTransactionBuilder).setEnabled(
@@ -285,7 +285,7 @@
categoryToPackage.put("blah.category", new OverlayIdentifier("com.example.blah.category"));
mManager.applyCurrentUserOverlays(categoryToPackage, null, TEST_USER.getIdentifier(),
- TEST_USER_HANDLES);
+ TEST_USER_HANDLES, null);
verify(mTransactionBuilder, never()).setEnabled(
eq(new OverlayIdentifier("com.example.blah.category")), eq(false),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
index c454b45..8858f0f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
@@ -36,6 +36,7 @@
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
+import android.app.ActivityManager;
import android.app.UiModeManager;
import android.app.WallpaperColors;
import android.app.WallpaperManager;
@@ -120,6 +121,8 @@
private WakefulnessLifecycle mWakefulnessLifecycle;
@Mock
private UiModeManager mUiModeManager;
+ @Mock
+ private ActivityManager mActivityManager;
@Captor
private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiver;
@Captor
@@ -154,7 +157,7 @@
mBroadcastDispatcher, mBgHandler, mMainExecutor, mBgExecutor, mThemeOverlayApplier,
mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle,
- mUiModeManager) {
+ mUiModeManager, mActivityManager) {
@VisibleForTesting
protected boolean isNightMode() {
return false;
@@ -206,7 +209,7 @@
ArgumentCaptor.forClass(Map.class);
verify(mThemeOverlayApplier)
- .applyCurrentUserOverlays(themeOverlays.capture(), any(), anyInt(), any());
+ .applyCurrentUserOverlays(themeOverlays.capture(), any(), anyInt(), any(), any());
// Assert that we received the colors that we were expecting
assertThat(themeOverlays.getValue().get(OVERLAY_CATEGORY_SYSTEM_PALETTE))
@@ -231,7 +234,7 @@
mBroadcastReceiver.getValue().onReceive(null, intent);
mColorsListener.getValue().onColorsChanged(new WallpaperColors(Color.valueOf(Color.BLACK),
null, null), WallpaperManager.FLAG_SYSTEM, USER_SYSTEM);
- verify(mThemeOverlayApplier).applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ verify(mThemeOverlayApplier).applyCurrentUserOverlays(any(), any(), anyInt(), any(), any());
}
@Test
@@ -245,7 +248,7 @@
ArgumentCaptor.forClass(Map.class);
verify(mThemeOverlayApplier)
- .applyCurrentUserOverlays(themeOverlays.capture(), any(), anyInt(), any());
+ .applyCurrentUserOverlays(themeOverlays.capture(), any(), anyInt(), any(), any());
// Should not change theme after changing wallpapers, if intent doesn't have
// WallpaperManager.EXTRA_FROM_FOREGROUND_APP set to true.
@@ -254,7 +257,7 @@
mColorsListener.getValue().onColorsChanged(new WallpaperColors(Color.valueOf(Color.BLACK),
null, null), WallpaperManager.FLAG_SYSTEM, USER_SYSTEM);
verify(mThemeOverlayApplier, never())
- .applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ .applyCurrentUserOverlays(any(), any(), anyInt(), any(), any());
}
@Test
@@ -276,7 +279,7 @@
ArgumentCaptor.forClass(Map.class);
verify(mThemeOverlayApplier)
- .applyCurrentUserOverlays(themeOverlays.capture(), any(), anyInt(), any());
+ .applyCurrentUserOverlays(themeOverlays.capture(), any(), anyInt(), any(), any());
// Assert that we received the colors that we were expecting
assertThat(themeOverlays.getValue().get(OVERLAY_CATEGORY_SYSTEM_PALETTE))
@@ -315,7 +318,7 @@
.isFalse();
verify(mThemeOverlayApplier)
- .applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ .applyCurrentUserOverlays(any(), any(), anyInt(), any(), any());
}
@Test
@@ -350,7 +353,7 @@
"android.theme.customization.color_both\":\"0")).isTrue();
verify(mThemeOverlayApplier)
- .applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ .applyCurrentUserOverlays(any(), any(), anyInt(), any(), any());
}
@Test
@@ -405,7 +408,7 @@
assertThat(updatedSetting.getValue().contains(
"android.theme.customization.color_both\":\"1")).isTrue();
verify(mThemeOverlayApplier)
- .applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ .applyCurrentUserOverlays(any(), any(), anyInt(), any(), any());
}
@Test
@@ -474,7 +477,7 @@
"android.theme.customization.color_both\":\"1")).isTrue();
verify(mThemeOverlayApplier)
- .applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ .applyCurrentUserOverlays(any(), any(), anyInt(), any(), any());
}
@Test
@@ -505,7 +508,7 @@
assertThat(updatedSetting.getValue().contains("android.theme.customization.color_index"))
.isFalse();
verify(mThemeOverlayApplier)
- .applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ .applyCurrentUserOverlays(any(), any(), anyInt(), any(), any());
}
@Test
@@ -536,7 +539,7 @@
assertThat(updatedSetting.getValue().contains("android.theme.customization.color_index"))
.isFalse();
verify(mThemeOverlayApplier)
- .applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ .applyCurrentUserOverlays(any(), any(), anyInt(), any(), any());
}
@Test
@@ -569,7 +572,7 @@
anyInt());
verify(mThemeOverlayApplier)
- .applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ .applyCurrentUserOverlays(any(), any(), anyInt(), any(), any());
}
@Test
@@ -602,7 +605,7 @@
eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), updatedSetting.capture());
// Apply overlay by existing theme from secure setting
- verify(mThemeOverlayApplier).applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ verify(mThemeOverlayApplier).applyCurrentUserOverlays(any(), any(), anyInt(), any(), any());
}
@Test
@@ -635,7 +638,7 @@
verify(mThemeOverlayApplier, never())
- .applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ .applyCurrentUserOverlays(any(), any(), anyInt(), any(), any());
}
@Test
@@ -657,7 +660,7 @@
ArgumentCaptor<Map<String, OverlayIdentifier>> themeOverlays =
ArgumentCaptor.forClass(Map.class);
verify(mThemeOverlayApplier)
- .applyCurrentUserOverlays(themeOverlays.capture(), any(), anyInt(), any());
+ .applyCurrentUserOverlays(themeOverlays.capture(), any(), anyInt(), any(), any());
// Assert that we received secondary user colors
assertThat(themeOverlays.getValue().get(OVERLAY_CATEGORY_SYSTEM_PALETTE))
@@ -670,7 +673,7 @@
public void onProfileAdded_setsTheme() {
mBroadcastReceiver.getValue().onReceive(null,
new Intent(Intent.ACTION_MANAGED_PROFILE_ADDED));
- verify(mThemeOverlayApplier).applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ verify(mThemeOverlayApplier).applyCurrentUserOverlays(any(), any(), anyInt(), any(), any());
}
@Test
@@ -680,7 +683,7 @@
mBroadcastReceiver.getValue().onReceive(null,
new Intent(Intent.ACTION_MANAGED_PROFILE_ADDED));
verify(mThemeOverlayApplier)
- .applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ .applyCurrentUserOverlays(any(), any(), anyInt(), any(), any());
}
@Test
@@ -690,7 +693,7 @@
mBroadcastReceiver.getValue().onReceive(null,
new Intent(Intent.ACTION_MANAGED_PROFILE_ADDED));
verify(mThemeOverlayApplier, never())
- .applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ .applyCurrentUserOverlays(any(), any(), anyInt(), any(), any());
}
@Test
@@ -703,7 +706,7 @@
mColorsListener.getValue().onColorsChanged(mainColors, WallpaperManager.FLAG_SYSTEM,
USER_SYSTEM);
- verify(mThemeOverlayApplier).applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ verify(mThemeOverlayApplier).applyCurrentUserOverlays(any(), any(), anyInt(), any(), any());
// Regression test: null events should not reset the internal state and allow colors to be
// applied again.
@@ -713,11 +716,11 @@
mBroadcastReceiver.getValue().onReceive(null, intent);
mColorsListener.getValue().onColorsChanged(null, WallpaperManager.FLAG_SYSTEM, USER_SYSTEM);
verify(mThemeOverlayApplier, never()).applyCurrentUserOverlays(any(), any(), anyInt(),
- any());
+ any(), any());
mColorsListener.getValue().onColorsChanged(new WallpaperColors(Color.valueOf(Color.GREEN),
null, null), WallpaperManager.FLAG_SYSTEM, USER_SYSTEM);
verify(mThemeOverlayApplier, never()).applyCurrentUserOverlays(any(), any(), anyInt(),
- any());
+ any(), any());
}
@Test
@@ -736,7 +739,7 @@
mBroadcastDispatcher, mBgHandler, executor, executor, mThemeOverlayApplier,
mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle,
- mUiModeManager) {
+ mUiModeManager, mActivityManager) {
@VisibleForTesting
protected boolean isNightMode() {
return false;
@@ -757,7 +760,7 @@
verify(mDeviceProvisionedController).addCallback(mDeviceProvisionedListener.capture());
// Colors were applied during controller initialization.
- verify(mThemeOverlayApplier).applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ verify(mThemeOverlayApplier).applyCurrentUserOverlays(any(), any(), anyInt(), any(), any());
clearInvocations(mThemeOverlayApplier);
}
@@ -776,7 +779,7 @@
mBroadcastDispatcher, mBgHandler, executor, executor, mThemeOverlayApplier,
mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle,
- mUiModeManager) {
+ mUiModeManager, mActivityManager) {
@VisibleForTesting
protected boolean isNightMode() {
return false;
@@ -797,7 +800,7 @@
verify(mDeviceProvisionedController).addCallback(mDeviceProvisionedListener.capture());
// Colors were applied during controller initialization.
- verify(mThemeOverlayApplier).applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ verify(mThemeOverlayApplier).applyCurrentUserOverlays(any(), any(), anyInt(), any(), any());
clearInvocations(mThemeOverlayApplier);
WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED),
@@ -819,12 +822,12 @@
// Defers event because we already have initial colors.
verify(mThemeOverlayApplier, never())
- .applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ .applyCurrentUserOverlays(any(), any(), anyInt(), any(), any());
// Then event happens after setup phase is over.
when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
mDeviceProvisionedListener.getValue().onUserSetupChanged();
- verify(mThemeOverlayApplier).applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ verify(mThemeOverlayApplier).applyCurrentUserOverlays(any(), any(), anyInt(), any(), any());
}
@Test
@@ -847,11 +850,11 @@
mColorsListener.getValue().onColorsChanged(mainColors, WallpaperManager.FLAG_SYSTEM,
USER_SYSTEM);
verify(mThemeOverlayApplier, never())
- .applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ .applyCurrentUserOverlays(any(), any(), anyInt(), any(), any());
mWakefulnessLifecycle.dispatchFinishedGoingToSleep();
verify(mThemeOverlayApplier, never())
- .applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ .applyCurrentUserOverlays(any(), any(), anyInt(), any(), any());
}
@Test
@@ -873,10 +876,10 @@
mColorsListener.getValue().onColorsChanged(mainColors, WallpaperManager.FLAG_SYSTEM,
USER_SYSTEM);
verify(mThemeOverlayApplier, never())
- .applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ .applyCurrentUserOverlays(any(), any(), anyInt(), any(), any());
mWakefulnessLifecycleObserver.getValue().onFinishedGoingToSleep();
- verify(mThemeOverlayApplier).applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ verify(mThemeOverlayApplier).applyCurrentUserOverlays(any(), any(), anyInt(), any(), any());
}
@Test
@@ -896,7 +899,7 @@
ArgumentCaptor.forClass(Map.class);
verify(mThemeOverlayApplier)
- .applyCurrentUserOverlays(themeOverlays.capture(), any(), anyInt(), any());
+ .applyCurrentUserOverlays(themeOverlays.capture(), any(), anyInt(), any(), any());
// Assert that we received the colors that we were expecting
assertThat(themeOverlays.getValue().get(OVERLAY_CATEGORY_SYSTEM_PALETTE))
@@ -915,19 +918,19 @@
mColorsListener.getValue().onColorsChanged(startingColors, WallpaperManager.FLAG_SYSTEM,
USER_SYSTEM);
verify(mThemeOverlayApplier)
- .applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ .applyCurrentUserOverlays(any(), any(), anyInt(), any(), any());
clearInvocations(mThemeOverlayApplier);
// Set to the same colors.
mColorsListener.getValue().onColorsChanged(sameColors, WallpaperManager.FLAG_SYSTEM,
USER_SYSTEM);
verify(mThemeOverlayApplier, never())
- .applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ .applyCurrentUserOverlays(any(), any(), anyInt(), any(), any());
// Verify that no change resulted.
mWakefulnessLifecycleObserver.getValue().onFinishedGoingToSleep();
verify(mThemeOverlayApplier, never()).applyCurrentUserOverlays(any(), any(), anyInt(),
- any());
+ any(), any());
}
@Test
@@ -941,7 +944,7 @@
ArgumentCaptor.forClass(FabricatedOverlay[].class);
verify(mThemeOverlayApplier)
- .applyCurrentUserOverlays(any(), themeOverlays.capture(), anyInt(), any());
+ .applyCurrentUserOverlays(any(), themeOverlays.capture(), anyInt(), any(), any());
FabricatedOverlay[] overlays = themeOverlays.getValue();
FabricatedOverlay accents = overlays[0];
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 4dad2d5..ec80445 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -513,6 +513,7 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiFunction;
import java.util.function.Consumer;
@@ -910,6 +911,16 @@
@GuardedBy("this")
final ComponentAliasResolver mComponentAliasResolver;
+ private static final long HOME_LAUNCH_TIMEOUT_MS = 15000;
+ private final AtomicBoolean mHasHomeDelay = new AtomicBoolean(false);
+
+ /**
+ * Tracks all users with computed color resources by ThemeOverlaycvontroller
+ */
+ @GuardedBy("this")
+ private final Set<Integer> mThemeOverlayReadyUsers = new HashSet<>();
+
+
/**
* Tracks association information for a particular package along with debuggability.
* <p> Associations for a package A are allowed to package B if B is part of the
@@ -2269,6 +2280,7 @@
mService.startBroadcastObservers();
} else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
mService.mPackageWatchdog.onPackagesReady();
+ mService.scheduleHomeTimeout();
}
}
@@ -5235,6 +5247,61 @@
}
}
+ /**
+ * Starts Home if there is no completion signal from ThemeOverlayController
+ */
+ private void scheduleHomeTimeout() {
+ if (mHasHomeDelay.compareAndSet(false, true)) {
+ int userId = mUserController.getCurrentUserId();
+ mHandler.postDelayed(() -> {
+ if (!isThemeOverlayReady(userId)) {
+ Slog.d(TAG,
+ "ThemeHomeDelay: ThemeOverlayController not responding, launching "
+ + "Home after "
+ + HOME_LAUNCH_TIMEOUT_MS + "ms");
+ setThemeOverlayReady(userId);
+ }
+ }, HOME_LAUNCH_TIMEOUT_MS);
+ }
+ }
+
+ /**
+ * Used by ThemeOverlayController to notify when color
+ * palette is ready.
+ *
+ * @param userId The ID of the user where ThemeOverlayController is ready.
+ *
+ * @throws RemoteException
+ *
+ * @hide
+ */
+ @Override
+ public void setThemeOverlayReady(@UserIdInt int userId) {
+ enforceCallingPermission(Manifest.permission.SET_THEME_OVERLAY_CONTROLLER_READY,
+ "setThemeOverlayReady");
+
+ boolean updateUser;
+ synchronized (mThemeOverlayReadyUsers) {
+ updateUser = mThemeOverlayReadyUsers.add(userId);
+ }
+
+ if (updateUser) {
+ mAtmInternal.startHomeOnAllDisplays(userId, "setThemeOverlayReady");
+ }
+ }
+
+ /**
+ * Returns current state of ThemeOverlayController color
+ * palette readiness.
+ *
+ * @hide
+ */
+ public boolean isThemeOverlayReady(int userId) {
+ synchronized (mThemeOverlayReadyUsers) {
+ return mThemeOverlayReadyUsers.contains(userId);
+ }
+ }
+
final void ensureBootCompleted() {
boolean booting;
boolean enableScreen;
@@ -17612,6 +17679,10 @@
mAtmInternal.onUserStopped(userId);
// Clean up various services by removing the user
mBatteryStatsService.onUserRemoved(userId);
+
+ synchronized (mThemeOverlayReadyUsers) {
+ mThemeOverlayReadyUsers.remove(userId);
+ }
}
@Override
@@ -18966,6 +19037,11 @@
return ActivityManagerService.this.clearApplicationUserData(packageName, keepState,
isRestore, observer, userId);
}
+
+ @Override
+ public boolean isThemeOverlayReady(int userId) {
+ return ActivityManagerService.this.isThemeOverlayReady(userId);
+ }
}
long inputDispatchingTimedOut(int pid, final boolean aboveSystem, TimeoutRecord timeoutRecord) {
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index 4b8b431..b4e27d7 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -1415,11 +1415,11 @@
.getDrawable(R.drawable.ic_safety_protection);
toastToShow = Toast.makeCustomToastWithIcon(toastContext,
UiThread.get().getLooper(), message,
- Toast.LENGTH_SHORT, safetyProtectionIcon);
+ Toast.LENGTH_LONG, safetyProtectionIcon);
} else {
toastToShow = Toast.makeText(
toastContext, UiThread.get().getLooper(), message,
- Toast.LENGTH_SHORT);
+ Toast.LENGTH_LONG);
}
toastToShow.show();
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index cddc71b..5f855f2 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -3393,8 +3393,19 @@
null /* options */);
record = getToastRecord(callingUid, callingPid, pkg, isSystemToast, token,
text, callback, duration, windowToken, displayId, textCallback);
- mToastQueue.add(record);
- index = mToastQueue.size() - 1;
+
+ // Insert system toasts at the front of the queue
+ int systemToastInsertIdx = mToastQueue.size();
+ if (isSystemToast) {
+ systemToastInsertIdx = getInsertIndexForSystemToastLocked();
+ }
+ if (systemToastInsertIdx < mToastQueue.size()) {
+ index = systemToastInsertIdx;
+ mToastQueue.add(index, record);
+ } else {
+ mToastQueue.add(record);
+ index = mToastQueue.size() - 1;
+ }
keepProcessAliveForToastIfNeededLocked(callingPid);
}
// If it's at index 0, it's the current toast. It doesn't matter if it's
@@ -3410,6 +3421,23 @@
}
}
+ @GuardedBy("mToastQueue")
+ private int getInsertIndexForSystemToastLocked() {
+ // If there are other system toasts: insert after the last one
+ int idx = 0;
+ for (ToastRecord r : mToastQueue) {
+ if (idx == 0 && mIsCurrentToastShown) {
+ idx++;
+ continue;
+ }
+ if (!r.isSystemToast) {
+ return idx;
+ }
+ idx++;
+ }
+ return idx;
+ }
+
private boolean checkCanEnqueueToast(String pkg, int callingUid, int displayId,
boolean isAppRenderedToast, boolean isSystemToast) {
final boolean isPackageSuspended = isPackagePaused(pkg);
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index d4fdc12..29db204 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -1452,6 +1452,11 @@
return false;
}
+ if (!mService.mAmInternal.isThemeOverlayReady(userId)) {
+ Slog.d(TAG, "ThemeHomeDelay: Home launch was deferred.");
+ return false;
+ }
+
// Updates the home component of the intent.
homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index e4950a2..b93ae57 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -7734,6 +7734,74 @@
assertEquals(NotificationManagerService.MAX_PACKAGE_TOASTS, mService.mToastQueue.size());
}
+ @Test
+ public void testPrioritizeSystemToasts() throws Exception {
+ // Insert non-system toasts
+ final String testPackage = "testPackageName";
+ assertEquals(0, mService.mToastQueue.size());
+ mService.isSystemUid = false;
+ mService.isSystemAppId = false;
+ setToastRateIsWithinQuota(true);
+ setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
+
+ // package is not suspended
+ when(mPackageManager.isPackageSuspendedForUser(testPackage, mUserId))
+ .thenReturn(false);
+
+ INotificationManager nmService = (INotificationManager) mService.mService;
+
+ // Enqueue maximum number of toasts for test package
+ for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_TOASTS; i++) {
+ enqueueTextToast(testPackage, "Text");
+ }
+
+ // Enqueue system toast
+ final String testPackageSystem = "testPackageNameSystem";
+ mService.isSystemUid = true;
+ setIfPackageHasPermissionToAvoidToastRateLimiting(testPackageSystem, false);
+ when(mPackageManager.isPackageSuspendedForUser(testPackageSystem, mUserId))
+ .thenReturn(false);
+
+ enqueueToast(testPackageSystem, new TestableToastCallback());
+
+ // System toast is inserted at the front of the queue, behind current showing toast
+ assertEquals(testPackageSystem, mService.mToastQueue.get(1).pkg);
+ }
+
+ @Test
+ public void testPrioritizeSystemToasts_enqueueAfterExistingSystemToast() throws Exception {
+ // Insert system toasts
+ final String testPackageSystem1 = "testPackageNameSystem1";
+ assertEquals(0, mService.mToastQueue.size());
+ mService.isSystemUid = true;
+ setToastRateIsWithinQuota(true);
+ setIfPackageHasPermissionToAvoidToastRateLimiting(testPackageSystem1, false);
+
+ // package is not suspended
+ when(mPackageManager.isPackageSuspendedForUser(testPackageSystem1, mUserId))
+ .thenReturn(false);
+
+ INotificationManager nmService = (INotificationManager) mService.mService;
+
+ // Enqueue maximum number of toasts for test package
+ for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_TOASTS; i++) {
+ enqueueTextToast(testPackageSystem1, "Text");
+ }
+
+ // Enqueue another system toast
+ final String testPackageSystem2 = "testPackageNameSystem2";
+ mService.isSystemUid = true;
+ setIfPackageHasPermissionToAvoidToastRateLimiting(testPackageSystem2, false);
+ when(mPackageManager.isPackageSuspendedForUser(testPackageSystem2, mUserId))
+ .thenReturn(false);
+
+ enqueueToast(testPackageSystem2, new TestableToastCallback());
+
+ // System toast is inserted at the back of the queue, after the other system toasts
+ assertEquals(testPackageSystem2,
+ mService.mToastQueue.get(mService.mToastQueue.size() - 1).pkg);
+ }
+
private void setAppInForegroundForToasts(int uid, boolean inForeground) {
int importance = (inForeground) ? IMPORTANCE_FOREGROUND : IMPORTANCE_NONE;
when(mActivityManager.getUidImportance(mUid)).thenReturn(importance);
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index 7edfd9a..0f765a7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -311,6 +311,7 @@
doReturn(true).when(amInternal).hasStartedUserState(anyInt());
doReturn(false).when(amInternal).shouldConfirmCredentials(anyInt());
doReturn(false).when(amInternal).isActivityStartsLoggingEnabled();
+ doReturn(true).when(amInternal).isThemeOverlayReady(anyInt());
LocalServices.addService(ActivityManagerInternal.class, amInternal);
final ActivityManagerService amService =