diff options
24 files changed, 176 insertions, 105 deletions
diff --git a/apex/Android.bp b/apex/Android.bp index 371bd7fc9479..992648b04ef0 100644 --- a/apex/Android.bp +++ b/apex/Android.bp @@ -94,10 +94,8 @@ java_defaults { annotations_enabled: true, - // The stub libraries must be visible to frameworks/base so they can be combined - // into API specific libraries. stubs_library_visibility: [ - "//frameworks/base", // Framework + "//visibility:public", ], // Set the visibility of the modules creating the stubs source. diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 0e3f35e358c0..79d2a8102358 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -96,9 +96,9 @@ import com.android.internal.util.ContrastColorUtil; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Objects; @@ -1620,7 +1620,7 @@ public class Notification implements Parcelable * of non-textual RemoteInputs do not access these remote inputs. */ public RemoteInput[] getDataOnlyRemoteInputs() { - return (RemoteInput[]) mExtras.getParcelableArray(EXTRA_DATA_ONLY_INPUTS); + return getParcelableArrayFromBundle(mExtras, EXTRA_DATA_ONLY_INPUTS, RemoteInput.class); } /** @@ -1802,8 +1802,8 @@ public class Notification implements Parcelable checkContextualActionNullFields(); ArrayList<RemoteInput> dataOnlyInputs = new ArrayList<>(); - RemoteInput[] previousDataInputs = - (RemoteInput[]) mExtras.getParcelableArray(EXTRA_DATA_ONLY_INPUTS); + RemoteInput[] previousDataInputs = getParcelableArrayFromBundle( + mExtras, EXTRA_DATA_ONLY_INPUTS, RemoteInput.class); if (previousDataInputs != null) { for (RemoteInput input : previousDataInputs) { dataOnlyInputs.add(input); @@ -5368,8 +5368,8 @@ public class Notification implements Parcelable big.setViewVisibility(R.id.actions_container, View.GONE); } - RemoteInputHistoryItem[] replyText = (RemoteInputHistoryItem[]) - mN.extras.getParcelableArray(EXTRA_REMOTE_INPUT_HISTORY_ITEMS); + RemoteInputHistoryItem[] replyText = getParcelableArrayFromBundle( + mN.extras, EXTRA_REMOTE_INPUT_HISTORY_ITEMS, RemoteInputHistoryItem.class); if (validRemoteInput && replyText != null && replyText.length > 0 && !TextUtils.isEmpty(replyText[0].getText()) && p.maxRemoteInputHistory > 0) { @@ -8155,8 +8155,9 @@ public class Notification implements Parcelable if (mBuilder.mActions.size() > 0) { maxRows--; } - RemoteInputHistoryItem[] remoteInputHistory = (RemoteInputHistoryItem[]) - mBuilder.mN.extras.getParcelableArray(EXTRA_REMOTE_INPUT_HISTORY_ITEMS); + RemoteInputHistoryItem[] remoteInputHistory = getParcelableArrayFromBundle( + mBuilder.mN.extras, EXTRA_REMOTE_INPUT_HISTORY_ITEMS, + RemoteInputHistoryItem.class); if (remoteInputHistory != null && remoteInputHistory.length > NUMBER_OF_HISTORY_ALLOWED_UNTIL_REDUCTION) { // Let's remove some messages to make room for the remote input history. @@ -9579,8 +9580,8 @@ public class Notification implements Parcelable mFlags = wearableBundle.getInt(KEY_FLAGS, DEFAULT_FLAGS); mDisplayIntent = wearableBundle.getParcelable(KEY_DISPLAY_INTENT); - Notification[] pages = getNotificationArrayFromBundle( - wearableBundle, KEY_PAGES); + Notification[] pages = getParcelableArrayFromBundle( + wearableBundle, KEY_PAGES, Notification.class); if (pages != null) { Collections.addAll(mPages, pages); } @@ -10838,17 +10839,22 @@ public class Notification implements Parcelable } /** - * Get an array of Notification objects from a parcelable array bundle field. + * Get an array of Parcelable objects from a parcelable array bundle field. * Update the bundle to have a typed array so fetches in the future don't need * to do an array copy. */ - private static Notification[] getNotificationArrayFromBundle(Bundle bundle, String key) { - Parcelable[] array = bundle.getParcelableArray(key); - if (array instanceof Notification[] || array == null) { - return (Notification[]) array; + @Nullable + private static <T extends Parcelable> T[] getParcelableArrayFromBundle( + Bundle bundle, String key, Class<T> itemClass) { + final Parcelable[] array = bundle.getParcelableArray(key); + final Class<?> arrayClass = Array.newInstance(itemClass, 0).getClass(); + if (arrayClass.isInstance(array) || array == null) { + return (T[]) array; + } + final T[] typedArray = (T[]) Array.newInstance(itemClass, array.length); + for (int i = 0; i < array.length; i++) { + typedArray[i] = (T) array[i]; } - Notification[] typedArray = Arrays.copyOf(array, array.length, - Notification[].class); bundle.putParcelableArray(key, typedArray); return typedArray; } diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 76071278edf8..5c6269421a1f 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -1454,11 +1454,22 @@ public interface WindowManager extends ViewManager { @Deprecated public static final int FLAG_LAYOUT_INSET_DECOR = 0x00010000; - /** Window flag: When set, input method can't interact with the focusable window - * and can be placed to use more space and cover the input method. - * Note: When combined with {@link #FLAG_NOT_FOCUSABLE}, this flag has no - * effect since input method cannot interact with windows having {@link #FLAG_NOT_FOCUSABLE} - * flag set. + /** Window flag: when set, inverts the input method focusability of the window. + * + * The effect of setting this flag depends on whether {@link #FLAG_NOT_FOCUSABLE} is set: + * <p> + * If {@link #FLAG_NOT_FOCUSABLE} is <em>not</em> set, i.e. when the window is focusable, + * setting this flag prevents this window from becoming the target of the input method. + * Consequently, it will <em>not</em> be able to interact with the input method, + * and will be layered above the input method (unless there is another input method + * target above it). + * + * <p> + * If {@link #FLAG_NOT_FOCUSABLE} <em>is</em> set, setting this flag requests for the window + * to be the input method target even though the window is <em>not</em> focusable. + * Consequently, it will be layered below the input method. + * Note: Windows that set {@link #FLAG_NOT_FOCUSABLE} cannot interact with the input method, + * regardless of this flag. */ public static final int FLAG_ALT_FOCUSABLE_IM = 0x00020000; @@ -2142,13 +2153,12 @@ public interface WindowManager extends ViewManager { * focus. In particular, this checks the * {@link #FLAG_NOT_FOCUSABLE} and {@link #FLAG_ALT_FOCUSABLE_IM} * flags and returns true if the combination of the two corresponds - * to a window that needs to be behind the input method so that the - * user can type into it. + * to a window that can use the input method. * * @param flags The current window manager flags. * - * @return Returns {@code true} if such a window should be behind/interact - * with an input method, {@code false} if not. + * @return Returns {@code true} if a window with the given flags would be able to + * use the input method, {@code false} if not. */ public static boolean mayUseInputMethod(int flags) { return (flags & FLAG_NOT_FOCUSABLE) != FLAG_NOT_FOCUSABLE diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 5c101888aff8..1966a223c680 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -1169,7 +1169,7 @@ <string name="Midnight" msgid="8176019203622191377">"منتصف الليل"</string> <string name="elapsed_time_short_format_mm_ss" msgid="8689459651807876423">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string> <string name="elapsed_time_short_format_h_mm_ss" msgid="2302144714803345056">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string> - <string name="selectAll" msgid="1532369154488982046">"اختيار الكل"</string> + <string name="selectAll" msgid="1532369154488982046">"تحديد الكل"</string> <string name="cut" msgid="2561199725874745819">"قص"</string> <string name="copy" msgid="5472512047143665218">"نسخ"</string> <string name="failed_to_copy_to_clipboard" msgid="725919885138539875">"تعذّر النسخ في الحافظة"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 9b47f8090e89..59da793851b9 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -1548,7 +1548,7 @@ <string name="launchBrowserDefault" msgid="6328349989932924119">"ब्राउज़र लॉन्च करें?"</string> <string name="SetupCallDefault" msgid="5581740063237175247">"कॉल स्वीकार करें?"</string> <string name="activity_resolver_use_always" msgid="5575222334666843269">"हमेशा"</string> - <string name="activity_resolver_use_once" msgid="948462794469672658">"केवल एक बार"</string> + <string name="activity_resolver_use_once" msgid="948462794469672658">"सिर्फ़ एक बार"</string> <string name="activity_resolver_work_profiles_support" msgid="4071345609235361269">"%1$s वर्क प्रोफ़ाइल का समर्थन नहीं करता"</string> <string name="default_audio_route_name" product="tablet" msgid="367936735632195517">"टैबलेट"</string> <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"टीवी"</string> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index 7fcad66d0003..a86636218292 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -1108,7 +1108,7 @@ <string name="inputMethod" msgid="1784759500516314751">"Киргизүү ыкмасы"</string> <string name="editTextMenuTitle" msgid="857666911134482176">"Текст боюнча иштер"</string> <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Сактагычта орун калбай баратат"</string> - <string name="low_internal_storage_view_text" msgid="8172166728369697835">"Системанын кээ бир функциялары иштебеши мүмкүн"</string> + <string name="low_internal_storage_view_text" msgid="8172166728369697835">"Айрым функциялар иштебеши мүмкүн"</string> <string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"Тутумда сактагыч жетишсиз. 250МБ бош орун бар экенин текшерип туруп, өчүрүп күйгүзүңүз."</string> <string name="app_running_notification_title" msgid="8985999749231486569">"<xliff:g id="APP_NAME">%1$s</xliff:g> иштөөдө"</string> <string name="app_running_notification_text" msgid="5120815883400228566">"Көбүрөөк маалымат үчүн же колдонмону токтотуш үчүн таптап коюңуз."</string> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index 65b80d50d77f..3ecad6fce138 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -1547,7 +1547,7 @@ <string name="sending" msgid="206925243621664438">"അയയ്ക്കുന്നു…"</string> <string name="launchBrowserDefault" msgid="6328349989932924119">"ബ്രൗസർ സമാരംഭിക്കണോ?"</string> <string name="SetupCallDefault" msgid="5581740063237175247">"കോൾ സ്വീകരിക്കണോ?"</string> - <string name="activity_resolver_use_always" msgid="5575222334666843269">"എല്ലായ്പ്പോഴും"</string> + <string name="activity_resolver_use_always" msgid="5575222334666843269">"എല്ലായ്പ്പോഴും"</string> <string name="activity_resolver_use_once" msgid="948462794469672658">"ഒരിക്കൽ മാത്രം"</string> <string name="activity_resolver_work_profiles_support" msgid="4071345609235361269">"%1$s, ഔദ്യോഗിക പ്രൊഫൈലിനെ പിന്തുണയ്ക്കുന്നില്ല"</string> <string name="default_audio_route_name" product="tablet" msgid="367936735632195517">"ടാബ്ലെറ്റ്"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 18aaf61798a3..74b7ac89f315 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -536,7 +536,7 @@ <string name="permdesc_imagesWrite" msgid="5195054463269193317">"Cho phép ứng dụng này sửa đổi bộ sưu tập ảnh của bạn."</string> <string name="permlab_mediaLocation" msgid="7368098373378598066">"đọc vị trí từ bộ sưu tập phương tiện"</string> <string name="permdesc_mediaLocation" msgid="597912899423578138">"Cho phép ứng dụng này đọc vị trí từ bộ sưu tập phương tiện của bạn."</string> - <string name="biometric_dialog_default_title" msgid="55026799173208210">"Xác minh đó là bạn"</string> + <string name="biometric_dialog_default_title" msgid="55026799173208210">"Xác minh danh tính của bạn"</string> <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Không có phần cứng sinh trắc học"</string> <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Đã hủy xác thực"</string> <string name="biometric_not_recognized" msgid="5106687642694635888">"Không nhận dạng được"</string> diff --git a/packages/SettingsLib/res/drawable/ic_media_display_device.xml b/packages/SettingsLib/res/drawable/ic_media_display_device.xml index 78b4e2a23d45..54fec782c7d1 100644 --- a/packages/SettingsLib/res/drawable/ic_media_display_device.xml +++ b/packages/SettingsLib/res/drawable/ic_media_display_device.xml @@ -15,16 +15,12 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="14dp" - android:height="11dp" - android:viewportWidth="14" - android:viewportHeight="11" - android:tint="?android:attr/colorControlNormal"> + android:width="18dp" + android:height="18dp" + android:viewportWidth="18" + android:viewportHeight="18"> <path - android:pathData="M10,10v1H4v-1H1.5A1.5,1.5 0,0 1,0 8.5v-7A1.5,1.5 0, - 0 1,1.5 0h11A1.5,1.5 0,0 1,14 1.5v7a1.5,1.5 0,0 1,-1.5 1.5H10zM1.5, - 1a0.5,0.5 0,0 0,-0.5 0.5v7a0.5,0.5 0,0 0,0.5 0.5h11a0.5,0.5 0,0 0, - 0.5 -0.5v-7a0.5,0.5 0,0 0,-0.5 -0.5h-11z" - android:fillColor="#000000" + android:pathData="M12,14V15H6V14H3.5C3.1022,14 2.7206,13.842 2.4393,13.5607C2.158,13.2794 2,12.8978 2,12.5V5.5C2,5.1022 2.158,4.7206 2.4393,4.4393C2.7206,4.158 3.1022,4 3.5,4H14.5C14.8978,4 15.2794,4.158 15.5607,4.4393C15.842,4.7206 16,5.1022 16,5.5V12.5C16,12.8978 15.842,13.2794 15.5607,13.5607C15.2794,13.842 14.8978,14 14.5,14H12ZM3.5,5C3.3674,5 3.2402,5.0527 3.1465,5.1465C3.0527,5.2402 3,5.3674 3,5.5V12.5C3,12.6326 3.0527,12.7598 3.1465,12.8536C3.2402,12.9473 3.3674,13 3.5,13H14.5C14.6326,13 14.7598,12.9473 14.8536,12.8536C14.9473,12.7598 15,12.6326 15,12.5V5.5C15,5.3674 14.9473,5.2402 14.8536,5.1465C14.7598,5.0527 14.6326,5 14.5,5H3.5Z" + android:fillColor="#5F6368" android:fillType="evenOdd"/> </vector>
\ No newline at end of file diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index c27973f8bc86..287a1aca2fbd 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -22,7 +22,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="2333336097603822490">"No se pueden buscar las redes."</string> <string name="wifi_security_none" msgid="7392696451280611452">"Ninguna"</string> - <string name="wifi_remembered" msgid="3266709779723179188">"Guardada"</string> + <string name="wifi_remembered" msgid="3266709779723179188">"Guardado"</string> <string name="wifi_disconnected" msgid="7054450256284661757">"Desconectado"</string> <string name="wifi_disabled_generic" msgid="2651916945380294607">"Inhabilitada"</string> <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Error de configuración IP"</string> diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml index 3e8b1c1b9cde..f9d57c453f69 100644 --- a/packages/SettingsLib/res/values-gl/strings.xml +++ b/packages/SettingsLib/res/values-gl/strings.xml @@ -37,7 +37,7 @@ <string name="wifi_no_internet" msgid="1774198889176926299">"Sen acceso a Internet"</string> <string name="saved_network" msgid="7143698034077223645">"Gardada por <xliff:g id="NAME">%1$s</xliff:g>"</string> <string name="connected_via_network_scorer" msgid="7665725527352893558">"Conectouse automaticamente a través de %1$s"</string> - <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Conectada automaticamente a través dun provedor de valoración de rede"</string> + <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Conectada automaticamente a través dun provedor de valoración de redes"</string> <string name="connected_via_passpoint" msgid="7735442932429075684">"Conectado a través de %1$s"</string> <string name="connected_via_app" msgid="3532267661404276584">"Wifi conectada a través de <xliff:g id="NAME">%1$s</xliff:g>"</string> <string name="available_via_passpoint" msgid="1716000261192603682">"Dispoñible a través de %1$s"</string> diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml index 08cf5f9fd5a9..8407db6d3a08 100644 --- a/packages/SettingsLib/res/values-mn/strings.xml +++ b/packages/SettingsLib/res/values-mn/strings.xml @@ -211,8 +211,8 @@ <string name="adb_wireless_error" msgid="721958772149779856">"Алдаа"</string> <string name="adb_wireless_settings" msgid="2295017847215680229">"Wireless debugging"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Боломжтой төхөөрөмжүүдийг харах болох ашиглахын тулд wireless debugging-г асаана уу"</string> - <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Хурдан хариу үйлдлийн кодоор төхөөрөмжийг хослуул"</string> - <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Хурдан хариу үйлдлийн кодын сканнер ашиглан шинэ төхөөрөмжүүдийг хослуулна уу"</string> + <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR кодоор төхөөрөмжийг хослуул"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR кодын сканнер ашиглан шинэ төхөөрөмжүүдийг хослуулна уу"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Хослуулах кодоор төхөөрөмжийг хослуулна уу"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Зургаан оронтой кодыг ашиглан шинэ төхөөрөмжүүдийг хослуулна уу"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Хослуулсан төхөөрөмжүүд"</string> @@ -226,12 +226,12 @@ <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Wi‑Fi хослуулах код"</string> <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"Хослуулалт амжилтгүй боллоо"</string> <string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Төхөөрөмжийг ижил сүлжээнд холбосон эсэхийг шалгана уу."</string> - <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Хурдан хариу үйлдлийн кодыг скан хийж Wi-Fi-р төхөөрөмжийг хослуулна уу"</string> + <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"QR кодыг скан хийж Wi-Fi-р төхөөрөмжийг хослуулна уу"</string> <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Төхөөрөмжийг хослуулж байна…"</string> - <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Төхөөрөмжийг хослуулж чадсангүй. Хурдан хариу үйлдлийн код буруу эсвэл төхөөрөмжийг ижил сүлжээнд холбоогүй байна."</string> + <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Төхөөрөмжийг хослуулж чадсангүй. QR код буруу эсвэл төхөөрөмжийг ижил сүлжээнд холбоогүй байна."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP хаяг ба порт"</string> - <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Хурдан хариу үйлдлийн кодыг скан хийх"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Хурдан хариу үйлдлийн кодыг скан хийж Wi-Fi-р төхөөрөмжийг хослуулна уу"</string> + <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR кодыг скан хийх"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR кодыг скан хийж Wi-Fi-р төхөөрөмжийг хослуулна уу"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Wi-Fi сүлжээнд холбогдоно уу"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, дебаг хийх, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Алдаа мэдээлэх товчлол"</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java index ea71e52dc9c9..949b2456042c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java @@ -15,6 +15,8 @@ */ package com.android.settingslib.media; +import static android.media.MediaRoute2Info.FEATURE_REMOTE_GROUP_PLAYBACK; +import static android.media.MediaRoute2Info.FEATURE_REMOTE_VIDEO_PLAYBACK; import static android.media.MediaRoute2Info.TYPE_GROUP; import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER; import static android.media.MediaRoute2Info.TYPE_REMOTE_TV; @@ -29,6 +31,8 @@ import androidx.annotation.VisibleForTesting; import com.android.settingslib.R; import com.android.settingslib.bluetooth.BluetoothUtils; +import java.util.List; + /** * InfoMediaDevice extends MediaDevice to represents wifi device. */ @@ -62,7 +66,7 @@ public class InfoMediaDevice extends MediaDevice { @Override public Drawable getIconWithoutBackground() { - return mContext.getDrawable(getDrawableResId()); + return mContext.getDrawable(getDrawableResIdByFeature()); } @VisibleForTesting @@ -83,6 +87,21 @@ public class InfoMediaDevice extends MediaDevice { return resId; } + @VisibleForTesting + int getDrawableResIdByFeature() { + int resId; + final List<String> features = mRouteInfo.getFeatures(); + if (features.contains(FEATURE_REMOTE_GROUP_PLAYBACK)) { + resId = R.drawable.ic_media_group_device; + } else if (features.contains(FEATURE_REMOTE_VIDEO_PLAYBACK)) { + resId = R.drawable.ic_media_display_device; + } else { + resId = R.drawable.ic_media_speaker_device; + } + + return resId; + } + @Override public String getId() { return MediaDeviceUtils.getId(mRouteInfo); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaDeviceTest.java index 49b236a2188f..c45b7f333fa1 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaDeviceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaDeviceTest.java @@ -16,6 +16,9 @@ package com.android.settingslib.media; +import static android.media.MediaRoute2Info.FEATURE_REMOTE_AUDIO_PLAYBACK; +import static android.media.MediaRoute2Info.FEATURE_REMOTE_GROUP_PLAYBACK; +import static android.media.MediaRoute2Info.FEATURE_REMOTE_VIDEO_PLAYBACK; import static android.media.MediaRoute2Info.TYPE_GROUP; import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER; import static android.media.MediaRoute2Info.TYPE_REMOTE_TV; @@ -38,6 +41,8 @@ import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import java.util.ArrayList; + @RunWith(RobolectricTestRunner.class) public class InfoMediaDeviceTest { @@ -107,4 +112,28 @@ public class InfoMediaDeviceTest { assertThat(mInfoMediaDevice.getDrawableResId()).isEqualTo(R.drawable.ic_media_group_device); } + + @Test + public void getDrawableResIdByFeature_returnCorrectResId() { + final ArrayList<String> features = new ArrayList<>(); + features.add(FEATURE_REMOTE_VIDEO_PLAYBACK); + when(mRouteInfo.getFeatures()).thenReturn(features); + + assertThat(mInfoMediaDevice.getDrawableResIdByFeature()).isEqualTo( + R.drawable.ic_media_display_device); + + features.clear(); + features.add(FEATURE_REMOTE_AUDIO_PLAYBACK); + when(mRouteInfo.getFeatures()).thenReturn(features); + + assertThat(mInfoMediaDevice.getDrawableResIdByFeature()).isEqualTo( + R.drawable.ic_media_speaker_device); + + features.clear(); + features.add(FEATURE_REMOTE_GROUP_PLAYBACK); + when(mRouteInfo.getFeatures()).thenReturn(features); + + assertThat(mInfoMediaDevice.getDrawableResIdByFeature()).isEqualTo( + R.drawable.ic_media_group_device); + } } diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 6e8eca3f46cf..678387c540ed 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -4736,7 +4736,7 @@ class StorageManagerService extends IStorageManager.Stub return true; } - private void killAppForOpChange(int code, int uid, String packageName) { + private void killAppForOpChange(int code, int uid) { final IActivityManager am = ActivityManager.getService(); try { am.killUid(UserHandle.getAppId(uid), UserHandle.USER_ALL, @@ -4753,7 +4753,7 @@ class StorageManagerService extends IStorageManager.Stub switch(code) { case OP_REQUEST_INSTALL_PACKAGES: // Always kill regardless of op change, to remount apps /storage - killAppForOpChange(code, uid, packageName); + killAppForOpChange(code, uid); return; case OP_MANAGE_EXTERNAL_STORAGE: if (mode != MODE_ALLOWED) { @@ -4762,12 +4762,7 @@ class StorageManagerService extends IStorageManager.Stub // results in a bad UX, especially since the gid only gives access // to unreliable volumes, USB OTGs that are rarely mounted. The app // will get the external_storage gid on next organic restart. - if (packageName != null) { - killAppForOpChange(code, uid, packageName); - } else { - // TODO(b/158283222) this can happen, figure out if we need - // to kill in this case as well. - } + killAppForOpChange(code, uid); } return; case OP_LEGACY_STORAGE: diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index b45d450cd200..9b356f0e8eef 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -2099,7 +2099,7 @@ public class MediaSessionService extends SystemService implements Monitor { boolean asSystemService, KeyEvent keyEvent, boolean needWakeLock) { if (mCurrentFullUserRecord.getMediaButtonSessionLocked() instanceof MediaSession2Record) { - // TODO(jaewan): Implement + // TODO(jaewan): Make MediaSession2 to receive media key event return; } MediaSessionRecord session = null; diff --git a/services/core/java/com/android/server/media/MediaSessionStack.java b/services/core/java/com/android/server/media/MediaSessionStack.java index 402355a0161a..b678c8962a21 100644 --- a/services/core/java/com/android/server/media/MediaSessionStack.java +++ b/services/core/java/com/android/server/media/MediaSessionStack.java @@ -244,6 +244,10 @@ class MediaSessionStack { private MediaSessionRecordImpl findMediaButtonSession(int uid) { MediaSessionRecordImpl mediaButtonSession = null; for (MediaSessionRecordImpl session : mSessions) { + if (session instanceof MediaSession2Record) { + // TODO(jaewan): Make MediaSession2 to receive media key event + continue; + } if (uid == session.getUid()) { if (session.checkPlaybackActiveState( mAudioPlayerStateMonitor.isPlaybackActive(session.getUid()))) { diff --git a/services/core/java/com/android/server/uri/UriGrantsManagerService.java b/services/core/java/com/android/server/uri/UriGrantsManagerService.java index 5f6323369d0a..c38d649ada9b 100644 --- a/services/core/java/com/android/server/uri/UriGrantsManagerService.java +++ b/services/core/java/com/android/server/uri/UriGrantsManagerService.java @@ -115,7 +115,7 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub { private static final String TAG = "UriGrantsManagerService"; // Maximum number of persisted Uri grants a package is allowed private static final int MAX_PERSISTED_URI_GRANTS = 128; - private static final boolean ENABLE_DYNAMIC_PERMISSIONS = true; + private static final boolean ENABLE_DYNAMIC_PERMISSIONS = false; private final Object mLock = new Object(); private final H mH; diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 2e9f70448488..241f5e88935a 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -268,6 +268,7 @@ import android.os.storage.StorageManager; import android.service.dreams.DreamActivity; import android.service.dreams.DreamManagerInternal; import android.service.voice.IVoiceInteractionSession; +import android.text.TextUtils; import android.util.ArraySet; import android.util.EventLog; import android.util.Log; @@ -2054,23 +2055,28 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } static boolean canLaunchDreamActivity(String packageName) { - final DreamManagerInternal dreamManager = - LocalServices.getService(DreamManagerInternal.class); - - // Verify that the package is the current active dream. The getActiveDreamComponent() - // call path does not acquire the DreamManager lock and thus is safe to use. - final ComponentName activeDream = dreamManager.getActiveDreamComponent(false /* doze */); - if (activeDream == null || activeDream.getPackageName() == null - || !activeDream.getPackageName().equals(packageName)) { + if (packageName == null) { return false; } - // Verify that the device is dreaming. if (!LocalServices.getService(ActivityTaskManagerInternal.class).isDreaming()) { return false; } - return true; + final DreamManagerInternal dreamManager = + LocalServices.getService(DreamManagerInternal.class); + + // Verify that the package is the current active dream or doze component. The + // getActiveDreamComponent() call path does not acquire the DreamManager lock and thus + // is safe to use. + final ComponentName activeDream = dreamManager.getActiveDreamComponent(false /* doze */); + final ComponentName activeDoze = dreamManager.getActiveDreamComponent(true /* doze */); + return TextUtils.equals(packageName, getPackageName(activeDream)) + || TextUtils.equals(packageName, getPackageName(activeDoze)); + } + + private static String getPackageName(ComponentName componentName) { + return componentName != null ? componentName.getPackageName() : null; } private void setActivityType(boolean componentSpecified, int launchedFromUid, Intent intent, diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java index 4c10d5819c10..9c535e4a41d7 100644 --- a/services/core/java/com/android/server/wm/KeyguardController.java +++ b/services/core/java/com/android/server/wm/KeyguardController.java @@ -133,10 +133,11 @@ class KeyguardController { * Update the Keyguard showing state. */ void setKeyguardShown(boolean keyguardShowing, boolean aodShowing) { - // If keyguard is going away, but SystemUI aborted the transition, need to reset state. - final boolean keyguardChanged = keyguardShowing != mKeyguardShowing - || mKeyguardGoingAway && keyguardShowing; final boolean aodChanged = aodShowing != mAodShowing; + // If keyguard is going away, but SystemUI aborted the transition, need to reset state. + // Do not reset keyguardChanged status if this is aodChanged. + final boolean keyguardChanged = (keyguardShowing != mKeyguardShowing) + || (mKeyguardGoingAway && keyguardShowing && !aodChanged); if (!keyguardChanged && !aodChanged) { return; } diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java index 51cf858715b4..c2021303c11c 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotController.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java @@ -40,6 +40,7 @@ import android.util.ArraySet; import android.util.Slog; import android.view.InsetsSource; import android.view.InsetsState; +import android.view.InsetsState.InternalInsetsType; import android.view.SurfaceControl; import android.view.ThreadedRenderer; import android.view.WindowInsets; @@ -480,7 +481,9 @@ class TaskSnapshotController { task.getTaskDescription().getBackgroundColor(), 255); final LayoutParams attrs = mainWindow.getAttrs(); final InsetsPolicy insetsPolicy = mainWindow.getDisplayContent().getInsetsPolicy(); - final InsetsState insetsState = insetsPolicy.getInsetsForDispatch(mainWindow); + final InsetsState insetsState = + new InsetsState(insetsPolicy.getInsetsForDispatch(mainWindow)); + mergeInsetsSources(insetsState, mainWindow.getRequestedInsetsState()); final Rect systemBarInsets = getSystemBarInsets(mainWindow.getFrameLw(), insetsState); final SystemBarBackgroundPainter decorPainter = new SystemBarBackgroundPainter(attrs.flags, attrs.privateFlags, attrs.systemUiVisibility, task.getTaskDescription(), @@ -600,6 +603,15 @@ class TaskSnapshotController { return 0; } + static void mergeInsetsSources(InsetsState base, InsetsState other) { + for (@InternalInsetsType int type = 0; type < InsetsState.SIZE; type++) { + final InsetsSource source = other.peekSource(type); + if (source != null) { + base.addSource(source); + } + } + } + static Rect getSystemBarInsets(Rect frame, InsetsState state) { return state.calculateInsets(frame, null /* ignoringVisibilityState */, false /* isScreenRound */, false /* alwaysConsumeSystemBars */, diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java index 3fc09c93550c..448b4aae7a88 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java @@ -42,6 +42,7 @@ import static com.android.internal.policy.DecorView.STATUS_BAR_COLOR_VIEW_ATTRIB import static com.android.internal.policy.DecorView.getNavigationBarRect; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW; import static com.android.server.wm.TaskSnapshotController.getSystemBarInsets; +import static com.android.server.wm.TaskSnapshotController.mergeInsetsSources; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; @@ -243,7 +244,9 @@ class TaskSnapshotSurface implements StartingSurface { final InsetsPolicy insetsPolicy = topFullscreenOpaqueWindow.getDisplayContent() .getInsetsPolicy(); - insetsState = insetsPolicy.getInsetsForDispatch(topFullscreenOpaqueWindow); + insetsState = + new InsetsState(insetsPolicy.getInsetsForDispatch(topFullscreenOpaqueWindow)); + mergeInsetsSources(insetsState, topFullscreenOpaqueWindow.getRequestedInsetsState()); } try { final int res = session.addToDisplay(window, window.mSeq, layoutParams, diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index d4d2f4d7a492..837fafec1634 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -26,6 +26,7 @@ import static android.app.WindowConfiguration.isSplitScreenWindowingMode; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.os.PowerManager.DRAW_WAKE_LOCK; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; +import static android.view.InsetsState.ITYPE_IME; import static android.view.SurfaceControl.Transaction; import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; @@ -757,6 +758,12 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP oldRotation = mPendingSeamlessRotate.getOldRotation(); } + // Skip performing seamless rotation when the controlled insets is IME with visible state. + if (mControllableInsetProvider != null + && mControllableInsetProvider.getSource().getType() == ITYPE_IME) { + return; + } + if (mForceSeamlesslyRotate || requested) { if (mControllableInsetProvider != null) { mControllableInsetProvider.startSeamlessRotation(); @@ -2394,12 +2401,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP if (mAttrs.type == TYPE_APPLICATION_STARTING) { // Ignore mayUseInputMethod for starting window for now. // TODO(b/159911356): Remove this special casing (originally added in commit e75d872). - } else if (PixelFormat.formatHasAlpha(mAttrs.format)) { - // Support legacy use cases where transparent windows can still be ime target with - // FLAG_NOT_FOCUSABLE and ALT_FOCUSABLE_IM set. - // Certain apps listen for IME insets using transparent windows and ADJUST_NOTHING to - // manually synchronize app content to IME animation b/144619551. - // TODO(b/145812508): remove this once new focus management is complete b/141738570 + } else { + // TODO(b/145812508): Clean this up in S, may depend on b/141738570 + // The current logic lets windows become the "ime target" even though they are + // not-focusable and can thus never actually start input. + // Ideally, this would reject windows where mayUseInputMethod() == false, but this + // also impacts Z-ordering of and delivery of IME insets to child windows, which means + // that simply disallowing non-focusable windows would break apps. + // See b/159438771, b/144619551. + final int fl = mAttrs.flags & (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM); // Can only be an IME target if both FLAG_NOT_FOCUSABLE and FLAG_ALT_FOCUSABLE_IM are @@ -2407,12 +2417,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP if (fl != 0 && fl != (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM)) { return false; } - } else if (!WindowManager.LayoutParams.mayUseInputMethod(mAttrs.flags)) { - // Can be an IME target only if: - // 1. FLAG_NOT_FOCUSABLE is not set - // 2. FLAG_ALT_FOCUSABLE_IM is not set - // 3. not a starting window. - return false; } if (DEBUG_INPUT_METHOD) { diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java index 4a0f48cf2ccb..360d73b5bd87 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -67,7 +67,6 @@ import static org.mockito.Mockito.when; import android.graphics.Insets; import android.graphics.Matrix; -import android.graphics.PixelFormat; import android.graphics.Rect; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; @@ -229,21 +228,10 @@ public class WindowStateTests extends WindowTestsBase { appWindow.mAttrs.flags |= (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM); imeWindow.mAttrs.flags |= (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM); - // Visible app window with flags FLAG_NOT_FOCUSABLE or FLAG_ALT_FOCUSABLE_IM can't be IME - // target while an IME window can never be an IME target regardless of its visibility - // or flags. - assertFalse(appWindow.canBeImeTarget()); - assertFalse(imeWindow.canBeImeTarget()); - - // b/145812508: special legacy use-case for transparent/translucent windows. - appWindow.mAttrs.format = PixelFormat.TRANSPARENT; - assertTrue(appWindow.canBeImeTarget()); - - appWindow.mAttrs.format = PixelFormat.OPAQUE; - appWindow.mAttrs.flags &= ~FLAG_ALT_FOCUSABLE_IM; - assertFalse(appWindow.canBeImeTarget()); - appWindow.mAttrs.flags &= ~FLAG_NOT_FOCUSABLE; + // Visible app window with flags can be IME target while an IME window can never be an IME + // target regardless of its visibility or flags. assertTrue(appWindow.canBeImeTarget()); + assertFalse(imeWindow.canBeImeTarget()); // Verify PINNED windows can't be IME target. int initialMode = appWindow.mActivityRecord.getWindowingMode(); |