diff options
98 files changed, 1584 insertions, 247 deletions
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index cf858f585c85..a74c34ff4a88 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -8391,7 +8391,7 @@ public class PackageParser { public static PackageInfo generatePackageInfoFromApex(ApexInfo apexInfo, int flags) throws PackageParserException { PackageParser pp = new PackageParser(); - File apexFile = new File(apexInfo.packagePath); + File apexFile = new File(apexInfo.modulePath); final Package p = pp.parsePackage(apexFile, flags, false); PackageUserState state = new PackageUserState(); PackageInfo pi = generatePackageInfo(p, EmptyArray.INT, flags, 0, 0, diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java index 660cd848d1df..43ea5891d7f7 100644 --- a/core/java/android/net/NetworkAgent.java +++ b/core/java/android/net/NetworkAgent.java @@ -437,15 +437,23 @@ public abstract class NetworkAgent extends Handler { } /** - * Called by the bearer to indicate this network was manually selected by the user. + * Called by the bearer to indicate whether the network was manually selected by the user. * This should be called before the NetworkInfo is marked CONNECTED so that this - * Network can be given special treatment at that time. If {@code acceptUnvalidated} is - * {@code true}, then the system will switch to this network. If it is {@code false} and the - * network cannot be validated, the system will ask the user whether to switch to this network. - * If the user confirms and selects "don't ask again", then the system will call - * {@link #saveAcceptUnvalidated} to persist the user's choice. Thus, if the transport ever - * calls this method with {@code acceptUnvalidated} set to {@code false}, it must also implement - * {@link #saveAcceptUnvalidated} to respect the user's choice. + * Network can be given special treatment at that time. + * + * If {@code explicitlySelected} is {@code true}, and {@code acceptUnvalidated} is {@code true}, + * then the system will switch to this network. If {@code explicitlySelected} is {@code true} + * and {@code acceptUnvalidated} is {@code false}, and the network cannot be validated, the + * system will ask the user whether to switch to this network. If the user confirms and selects + * "don't ask again", then the system will call {@link #saveAcceptUnvalidated} to persist the + * user's choice. Thus, if the transport ever calls this method with {@code explicitlySelected} + * set to {@code true} and {@code acceptUnvalidated} set to {@code false}, it must also + * implement {@link #saveAcceptUnvalidated} to respect the user's choice. + * + * If {@code explicitlySelected} is {@code false} and {@code acceptUnvalidated} is + * {@code true}, the system will interpret this as the user having accepted partial connectivity + * on this network. Thus, the system will switch to the network and consider it validated even + * if it only provides partial connectivity, but the network is not otherwise treated specially. */ public void explicitlySelected(boolean explicitlySelected, boolean acceptUnvalidated) { queueOrSendMessage(EVENT_SET_EXPLICITLY_SELECTED, diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index e615988060d5..9e1bb941004a 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -8276,6 +8276,16 @@ public final class Settings { BOOLEAN_VALIDATOR; /** + * Whether or not media is shown automatically when bypassing as a heads up. + * @hide + */ + public static final String SHOW_MEDIA_WHEN_BYPASSING = + "show_media_when_bypassing"; + + private static final Validator SHOW_MEDIA_WHEN_BYPASSING_VALIDATOR = + BOOLEAN_VALIDATOR; + + /** * Whether or not face unlock requires attention. This is a cached value, the source of * truth is obtained through the HAL. * @hide @@ -8974,6 +8984,7 @@ public final class Settings { NFC_PAYMENT_DEFAULT_COMPONENT, AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN, FACE_UNLOCK_KEYGUARD_ENABLED, + SHOW_MEDIA_WHEN_BYPASSING, FACE_UNLOCK_DISMISSES_KEYGUARD, FACE_UNLOCK_APP_ENABLED, FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, @@ -9150,6 +9161,7 @@ public final class Settings { VALIDATORS.put(FACE_UNLOCK_KEYGUARD_ENABLED, FACE_UNLOCK_KEYGUARD_ENABLED_VALIDATOR); VALIDATORS.put(FACE_UNLOCK_DISMISSES_KEYGUARD, FACE_UNLOCK_DISMISSES_KEYGUARD_VALIDATOR); + VALIDATORS.put(SHOW_MEDIA_WHEN_BYPASSING, SHOW_MEDIA_WHEN_BYPASSING_VALIDATOR); VALIDATORS.put(FACE_UNLOCK_APP_ENABLED, FACE_UNLOCK_APP_ENABLED_VALIDATOR); VALIDATORS.put(FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION_VALIDATOR); diff --git a/core/java/android/view/TEST_MAPPING b/core/java/android/view/TEST_MAPPING index 87d428ab551e..4ea4310b25a4 100644 --- a/core/java/android/view/TEST_MAPPING +++ b/core/java/android/view/TEST_MAPPING @@ -1,10 +1,12 @@ { "presubmit": [ { - "name": "CtsUiRenderingTestCases" - }, - { "name": "CtsAccelerationTestCases" } + ], + "imports": [ + { + "path": "cts/tests/tests/uirendering" + } ] }
\ No newline at end of file diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java index 3d3d5dc7db32..f18aa81b95e5 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -17,6 +17,7 @@ package android.view; import android.annotation.NonNull; +import android.annotation.Nullable; import android.content.Context; import android.content.res.TypedArray; import android.graphics.HardwareRenderer; @@ -35,6 +36,7 @@ import com.android.internal.R; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.ArrayList; /** * Threaded renderer that proxies the rendering to a render thread. Most calls @@ -300,7 +302,8 @@ public final class ThreadedRenderer extends HardwareRenderer { private boolean mEnabled; private boolean mRequested = true; - private FrameDrawingCallback mNextRtFrameCallback; + @Nullable + private ArrayList<FrameDrawingCallback> mNextRtFrameCallbacks; ThreadedRenderer(Context context, boolean translucent, String name) { super(); @@ -441,8 +444,11 @@ public final class ThreadedRenderer extends HardwareRenderer { * * @param callback The callback to register. */ - void registerRtFrameCallback(FrameDrawingCallback callback) { - mNextRtFrameCallback = callback; + void registerRtFrameCallback(@NonNull FrameDrawingCallback callback) { + if (mNextRtFrameCallbacks == null) { + mNextRtFrameCallbacks = new ArrayList<>(); + } + mNextRtFrameCallbacks.add(callback); } /** @@ -583,10 +589,14 @@ public final class ThreadedRenderer extends HardwareRenderer { // Consume and set the frame callback after we dispatch draw to the view above, but before // onPostDraw below which may reset the callback for the next frame. This ensures that // updates to the frame callback during scroll handling will also apply in this frame. - final FrameDrawingCallback callback = mNextRtFrameCallback; - mNextRtFrameCallback = null; - if (callback != null) { - setFrameCallback(callback); + if (mNextRtFrameCallbacks != null) { + final ArrayList<FrameDrawingCallback> frameCallbacks = mNextRtFrameCallbacks; + mNextRtFrameCallbacks = null; + setFrameCallback(frame -> { + for (int i = 0; i < frameCallbacks.size(); ++i) { + frameCallbacks.get(i).onFrameDraw(frame); + } + }); } if (mRootNodeNeedsUpdate || !mRootNode.hasDisplayList()) { diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index cb51545a8a69..613ddcf577ed 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -1132,7 +1132,7 @@ public final class ViewRootImpl implements ViewParent, * * @param callback The callback to register. */ - public void registerRtFrameCallback(FrameDrawingCallback callback) { + public void registerRtFrameCallback(@NonNull FrameDrawingCallback callback) { if (mAttachInfo.mThreadedRenderer != null) { mAttachInfo.mThreadedRenderer.registerRtFrameCallback(frame -> { try { diff --git a/core/jni/Android.bp b/core/jni/Android.bp index b21221f2efff..b50b8248ee8d 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -100,7 +100,6 @@ cc_library_shared { ], shared_libs: [ - "libandroidicu", "libbase", "libcutils", "libharfbuzz_ng", @@ -267,6 +266,7 @@ cc_library_shared { ], shared_libs: [ + "libandroidicu", "libbpf_android", "libnetdbpf", "libnetdutils", @@ -344,6 +344,10 @@ cc_library_shared { include_dirs: [ "external/vulkan-headers/include", ], + shared_libs: [ + "libicui18n", + "libicuuc", + ], static_libs: [ "libandroidfw", "libcompiler_rt", diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index a62a1fb5bfef..f515b2dd45f0 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -3783,9 +3783,11 @@ <integer name="config_stableDeviceDisplayWidth">-1</integer> <integer name="config_stableDeviceDisplayHeight">-1</integer> - <!-- Decide whether to display 'No service' on status bar instead of 'Emergency calls only' - when SIM is unready. --> - <bool name="config_display_no_service_when_sim_unready">false</bool> + <!-- List of countries in which we display 'No service' on status bar + instead of 'Emergency calls only' when SIM is unready. --> + <string-array translatable="false" name="config_display_no_service_when_sim_unready"> + <item>"DE"</item> + </string-array> <!-- Class names of device specific services inheriting com.android.server.SystemService. The classes are instantiated in the order of the array. --> @@ -4114,6 +4116,15 @@ M9,10l-2,0l0,-2l-2,0l0,2l-2,0l0,2l2,0l0,2l2,0l0,-2l2,0z </string> + <!-- X path for SignalDrawable as defined on a 24x24 canvas. --> + <string name="config_signalXPath" translatable="false"> + M22,16.41L20.59,15l-2.09,2.09L16.41,15L15,16.41l2.09,2.09L15,20.59L16.41,22l2.09-2.08L20.59,22L22,20.59l-2.08-2.09 L22,16.41z + </string> + <!-- config_signalCutout{Height,Width}Fraction define fraction of the 24x24 canvas that + should be cut out to display config_signalXPath.--> + <item name="config_signalCutoutWidthFraction" format="float" type="dimen">11</item> + <item name="config_signalCutoutHeightFraction" format="float" type="dimen">11</item> + <!-- A dual tone battery meter draws the perimeter path twice - once to define the shape and a second time clipped to the fill level to indicate charge --> <bool name="config_batterymeterDualTone">false</bool> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 5ca77f9207f9..6c908aac1ee8 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3269,6 +3269,9 @@ <java-symbol type="string" name="config_batterymeterBoltPath" /> <java-symbol type="string" name="config_batterymeterPowersavePath" /> <java-symbol type="bool" name="config_batterymeterDualTone" /> + <java-symbol type="string" name="config_signalXPath" /> + <java-symbol type="dimen" name="config_signalCutoutWidthFraction" /> + <java-symbol type="dimen" name="config_signalCutoutHeightFraction" /> <java-symbol type="bool" name="config_debugEnableAutomaticSystemServerHeapDumps" /> <java-symbol type="integer" name="config_debugSystemServerPssThresholdBytes" /> @@ -3554,7 +3557,7 @@ <java-symbol type="integer" name="config_stableDeviceDisplayWidth" /> <java-symbol type="integer" name="config_stableDeviceDisplayHeight" /> - <java-symbol type="bool" name="config_display_no_service_when_sim_unready" /> + <java-symbol type="array" name="config_display_no_service_when_sim_unready" /> <java-symbol type="layout" name="slice_grid" /> <java-symbol type="layout" name="slice_message_local" /> diff --git a/core/tests/coretests/res/values/overlayable_icons_test.xml b/core/tests/coretests/res/values/overlayable_icons_test.xml index ce209ce90905..6503f3ee6d57 100644 --- a/core/tests/coretests/res/values/overlayable_icons_test.xml +++ b/core/tests/coretests/res/values/overlayable_icons_test.xml @@ -70,6 +70,7 @@ <item>@*android:drawable/ic_wifi_signal_3</item> <item>@*android:drawable/ic_wifi_signal_4</item> <item>@*android:drawable/perm_group_activity_recognition</item> + <item>@*android:drawable/perm_group_aural</item> <item>@*android:drawable/perm_group_calendar</item> <item>@*android:drawable/perm_group_call_log</item> <item>@*android:drawable/perm_group_camera</item> diff --git a/core/tests/coretests/src/android/content/pm/PackageParserTest.java b/core/tests/coretests/src/android/content/pm/PackageParserTest.java index 71d9a46eaa24..58c43ac2cf91 100644 --- a/core/tests/coretests/src/android/content/pm/PackageParserTest.java +++ b/core/tests/coretests/src/android/content/pm/PackageParserTest.java @@ -498,14 +498,14 @@ public class PackageParserTest { @Test public void testApexPackageInfoGeneration() throws Exception { - String apexPackageName = "com.android.tzdata.apex"; - File apexFile = copyRawResourceToFile(apexPackageName, + String apexModuleName = "com.android.tzdata.apex"; + File apexFile = copyRawResourceToFile(apexModuleName, R.raw.com_android_tzdata); ApexInfo apexInfo = new ApexInfo(); apexInfo.isActive = true; apexInfo.isFactory = false; - apexInfo.packageName = apexPackageName; - apexInfo.packagePath = apexFile.getPath(); + apexInfo.moduleName = apexModuleName; + apexInfo.modulePath = apexFile.getPath(); apexInfo.versionCode = 191000070; int flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES; PackageInfo pi = PackageParser.generatePackageInfoFromApex(apexInfo, flags); diff --git a/libs/hwui/TEST_MAPPING b/libs/hwui/TEST_MAPPING index d9f2acbb49d2..b1719a979ce5 100644 --- a/libs/hwui/TEST_MAPPING +++ b/libs/hwui/TEST_MAPPING @@ -1,13 +1,15 @@ { "presubmit": [ { - "name": "CtsUiRenderingTestCases" - }, - { "name": "CtsGraphicsTestCases" }, { "name": "CtsAccelerationTestCases" } + ], + "imports": [ + { + "path": "cts/tests/tests/uirendering" + } ] }
\ No newline at end of file diff --git a/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl b/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl index 8238b8c4898d..7e3f2f8868fb 100644 --- a/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl +++ b/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl @@ -19,7 +19,9 @@ oneway interface IMediaBrowserServiceCallbacks { * the playback of the media app. * @param extra Extras returned by the media service. */ + @UnsupportedAppUsage void onConnect(String root, in MediaSession.Token session, in Bundle extras); + @UnsupportedAppUsage void onConnectFailed(); void onLoadChildren(String mediaId, in ParceledListSlice list); void onLoadChildrenWithOptions(String mediaId, in ParceledListSlice list, diff --git a/packages/InputDevices/res/values-hy/strings.xml b/packages/InputDevices/res/values-hy/strings.xml index c7523e391807..64ddf7ac1b20 100644 --- a/packages/InputDevices/res/values-hy/strings.xml +++ b/packages/InputDevices/res/values-hy/strings.xml @@ -40,7 +40,7 @@ <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"Եբրայերեն"</string> <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"Լիտվերեն"</string> <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"Իսպաներեն (Լատինական)"</string> - <string name="keyboard_layout_latvian" msgid="4405417142306250595">"լատիշերեն"</string> + <string name="keyboard_layout_latvian" msgid="4405417142306250595">"լատվիերեն"</string> <string name="keyboard_layout_persian" msgid="3920643161015888527">"պարսկերեն"</string> <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"ադրբեջաներեն"</string> <string name="keyboard_layout_polish" msgid="1121588624094925325">"լեհերեն"</string> diff --git a/packages/SettingsLib/SearchWidget/res/values-sw/strings.xml b/packages/SettingsLib/SearchWidget/res/values-sw/strings.xml index 297ecdb8b32a..199845bc51da 100644 --- a/packages/SettingsLib/SearchWidget/res/values-sw/strings.xml +++ b/packages/SettingsLib/SearchWidget/res/values-sw/strings.xml @@ -17,5 +17,5 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="search_menu" msgid="1604061903696928905">"Tafuta mipangilio"</string> + <string name="search_menu" msgid="1604061903696928905">"Tafuta katika mipangilio"</string> </resources> diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml index bdbde46fd95a..13890e029274 100644 --- a/packages/SettingsLib/res/values-bn/strings.xml +++ b/packages/SettingsLib/res/values-bn/strings.xml @@ -219,7 +219,7 @@ <string name="mock_location_app_set" msgid="8966420655295102685">"অনুরূপ লোকেশন অ্যাপ্লিকেশান: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="debug_networking_category" msgid="7044075693643009662">"নেটওয়ার্কিং"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"ওয়্যারলেস ডিসপ্লে সার্টিফিকেশন"</string> - <string name="wifi_verbose_logging" msgid="4203729756047242344">"ওয়াই-ফাই ভারবোস লগিং সক্ষম করুন"</string> + <string name="wifi_verbose_logging" msgid="4203729756047242344">"ওয়াই-ফাই ভারবোস লগিং চালু করুন"</string> <string name="wifi_scan_throttling" msgid="160014287416479843">"ওয়াই-ফাই স্ক্যান থ্রোটলিং"</string> <string name="mobile_data_always_on" msgid="8774857027458200434">"মোবাইল ডেটা সব সময় সক্রিয় থাক"</string> <string name="tethering_hardware_offload" msgid="7470077827090325814">"টিথারিং হার্ডওয়্যার অ্যাক্সিলারেশন"</string> @@ -262,7 +262,7 @@ <string name="allow_mock_location_summary" msgid="317615105156345626">"মক অবস্থানগুলি মঞ্জুর করুন"</string> <string name="debug_view_attributes" msgid="6485448367803310384">"অ্যাট্রিবিউট ইন্সপেকশন দেখা চালু করুন"</string> <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"ওয়াই-ফাই সক্রিয় থাকার সময়েও (দ্রুত নেটওয়ার্কে পাল্টানোর জন্য) সর্বদা মোবাইল ডেটা সক্রিয় রাখুন।"</string> - <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"টিথারিং হার্ডওয়্যার অ্যাক্সিলারেশন উপলব্ধ থাকলে ব্যবহার করুন"</string> + <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"টিথারিং হার্ডওয়্যার অ্যাক্সিলারেশন উপলভ্য থাকলে ব্যবহার করুন"</string> <string name="adb_warning_title" msgid="6234463310896563253">"USB ডিবাগিং মঞ্জুর করবেন?"</string> <string name="adb_warning_message" msgid="7316799925425402244">"USB ডিবাগিং কেবলমাত্র বিকাশ করার উদ্দেশ্যে। আপনার কম্পিউটার এবং আপনার ডিভাইসের মধ্যে ডেটা অনুলিপি করতে এটি ব্যবহার করুন, বিজ্ঞপ্তি ছাড়া আপনার ডিভাইসে অ্যাপ্লিকেশানগুলি ইনস্টল করুন এবং ডেটা লগ পড়ুন।"</string> <string name="adb_keys_warning_message" msgid="5659849457135841625">"আপনি আগে যে সব কম্পিউটার USB ডিবাগিং এর অ্যাক্সেসের অনুমতি দিয়েছিলেন তা প্রত্যাহার করবেন?"</string> diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml index d464256f8f50..afdb105ca560 100644 --- a/packages/SettingsLib/res/values-ca/strings.xml +++ b/packages/SettingsLib/res/values-ca/strings.xml @@ -220,7 +220,7 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Xarxes"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Certificació de pantalla sense fil"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Activa el registre Wi‑Fi detallat"</string> - <string name="wifi_scan_throttling" msgid="160014287416479843">"Regulació de la cerca de xarxes Wi‑Fi"</string> + <string name="wifi_scan_throttling" msgid="160014287416479843">"Limitació de la cerca de xarxes Wi‑Fi"</string> <string name="mobile_data_always_on" msgid="8774857027458200434">"Dades mòbils sempre actives"</string> <string name="tethering_hardware_offload" msgid="7470077827090325814">"Acceleració per maquinari per a compartició de xarxa"</string> <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostra els dispositius Bluetooth sense el nom"</string> diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml index 7c03afb30379..d8da638fcd2b 100644 --- a/packages/SettingsLib/res/values-de/strings.xml +++ b/packages/SettingsLib/res/values-de/strings.xml @@ -246,7 +246,7 @@ <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"Hostname des DNS-Anbieters eingeben"</string> <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Verbindung nicht möglich"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Optionen zur Zertifizierung für kabellose Übertragung anzeigen"</string> - <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"WLAN-Protokollierungsebene erhöhen, in WiFi Picker pro SSID RSSI anzeigen"</string> + <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"WLAN-Protokollierungsebene erhöhen, pro SSID RSSI in WiFi Picker anzeigen"</string> <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Verringert den Akkuverbrauch und verbessert die Netzwerkleistung"</string> <string name="wifi_metered_label" msgid="4514924227256839725">"Kostenpflichtig"</string> <string name="wifi_unmetered_label" msgid="6124098729457992931">"Kostenlos"</string> diff --git a/packages/SettingsLib/res/values-es/arrays.xml b/packages/SettingsLib/res/values-es/arrays.xml index 5e502972c3a3..63f6c3e3ea98 100644 --- a/packages/SettingsLib/res/values-es/arrays.xml +++ b/packages/SettingsLib/res/values-es/arrays.xml @@ -43,7 +43,7 @@ <item msgid="8937994881315223448">"Conectado a <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item> <item msgid="1330262655415760617">"Suspendida"</item> <item msgid="7698638434317271902">"Desconectando de <xliff:g id="NETWORK_NAME">%1$s</xliff:g>..."</item> - <item msgid="197508606402264311">"Desconectada"</item> + <item msgid="197508606402264311">"Desconectado"</item> <item msgid="8578370891960825148">"Con error"</item> <item msgid="5660739516542454527">"Bloqueada"</item> <item msgid="1805837518286731242">"Inhabilitando conexión inestable temporalmente..."</item> diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml index e1277d862122..8baf7a21c1ae 100644 --- a/packages/SettingsLib/res/values-es/strings.xml +++ b/packages/SettingsLib/res/values-es/strings.xml @@ -23,7 +23,7 @@ <string name="wifi_fail_to_scan" msgid="1265540342578081461">"No se puede buscar redes."</string> <string name="wifi_security_none" msgid="7985461072596594400">"Ninguna"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Guardado"</string> - <string name="wifi_disconnected" msgid="8085419869003922556">"Desconectada"</string> + <string name="wifi_disconnected" msgid="8085419869003922556">"Desconectado"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Inhabilitado"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Error de configuración de IP"</string> <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"No conectado debido a la baja calidad de la red"</string> diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml index d2e3a3868a5f..fd3936d39ed3 100644 --- a/packages/SettingsLib/res/values-eu/strings.xml +++ b/packages/SettingsLib/res/values-eu/strings.xml @@ -246,7 +246,7 @@ <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"Idatzi DNS hornitzailearen ostalari-izena"</string> <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Ezin izan da konektatu"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Erakutsi hari gabe bistaratzeko ziurtagiriaren aukerak"</string> - <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Erakutsi datu gehiago wifi-sareetan saioa hastean. Erakutsi sarearen identifikatzailea eta seinalearen indarra wifi-sareen hautagailuan."</string> + <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Erakutsi datu gehiago wifi-sareetan saioa hastean. Erakutsi sarearen identifikatzailea eta seinalearen indarra wifi-sareen hautatzailean."</string> <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Bateria gutxiago kontsumituko da, eta sarearen errendimendua hobetuko."</string> <string name="wifi_metered_label" msgid="4514924227256839725">"Sare neurtua"</string> <string name="wifi_unmetered_label" msgid="6124098729457992931">"Neurtu gabeko sarea"</string> @@ -261,7 +261,7 @@ <string name="allow_mock_location" msgid="2787962564578664888">"Onartu kokapen faltsuak"</string> <string name="allow_mock_location_summary" msgid="317615105156345626">"Onartu kokapen faltsuak"</string> <string name="debug_view_attributes" msgid="6485448367803310384">"Gaitu ikuspegiaren atributuak ikuskatzeko aukera"</string> - <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mantendu mugikorreko datuak beti aktibo, baita wifi-konexioa aktibo dagoenean ere (sarez bizkor aldatu ahal izateko)"</string> + <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mantendu datu-konexioa beti aktibo, baita wifi-konexioa aktibo dagoenean ere (sare batetik bestera bizkor aldatu ahal izateko)."</string> <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Erabilgarri badago, erabili konexioa partekatzeko hardwarearen azelerazioa"</string> <string name="adb_warning_title" msgid="6234463310896563253">"USB arazketa onartu?"</string> <string name="adb_warning_message" msgid="7316799925425402244">"USB arazketa garapen-xedeetarako soilik dago diseinatuta. Erabil ezazu ordenagailuaren eta gailuaren artean datuak kopiatzeko, aplikazioak gailuan jakinarazi gabe instalatzeko eta erregistro-datuak irakurtzeko."</string> @@ -462,7 +462,7 @@ <string name="alarm_template_far" msgid="3779172822607461675">"data: <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="zen_mode_duration_settings_title" msgid="229547412251222757">"Iraupena"</string> <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Galdetu beti"</string> - <string name="zen_mode_forever" msgid="2704305038191592967">"Desaktibatu arte"</string> + <string name="zen_mode_forever" msgid="2704305038191592967">"Zuk desaktibatu arte"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Oraintxe"</string> <string name="media_transfer_this_device_name" msgid="1636276898262571213">"Gailu hau"</string> </resources> diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index 6632752c629c..352c27683834 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -261,7 +261,7 @@ <string name="allow_mock_location" msgid="2787962564578664888">"مکانهای کاذب مجاز هستند"</string> <string name="allow_mock_location_summary" msgid="317615105156345626">"مکانهای کاذب مجاز هستند"</string> <string name="debug_view_attributes" msgid="6485448367803310384">"فعال کردن نمایش بازبینی ویژگی"</string> - <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"داده سلولی همیشه فعال نگه داشته میشود، حتی وقتی Wi-Fi فعال است (برای جابهجایی سریع شبکه)."</string> + <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"داده تلفن همراه همیشه فعال نگه داشته میشود، حتی وقتی Wi-Fi فعال است (برای جابهجایی سریع شبکه)."</string> <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"استفاده از شتاب سختافزاری اشتراکگذاری اینترنت درصورت دردسترس بودن"</string> <string name="adb_warning_title" msgid="6234463310896563253">"اشکالزدایی USB انجام شود؟"</string> <string name="adb_warning_message" msgid="7316799925425402244">"اشکالزدایی USB فقط برای اهداف برنامهنویسی در نظر گرفته شده است. از آن برای رونوشتبرداری داده بین رایانه و دستگاهتان، نصب برنامهها در دستگاهتان بدون اعلان و خواندن دادههای گزارش استفاده کنید."</string> diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml index 3aa8db984c3d..cf4ee1302872 100644 --- a/packages/SettingsLib/res/values-fr/strings.xml +++ b/packages/SettingsLib/res/values-fr/strings.xml @@ -146,7 +146,7 @@ <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Partage connexion Bluetooth"</string> <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"Partage de connexion"</string> <string name="tether_settings_title_all" msgid="8356136101061143841">"Partage de connexion"</string> - <string name="managed_user_title" msgid="8109605045406748842">"Toutes applis profession."</string> + <string name="managed_user_title" msgid="8109605045406748842">"Toutes les applis professionnelles"</string> <string name="user_guest" msgid="8475274842845401871">"Invité"</string> <string name="unknown" msgid="1592123443519355854">"Inconnu"</string> <string name="running_process_item_user_label" msgid="3129887865552025943">"Utilisateur : <xliff:g id="USER_NAME">%1$s</xliff:g>"</string> @@ -243,7 +243,7 @@ <string name="private_dns_mode_off" msgid="8236575187318721684">"Désactivé"</string> <string name="private_dns_mode_opportunistic" msgid="8314986739896927399">"Automatique"</string> <string name="private_dns_mode_provider" msgid="8354935160639360804">"Nom d\'hôte du fournisseur DNS privé"</string> - <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"Saisissez le nom d\'hôte du fournisseur DNS"</string> + <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"Indiquez le nom d\'hôte du fournisseur DNS"</string> <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Impossible de se connecter"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Afficher les options pour la certification de l\'affichage sans fil"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Détailler les infos Wi-Fi, afficher par RSSI de SSID dans l\'outil de sélection Wi-Fi"</string> @@ -385,8 +385,8 @@ <string name="power_discharging_duration_enhanced" msgid="1992003260664804080">"Temps restant en fonction de votre utilisation (<xliff:g id="LEVEL">%2$s</xliff:g>) : environ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <!-- no translation found for power_remaining_duration_only_short (9183070574408359726) --> <skip /> - <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> en fonction de votre utilisation (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> en fonction de votre utilisation"</string> + <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> selon utilisation (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> selon utilisation"</string> <string name="power_discharge_by" msgid="6453537733650125582">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Jusqu\'à <xliff:g id="TIME">%1$s</xliff:g>"</string> diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml index 4bd1c785080c..b998a74700b5 100644 --- a/packages/SettingsLib/res/values-gl/strings.xml +++ b/packages/SettingsLib/res/values-gl/strings.xml @@ -402,8 +402,8 @@ <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"É posible que a tableta se apague en breve (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string> <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"É posible que o dispositivo se apague en breve (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> - <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Tempo que queda ata cargar de todo: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ata completar a carga"</string> + <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Tempo que queda para completar a carga: <xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar a carga"</string> <string name="battery_info_status_unknown" msgid="196130600938058547">"Descoñecido"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string> <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"cargando"</string> diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml index 8c6ff8e51f88..5d512a84ef99 100644 --- a/packages/SettingsLib/res/values-hi/strings.xml +++ b/packages/SettingsLib/res/values-hi/strings.xml @@ -37,7 +37,7 @@ <string name="wifi_no_internet" msgid="4663834955626848401">"इंटरनेट नहीं है"</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> के द्वारा सहेजा गया"</string> <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s के ज़रिए ऑटोमैटिक रूप से कनेक्ट है"</string> - <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"नेटवर्क रेटिंग प्रदाता के ज़रिए अपने आप कनेक्ट है"</string> + <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"नेटवर्क रेटिंग कंपनी के ज़रिए अपने आप कनेक्ट है"</string> <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s के द्वारा उपलब्ध"</string> <string name="connected_via_app" msgid="5571999941988929520">"<xliff:g id="NAME">%1$s</xliff:g> के ज़रिए कनेक्ट किया गया"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s के द्वारा उपलब्ध"</string> diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml index 0684b3d292a5..798ea3c80cb0 100644 --- a/packages/SettingsLib/res/values-in/strings.xml +++ b/packages/SettingsLib/res/values-in/strings.xml @@ -41,7 +41,7 @@ <string name="connected_via_passpoint" msgid="2826205693803088747">"Terhubung melalui %1$s"</string> <string name="connected_via_app" msgid="5571999941988929520">"Tersambung melalui <xliff:g id="NAME">%1$s</xliff:g>"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Tersedia melalui %1$s"</string> - <string name="tap_to_sign_up" msgid="6449724763052579434">"Tap untuk mendaftar"</string> + <string name="tap_to_sign_up" msgid="6449724763052579434">"Ketuk untuk mendaftar"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Tersambung, tidak ada internet"</string> <string name="wifi_limited_connection" msgid="7717855024753201527">"Koneksi terbatas"</string> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Tidak ada internet"</string> @@ -52,7 +52,7 @@ <string name="osu_opening_provider" msgid="5488997661548640424">"Membuka <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string> <string name="osu_connect_failed" msgid="2187750899158158934">"Tidak dapat tersambung"</string> <string name="osu_completing_sign_up" msgid="9037638564719197082">"Menyelesaikan pendaftaran…"</string> - <string name="osu_sign_up_failed" msgid="7296159750352873260">"Tidak dapat menyelesaikan pendaftaran. Tap untuk mencoba lagi."</string> + <string name="osu_sign_up_failed" msgid="7296159750352873260">"Tidak dapat menyelesaikan pendaftaran. Ketuk untuk mencoba lagi."</string> <string name="osu_sign_up_complete" msgid="8207626049093289203">"Pendaftaran selesai. Menyambungkan…"</string> <string name="speed_label_very_slow" msgid="1867055264243608530">"Sangat Lambat"</string> <string name="speed_label_slow" msgid="813109590815810235">"Lambat"</string> @@ -338,7 +338,7 @@ <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Aktifkan dukungan untuk jendela eksperimental berformat bebas."</string> <string name="local_backup_password_title" msgid="3860471654439418822">"Sandi backup desktop"</string> <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Saat ini backup desktop sepenuhnya tidak dilindungi"</string> - <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Tap guna mengubah atau menghapus sandi untuk cadangan lengkap desktop"</string> + <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Ketuk guna mengubah atau menghapus sandi untuk cadangan lengkap desktop"</string> <string name="local_backup_password_toast_success" msgid="582016086228434290">"Sandi cadangan baru telah disetel"</string> <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Sandi baru dan konfirmasinya tidak cocok."</string> <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Gagal menyetel sandi cadangan"</string> @@ -354,8 +354,8 @@ <item msgid="5363960654009010371">"Warna yang dioptimalkan untuk konten digital"</item> </string-array> <string name="inactive_apps_title" msgid="9042996804461901648">"Aplikasi standby"</string> - <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Tidak aktif. Tap untuk beralih."</string> - <string name="inactive_app_active_summary" msgid="4174921824958516106">"Aktif. Tap untuk beralih."</string> + <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Tidak aktif. Ketuk untuk beralih."</string> + <string name="inactive_app_active_summary" msgid="4174921824958516106">"Aktif. Ketuk untuk beralih."</string> <string name="standby_bucket_summary" msgid="6567835350910684727">"Status standby aplikasi:<xliff:g id="BUCKET"> %s</xliff:g>"</string> <string name="runningservices_settings_title" msgid="8097287939865165213">"Layanan yang sedang berjalan"</string> <string name="runningservices_settings_summary" msgid="854608995821032748">"Melihat dan mengontrol layanan yang sedang berjalan"</string> diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml index c5176b02a31a..68c0f17a3b41 100644 --- a/packages/SettingsLib/res/values-it/strings.xml +++ b/packages/SettingsLib/res/values-it/strings.xml @@ -220,7 +220,7 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Reti"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Certificazione display wireless"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Attiva logging dettagliato Wi-Fi"</string> - <string name="wifi_scan_throttling" msgid="160014287416479843">"Limitazione della ricerca di reti Wi‑Fi"</string> + <string name="wifi_scan_throttling" msgid="160014287416479843">"Limita ricerca di reti Wi‑Fi"</string> <string name="mobile_data_always_on" msgid="8774857027458200434">"Dati mobili sempre attivi"</string> <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering accelerazione hardware"</string> <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostra dispositivi Bluetooth senza nome"</string> diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml index 1e572972a78f..246e3eb3c532 100644 --- a/packages/SettingsLib/res/values-kk/strings.xml +++ b/packages/SettingsLib/res/values-kk/strings.xml @@ -221,7 +221,7 @@ <string name="wifi_display_certification" msgid="8611569543791307533">"Сымсыз дисплей сертификаты"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi егжей-тегжейлі журналы"</string> <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi іздеуін шектеу"</string> - <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобильдік деректер әрқашан қосулы"</string> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобильдік интернет әрқашан қосулы"</string> <string name="tethering_hardware_offload" msgid="7470077827090325814">"Тетеринг режиміндегі аппараттық жеделдету"</string> <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Bluetooth құрылғыларын атаусыз көрсету"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Абсолютті дыбыс деңгейін өшіру"</string> diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml index fb09c2f494a0..36cf2d473faa 100644 --- a/packages/SettingsLib/res/values-km/strings.xml +++ b/packages/SettingsLib/res/values-km/strings.xml @@ -402,8 +402,8 @@ <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"ថេប្លេតអាចនឹងបិទក្នុងពេលបន្តិចទៀត (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string> <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"ឧបករណ៍អាចនឹងបិទក្នុងពេលបន្តិចទៀត (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> - <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"សល់ <xliff:g id="TIME">%1$s</xliff:g> ទើបសាកថ្មពេញ"</string> - <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> រហូតដល់សាកពេញ"</string> + <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> ទៀតទើបសាកថ្មពេញ"</string> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ទៀតទើបសាកថ្មពេញ"</string> <string name="battery_info_status_unknown" msgid="196130600938058547">"មិនស្គាល់"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"កំពុងបញ្ចូលថ្ម"</string> <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"កំពុងសាកថ្ម"</string> diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml index abdfa041ada8..8f8bbc1a4721 100644 --- a/packages/SettingsLib/res/values-ko/strings.xml +++ b/packages/SettingsLib/res/values-ko/strings.xml @@ -247,7 +247,7 @@ <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"연결할 수 없음"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"무선 디스플레이 인증서 옵션 표시"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi 로깅 수준을 높이고, Wi‑Fi 선택도구에서 SSID RSSI당 값을 표시"</string> - <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"배터리 소모를 줄이고 네트워크 성능을 개선합니다."</string> + <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"배터리 소모를 줄이고 네트워크 성능 개선"</string> <string name="wifi_metered_label" msgid="4514924227256839725">"종량제 네트워크"</string> <string name="wifi_unmetered_label" msgid="6124098729457992931">"무제한 네트워크"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"로거 버퍼 크기"</string> diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml index 8bed22f1e763..dda346242616 100644 --- a/packages/SettingsLib/res/values-mk/strings.xml +++ b/packages/SettingsLib/res/values-mk/strings.xml @@ -262,7 +262,7 @@ <string name="allow_mock_location_summary" msgid="317615105156345626">"Овозможи лажни локации"</string> <string name="debug_view_attributes" msgid="6485448367803310384">"Овозможете проверка на атрибутот на приказот"</string> <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Секогаш држи го активен мобилниот интернет, дури и при активно Wi-Fi (за брзо префрлување мрежа)."</string> - <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Ако е достапно, користете хардверско забрзување за врзување"</string> + <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Ако е достапно, користи хардверско забрзување за врзување"</string> <string name="adb_warning_title" msgid="6234463310896563253">"Овозможи отстранување грешки на USB?"</string> <string name="adb_warning_message" msgid="7316799925425402244">"Отстранувањето грешки на USB е наменето само за целите на развој. Користете го за копирање податоци меѓу вашиот компјутер и вашиот уред, за инсталирање апликации на вашиот уред без известување и за читање евиденција на податоци."</string> <string name="adb_keys_warning_message" msgid="5659849457135841625">"Отповикај пристап кон отстранување грешка од USB од сите претходно овластени компјутери?"</string> diff --git a/packages/SettingsLib/res/values-mr/arrays.xml b/packages/SettingsLib/res/values-mr/arrays.xml index a364db91beff..7b467601f9d5 100644 --- a/packages/SettingsLib/res/values-mr/arrays.xml +++ b/packages/SettingsLib/res/values-mr/arrays.xml @@ -145,9 +145,9 @@ </string-array> <string-array name="bluetooth_audio_active_device_summaries"> <item msgid="4862957058729193940"></item> - <item msgid="6481691720774549651">", अॅक्टिव्ह"</item> - <item msgid="8962366465966010158">", अॅक्टिव्ह (मीडिया)"</item> - <item msgid="4046665544396189228">", अॅक्टिव्ह (फोन)"</item> + <item msgid="6481691720774549651">", अॅक्टिव्ह"</item> + <item msgid="8962366465966010158">", अॅक्टिव्ह (मीडिया)"</item> + <item msgid="4046665544396189228">", अॅक्टिव्ह (फोन)"</item> </string-array> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"बंद"</item> diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml index 367b13d4ce09..54723a80b51c 100644 --- a/packages/SettingsLib/res/values-mr/strings.xml +++ b/packages/SettingsLib/res/values-mr/strings.xml @@ -34,7 +34,7 @@ <string name="wifi_check_password_try_again" msgid="516958988102584767">"पासवर्ड तपासा आणि पुन्हा प्रयत्न करा"</string> <string name="wifi_not_in_range" msgid="1136191511238508967">"परिक्षेत्रामध्ये नाही"</string> <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"स्वयंचलितपणे कनेक्ट करणार नाही"</string> - <string name="wifi_no_internet" msgid="4663834955626848401">"इंटरनेट अॅक्सेस नाही"</string> + <string name="wifi_no_internet" msgid="4663834955626848401">"इंटरनेट अॅक्सेस नाही"</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> द्वारे सेव्ह केले"</string> <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s द्वारे स्वयंचलितपणे कनेक्ट केले"</string> <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"नेटवर्क रेटिंग प्रदात्याद्वारे स्वयंचलितपणे कनेक्ट केले"</string> @@ -46,7 +46,7 @@ <string name="wifi_limited_connection" msgid="7717855024753201527">"मर्यादित कनेक्शन"</string> <string name="wifi_status_no_internet" msgid="5784710974669608361">"इंटरनेट नाही"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"साइन इन करणे आवश्यक आहे"</string> - <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"अॅक्सेस पॉइंट तात्पुरते भरलेले"</string> + <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"अॅक्सेस पॉइंट तात्पुरते भरलेले"</string> <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s ने कनेक्ट केले"</string> <string name="available_via_carrier" msgid="1469036129740799053">"%1$s ने उपलब्ध"</string> <string name="osu_opening_provider" msgid="5488997661548640424">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> उघडत आहे"</string> @@ -74,8 +74,8 @@ <string name="bluetooth_connected_no_headset_battery_level" msgid="1610296229139400266">"कनेक्ट केले (फोन नाही), बॅटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"कनेक्ट केले (मीडिया नाही), बॅटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"कनेक्ट केले (फोन किंवा मीडिया नाही), बॅटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> - <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"अॅक्टिव्ह, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बॅटरी"</string> - <string name="bluetooth_active_battery_level_untethered" msgid="6662649951391456747">"अॅक्टिव्ह, L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> बॅटरी, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> बॅटरी"</string> + <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"अॅक्टिव्ह, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बॅटरी"</string> + <string name="bluetooth_active_battery_level_untethered" msgid="6662649951391456747">"अॅक्टिव्ह, L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> बॅटरी, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> बॅटरी"</string> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बॅटरी"</string> <string name="bluetooth_battery_level_untethered" msgid="5974406100211667177">"L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> बॅटरी, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> बॅटरी"</string> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"अॅक्टिव्ह"</string> @@ -83,12 +83,12 @@ <string name="bluetooth_profile_headset" msgid="7815495680863246034">"फोन कॉल"</string> <string name="bluetooth_profile_opp" msgid="9168139293654233697">"फाइल स्थानांतरण"</string> <string name="bluetooth_profile_hid" msgid="3680729023366986480">"इनपुट डिव्हाइस"</string> - <string name="bluetooth_profile_pan" msgid="3391606497945147673">"इंटरनेट अॅक्सेस"</string> + <string name="bluetooth_profile_pan" msgid="3391606497945147673">"इंटरनेट अॅक्सेस"</string> <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"संपर्क शेअरिंग"</string> <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"संपर्क सामायिकरणासाठी वापरा"</string> <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"इंटरनेट कनेक्शन शेअररण"</string> <string name="bluetooth_profile_map" msgid="1019763341565580450">"मजकूर मेसेज"</string> - <string name="bluetooth_profile_sap" msgid="5764222021851283125">"सिम अॅक्सेस"</string> + <string name="bluetooth_profile_sap" msgid="5764222021851283125">"सिम अॅक्सेस"</string> <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ऑडिओ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string> <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ऑडिओ"</string> <string name="bluetooth_profile_hearing_aid" msgid="6680721080542444257">"श्रवण यंत्रे"</string> @@ -102,7 +102,7 @@ <string name="bluetooth_hid_profile_summary_connected" msgid="3381760054215168689">"इनपुट डिव्हाइसवर कनेक्ट केले"</string> <string name="bluetooth_pan_user_profile_summary_connected" msgid="6436258151814414028">"इंटरनेट अॅक्सेससाठी डिव्हाइसशी कनेक्ट केले"</string> <string name="bluetooth_pan_nap_profile_summary_connected" msgid="1322694224800769308">"डिव्हाइससह स्थानिक इंटरनेट कनेक्शन शेअर करत आहे"</string> - <string name="bluetooth_pan_profile_summary_use_for" msgid="5736111170225304239">"इंटरनेट अॅक्सेस करण्यासाठी वापरा"</string> + <string name="bluetooth_pan_profile_summary_use_for" msgid="5736111170225304239">"इंटरनेट अॅक्सेस करण्यासाठी वापरा"</string> <string name="bluetooth_map_profile_summary_use_for" msgid="5154200119919927434">"नकाशासाठी वापरा"</string> <string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"SIM प्रवेशासाठी वापरा"</string> <string name="bluetooth_a2dp_profile_summary_use_for" msgid="4630849022250168427">"मीडिया ऑडिओसाठी वापरा"</string> @@ -113,7 +113,7 @@ <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"पेअर करा"</string> <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"पेअर करा"</string> <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"रद्द करा"</string> - <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"कनेक्ट केल्यावर पेअरींग तुमचे संपर्क आणि कॉल इतिहास यामध्ये अॅक्सेस देते."</string> + <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"कनेक्ट केल्यावर पेअरींग तुमचे संपर्क आणि कॉल इतिहास यामध्ये अॅक्सेस देते."</string> <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> शी जोडू शकलो नाही."</string> <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"अयोग्य पिन किंवा पासकीमुळे <xliff:g id="DEVICE_NAME">%1$s</xliff:g> सह जोडू शकलो नाही."</string> <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> शी संवाद प्रस्थापित करू शकत नाही."</string> @@ -138,15 +138,15 @@ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"नेटवर्क उघडा"</string> <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"सुरक्षित नेटवर्क"</string> <string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string> - <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"काढलेले अॅप्स"</string> - <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"काढलेले अॅप्स आणि वापरकर्ते"</string> + <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"काढलेले अॅप्स"</string> + <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"काढलेले अॅप्स आणि वापरकर्ते"</string> <string name="data_usage_ota" msgid="5377889154805560860">"सिस्टम अपडेट"</string> <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB टेदरिंग"</string> <string name="tether_settings_title_wifi" msgid="3277144155960302049">"पोर्टेबल हॉटस्पॉट"</string> <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"ब्लूटूथ टेदरिंग"</string> <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"टेदरिंग"</string> <string name="tether_settings_title_all" msgid="8356136101061143841">"टेदरिंग आणि पोर्टेबल हॉटस्पॉट"</string> - <string name="managed_user_title" msgid="8109605045406748842">"सर्व कार्य अॅप्स"</string> + <string name="managed_user_title" msgid="8109605045406748842">"सर्व कार्य अॅप्स"</string> <string name="user_guest" msgid="8475274842845401871">"अतिथी"</string> <string name="unknown" msgid="1592123443519355854">"अज्ञात"</string> <string name="running_process_item_user_label" msgid="3129887865552025943">"वापरकर्ता: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string> @@ -200,7 +200,7 @@ <string name="development_settings_not_available" msgid="4308569041701535607">"या वापरकर्त्यासाठी डेव्हलपर पर्याय उपलब्ध नाहीत"</string> <string name="vpn_settings_not_available" msgid="956841430176985598">"या वापरकर्त्यासाठी VPN सेटिंग्ज उपलब्ध नाहीत"</string> <string name="tethering_settings_not_available" msgid="6765770438438291012">"या वापरकर्त्यासाठी टेदरिंग सेटिंग्ज उपलब्ध नाहीत"</string> - <string name="apn_settings_not_available" msgid="7873729032165324000">"या वापरकर्त्यासाठी अॅक्सेस बिंदू नाव सेटिंग्ज उपलब्ध नाहीत"</string> + <string name="apn_settings_not_available" msgid="7873729032165324000">"या वापरकर्त्यासाठी अॅक्सेस बिंदू नाव सेटिंग्ज उपलब्ध नाहीत"</string> <string name="enable_adb" msgid="7982306934419797485">"USB डीबग करणे"</string> <string name="enable_adb_summary" msgid="4881186971746056635">"USB कनेक्ट केलेले असताना डीबग मोड"</string> <string name="clear_adb_keys" msgid="4038889221503122743">"USB डीबग करणारी प्रमाणीकरणे रीव्होक करा"</string> @@ -261,14 +261,14 @@ <string name="allow_mock_location" msgid="2787962564578664888">"बनावट स्थानांना अनुमती द्या"</string> <string name="allow_mock_location_summary" msgid="317615105156345626">"बनावट स्थानांना अनुमती द्या"</string> <string name="debug_view_attributes" msgid="6485448367803310384">"दृश्य विशेषता तपासणी सुरू करा"</string> - <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"जरी वाय-फाय चालू असले तरीही, मोबाईल डेटा नेहमी चालू ठेवा (नेटवर्क जलदरीत्या स्विच करण्यासाठी)."</string> - <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"उपलब्ध असल्यास टेदरिंग हार्डवेअर प्रवेग वापरा"</string> + <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"वाय-फाय चालू असतानाही मोबाइल डेटा नेहमी सुरू ठेवा (नेटवर्क जलदरीत्या स्विच करण्यासाठी)."</string> + <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"उपलब्ध असल्यास टेदरिंग हार्डवेअर अॅक्सिलरेशन वापरा"</string> <string name="adb_warning_title" msgid="6234463310896563253">"USB डीबग करण्यास अनुमती द्यायची?"</string> - <string name="adb_warning_message" msgid="7316799925425402244">"USB डीबग करण्याचा हेतू फक्त विकास उद्देशांसाठी आहे. याचा वापर तुमचा कॉंप्युटर आणि तुमचे डिव्हाइस यांच्या दरम्यान डेटा कॉपी करण्यासाठी करा, सूचनेशिवाय तुमच्या डिव्हाइस वर अॅप्स इंस्टॉल करा आणि लॉग डेटा वाचा."</string> - <string name="adb_keys_warning_message" msgid="5659849457135841625">"तुम्ही पूर्वी अॉथोराइझ केलेल्या सर्व संगणकांवरुन USB डीबग करण्यासाठी अॅक्सेस रीव्होक करायचा?"</string> + <string name="adb_warning_message" msgid="7316799925425402244">"USB डीबग करण्याचा हेतू फक्त विकास उद्देशांसाठी आहे. याचा वापर तुमचा कॉंप्युटर आणि तुमचे डिव्हाइस यांच्या दरम्यान डेटा कॉपी करण्यासाठी करा, सूचनेशिवाय तुमच्या डिव्हाइस वर अॅप्स इंस्टॉल करा आणि लॉग डेटा वाचा."</string> + <string name="adb_keys_warning_message" msgid="5659849457135841625">"तुम्ही पूर्वी अॉथोराइझ केलेल्या सर्व संगणकांवरुन USB डीबग करण्यासाठी अॅक्सेस रीव्होक करायचा?"</string> <string name="dev_settings_warning_title" msgid="7244607768088540165">"विकास सेटिंग्जला अनुमती द्यायची?"</string> <string name="dev_settings_warning_message" msgid="2298337781139097964">"या सेटिंग्जचा हेतू फक्त विकास वापरासाठी आहे. त्यामुळे तुमचे डिव्हाइस आणि त्यावरील अॅप्लिकेशन ब्रेक होऊ शकतात किंवा नेहमीपेक्षा वेगळे वर्तन करू शकतात."</string> - <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB वर अॅप्स पडताळून पाहा"</string> + <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB वर अॅप्स पडताळून पाहा"</string> <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"हानिकारक वर्तनासाठी ADB/ADT द्वारे इंस्टॉल अॅप्स तपासा."</string> <string name="bluetooth_show_devices_without_names_summary" msgid="2351196058115755520">"नावांशिवाय ब्लूटूथ डीव्हाइस (फक्त MAC पत्ते) दाखवले जातील"</string> <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"रिमोट डिव्हाइसमध्ये सहन न होणारा मोठा आवाज किंवा नियंत्रणाचा अभाव यासारखी आवाजाची समस्या असल्यास ब्लूटूथ संपूर्ण आवाज वैशिष्ट्य बंद करते."</string> @@ -290,7 +290,7 @@ <string name="media_category" msgid="4388305075496848353">"मीडिया"</string> <string name="debug_monitoring_category" msgid="7640508148375798343">"परीक्षण"</string> <string name="strict_mode" msgid="1938795874357830695">"कठोर मोड सुरू"</string> - <string name="strict_mode_summary" msgid="142834318897332338">"मुख्य थ्रेडवर अॅप्स मोठी कार्ये करतात तेव्हा स्क्रीन फ्लॅश करा"</string> + <string name="strict_mode_summary" msgid="142834318897332338">"मुख्य थ्रेडवर अॅप्स मोठी कार्ये करतात तेव्हा स्क्रीन फ्लॅश करा"</string> <string name="pointer_location" msgid="6084434787496938001">"पॉइंटर स्थान"</string> <string name="pointer_location_summary" msgid="840819275172753713">"वर्तमान स्पर्श डेटा दर्शविणारे स्क्रीन ओव्हरले"</string> <string name="show_touches" msgid="2642976305235070316">"टॅप दाखवा"</string> @@ -322,7 +322,7 @@ <string name="transition_animation_scale_title" msgid="387527540523595875">"ट्रांझिशन अॅनिमेशन स्केल"</string> <string name="animator_duration_scale_title" msgid="3406722410819934083">"अॅनिमेटर कालावधी स्केल"</string> <string name="overlay_display_devices_title" msgid="5364176287998398539">"दुय्यम डिस्प्ले सिम्युलेट करा"</string> - <string name="debug_applications_category" msgid="4206913653849771549">"अॅप्स"</string> + <string name="debug_applications_category" msgid="4206913653849771549">"अॅप्स"</string> <string name="immediately_destroy_activities" msgid="1579659389568133959">"अॅक्टिव्हिटी ठेवू नका"</string> <string name="immediately_destroy_activities_summary" msgid="3592221124808773368">"वापरकर्त्याने प्रत्येक अॅक्टिव्हिटी सोडताच ती नष्ट करा"</string> <string name="app_process_limit_title" msgid="4280600650253107163">"पार्श्वभूमी प्रक्रिया मर्यादा"</string> @@ -353,7 +353,7 @@ <item msgid="8280754435979370728">"डोळ्यांनी पाहिले तसे नैसर्गिक रंग"</item> <item msgid="5363960654009010371">"डिजिटल सामग्रीसाठी ऑप्टिमाइझ केलेले रंग"</item> </string-array> - <string name="inactive_apps_title" msgid="9042996804461901648">"स्टँडबाय अॅप्स"</string> + <string name="inactive_apps_title" msgid="9042996804461901648">"स्टँडबाय अॅप्स"</string> <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"निष्क्रिय. टॉगल करण्यासाठी टॅप करा."</string> <string name="inactive_app_active_summary" msgid="4174921824958516106">"सक्रिय. टॉगल करण्यासाठी टॅप करा."</string> <string name="standby_bucket_summary" msgid="6567835350910684727">"अॅप स्टँडबाय स्थिती: <xliff:g id="BUCKET"> %s</xliff:g>"</string> diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml index 648cc4a99b4e..5725c22a5456 100644 --- a/packages/SettingsLib/res/values-or/strings.xml +++ b/packages/SettingsLib/res/values-or/strings.xml @@ -247,7 +247,7 @@ <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"କନେକ୍ଟ କରିହେଲା ନାହିଁ"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ୱେୟାରଲେସ୍ ଡିସ୍ପ୍ଲେ ସାର୍ଟିଫିକେସନ୍ ପାଇଁ ବିକଳ୍ପ ଦେଖାନ୍ତୁ"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ୱାଇ-ଫାଇ ଲଗିଙ୍ଗ ସ୍ତର ବଢ଼ାନ୍ତୁ, ୱାଇ-ଫାଇ ପିକର୍ରେ ପ୍ରତି SSID RSSI ଦେଖାନ୍ତୁ"</string> - <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"ବ୍ୟାଟେରୀ ଖର୍ଚ୍ଚ କମ୍ ଏବଂ ନେଟ୍ୱାର୍କ ପ୍ରଦର୍ଶନ ଉନ୍ନତ କରିଥାଏ"</string> + <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"ବ୍ୟାଟେରୀ ଖର୍ଚ୍ଚ କମ୍ ଏବଂ ନେଟ୍ୱାର୍କ କାର୍ଯ୍ୟକ୍ଷମତା ଉନ୍ନତ କରିଥାଏ"</string> <string name="wifi_metered_label" msgid="4514924227256839725">"ମପାଯାଉଥିବା"</string> <string name="wifi_unmetered_label" msgid="6124098729457992931">"ମପାଯାଉନଥିବା"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"ଲଗର୍ ବଫର୍ ସାଇଜ୍"</string> diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml index 7967c71669c2..faccda7e9395 100644 --- a/packages/SettingsLib/res/values-pa/strings.xml +++ b/packages/SettingsLib/res/values-pa/strings.xml @@ -403,7 +403,7 @@ <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"ਡੀਵਾਈਸ ਛੇਤੀ ਹੀ ਬੰਦ ਹੋ ਸਕਦਾ ਹੈ (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"ਪੂਰੀ ਤਰ੍ਹਾਂ ਚਾਰਜ ਹੋਣ ਲਈ <xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string> - <string name="power_charging_duration" msgid="4676999980973411875">"ਪੂਰੀ ਤਰ੍ਹਾਂ ਚਾਰਜ ਹੋਣ ਤੱਕ <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਪੂਰੀ ਤਰ੍ਹਾਂ ਚਾਰਜ ਹੋਣ ਵਿੱਚ <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="battery_info_status_unknown" msgid="196130600938058547">"ਅਗਿਆਤ"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string> <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ਚਾਰਜ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string> diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml index 0401e7fd2d02..806be6e5cdd6 100644 --- a/packages/SettingsLib/res/values-ru/strings.xml +++ b/packages/SettingsLib/res/values-ru/strings.xml @@ -220,7 +220,7 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Сети"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Серт. беспроводн. мониторов"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Подробный журнал Wi‑Fi"</string> - <string name="wifi_scan_throttling" msgid="160014287416479843">"Регулирование поиска сетей Wi‑Fi"</string> + <string name="wifi_scan_throttling" msgid="160014287416479843">"Ограничивать поиск сетей Wi‑Fi"</string> <string name="mobile_data_always_on" msgid="8774857027458200434">"Не отключать мобильный Интернет"</string> <string name="tethering_hardware_offload" msgid="7470077827090325814">"Аппаратное ускорение в режиме модема"</string> <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Показывать Bluetooth-устройства без названий"</string> @@ -247,7 +247,7 @@ <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Ошибка подключения"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Показывать параметры сертификации беспроводных мониторов"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Вести подробный журнал, показывать RSSI для каждого SSID при выборе сети"</string> - <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Уменьшает расход заряда батареи и улучшает работу сетей."</string> + <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Уменьшает расход заряда батареи и улучшает работу сети"</string> <string name="wifi_metered_label" msgid="4514924227256839725">"Сеть с тарификацией трафика"</string> <string name="wifi_unmetered_label" msgid="6124098729457992931">"Сеть без тарификации трафика"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Размер буфера журнала"</string> diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml index 213b28557142..b16d5d91f7eb 100644 --- a/packages/SettingsLib/res/values-sl/strings.xml +++ b/packages/SettingsLib/res/values-sl/strings.xml @@ -246,7 +246,7 @@ <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"Vnesite ime gostitelja pri ponudniku DNS"</string> <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Povezave ni bilo mogoče vzpostaviti"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Pokaži možnosti za potrdilo brezžičnega zaslona"</string> - <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povečaj raven zapis. dnev. za Wi-Fi; v izbir. Wi‑Fi-ja pokaži glede na SSID RSSI"</string> + <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povečaj raven zapisovanja dnevnika za Wi-Fi; v izbirniku Wi‑Fi-ja pokaži glede na SSID RSSI"</string> <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Zmanjša porabo energije akumulatorja in izboljša delovanje omrežja"</string> <string name="wifi_metered_label" msgid="4514924227256839725">"Omejen prenos podatkov"</string> <string name="wifi_unmetered_label" msgid="6124098729457992931">"Z neomejenim prenosom podatkov"</string> diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml index 910b94ecdf03..0b184d241b55 100644 --- a/packages/SettingsLib/res/values-th/strings.xml +++ b/packages/SettingsLib/res/values-th/strings.xml @@ -247,7 +247,7 @@ <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"เชื่อมต่อไม่ได้"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"แสดงตัวเลือกสำหรับการรับรองการแสดงผล แบบไร้สาย"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"เพิ่มระดับการบันทึก Wi‑Fi แสดงต่อ SSID RSSI ในตัวเลือก Wi‑Fi"</string> - <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"ลดการหมดเปลืองแบตเตอรี่และเพิ่มประสิทธิภาพเครือข่าย"</string> + <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"ลดการเปลืองแบตเตอรี่และเพิ่มประสิทธิภาพเครือข่าย"</string> <string name="wifi_metered_label" msgid="4514924227256839725">"มีการวัดปริมาณอินเทอร์เน็ต"</string> <string name="wifi_unmetered_label" msgid="6124098729457992931">"ไม่มีการวัดปริมาณอินเทอร์เน็ต"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"ขนาดบัฟเฟอร์ของตัวบันทึก"</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java b/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java index c7380c580e2f..5ac788e1b374 100644 --- a/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java +++ b/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java @@ -22,6 +22,7 @@ import android.content.Context; import android.content.res.ColorStateList; import android.graphics.Canvas; import android.graphics.ColorFilter; +import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Path.Direction; @@ -33,6 +34,7 @@ import android.graphics.drawable.DrawableWrapper; import android.os.Handler; import android.telephony.SignalStrength; import android.util.LayoutDirection; +import android.util.PathParser; import com.android.settingslib.R; import com.android.settingslib.Utils; @@ -48,7 +50,6 @@ public class SignalDrawable extends DrawableWrapper { private static final float VIEWPORT = 24f; private static final float PAD = 2f / VIEWPORT; - private static final float CUT_OUT = 7.9f / VIEWPORT; private static final float DOT_SIZE = 3f / VIEWPORT; private static final float DOT_PADDING = 1.5f / VIEWPORT; @@ -65,21 +66,6 @@ public class SignalDrawable extends DrawableWrapper { private static final long DOT_DELAY = 1000; - private static float[][] X_PATH = new float[][]{ - {21.9f / VIEWPORT, 17.0f / VIEWPORT}, - {-1.1f / VIEWPORT, -1.1f / VIEWPORT}, - {-1.9f / VIEWPORT, 1.9f / VIEWPORT}, - {-1.9f / VIEWPORT, -1.9f / VIEWPORT}, - {-1.1f / VIEWPORT, 1.1f / VIEWPORT}, - {1.9f / VIEWPORT, 1.9f / VIEWPORT}, - {-1.9f / VIEWPORT, 1.9f / VIEWPORT}, - {1.1f / VIEWPORT, 1.1f / VIEWPORT}, - {1.9f / VIEWPORT, -1.9f / VIEWPORT}, - {1.9f / VIEWPORT, 1.9f / VIEWPORT}, - {1.1f / VIEWPORT, -1.1f / VIEWPORT}, - {-1.9f / VIEWPORT, -1.9f / VIEWPORT}, - }; - private final Paint mForegroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private final Paint mTransparentPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private final int mDarkModeFillColor; @@ -87,7 +73,11 @@ public class SignalDrawable extends DrawableWrapper { private final Path mCutoutPath = new Path(); private final Path mForegroundPath = new Path(); private final Path mXPath = new Path(); + private final Matrix mXScaleMatrix = new Matrix(); + private final Path mScaledXPath = new Path(); private final Handler mHandler; + private final float mCutoutWidthFraction; + private final float mCutoutHeightFraction; private float mDarkIntensity = -1; private final int mIntrinsicSize; private boolean mAnimating; @@ -95,6 +85,14 @@ public class SignalDrawable extends DrawableWrapper { public SignalDrawable(Context context) { super(context.getDrawable(com.android.internal.R.drawable.ic_signal_cellular)); + final String xPathString = context.getString( + com.android.internal.R.string.config_signalXPath); + mXPath.set(PathParser.createPathFromPathData(xPathString)); + updateScaledXPath(); + mCutoutWidthFraction = context.getResources().getFloat( + com.android.internal.R.dimen.config_signalCutoutWidthFraction); + mCutoutHeightFraction = context.getResources().getFloat( + com.android.internal.R.dimen.config_signalCutoutHeightFraction); mDarkModeFillColor = Utils.getColorStateListDefaultColor(context, R.color.dark_mode_icon_color_single_tone); mLightModeFillColor = Utils.getColorStateListDefaultColor(context, @@ -106,6 +104,15 @@ public class SignalDrawable extends DrawableWrapper { setDarkIntensity(0); } + private void updateScaledXPath() { + if (getBounds().isEmpty()) { + mXScaleMatrix.setScale(1f, 1f); + } else { + mXScaleMatrix.setScale(getBounds().width() / VIEWPORT, getBounds().height() / VIEWPORT); + } + mXPath.transform(mXScaleMatrix, mScaledXPath); + } + @Override public int getIntrinsicWidth() { return mIntrinsicSize; @@ -170,6 +177,7 @@ public class SignalDrawable extends DrawableWrapper { @Override protected void onBoundsChange(Rect bounds) { super.onBoundsChange(bounds); + updateScaledXPath(); invalidateSelf(); } @@ -205,19 +213,15 @@ public class SignalDrawable extends DrawableWrapper { canvas.drawPath(mCutoutPath, mTransparentPaint); canvas.drawPath(mForegroundPath, mForegroundPaint); } else if (isInState(STATE_CUT)) { - float cut = (CUT_OUT * width); - mCutoutPath.moveTo(width - padding, height - padding); - mCutoutPath.rLineTo(-cut, 0); - mCutoutPath.rLineTo(0, -cut); - mCutoutPath.rLineTo(cut, 0); - mCutoutPath.rLineTo(0, cut); + float cutX = (mCutoutWidthFraction * width / VIEWPORT); + float cutY = (mCutoutHeightFraction * height / VIEWPORT); + mCutoutPath.moveTo(width, height); + mCutoutPath.rLineTo(-cutX, 0); + mCutoutPath.rLineTo(0, -cutY); + mCutoutPath.rLineTo(cutX, 0); + mCutoutPath.rLineTo(0, cutY); canvas.drawPath(mCutoutPath, mTransparentPaint); - mXPath.reset(); - mXPath.moveTo(X_PATH[0][0] * width, X_PATH[0][1] * height); - for (int i = 1; i < X_PATH.length; i++) { - mXPath.rLineTo(X_PATH[i][0] * width, X_PATH[i][1] * height); - } - canvas.drawPath(mXPath, mForegroundPaint); + canvas.drawPath(mScaledXPath, mForegroundPaint); } if (isRtl) { canvas.restore(); diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 38675122c501..a549870ec780 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -141,6 +141,9 @@ <!-- The number of milliseconds before the heads up notification auto-dismisses. --> <integer name="heads_up_notification_decay">5000</integer> + <!-- The number of milliseconds before the heads up notification sent automatically by the system auto-dismisses. --> + <integer name="auto_heads_up_notification_decay">3000</integer> + <!-- The number of milliseconds after a heads up notification is pushed back before the app can interrupt again. --> <integer name="heads_up_default_snooze_length_ms">60000</integer> diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java index 06352310b3dd..5136682bb292 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java @@ -52,6 +52,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.R; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.NotificationMediaManager; +import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.policy.NextAlarmController; import com.android.systemui.statusbar.policy.NextAlarmControllerImpl; @@ -103,8 +104,8 @@ public class KeyguardSliceProvider extends SliceProvider implements private final Date mCurrentTime = new Date(); private final Handler mHandler; private final AlarmManager.OnAlarmListener mUpdateNextAlarm = this::updateNextAlarm; - private final HashSet<Integer> mMediaInvisibleStates; private final Object mMediaToken = new Object(); + private DozeParameters mDozeParameters; @VisibleForTesting protected SettableWakeLock mMediaWakeLock; @VisibleForTesting @@ -184,11 +185,6 @@ public class KeyguardSliceProvider extends SliceProvider implements mAlarmUri = Uri.parse(KEYGUARD_NEXT_ALARM_URI); mDndUri = Uri.parse(KEYGUARD_DND_URI); mMediaUri = Uri.parse(KEYGUARD_MEDIA_URI); - - mMediaInvisibleStates = new HashSet<>(); - mMediaInvisibleStates.add(PlaybackState.STATE_NONE); - mMediaInvisibleStates.add(PlaybackState.STATE_STOPPED); - mMediaInvisibleStates.add(PlaybackState.STATE_PAUSED); } /** @@ -201,12 +197,14 @@ public class KeyguardSliceProvider extends SliceProvider implements public void initDependencies( NotificationMediaManager mediaManager, StatusBarStateController statusBarStateController, - KeyguardBypassController keyguardBypassController) { + KeyguardBypassController keyguardBypassController, + DozeParameters dozeParameters) { mMediaManager = mediaManager; mMediaManager.addCallback(this); mStatusBarStateController = statusBarStateController; mStatusBarStateController.addCallback(this); mKeyguardBypassController = keyguardBypassController; + mDozeParameters = dozeParameters; } @AnyThread @@ -231,9 +229,9 @@ public class KeyguardSliceProvider extends SliceProvider implements } protected boolean needsMediaLocked() { - boolean isBypass = mKeyguardBypassController != null - && mKeyguardBypassController.getBypassEnabled(); - return !TextUtils.isEmpty(mMediaTitle) && mMediaIsVisible && (mDozing || isBypass); + boolean keepWhenAwake = mKeyguardBypassController != null + && mKeyguardBypassController.getBypassEnabled() && mDozeParameters.getAlwaysOn(); + return !TextUtils.isEmpty(mMediaTitle) && mMediaIsVisible && (mDozing || keepWhenAwake); } protected void addMediaLocked(ListBuilder listBuilder) { @@ -458,7 +456,7 @@ public class KeyguardSliceProvider extends SliceProvider implements @Override public void onMetadataOrStateChanged(MediaMetadata metadata, @PlaybackState.State int state) { synchronized (this) { - boolean nextVisible = !mMediaInvisibleStates.contains(state); + boolean nextVisible = NotificationMediaManager.isPlayingState(state); mHandler.removeCallbacksAndMessages(mMediaToken); if (mMediaIsVisible && !nextVisible) { // We need to delay this event for a few millis when stopping to avoid jank in the @@ -477,7 +475,7 @@ public class KeyguardSliceProvider extends SliceProvider implements } private void updateMediaStateLocked(MediaMetadata metadata, @PlaybackState.State int state) { - boolean nextVisible = !mMediaInvisibleStates.contains(state); + boolean nextVisible = NotificationMediaManager.isPlayingState(state); CharSequence title = null; if (metadata != null) { title = metadata.getText(MediaMetadata.METADATA_KEY_TITLE); diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java index b9fb1a1c91c8..21f58128322d 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java @@ -239,9 +239,8 @@ public class PipMenuActivity extends Activity { }); mDismissButton = findViewById(R.id.dismiss); mDismissButton.setAlpha(0); - mDismissButton.setOnClickListener((v) -> { - dismissPip(); - }); + mDismissButton.setOnClickListener(v -> dismissPip()); + findViewById(R.id.expand_button).setOnClickListener(v -> expandPip()); mActionsGroup = findViewById(R.id.actions_group); mBetweenActionPaddingLand = getResources().getDimensionPixelSize( R.dimen.pip_between_action_padding_land); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java index a59d590c9719..f001561754aa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java @@ -69,6 +69,7 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Set; @@ -91,6 +92,14 @@ public class NotificationMediaManager implements Dumpable { private final SysuiColorExtractor mColorExtractor = Dependency.get(SysuiColorExtractor.class); private final KeyguardMonitor mKeyguardMonitor = Dependency.get(KeyguardMonitor.class); private final KeyguardBypassController mKeyguardBypassController; + private static final HashSet<Integer> PAUSED_MEDIA_STATES = new HashSet<>(); + static { + PAUSED_MEDIA_STATES.add(PlaybackState.STATE_NONE); + PAUSED_MEDIA_STATES.add(PlaybackState.STATE_STOPPED); + PAUSED_MEDIA_STATES.add(PlaybackState.STATE_PAUSED); + PAUSED_MEDIA_STATES.add(PlaybackState.STATE_ERROR); + } + // Late binding private NotificationEntryManager mEntryManager; @@ -207,6 +216,10 @@ public class NotificationMediaManager implements Dumpable { mPropertiesChangedListener); } + public static boolean isPlayingState(int state) { + return !PAUSED_MEDIA_STATES.contains(state); + } + public void setUpWithPresenter(NotificationPresenter presenter) { mPresenter = presenter; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java index 0a8b7f8aa0da..4ccd0cd3353b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java @@ -18,6 +18,7 @@ package com.android.systemui.statusbar; import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN_REVERSE; import static com.android.systemui.statusbar.phone.NotificationIconContainer.IconState.NO_VALUE; +import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT; import android.content.Context; import android.content.res.Configuration; @@ -48,8 +49,12 @@ import com.android.systemui.statusbar.notification.stack.AnimationProperties; import com.android.systemui.statusbar.notification.stack.ExpandableViewState; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.notification.stack.ViewState; +import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.NotificationIconContainer; +import javax.inject.Inject; +import javax.inject.Named; + /** * A notification shelf view that is placed inside the notification scroller. It manages the * overflow icons that don't fit into the regular list anymore. @@ -63,6 +68,7 @@ public class NotificationShelf extends ActivatableNotificationView implements = SystemProperties.getBoolean("debug.icon_scroll_animations", true); private static final int TAG_CONTINUOUS_CLIPPING = R.id.continuous_clipping_tag; private static final String TAG = "NotificationShelf"; + private final KeyguardBypassController mBypassController; private NotificationIconContainer mShelfIcons; private int[] mTmp = new int[2]; @@ -93,8 +99,12 @@ public class NotificationShelf extends ActivatableNotificationView implements private int mCutoutHeight; private int mGapHeight; - public NotificationShelf(Context context, AttributeSet attrs) { + @Inject + public NotificationShelf(@Named(VIEW_CONTEXT) Context context, + AttributeSet attrs, + KeyguardBypassController keyguardBypassController) { super(context, attrs); + mBypassController = keyguardBypassController; } @Override @@ -309,7 +319,10 @@ public class NotificationShelf extends ActivatableNotificationView implements colorTwoBefore = previousColor; transitionAmount = inShelfAmount; } - if (isLastChild) { + // We don't want to modify the color if the notification is hun'd + boolean canModifyColor = mAmbientState.isShadeExpanded() + && !(mAmbientState.isOnKeyguard() && mBypassController.getBypassEnabled()); + if (isLastChild && canModifyColor) { if (colorOfViewBeforeLast == NO_COLOR) { colorOfViewBeforeLast = ownColorUntinted; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java index 787cc971e6a1..aeb85748fd1a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java @@ -16,8 +16,11 @@ package com.android.systemui.statusbar; +import static com.android.systemui.Dependency.MAIN_HANDLER_NAME; + import android.content.Context; import android.content.res.Resources; +import android.os.Handler; import android.os.Trace; import android.os.UserHandle; import android.util.Log; @@ -44,6 +47,7 @@ import java.util.List; import java.util.Stack; import javax.inject.Inject; +import javax.inject.Named; import javax.inject.Singleton; import dagger.Lazy; @@ -59,6 +63,8 @@ import dagger.Lazy; public class NotificationViewHierarchyManager implements DynamicPrivacyController.Listener { private static final String TAG = "NotificationViewHierarchyManager"; + private final Handler mHandler; + //TODO: change this top <Entry, List<Entry>>? private final HashMap<ExpandableNotificationRow, List<ExpandableNotificationRow>> mTmpChildOrderMap = new HashMap<>(); @@ -88,9 +94,13 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle // Used to help track down re-entrant calls to our update methods, which will cause bugs. private boolean mPerformingUpdate; + // Hack to get around re-entrant call in onDynamicPrivacyChanged() until we can track down + // the problem. + private boolean mIsHandleDynamicPrivacyChangeScheduled; @Inject public NotificationViewHierarchyManager(Context context, + @Named(MAIN_HANDLER_NAME) Handler mainHandler, NotificationLockscreenUserManager notificationLockscreenUserManager, NotificationGroupManager groupManager, VisualStabilityManager visualStabilityManager, @@ -100,6 +110,7 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle BubbleData bubbleData, KeyguardBypassController bypassController, DynamicPrivacyController privacyController) { + mHandler = mainHandler; mLockscreenUserManager = notificationLockscreenUserManager; mBypassController = bypassController; mGroupManager = groupManager; @@ -438,6 +449,20 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle @Override public void onDynamicPrivacyChanged() { + if (mPerformingUpdate) { + Log.w(TAG, "onDynamicPrivacyChanged made a re-entrant call"); + } + // This listener can be called from updateNotificationViews() via a convoluted listener + // chain, so we post here to prevent a re-entrant call. See b/136186188 + // TODO: Refactor away the need for this + if (!mIsHandleDynamicPrivacyChangeScheduled) { + mIsHandleDynamicPrivacyChangeScheduled = true; + mHandler.post(this::onHandleDynamicPrivacyChanged); + } + } + + private void onHandleDynamicPrivacyChanged() { + mIsHandleDynamicPrivacyChangeScheduled = false; updateNotificationViews(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/BypassHeadsUpNotifier.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/BypassHeadsUpNotifier.kt new file mode 100644 index 000000000000..ea474ced7632 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/BypassHeadsUpNotifier.kt @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.systemui.statusbar.notification + +import android.content.Context +import android.media.MediaMetadata +import android.provider.Settings +import com.android.keyguard.KeyguardUpdateMonitor +import com.android.systemui.plugins.statusbar.StatusBarStateController +import com.android.systemui.statusbar.NotificationMediaManager +import com.android.systemui.statusbar.StatusBarState +import com.android.systemui.statusbar.notification.collection.NotificationEntry +import com.android.systemui.statusbar.phone.HeadsUpManagerPhone +import com.android.systemui.statusbar.phone.KeyguardBypassController +import com.android.systemui.tuner.TunerService +import javax.inject.Inject +import javax.inject.Singleton + +/** + * A class that automatically creates heads up for important notification when bypassing the + * lockscreen + */ +@Singleton +class BypassHeadsUpNotifier @Inject constructor( + private val context: Context, + private val bypassController: KeyguardBypassController, + private val statusBarStateController: StatusBarStateController, + private val headsUpManager: HeadsUpManagerPhone, + private val mediaManager: NotificationMediaManager, + tunerService: TunerService) : StatusBarStateController.StateListener, + NotificationMediaManager.MediaListener { + + private lateinit var entryManager: NotificationEntryManager + private var currentMediaEntry: NotificationEntry? = null + private var enabled = true + + var fullyAwake = false + set(value) { + field = value + if (value) { + updateAutoHeadsUp(currentMediaEntry) + } + } + + init { + statusBarStateController.addCallback(this) + tunerService.addTunable( + TunerService.Tunable { _, _ -> + enabled = Settings.Secure.getIntForUser( + context.contentResolver, + Settings.Secure.SHOW_MEDIA_WHEN_BYPASSING, + 1 /* default */, + KeyguardUpdateMonitor.getCurrentUser()) != 0 + }, Settings.Secure.SHOW_MEDIA_WHEN_BYPASSING) + } + + fun setUp(entryManager: NotificationEntryManager) { + this.entryManager = entryManager + mediaManager.addCallback(this) + } + + override fun onMetadataOrStateChanged(metadata: MediaMetadata?, state: Int) { + val previous = currentMediaEntry + var newEntry = entryManager.notificationData.get(mediaManager.mediaNotificationKey) + if (!NotificationMediaManager.isPlayingState(state)) { + newEntry = null + } + if (newEntry?.isSensitive == true) { + newEntry = null + } + currentMediaEntry = newEntry + updateAutoHeadsUp(previous) + updateAutoHeadsUp(currentMediaEntry) + } + + private fun updateAutoHeadsUp(entry: NotificationEntry?) { + entry?.let { + val autoHeadsUp = it == currentMediaEntry && canAutoHeadsUp() + it.isAutoHeadsUp = autoHeadsUp + if (autoHeadsUp) { + headsUpManager.showNotification(it) + } + } + } + + override fun onStatePostChange() { + updateAutoHeadsUp(currentMediaEntry) + } + + private fun canAutoHeadsUp() : Boolean { + if (!enabled) { + return false + } + if (!bypassController.bypassEnabled) { + return false + } + if (statusBarStateController.state != StatusBarState.KEYGUARD) { + return false + } + if (!fullyAwake) { + return false + } + return true + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java index 8a23f718ef9a..d71d40781f2e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java @@ -24,7 +24,6 @@ import android.service.notification.StatusBarNotification; import android.util.Log; import com.android.internal.statusbar.NotificationVisibility; -import com.android.systemui.statusbar.AlertingNotificationManager; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; @@ -119,12 +118,11 @@ public class NotificationAlertingManager { shouldAlert = mNotificationInterruptionStateProvider.shouldHeadsUp(entry); final boolean wasAlerting = mHeadsUpManager.isAlerting(entry.key); if (wasAlerting) { - if (!shouldAlert) { - // We don't want this to be interrupting anymore, let's remove it - mHeadsUpManager.removeNotification(entry.key, - false /* ignoreEarliestRemovalTime */); - } else { + if (shouldAlert) { mHeadsUpManager.updateNotification(entry.key, alertAgain); + } else if (!mHeadsUpManager.isEntryAutoHeadsUpped(entry.key)) { + // We don't want this to be interrupting anymore, let's remove it + mHeadsUpManager.removeNotification(entry.key, false /* removeImmediately */); } } else if (shouldAlert && alertAgain) { // This notification was updated to be alerting, show it! diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java index 1aa6bc9ae5f9..dfc64508cadf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java @@ -24,6 +24,8 @@ import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.NotificationContentInflater.InflationFlag; +import androidx.annotation.NonNull; + /** * Listener interface for changes sent by NotificationEntryManager. */ @@ -45,7 +47,7 @@ public interface NotificationEntryListener { /** * Called when a new entry is created. */ - default void onNotificationAdded(NotificationEntry entry) { + default void onNotificationAdded(@NonNull NotificationEntry entry) { } /** @@ -61,7 +63,7 @@ public interface NotificationEntryListener { /** * Called when a notification was updated, after any filtering of notifications have occurred. */ - default void onPostEntryUpdated(NotificationEntry entry) { + default void onPostEntryUpdated(@NonNull NotificationEntry entry) { } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java index 9db715d129a5..b19d2ca29c96 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java @@ -175,6 +175,7 @@ public final class NotificationEntry { private boolean mHighPriority; private boolean mSensitive = true; private Runnable mOnSensitiveChangedListener; + private boolean mAutoHeadsUp; public NotificationEntry(StatusBarNotification n) { this(n, null); @@ -670,11 +671,25 @@ public final class NotificationEntry { if (row != null) row.setHeadsUp(shouldHeadsUp); } - public void setHeadsUpAnimatingAway(boolean animatingAway) { if (row != null) row.setHeadsUpAnimatingAway(animatingAway); } + /** + * Set that this notification was automatically heads upped. This happens for example when + * the user bypasses the lockscreen and media is playing. + */ + public void setAutoHeadsUp(boolean autoHeadsUp) { + mAutoHeadsUp = autoHeadsUp; + } + + /** + * @return if this notification was automatically heads upped. This happens for example when + * * the user bypasses the lockscreen and media is playing. + */ + public boolean isAutoHeadsUp() { + return mAutoHeadsUp; + } public boolean mustStayOnScreen() { return row != null && row.mustStayOnScreen(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index ae534d278116..a8327f63dcf7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -2698,6 +2698,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView l.setAlpha(1.0f); l.setLayerType(LAYER_TYPE_NONE, null); } + } else { + setHeadsUpAnimatingAway(false); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index e2cb8d4517ff..58e639924f4f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -837,7 +837,13 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd break; } } - if (!mAmbientState.isDozing() || anySectionHasVisibleChild) { + boolean shouldDrawBackground; + if (mKeyguardBypassController.getBypassEnabled() && onKeyguard()) { + shouldDrawBackground = isPulseExpanding(); + } else { + shouldDrawBackground = !mAmbientState.isDozing() || anySectionHasVisibleChild; + } + if (shouldDrawBackground) { drawBackgroundRects(canvas, left, right, top, backgroundTopAnimationOffset); } @@ -3396,10 +3402,20 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd for (Pair<ExpandableNotificationRow, Boolean> eventPair : mHeadsUpChangeAnimations) { ExpandableNotificationRow row = eventPair.first; boolean isHeadsUp = eventPair.second; + if (isHeadsUp != row.isHeadsUp()) { + // For cases where we have a heads up showing and appearing again we shouldn't + // do the animations at all. + continue; + } int type = AnimationEvent.ANIMATION_TYPE_HEADS_UP_OTHER; boolean onBottom = false; boolean pinnedAndClosed = row.isPinned() && !mIsExpanded; - if (!mIsExpanded && !isHeadsUp) { + boolean performDisappearAnimation = !mIsExpanded + // Only animate if we still have pinned heads up, otherwise we just have the + // regular collapse animation of the lock screen + || (mKeyguardBypassController.getBypassEnabled() && onKeyguard() + && mHeadsUpManager.hasPinnedHeadsUp()); + if (performDisappearAnimation && !isHeadsUp) { type = row.wasJustClicked() ? AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK : AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR; @@ -6246,6 +6262,15 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd mAmbientState.onDragFinished(animView); updateContinuousShadowDrawing(); updateContinuousBackgroundDrawing(); + if (animView instanceof ExpandableNotificationRow) { + ExpandableNotificationRow row = (ExpandableNotificationRow) animView; + if (row.isPinned() && !canChildBeDismissed(row) + && row.getStatusBarNotification().getNotification().fullScreenIntent + == null) { + mHeadsUpManager.removeNotification(row.getStatusBarNotification().getKey(), + true /* removeImmediately */); + } + } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java index 09c6968867b8..35ba801c75ba 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java @@ -546,12 +546,12 @@ public class StackScrollAlgorithm { ExpandableViewState topState = topHeadsUpEntry == null ? null : topHeadsUpEntry.getViewState(); if (topState != null && !isTopEntry && (!mIsExpanded - || unmodifiedEndLocation < topState.yTranslation + topState.height)) { + || unmodifiedEndLocation > topState.yTranslation + topState.height)) { // Ensure that a headsUp doesn't vertically extend further than the heads-up at // the top most z-position childState.height = row.getIntrinsicHeight(); - childState.yTranslation = topState.yTranslation + topState.height - - childState.height; + childState.yTranslation = Math.min(topState.yTranslation + topState.height + - childState.height, childState.yTranslation); } // heads up notification show and this row is the top entry of heads up diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java index 4f169eb50f88..0996ff27e9a3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java @@ -28,6 +28,7 @@ import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.StatusBarIconView; +import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.ExpandableView; @@ -451,7 +452,11 @@ public class StackStateAnimator { if (row.isDismissed()) { needsAnimation = false; } - StatusBarIconView icon = row.getEntry().icon; + NotificationEntry entry = row.getEntry(); + StatusBarIconView icon = entry.icon; + if (entry.centeredIcon != null && entry.centeredIcon.getParent() != null) { + icon = entry.centeredIcon; + } if (icon.getParent() != null) { icon.getLocationOnScreen(mTmpLocation); float iconPosition = mTmpLocation[0] - icon.getTranslationX() diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java index ade855e755e3..c44f953615e3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java @@ -32,7 +32,6 @@ import android.view.ViewTreeObserver; import androidx.collection.ArraySet; import com.android.internal.annotations.VisibleForTesting; -import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.R; import com.android.systemui.ScreenDecorations; @@ -67,6 +66,7 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, final int mExtensionTime; private final StatusBarStateController mStatusBarStateController; private final KeyguardBypassController mBypassController; + private final int mAutoHeadsUpNotificationDecay; private View mStatusBarWindowView; private NotificationGroupManager mGroupManager; private VisualStabilityManager mVisualStabilityManager; @@ -81,6 +81,7 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, private boolean mTrackingHeadsUp; private HashSet<String> mSwipedOutKeys = new HashSet<>(); private HashSet<NotificationEntry> mEntriesToRemoveAfterExpand = new HashSet<>(); + private HashSet<String> mKeysToRemoveWhenLeavingKeyguard = new HashSet<>(); private ArraySet<NotificationEntry> mEntriesToRemoveWhenReorderingAllowed = new ArraySet<>(); private boolean mIsExpanded; @@ -121,6 +122,8 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, mAutoDismissNotificationDecayDozing = resources.getInteger( R.integer.heads_up_notification_decay_dozing); mExtensionTime = resources.getInteger(R.integer.ambient_notification_extension_time); + mAutoHeadsUpNotificationDecay = resources.getInteger( + R.integer.auto_heads_up_notification_decay); mStatusBarStateController = statusBarStateController; mStatusBarStateController.addCallback(this); mBypassController = bypassController; @@ -231,7 +234,16 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, @Override public void onStateChanged(int newState) { + boolean wasKeyguard = mStatusBarState == StatusBarState.KEYGUARD; + boolean isKeyguard = newState == StatusBarState.KEYGUARD; mStatusBarState = newState; + if (wasKeyguard && !isKeyguard && mKeysToRemoveWhenLeavingKeyguard.size() != 0) { + String[] keys = mKeysToRemoveWhenLeavingKeyguard.toArray(new String[0]); + for (String key : keys) { + removeAlertEntry(key); + } + mKeysToRemoveWhenLeavingKeyguard.clear(); + } } @Override @@ -245,6 +257,15 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, } } + @Override + public boolean isEntryAutoHeadsUpped(String key) { + HeadsUpEntryPhone headsUpEntryPhone = getHeadsUpEntryPhone(key); + if (headsUpEntryPhone == null) { + return false; + } + return headsUpEntryPhone.isAutoHeadsUp(); + } + /** * Set that we are exiting the headsUp pinned mode, but some notifications might still be * animating out. This is used to keep the touchable regions in a sane state. @@ -420,6 +441,7 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, @Override protected void onAlertEntryRemoved(AlertEntry alertEntry) { + mKeysToRemoveWhenLeavingKeyguard.remove(alertEntry.mEntry.key); super.onAlertEntryRemoved(alertEntry); mEntryPool.release((HeadsUpEntryPhone) alertEntry); } @@ -479,6 +501,11 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, */ private boolean extended; + /** + * Was this entry received while on keyguard + */ + private boolean mIsAutoHeadsUp; + @Override protected boolean isSticky() { @@ -494,10 +521,12 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, mEntriesToRemoveWhenReorderingAllowed.add(entry); mVisualStabilityManager.addReorderingAllowedCallback( HeadsUpManagerPhone.this); - } else if (!mTrackingHeadsUp) { - removeAlertEntry(entry.key); - } else { + } else if (mTrackingHeadsUp) { mEntriesToRemoveAfterExpand.add(entry); + } else if (mIsAutoHeadsUp && mStatusBarState == StatusBarState.KEYGUARD) { + mKeysToRemoveWhenLeavingKeyguard.add(entry.key); + } else { + removeAlertEntry(entry.key); } }; @@ -506,6 +535,7 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, @Override public void updateEntry(boolean updatePostTime) { + mIsAutoHeadsUp = mEntry.isAutoHeadsUp(); super.updateEntry(updatePostTime); if (mEntriesToRemoveAfterExpand.contains(mEntry)) { @@ -514,6 +544,7 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, if (mEntriesToRemoveWhenReorderingAllowed.contains(mEntry)) { mEntriesToRemoveWhenReorderingAllowed.remove(mEntry); } + mKeysToRemoveWhenLeavingKeyguard.remove(mEntry.key); } @Override @@ -548,6 +579,7 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, super.reset(); mMenuShownPinned = false; extended = false; + mIsAutoHeadsUp = false; } private void extendPulse() { @@ -558,13 +590,35 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, } @Override + public int compareTo(AlertEntry alertEntry) { + HeadsUpEntryPhone headsUpEntry = (HeadsUpEntryPhone) alertEntry; + boolean autoShown = isAutoHeadsUp(); + boolean otherAutoShown = headsUpEntry.isAutoHeadsUp(); + if (autoShown && !otherAutoShown) { + return 1; + } else if (!autoShown && otherAutoShown) { + return -1; + } + return super.compareTo(alertEntry); + } + + @Override protected long calculateFinishTime() { return mPostTime + getDecayDuration() + (extended ? mExtensionTime : 0); } private int getDecayDuration() { - return mStatusBarStateController.isDozing() ? mAutoDismissNotificationDecayDozing - : getRecommendedHeadsUpTimeoutMs(); + if (mStatusBarStateController.isDozing()) { + return mAutoDismissNotificationDecayDozing; + } else if (isAutoHeadsUp()) { + return getRecommendedHeadsUpTimeoutMs(mAutoHeadsUpNotificationDecay); + } else { + return getRecommendedHeadsUpTimeoutMs(mAutoDismissNotificationDecay); + } + } + + private boolean isAutoHeadsUp() { + return mIsAutoHeadsUp; } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java index 1e7c44cdba2f..49afae7415ae 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java @@ -53,6 +53,7 @@ import com.android.systemui.statusbar.phone.ScrimController.ScrimVisibility; import com.android.systemui.statusbar.policy.AccessibilityController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.KeyguardMonitor; +import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener; import java.lang.annotation.Retention; @@ -67,7 +68,8 @@ import javax.inject.Named; public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChangedListener, StatusBarStateController.StateListener, ConfigurationController.ConfigurationListener, UnlockMethodCache.OnUnlockMethodChangedListener, - NotificationWakeUpCoordinator.WakeUpListener, ViewTreeObserver.OnPreDrawListener { + NotificationWakeUpCoordinator.WakeUpListener, ViewTreeObserver.OnPreDrawListener, + OnHeadsUpChangedListener { private static final int STATE_LOCKED = 0; private static final int STATE_LOCK_OPEN = 1; @@ -82,6 +84,7 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange private final KeyguardMonitor mKeyguardMonitor; private final KeyguardBypassController mBypassController; private final NotificationWakeUpCoordinator mWakeUpCoordinator; + private final HeadsUpManagerPhone mHeadsUpManager; private int mLastState = 0; private boolean mForceUpdate; @@ -92,9 +95,10 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange private boolean mPulsing; private boolean mDozing; private boolean mDocked; + private boolean mBlockUpdates; private int mIconColor; private float mDozeAmount; - private boolean mBouncerShowing; + private boolean mBouncerShowingScrimmed; private boolean mWakeAndUnlockRunning; private boolean mKeyguardShowing; private boolean mShowingLaunchAffordance; @@ -104,8 +108,22 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange new KeyguardMonitor.Callback() { @Override public void onKeyguardShowingChanged() { + boolean force = false; + boolean wasShowing = mKeyguardShowing; mKeyguardShowing = mKeyguardMonitor.isShowing(); - update(); + if (!wasShowing && mKeyguardShowing && mBlockUpdates) { + mBlockUpdates = false; + force = true; + } + update(force); + } + + @Override + public void onKeyguardFadingAwayChanged() { + if (!mKeyguardMonitor.isKeyguardFadingAway() && mBlockUpdates) { + mBlockUpdates = false; + update(true /* force */); + } } }; private final DockManager.DockEventListener mDockEventListener = @@ -155,7 +173,8 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange KeyguardBypassController bypassController, NotificationWakeUpCoordinator wakeUpCoordinator, KeyguardMonitor keyguardMonitor, - @Nullable DockManager dockManager) { + @Nullable DockManager dockManager, + HeadsUpManagerPhone headsUpManager) { super(context, attrs); mContext = context; mUnlockMethodCache = UnlockMethodCache.getInstance(context); @@ -167,6 +186,7 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange mWakeUpCoordinator = wakeUpCoordinator; mKeyguardMonitor = keyguardMonitor; mDockManager = dockManager; + mHeadsUpManager = headsUpManager; } @Override @@ -256,7 +276,11 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange mIsFaceUnlockState = state == STATE_SCANNING_FACE; mLastState = state; - if (lastState != state || mForceUpdate) { + boolean shouldUpdate = lastState != state || mForceUpdate; + if (mBlockUpdates && canBlockUpdates()) { + shouldUpdate = false; + } + if (shouldUpdate) { mForceUpdate = false; @LockAnimIndex final int lockAnimIndex = getAnimationIndexForTransition(lastState, state, mPulsing, mDozing); @@ -296,11 +320,13 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange boolean onAodNotPulsingOrDocked = mDozing && (!mPulsing || mDocked); boolean invisible = onAodNotPulsingOrDocked || mWakeAndUnlockRunning || mShowingLaunchAffordance; - if (mBypassController.getBypassEnabled() - && mStatusBarStateController.getState() == StatusBarState.KEYGUARD - && !mWakeUpCoordinator.getNotificationsFullyHidden() - && !mBouncerShowing) { - invisible = true; + if (mBypassController.getBypassEnabled() && !mBouncerShowingScrimmed) { + if (mHeadsUpManager.isHeadsUpGoingAway() + || mHeadsUpManager.hasPinnedHeadsUp() + || (mStatusBarStateController.getState() == StatusBarState.KEYGUARD + && !mWakeUpCoordinator.getNotificationsFullyHidden())) { + invisible = true; + } } boolean wasInvisible = getVisibility() == INVISIBLE; if (invisible != wasInvisible) { @@ -323,6 +349,10 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange return true; } + private boolean canBlockUpdates() { + return mKeyguardShowing || mKeyguardMonitor.isKeyguardFadingAway(); + } + private void updateClickability() { if (mAccessibilityController == null) { return; @@ -408,8 +438,8 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange } } - public void setBouncerShowing(boolean bouncerShowing) { - mBouncerShowing = bouncerShowing; + public void setBouncerShowingScrimmed(boolean bouncerShowing) { + mBouncerShowingScrimmed = bouncerShowing; if (mBypassController.getBypassEnabled()) { update(); } @@ -529,11 +559,17 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange /** * We need to hide the lock whenever there's a fingerprint unlock, otherwise you'll see the * icon on top of the black front scrim. + * @param wakeAndUnlock are we wake and unlocking + * @param isUnlock are we currently unlocking */ - public void onBiometricAuthModeChanged(boolean wakeAndUnlock) { + public void onBiometricAuthModeChanged(boolean wakeAndUnlock, boolean isUnlock) { if (wakeAndUnlock) { mWakeAndUnlockRunning = true; } + if (isUnlock && mBypassController.getBypassEnabled() && canBlockUpdates()) { + // We don't want the icon to change while we are unlocking + mBlockUpdates = true; + } update(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java index cd9772237d59..d2159ca15b24 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java @@ -248,7 +248,7 @@ public class NotificationIconAreaController implements DarkReceiver, if (onlyShowCenteredIcon) { return isCenteredNotificationIcon; } - if (hideCenteredIcon && isCenteredNotificationIcon) { + if (hideCenteredIcon && isCenteredNotificationIcon && !entry.isRowHeadsUp()) { return false; } if (mEntryManager.getNotificationData().isAmbient(entry.key) && !showAmbient) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 9d1043850426..55f61fa8a6a0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -80,6 +80,7 @@ import android.metrics.LogMaker; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; +import android.os.Debug; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -193,6 +194,7 @@ import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.notification.ActivityLaunchAnimator; +import com.android.systemui.statusbar.notification.BypassHeadsUpNotifier; import com.android.systemui.statusbar.notification.NotificationActivityStarter; import com.android.systemui.statusbar.notification.NotificationAlertingManager; import com.android.systemui.statusbar.notification.NotificationClicker; @@ -373,6 +375,8 @@ public class StatusBar extends SystemUI implements DemoMode, KeyguardBypassController mKeyguardBypassController; @Inject protected HeadsUpManagerPhone mHeadsUpManager; + @Inject + BypassHeadsUpNotifier mBypassHeadsUpNotifier; @Nullable @Inject protected KeyguardLiftController mKeyguardLiftController; @@ -633,6 +637,7 @@ public class StatusBar extends SystemUI implements DemoMode, mGutsManager = Dependency.get(NotificationGutsManager.class); mMediaManager = Dependency.get(NotificationMediaManager.class); mEntryManager = Dependency.get(NotificationEntryManager.class); + mBypassHeadsUpNotifier.setUp(mEntryManager); mNotificationInterruptionStateProvider = Dependency.get(NotificationInterruptionStateProvider.class); mViewHierarchyManager = Dependency.get(NotificationViewHierarchyManager.class); @@ -649,7 +654,7 @@ public class StatusBar extends SystemUI implements DemoMode, KeyguardSliceProvider sliceProvider = KeyguardSliceProvider.getAttachedInstance(); if (sliceProvider != null) { sliceProvider.initDependencies(mMediaManager, mStatusBarStateController, - mKeyguardBypassController); + mKeyguardBypassController, DozeParameters.getInstance(mContext)); } else { Log.w(TAG, "Cannot init KeyguardSliceProvider dependencies"); } @@ -1154,8 +1159,9 @@ public class StatusBar extends SystemUI implements DemoMode, private void inflateShelf() { mNotificationShelf = - (NotificationShelf) LayoutInflater.from(mContext).inflate( - R.layout.status_bar_notification_shelf, mStackScroller, false); + (NotificationShelf) mInjectionInflater.injectable( + LayoutInflater.from(mContext)).inflate( + R.layout.status_bar_notification_shelf, mStackScroller, false); mNotificationShelf.setOnClickListener(mGoToLockedShadeListener); } @@ -3576,7 +3582,7 @@ public class StatusBar extends SystemUI implements DemoMode, mBouncerShowing = bouncerShowing; mKeyguardBypassController.setBouncerShowing(bouncerShowing); mPulseExpansionHandler.setBouncerShowing(bouncerShowing); - mStatusBarWindow.setBouncerShowing(bouncerShowing); + mStatusBarWindow.setBouncerShowingScrimmed(isBouncerShowingScrimmed()); if (mStatusBarView != null) mStatusBarView.setBouncerShowing(bouncerShowing); updateHideIconsForBouncer(true /* animate */); mCommandQueue.recomputeDisableFlags(mDisplayId, true /* animate */); @@ -3629,6 +3635,7 @@ public class StatusBar extends SystemUI implements DemoMode, notifyHeadsUpGoingToSleep(); dismissVolumeDialog(); mWakeUpCoordinator.setFullyAwake(false); + mBypassHeadsUpNotifier.setFullyAwake(false); mKeyguardBypassController.onStartedGoingToSleep(); } @@ -3653,6 +3660,7 @@ public class StatusBar extends SystemUI implements DemoMode, @Override public void onFinishedWakingUp() { mWakeUpCoordinator.setFullyAwake(true); + mBypassHeadsUpNotifier.setFullyAwake(true); mWakeUpCoordinator.setWakingUp(false); if (mLaunchCameraWhenFinishedWaking) { mNotificationPanel.launchCamera(false /* animate */, mLastCameraLaunchSource); @@ -3826,7 +3834,8 @@ public class StatusBar extends SystemUI implements DemoMode, public void notifyBiometricAuthModeChanged() { updateDozing(); updateScrimController(); - mStatusBarWindow.onBiometricAuthModeChanged(mBiometricUnlockController.isWakeAndUnlock()); + mStatusBarWindow.onBiometricAuthModeChanged(mBiometricUnlockController.isWakeAndUnlock(), + mBiometricUnlockController.isBiometricUnlock()); } @VisibleForTesting diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index 6dc2c8cab055..462b65f37ee0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -814,7 +814,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb */ public boolean shouldSubtleWindowAnimationsForUnlock() { return mStatusBar.mKeyguardBypassController.getBypassEnabled() - && mStatusBar.mState == StatusBarState.KEYGUARD; + && mStatusBar.mState == StatusBarState.KEYGUARD && !mBouncer.isAnimatingAway(); } public boolean isGoingToNotificationShade() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java index a82e14efca2f..94054188d769 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java @@ -272,10 +272,11 @@ public class StatusBarWindowView extends FrameLayout { /** * Called when the biometric authentication mode changes. * @param wakeAndUnlock If the type is {@link BiometricUnlockController#isWakeAndUnlock()} + * @param isUnlock If the type is {@link BiometricUnlockController#isBiometricUnlock()} () */ - public void onBiometricAuthModeChanged(boolean wakeAndUnlock) { + public void onBiometricAuthModeChanged(boolean wakeAndUnlock, boolean isUnlock) { if (mLockIcon != null) { - mLockIcon.onBiometricAuthModeChanged(wakeAndUnlock); + mLockIcon.onBiometricAuthModeChanged(wakeAndUnlock, isUnlock); } } @@ -525,9 +526,9 @@ public class StatusBarWindowView extends FrameLayout { mBypassController = bypassController; } - public void setBouncerShowing(boolean bouncerShowing) { + public void setBouncerShowingScrimmed(boolean bouncerShowing) { if (mLockIcon != null) { - mLockIcon.setBouncerShowing(bouncerShowing); + mLockIcon.setBouncerShowingScrimmed(bouncerShowing); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java index 40d5e4dcfd64..b84dc476dd6f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java @@ -356,6 +356,10 @@ public abstract class HeadsUpManager extends AlertingNotificationManager { public void onDensityOrFontScaleChanged() { } + public boolean isEntryAutoHeadsUpped(String key) { + return false; + } + /** * This represents a notification and how long it is in a heads up mode. It also manages its * lifecycle automatically when created. @@ -416,16 +420,17 @@ public abstract class HeadsUpManager extends AlertingNotificationManager { @Override protected long calculateFinishTime() { - return mPostTime + getRecommendedHeadsUpTimeoutMs(); + return mPostTime + getRecommendedHeadsUpTimeoutMs(mAutoDismissNotificationDecay); } /** * Get user-preferred or default timeout duration. The larger one will be returned. * @return milliseconds before auto-dismiss + * @param requestedTimeout */ - protected int getRecommendedHeadsUpTimeoutMs() { + protected int getRecommendedHeadsUpTimeoutMs(int requestedTimeout) { return mAccessibilityMgr.getRecommendedTimeoutMillis( - mAutoDismissNotificationDecay, + requestedTimeout, AccessibilityManager.FLAG_CONTENT_CONTROLS | AccessibilityManager.FLAG_CONTENT_ICONS | AccessibilityManager.FLAG_CONTENT_TEXT); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java index 01498e6bd54d..f61b556e22ab 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java @@ -50,5 +50,6 @@ public interface KeyguardMonitor extends CallbackController<Callback> { interface Callback { void onKeyguardShowingChanged(); + default void onKeyguardFadingAwayChanged() {} } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java index b53ff0e45cea..68d00708b0d3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java @@ -141,14 +141,24 @@ public class KeyguardMonitorImpl extends KeyguardUpdateMonitorCallback } public void notifyKeyguardFadingAway(long delay, long fadeoutDuration) { - mKeyguardFadingAway = true; + setKeyguardFadingAway(true); mKeyguardFadingAwayDelay = delay; mKeyguardFadingAwayDuration = fadeoutDuration; } + private void setKeyguardFadingAway(boolean keyguardFadingAway) { + if (mKeyguardFadingAway != keyguardFadingAway) { + mKeyguardFadingAway = keyguardFadingAway; + ArrayList<Callback> callbacks = new ArrayList<>(mCallbacks); + for (int i = 0; i < callbacks.size(); i++) { + callbacks.get(i).onKeyguardFadingAwayChanged(); + } + } + } + public void notifyKeyguardDoneFading() { - mKeyguardFadingAway = false; mKeyguardGoingAway = false; + setKeyguardFadingAway(false); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java index d521e5534ad4..ede30046d6c3 100644 --- a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java +++ b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java @@ -32,6 +32,7 @@ import com.android.systemui.qs.QSFooterImpl; import com.android.systemui.qs.QSPanel; import com.android.systemui.qs.QuickQSPanel; import com.android.systemui.qs.QuickStatusBarHeader; +import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.phone.LockIcon; import com.android.systemui.statusbar.phone.NotificationPanelView; @@ -138,6 +139,11 @@ public class InjectionInflationController { QSCarrierGroup createQSCarrierGroup(); /** + * Creates the Shelf. + */ + NotificationShelf creatNotificationShelf(); + + /** * Creates the KeyguardClockSwitch. */ KeyguardClockSwitch createKeyguardClockSwitch(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/IconPackOverlayTest.java b/packages/SystemUI/tests/src/com/android/systemui/IconPackOverlayTest.java new file mode 100644 index 000000000000..ccc9afcd4296 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/IconPackOverlayTest.java @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui; + +import static junit.framework.Assert.fail; + +import static org.junit.Assert.assertEquals; + +import android.annotation.DrawableRes; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.content.res.XmlResourceParser; +import android.text.TextUtils; +import android.util.TypedValue; + +import androidx.test.filters.MediumTest; +import androidx.test.runner.AndroidJUnit4; + +import com.android.internal.util.XmlUtils; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; + +@RunWith(AndroidJUnit4.class) +@MediumTest +public class IconPackOverlayTest extends SysuiTestCase { + + private static final String[] ICON_PACK_OVERLAY_PACKAGES = { + "com.android.theme.icon_pack.circular.systemui", + "com.android.theme.icon_pack.rounded.systemui", + "com.android.theme.icon_pack.filled.systemui", + }; + + private static final int[] VECTOR_ATTRIBUTES = { + android.R.attr.tint, + android.R.attr.height, + android.R.attr.width, + android.R.attr.alpha, + android.R.attr.autoMirrored, + }; + + private final TypedValue mTargetTypedValue = new TypedValue(); + private final TypedValue mOverlayTypedValue = new TypedValue(); + + private Resources mResources; + private TypedArray mOverlayableIcons; + + @Before + public void setup() { + mResources = mContext.getResources(); + mOverlayableIcons = mResources.obtainTypedArray(R.array.overlayable_icons); + } + + @After + public void teardown() { + mOverlayableIcons.recycle(); + } + + /** + * Ensure that all icons contained in overlayable_icons_test.xml exist in all 3 overlay icon + * packs for systemui. This test fails if you remove or rename an overlaid icon. If so, + * make the same change to the corresponding drawables in {@link #ICON_PACK_OVERLAY_PACKAGES}. + */ + @Test + public void testIconPack_containAllOverlayedIcons() { + StringBuilder errors = new StringBuilder(); + + for (String overlayPackage : ICON_PACK_OVERLAY_PACKAGES) { + Resources overlayResources; + try { + overlayResources = mContext.getPackageManager() + .getResourcesForApplication(overlayPackage); + } catch (PackageManager.NameNotFoundException e) { + continue; // No need to test overlay resources if apk is not on the system. + } + + for (int i = 0; i < mOverlayableIcons.length(); i++) { + int sysuiRid = mOverlayableIcons.getResourceId(i, 0); + String sysuiResourceName = mResources.getResourceName(sysuiRid); + String overlayResourceName = sysuiResourceName + .replace(mContext.getPackageName(), overlayPackage); + if (overlayResources.getIdentifier(overlayResourceName, null, null) + == Resources.ID_NULL) { + errors.append(String.format("[%s] is not contained in overlay package [%s]", + overlayResourceName, overlayPackage)); + } + } + } + + if (!TextUtils.isEmpty(errors)) { + fail(errors.toString()); + } + } + + /** + * Ensures that all overlay icons have the same values for {@link #VECTOR_ATTRIBUTES} as the + * underlying drawable in systemui. To fix this test, make the attribute change to all of the + * corresponding drawables in {@link #ICON_PACK_OVERLAY_PACKAGES}. + */ + @Test + public void testIconPacks_haveEqualVectorDrawableAttributes() { + StringBuilder errors = new StringBuilder(); + + for (String overlayPackage : ICON_PACK_OVERLAY_PACKAGES) { + Resources overlayResources; + try { + overlayResources = mContext.getPackageManager() + .getResourcesForApplication(overlayPackage); + } catch (PackageManager.NameNotFoundException e) { + continue; // No need to test overlay resources if apk is not on the system. + } + + for (int i = 0; i < mOverlayableIcons.length(); i++) { + int sysuiRid = mOverlayableIcons.getResourceId(i, 0); + String sysuiResourceName = mResources.getResourceName(sysuiRid); + TypedArray sysuiAttrs = getAVDAttributes(mResources, sysuiRid); + if (sysuiAttrs == null) { + errors.append(String.format("[%s] does not exist or is not a valid AVD.", + sysuiResourceName)); + continue; + } + + String overlayResourceName = sysuiResourceName + .replace(mContext.getPackageName(), overlayPackage); + int overlayRid = overlayResources.getIdentifier(overlayResourceName, null, null); + TypedArray overlayAttrs = getAVDAttributes(overlayResources, overlayRid); + if (overlayAttrs == null) { + errors.append(String.format("[%s] does not exist or is not a valid AVD.", + overlayResourceName)); + continue; + } + + if (!attributesEquals(sysuiAttrs, overlayAttrs)) { + errors.append(String.format("[%s] AVD attributes do not match [%s]\n", + sysuiResourceName, overlayResourceName)); + } + sysuiAttrs.recycle(); + overlayAttrs.recycle(); + } + } + + if (!TextUtils.isEmpty(errors)) { + fail(errors.toString()); + } + } + + private TypedArray getAVDAttributes(Resources resources, @DrawableRes int rid) { + try { + XmlResourceParser parser = resources.getXml(rid); + XmlUtils.nextElement(parser); + return resources.obtainAttributes(parser, VECTOR_ATTRIBUTES); + } catch (XmlPullParserException | IOException | Resources.NotFoundException e) { + return null; + } + } + + private boolean attributesEquals(TypedArray target, TypedArray overlay) { + assertEquals(target.length(), overlay.length()); + for (int i = 0; i < target.length(); i++) { + target.getValue(i, mTargetTypedValue); + overlay.getValue(i, mOverlayTypedValue); + if (!attributesEquals(mTargetTypedValue, mOverlayTypedValue)) { + return false; + } + } + return true; + } + + private boolean attributesEquals(TypedValue target, TypedValue overlay) { + return target.type == overlay.type && target.data == overlay.data; + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java index bf067947f2b9..893f3d184acb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java @@ -48,6 +48,7 @@ import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.NotificationMediaManager; +import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.util.wakelock.SettableWakeLock; @@ -84,6 +85,8 @@ public class KeyguardSliceProviderTest extends SysuiTestCase { private SettableWakeLock mMediaWakeLock; @Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor; + @Mock + private DozeParameters mDozeParameters; private TestableKeyguardSliceProvider mProvider; private boolean mIsZenMode; @@ -94,7 +97,7 @@ public class KeyguardSliceProviderTest extends SysuiTestCase { mProvider = new TestableKeyguardSliceProvider(); mProvider.attachInfo(getContext(), null); mProvider.initDependencies(mNotificationMediaManager, mStatusBarStateController, - mKeyguardBypassController); + mKeyguardBypassController, mDozeParameters); SliceProvider.setSpecs(new HashSet<>(Arrays.asList(SliceSpecs.LIST))); } @@ -130,6 +133,7 @@ public class KeyguardSliceProviderTest extends SysuiTestCase { MediaMetadata metadata = mock(MediaMetadata.class); when(metadata.getText(any())).thenReturn("metadata"); when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true); + when(mDozeParameters.getAlwaysOn()).thenReturn(true); mProvider.onMetadataOrStateChanged(metadata, PlaybackState.STATE_PLAYING); mProvider.onBindSlice(mProvider.getUri()); verify(metadata).getText(eq(MediaMetadata.METADATA_KEY_TITLE)); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java index 010b85edacdd..58fb53aae7bb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java @@ -20,12 +20,16 @@ import static junit.framework.Assert.assertTrue; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.clearInvocations; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.os.Handler; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.View; @@ -79,13 +83,19 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase { @Mock private VisualStabilityManager mVisualStabilityManager; @Mock private ShadeController mShadeController; + private TestableLooper mTestableLooper; + private Handler mHandler; private NotificationViewHierarchyManager mViewHierarchyManager; private NotificationTestHelper mHelper; + private boolean mMadeReentrantCall = false; @Before public void setUp() { MockitoAnnotations.initMocks(this); - Assert.sMainLooper = TestableLooper.get(this).getLooper(); + mTestableLooper = TestableLooper.get(this); + Assert.sMainLooper = mTestableLooper.getLooper(); + mHandler = Handler.createAsync(mTestableLooper.getLooper()); + mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager); mDependency.injectTestDependency(NotificationLockscreenUserManager.class, mLockscreenUserManager); @@ -98,7 +108,7 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase { when(mEntryManager.getNotificationData()).thenReturn(mNotificationData); mViewHierarchyManager = new NotificationViewHierarchyManager(mContext, - mLockscreenUserManager, mGroupManager, mVisualStabilityManager, + mHandler, mLockscreenUserManager, mGroupManager, mVisualStabilityManager, mock(StatusBarStateControllerImpl.class), mEntryManager, () -> mShadeController, new BubbleData(mContext), mock(KeyguardBypassController.class), @@ -215,9 +225,60 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase { verify(entry0.getRow(), times(1)).showAppOpsIcons(any()); } + @Test + public void testReentrantCallsToOnDynamicPrivacyChangedPostForLater() { + // GIVEN a ListContainer that will make a re-entrant call to updateNotificationViews() + mMadeReentrantCall = false; + doAnswer((invocation) -> { + if (!mMadeReentrantCall) { + mMadeReentrantCall = true; + mViewHierarchyManager.onDynamicPrivacyChanged(); + } + return null; + }).when(mListContainer).setMaxDisplayedNotifications(anyInt()); + + // WHEN we call updateNotificationViews() + mViewHierarchyManager.updateNotificationViews(); + + // THEN onNotificationViewUpdateFinished() is only called once + verify(mListContainer).onNotificationViewUpdateFinished(); + + // WHEN we drain the looper + mTestableLooper.processAllMessages(); + + // THEN updateNotificationViews() is called a second time (for the reentrant call) + verify(mListContainer, times(2)).onNotificationViewUpdateFinished(); + } + + @Test + public void testMultipleReentrantCallsToOnDynamicPrivacyChangedOnlyPostOnce() { + // GIVEN a ListContainer that will make many re-entrant calls to updateNotificationViews() + mMadeReentrantCall = false; + doAnswer((invocation) -> { + if (!mMadeReentrantCall) { + mMadeReentrantCall = true; + mViewHierarchyManager.onDynamicPrivacyChanged(); + mViewHierarchyManager.onDynamicPrivacyChanged(); + mViewHierarchyManager.onDynamicPrivacyChanged(); + mViewHierarchyManager.onDynamicPrivacyChanged(); + } + return null; + }).when(mListContainer).setMaxDisplayedNotifications(anyInt()); + + // WHEN we call updateNotificationViews() and drain the looper + mViewHierarchyManager.updateNotificationViews(); + verify(mListContainer).onNotificationViewUpdateFinished(); + clearInvocations(mListContainer); + mTestableLooper.processAllMessages(); + + // THEN updateNotificationViews() is called only one more time + verify(mListContainer).onNotificationViewUpdateFinished(); + } + private class FakeListContainer implements NotificationListContainer { final LinearLayout mLayout = new LinearLayout(mContext); final List<View> mRows = Lists.newArrayList(); + private boolean mMakeReentrantCallDuringSetMaxDisplayedNotifications; @Override public void setChildTransferInProgress(boolean childTransferInProgress) {} @@ -266,7 +327,11 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase { } @Override - public void setMaxDisplayedNotifications(int maxNotifications) {} + public void setMaxDisplayedNotifications(int maxNotifications) { + if (mMakeReentrantCallDuringSetMaxDisplayedNotifications) { + mViewHierarchyManager.onDynamicPrivacyChanged(); + } + } @Override public ViewGroup getViewParentForNotification(NotificationEntry entry) { @@ -301,5 +366,7 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase { return false; } + @Override + public void onNotificationViewUpdateFinished() { } } } diff --git a/packages/overlays/Android.mk b/packages/overlays/Android.mk index 3f16c128f664..3eb90491f902 100644 --- a/packages/overlays/Android.mk +++ b/packages/overlays/Android.mk @@ -44,7 +44,6 @@ LOCAL_REQUIRED_MODULES := \ IconPackRoundedSystemUIOverlay \ IconPackRoundedThemePickerUIOverlay \ IconShapeRoundedRectOverlay \ - IconShapeSquareOverlay \ IconShapeSquircleOverlay \ IconShapeTeardropOverlay \ NavigationBarMode3ButtonOverlay \ diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_aural.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_aural.xml new file mode 100644 index 000000000000..64802640a9ec --- /dev/null +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_aural.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2019 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="24dp" + android:tint="?android:attr/colorControlNormal" + android:viewportHeight="24" + android:viewportWidth="24" + android:width="24dp" > + <group + android:translateX="2.000000" + android:translateY="2.000000" > + <path + android:fillColor="@android:color/white" + android:fillType="evenOdd" + android:pathData="M12.64,3 L12.64,8.82352941 C12.2536,8.5 11.772,8.29411765 11.24,8.29411765 C10.0024,8.29411765 9,9.34705882 9,10.6470588 C9,11.9470588 10.0024,13 11.24,13 C12.4776,13 13.48,11.9470588 13.48,10.6470588 L13.48,5.00157166 L15.02,5.00157166 C15.5576,5.00157166 16,4.53686577 16,3.97215989 L16,3 L12.64,3 Z" + android:strokeWidth="1" /> + <path + android:fillColor="@android:color/white" + android:pathData="M20,2 C20,0.9 19.1,0 18,0 L6,0 C4.9,0 4,0.9 4,2 L4,14 C4,15.1 4.9,16 6,16 L18,16 C19.1,16 20,15.1 20,14 L20,2 Z M18.5,14 C18.5,14.28 18.28,14.5 18,14.5 L6,14.5 C5.72,14.5 5.5,14.28 5.5,14 L5.5,2 C5.5,1.72 5.72,1.5 6,1.5 L18,1.5 C18.28,1.5 18.5,1.72 18.5,2 L18.5,14 Z" + android:strokeWidth="1" /> + <path + android:fillColor="@android:color/white" + android:pathData="M0.5,4.75 L0.5,16.75 C0.5,18.27 1.73,19.5 3.25,19.5 L15.25,19.5 C15.66,19.5 16,19.16 16,18.75 C16,18.34 15.66,18 15.25,18 L3.25,18 C2.56,18 2,17.44 2,16.75 L2,4.75 C2,4.34 1.66,4 1.25,4 C0.84,4 0.5,4.34 0.5,4.75 Z" + android:strokeWidth="1" /> + </group> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/values/config.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/values/config.xml index ae5cc2bf9883..30f29f778858 100644 --- a/packages/overlays/IconPackCircularAndroidOverlay/res/values/config.xml +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/values/config.xml @@ -30,4 +30,12 @@ <string name="config_batterymeterPowersavePath" translatable="false"> M 3.75,11.25 H 5.25 V 12.75 C 5.25,13.16 5.59,13.5 6,13.5 6.41,13.5 6.75,13.16 6.75,12.75 V 11.25 H 8.25 C 8.66,11.25 9,10.91 9,10.5 9,10.09 8.6601,9.75 8.25,9.75 H 6.75 V 8.25 C 6.75,7.84 6.41,7.5 6,7.5 5.59,7.5 5.25,7.84 5.25,8.25 V 9.75 H 3.75 C 3.34,9.75 3,10.09 3,10.5 3,10.91 3.34,11.25 3.75,11.25 Z </string> + <!-- X path for SignalDrawable as defined on a 24x24 canvas. --> + <string name="config_signalXPath" translatable="false"> + M 17.81,18.75 L 19.81,16.75 C 20.01,16.56 20.09,16.28 20.02,16.02 C 19.96,15.75 19.75,15.54 19.48,15.47 C 19.22,15.41 18.94,15.49 18.75,15.69 L 16.75,17.69 L 14.75,15.69 C 14.56,15.49 14.28,15.41 14.02,15.47 C 13.75,15.54 13.54,15.75 13.47,16.02 C 13.41,16.28 13.49,16.56 13.69,16.75 L 15.69,18.75 L 13.69,20.75 C 13.4,21.04 13.4,21.52 13.69,21.81 C 13.98,22.1 14.46,22.1 14.75,21.81 L 16.75,19.81 L 18.75,21.81 C 19.04,22.1 19.52,22.1 19.81,21.81 C 20.1,21.52 20.1,21.04 19.81,20.75 Z + </string> + <!-- config_signalCutout{Height,Width}Fraction define fraction of the 24x24 canvas that + should be cut out to display config_signalXPath.--> + <item name="config_signalCutoutWidthFraction" format="float" type="dimen">10.5</item> + <item name="config_signalCutoutHeightFraction" format="float" type="dimen">11</item> </resources> diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_disable.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_disable.xml new file mode 100644 index 000000000000..0572fb72f82e --- /dev/null +++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_disable.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2019 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="24dp" + android:tint="?android:attr/colorControlNormal" + android:viewportHeight="24" + android:viewportWidth="24" + android:width="24dp" > + <group + android:translateX="1.000000" + android:translateY="2.000000" > + <path + android:fillColor="@android:color/white" + android:fillType="evenOdd" + android:pathData="M11,18.5 C6.313,18.5 2.5,14.687 2.5,10 C2.5,8.182 3.078,6.498 4.055,5.114 L15.887,16.945 C14.503,17.922 12.818,18.5 11,18.5 M20.031,18.969 L2.032,0.971 C1.739,0.678 1.264,0.678 0.971,0.971 C0.678,1.264 0.678,1.738 0.971,2.031 L2.983,4.043 C1.742,5.707 1,7.765 1,10 C1,15.522 5.477,20 11,20 C13.236,20 15.293,19.258 16.957,18.017 L18.971,20.029 C19.117,20.176 19.309,20.249 19.501,20.249 C19.693,20.249 19.885,20.176 20.031,20.029 C20.324,19.736 20.324,19.262 20.031,18.969" + android:strokeWidth="1" /> + <path + android:fillColor="@android:color/white" + android:fillType="evenOdd" + android:pathData="M11,1.5 C15.687,1.5 19.5,5.313 19.5,10 C19.5,11.782 18.946,13.436 18.006,14.804 L19.078,15.877 C20.281,14.226 21,12.199 21,10 C21,4.478 16.522,0 11,0 C8.801,0 6.774,0.719 5.124,1.922 L6.196,2.994 C7.564,2.054 9.218,1.5 11,1.5" + android:strokeWidth="1" /> + </group> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_enable.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_enable.xml new file mode 100644 index 000000000000..41962b27b270 --- /dev/null +++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_enable.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2019 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="24dp" + android:tint="?android:attr/colorControlNormal" + android:viewportHeight="24" + android:viewportWidth="24" + android:width="24dp" > + <group + android:translateX="2.000000" + android:translateY="2.000000" > + <path + android:fillColor="@android:color/white" + android:fillType="evenOdd" + android:pathData="M12.25,0.2637 L12.25,1.8127 C15.847,2.8017 18.5,6.0927 18.5,9.9997 C18.5,14.6867 14.687,18.4997 10,18.4997 C5.313,18.4997 1.5,14.6867 1.5,9.9997 C1.5,6.0927 4.153,2.8017 7.75,1.8127 L7.75,0.2637 C3.312,1.2847 0,5.2517 0,9.9997 C0,15.5227 4.477,19.9997 10,19.9997 C15.523,19.9997 20,15.5227 20,9.9997 C20,5.2517 16.687,1.2847 12.25,0.2637" + android:strokeWidth="1" /> + <path + android:fillColor="@android:color/white" + android:fillType="evenOdd" + android:pathData="M15.0303,9.9697 C14.7373,9.6767 14.2623,9.6767 13.9693,9.9697 L10.7503,13.1897 L10.7503,0.7387 C10.7503,0.3307 10.4143,-0.0003 10.0003,-0.0003 C9.5863,-0.0003 9.2503,0.3307 9.2503,0.7387 L9.2503,13.1897 L6.0303,9.9697 C5.7373,9.6767 5.2623,9.6767 4.9693,9.9697 C4.6763,10.2627 4.6763,10.7377 4.9693,11.0307 L10.0003,16.0607 L15.0303,11.0307 C15.3233,10.7377 15.3233,10.2627 15.0303,9.9697" + android:strokeWidth="1" /> + </group> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml new file mode 100644 index 000000000000..a0233ba8acc9 --- /dev/null +++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2019 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="24dp" + android:tint="?android:attr/colorControlNormal" + android:viewportHeight="24" + android:viewportWidth="24" + android:width="24dp" > + <group + android:translateX="4.000000" + android:translateY="3.000000" > + <path + android:fillColor="@android:color/white" + android:fillType="evenOdd" + android:pathData="M12.9902,13.5098 C12.9902,13.7858 12.7652,14.0098 12.4902,14.0098 C12.2142,14.0098 11.9902,13.7858 11.9902,13.5098 L11.9902,11.5098 C11.9902,11.2348 12.2142,11.0098 12.4902,11.0098 C12.7652,11.0098 12.9902,11.2348 12.9902,11.5098 L12.9902,13.5098 Z M12.4902,16.0098 C12.2142,16.0098 11.9902,15.7858 11.9902,15.5098 C11.9902,15.2348 12.2142,15.0098 12.4902,15.0098 C12.7652,15.0098 12.9902,15.2348 12.9902,15.5098 C12.9902,15.7858 12.7652,16.0098 12.4902,16.0098 L12.4902,16.0098 Z M15.5182,11.7848 C15.8372,10.9048 16.0102,9.9558 16.0102,8.9698 C16.0102,6.0698 14.5002,3.4798 12.1102,2.0098 L14.5102,2.0098 C14.9102,1.9998 15.2502,1.6598 15.2502,1.2498 C15.2502,0.8398 14.9102,0.4998 14.5002,0.4998 L9.2502,0.4998 L9.2502,6.2498 C9.2502,6.6598 9.5902,6.9998 10.0002,6.9998 C10.4102,6.9998 10.7502,6.6598 10.7502,6.2498 L10.7502,2.9398 C13.0302,4.0598 14.5002,6.3698 14.5002,8.9698 C14.5002,9.5068 14.4172,10.0238 14.2982,10.5268 C13.7682,10.2048 13.1542,10.0098 12.4902,10.0098 C10.5562,10.0098 8.9902,11.5768 8.9902,13.5098 C8.9902,15.4438 10.5562,17.0098 12.4902,17.0098 C14.4232,17.0098 15.9902,15.4438 15.9902,13.5098 C15.9902,12.8798 15.8092,12.2958 15.5182,11.7848 L15.5182,11.7848 Z" + android:strokeWidth="1" /> + <path + android:fillColor="@android:color/white" + android:fillType="evenOdd" + android:pathData="M6.3901,1.04 C2.6301,1.91 0.0001,5.21 0.0001,9.07 C0.0001,11.65 1.2001,13.98 3.1301,15.5 L1.5001,15.5 C1.0901,15.5 0.7501,15.84 0.7501,16.25 C0.7501,16.66 1.0901,17 1.5001,17 L6.7501,17 L6.7501,11.75 C6.7501,11.34 6.4101,11 6.0001,11 C5.5901,11 5.2501,11.34 5.2501,11.75 L5.2501,15.09 C2.9701,13.97 1.5001,11.66 1.5001,9.06 C1.5001,5.91 3.6501,3.21 6.7301,2.5 C7.1301,2.41 7.3901,2 7.2901,1.6 C7.2001,1.2 6.8001,0.95 6.3901,1.04" + android:strokeWidth="1" /> + </group> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_aural.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_aural.xml new file mode 100644 index 000000000000..3f5c75b66f4c --- /dev/null +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_aural.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2019 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="24dp" + android:tint="?android:attr/colorControlNormal" + android:viewportHeight="24" + android:viewportWidth="24" + android:width="24dp" > + <path android:pathData="M0 0h24v24H0z" /> + <path + android:fillColor="@android:color/white" + android:pathData="M20 2H8c-1.1 0-2 0.9-2 2v12c0 1.1 0.9 2 2 2h12c1.1 0 2-0.9 2-2V4c0-1.1-0.9-2-2-2zm-2 5h-3v5.5c0 1.38-1.12 2.5-2.5 2.5S10 13.88 10 12.5s1.12-2.5 2.5-2.5c0.57 0 1.08 0.19 1.5 0.51 V5h4v2zM4 6H2v14c0 1.1 0.9 2 2 2h14v-2H4V6z" /> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/values/config.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/values/config.xml index 6b59b6265c54..f1d8c7345396 100644 --- a/packages/overlays/IconPackFilledAndroidOverlay/res/values/config.xml +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/values/config.xml @@ -33,4 +33,12 @@ M 9,11 C 9,11.55 8.55,12 8,12 H 7 V 13 C 7,13.55 6.55,14 6,14 5.45,14 5,13.55 5,13 V 12 H 4 C 3.45,12 3,11.55 3,11 3,10.45 3.45,10.005 4,10 H 5 V 9 C 5,8.45 5.45,8 6,8 6.55,8 7,8.45 7,9 V 10 H 8 C 8.55,10 9,10.45 9,11 Z </string> <bool name="config_batterymeterDualTone">true</bool> + <!-- X path for SignalDrawable as defined on a 24x24 canvas. --> + <string name="config_signalXPath" translatable="false"> + M 21.7,20.28 L 19.92,18.5 L 21.7,16.72 C 22.1,16.32 22.1,15.68 21.71,15.29 C 21.32,14.9 20.68,14.9 20.28,15.3 L 18.5,17.08 L 16.72,15.3 C 16.32,14.9 15.68,14.9 15.29,15.29 C 14.9,15.68 14.9,16.32 15.3,16.72 L 17.08,18.5 L 15.3,20.28 C 14.9,20.68 14.9,21.32 15.29,21.71 C 15.68,22.1 16.32,22.1 16.72,21.7 L 18.5,19.92 L 20.28,21.7 C 20.68,22.1 21.32,22.1 21.71,21.71 C 22.1,21.32 22.1,20.68 21.7,20.28 + </string> + <!-- config_signalCutout{Height,Width}Fraction define fraction of the 24x24 canvas that + should be cut out to display config_signalXPath.--> + <item name="config_signalCutoutWidthFraction" format="float" type="dimen">11</item> + <item name="config_signalCutoutHeightFraction" format="float" type="dimen">11</item> </resources> diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_disable.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_disable.xml new file mode 100644 index 000000000000..b816e4e838fe --- /dev/null +++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_disable.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2019 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="24dp" + android:tint="?android:attr/colorControlNormal" + android:viewportHeight="24" + android:viewportWidth="24" + android:width="24dp" > + <group + android:scaleX="-1" + android:translateX="-12.000000" + android:translateY="-12.000000" > + <path + android:fillType="evenOdd" + android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" + android:strokeWidth="1" /> + </group> + <path + android:fillColor="@android:color/white" + android:pathData="M12.11,2 C10.33,2 8.67,2.46 7.22,3.28 L8.7,4.76 C9.74,4.28 10.89,4 12.11,4 C16.52,4 20.11,7.59 20.11,12 C20.11,13.22 19.83,14.37 19.35,15.41 L20.83,16.89 C21.65,15.44 22.11,13.78 22.11,12 C22.11,6.48 17.63,2 12.11,2 Z M18.23,17.13 L6.98,5.87 L4.12750442,3.01750442 C3.73635677,2.62635677 3.10252735,2.62523693 2.71,3.015 C2.31926097,3.40298735 2.31703029,4.0342698 2.70501764,4.42500883 C2.70584509,4.42584216 2.70667402,4.42667402 2.70750442,4.42750442 L4.19,5.91 C2.88,7.59 2.11,9.71 2.11,12 C2.11,17.52 6.59,22 12.11,22 C14.4,22 16.52,21.23 18.2,19.92 L19.685,21.405 C20.0743607,21.7943607 20.7056393,21.7943607 21.095,21.405 C21.4843607,21.0156393 21.4843607,20.3843607 21.095,19.995 L18.23,17.13 Z M12.11,20 C7.7,20 4.11,16.41 4.11,12 C4.11,10.26 4.67,8.65 5.62,7.34 L16.77,18.49 C15.46,19.44 13.85,20 12.11,20 Z M8.7,4.76 L7.22,3.28 L8.7,4.76 Z" + android:strokeWidth="1" /> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_enable.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_enable.xml new file mode 100644 index 000000000000..d0b6209b38ad --- /dev/null +++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_enable.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2019 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="24dp" + android:tint="?android:attr/colorControlNormal" + android:viewportHeight="24" + android:viewportWidth="24" + android:width="24dp" > + <group + android:scaleX="-1" + android:translateX="-12.000000" + android:translateY="-12.000000" > + <path + android:fillType="evenOdd" + android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" + android:strokeWidth="1" /> + </group> + <path + android:fillColor="@android:color/white" + android:pathData="M13.0016705,11.5012475 L15.3917467,11.5012475 C15.9314188,11.5012475 16.206996,12.1426752 15.8165949,12.5140281 L12.4292913,15.822445 C12.1961989,16.0553846 11.8138355,16.0598858 11.5761501,15.8314475 C11.5738536,15.8280716 11.5704089,15.8258209 11.5681124,15.822445 L8.17851232,12.5117775 C7.79729714,12.1392993 8.06713319,11.5012475 8.60565705,11.5012475 L11.002341,11.5012475 L11.002341,2.99966471 C11.002341,2.44756514 11.4499062,2 12.0020057,2 C12.5541053,2 13.0016705,2.44756514 13.0016705,2.99966471 L13.0016705,11.5012475 Z M15,2.46 L15,4.59 C17.93,5.78 20,8.65 20,12 C20,16.41 16.41,20 12,20 C7.59,20 4,16.41 4,12 C4,8.65 6.07,5.78 9,4.59 L9,2.46 C4.94,3.74 2,7.53 2,12 C2,17.52 6.48,22 12,22 C17.52,22 22,17.52 22,12 C22,7.53 19.06,3.74 15,2.46 Z" + android:strokeWidth="1" /> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml new file mode 100644 index 000000000000..f2dd9e818fc4 --- /dev/null +++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2019 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="24dp" + android:tint="?android:attr/colorControlNormal" + android:viewportHeight="24" + android:viewportWidth="24" + android:width="24dp" > + <path android:pathData="M0 0h24v24H0z" /> + <path + android:fillColor="@android:color/white" + android:pathData="M3 12c0 2.21 0.91 4.2 2.36 5.64L3 20h6v-6l-2.24 2.24C5.68 15.15 5 13.66 5 12c0-2.61 1.67-4.83 4-5.65V4.26C5.55 5.15 3 8.27 3 12zm8 5h2v-2h-2v2zM21 4h-6v6l2.24-2.24C18.32 8.85 19 10.34 19 12c0 2.61-1.67 4.83-4 5.65v2.09c3.45-0.89 6-4.01 6-7.74 0-2.21-0.91-4.2-2.36-5.64L21 4zm-10 9h2V7h-2v6z" /> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_aural.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_aural.xml new file mode 100644 index 000000000000..8cd240d47b2d --- /dev/null +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_aural.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2019 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="24dp" + android:tint="?android:attr/colorControlNormal" + android:viewportHeight="24" + android:viewportWidth="24" + android:width="24dp" > + <group + android:translateX="2.000000" + android:translateY="2.000000" > + <path + android:fillColor="@android:color/white" + android:pathData="M18,0 L6,0 C4.9,0 4,0.9 4,2 L4,14 C4,15.1 4.9,16 6,16 L18,16 C19.1,16 20,15.1 20,14 L20,2 C20,0.9 19.1,0 18,0 Z M18.5,14 C18.5,14.28 18.28,14.5 18,14.5 L6,14.5 C5.72,14.5 5.5,14.28 5.5,14 L5.5,2 C5.5,1.72 5.72,1.5 6,1.5 L18,1.5 C18.28,1.5 18.5,1.72 18.5,2 L18.5,14 Z" + android:strokeWidth="1" /> + <path + android:fillColor="@android:color/white" + android:fillType="evenOdd" + android:pathData="M15.86,3.10740288 C15.7704,3.02963963 15.6528,2.990758 15.5352,3.00186703 L13.0152,3.27959295 C12.8024,3.30736554 12.64,3.48511013 12.64,3.69618182 L12.64,9.056292 C12.2536,8.75079349 11.772,8.55638535 11.24,8.55638535 C10.0024,8.55638535 9,9.55064413 9,10.7781927 C9,12.0057412 10.0024,13 11.24,13 C12.4776,13 13.48,12.0057412 13.48,10.7781927 L13.48,5.01241596 L15.6248,4.77912619 C15.8376,4.7513536 16,4.57360901 16,4.36253732 L16,3.41845591 C16,3.30181102 15.9496,3.18516614 15.86,3.10740288 Z" + android:strokeWidth="1" /> + <path + android:fillColor="@android:color/white" + android:pathData="M15.25,18 L3.25,18 C2.56,18 2,17.44 2,16.75 L2,4.75 C2,4.34 1.66,4 1.25,4 C0.84,4 0.5,4.34 0.5,4.75 L0.5,16.75 C0.5,18.27 1.73,19.5 3.25,19.5 L15.25,19.5 C15.66,19.5 16,19.16 16,18.75 C16,18.34 15.66,18 15.25,18 Z" + android:strokeWidth="1" /> + </group> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/values/config.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/values/config.xml index ebcac82c695f..b7bfaad56249 100644 --- a/packages/overlays/IconPackRoundedAndroidOverlay/res/values/config.xml +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/values/config.xml @@ -30,4 +30,12 @@ <string name="config_batterymeterPowersavePath" translatable="false"> M 3.75,11.25 H 5.25 V 12.75 C 5.25,13.16 5.59,13.5 6,13.5 6.41,13.5 6.75,13.16 6.75,12.75 V 11.25 H 8.25 C 8.66,11.25 9,10.91 9,10.5 9,10.09 8.66,9.7499 8.25,9.7499 H 6.75 V 8.2499 C 6.75,7.8399 6.41,7.4999 6,7.4999 5.59,7.4999 5.2794,7.841 5.25,8.2499 V 9.7499 H 3.75 C 3.34,9.7499 3,10.09 3,10.5 3,10.91 3.3401,11.25 3.75,11.25 Z </string> + <!-- X path for SignalDrawable as defined on a 24x24 canvas. --> + <string name="config_signalXPath" translatable="false"> + M 20.72,16.22 L 19,17.94 L 17.28,16.22 C 16.99,15.93 16.51,15.93 16.22,16.22 C 15.93,16.51 15.93,16.99 16.22,17.28 L 17.94,19 L 16.22,20.72 C 15.93,21.01 15.93,21.49 16.22,21.78 C 16.37,21.93 16.56,22 16.75,22 C 16.94,22 17.13,21.93 17.28,21.78 L 19,20.06 L 20.72,21.78 C 20.87,21.93 21.06,22 21.25,22 C 21.44,22 21.63,21.93 21.78,21.78 C 22.07,21.49 22.07,21.01 21.78,20.72 L 20.06,19 L 21.78,17.28 C 22.07,16.99 22.07,16.51 21.78,16.22 C 21.49,15.93 21.01,15.93 20.72,16.22 Z + </string> + <!-- config_signalCutout{Height,Width}Fraction define fraction of the 24x24 canvas that + should be cut out to display config_signalXPath.--> + <item name="config_signalCutoutWidthFraction" format="float" type="dimen">10</item> + <item name="config_signalCutoutHeightFraction" format="float" type="dimen">10</item> </resources> diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_disable.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_disable.xml new file mode 100644 index 000000000000..0572fb72f82e --- /dev/null +++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_disable.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2019 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="24dp" + android:tint="?android:attr/colorControlNormal" + android:viewportHeight="24" + android:viewportWidth="24" + android:width="24dp" > + <group + android:translateX="1.000000" + android:translateY="2.000000" > + <path + android:fillColor="@android:color/white" + android:fillType="evenOdd" + android:pathData="M11,18.5 C6.313,18.5 2.5,14.687 2.5,10 C2.5,8.182 3.078,6.498 4.055,5.114 L15.887,16.945 C14.503,17.922 12.818,18.5 11,18.5 M20.031,18.969 L2.032,0.971 C1.739,0.678 1.264,0.678 0.971,0.971 C0.678,1.264 0.678,1.738 0.971,2.031 L2.983,4.043 C1.742,5.707 1,7.765 1,10 C1,15.522 5.477,20 11,20 C13.236,20 15.293,19.258 16.957,18.017 L18.971,20.029 C19.117,20.176 19.309,20.249 19.501,20.249 C19.693,20.249 19.885,20.176 20.031,20.029 C20.324,19.736 20.324,19.262 20.031,18.969" + android:strokeWidth="1" /> + <path + android:fillColor="@android:color/white" + android:fillType="evenOdd" + android:pathData="M11,1.5 C15.687,1.5 19.5,5.313 19.5,10 C19.5,11.782 18.946,13.436 18.006,14.804 L19.078,15.877 C20.281,14.226 21,12.199 21,10 C21,4.478 16.522,0 11,0 C8.801,0 6.774,0.719 5.124,1.922 L6.196,2.994 C7.564,2.054 9.218,1.5 11,1.5" + android:strokeWidth="1" /> + </group> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_enable.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_enable.xml new file mode 100644 index 000000000000..ec608cdf67dd --- /dev/null +++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_enable.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2019 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="24dp" + android:tint="?android:attr/colorControlNormal" + android:viewportHeight="24" + android:viewportWidth="24" + android:width="24dp" > + <group + android:translateX="2.000000" + android:translateY="2.000000" > + <path + android:fillColor="@android:color/white" + android:fillType="evenOdd" + android:pathData="M12.2502,0.2637 L12.2502,1.8127 C15.8472,2.8017 18.5002,6.0927 18.5002,9.9997 C18.5002,14.6867 14.6872,18.4997 10.0002,18.4997 C5.3132,18.4997 1.5002,14.6867 1.5002,9.9997 C1.5002,6.0927 4.1532,2.8017 7.7502,1.8127 L7.7502,0.2637 C3.3122,1.2847 0.0002,5.2517 0.0002,9.9997 C0.0002,15.5227 4.4772,19.9997 10.0002,19.9997 C15.5222,19.9997 20.0002,15.5227 20.0002,9.9997 C20.0002,5.2517 16.6872,1.2847 12.2502,0.2637" + android:strokeWidth="1" /> + <path + android:fillColor="@android:color/white" + android:fillType="evenOdd" + android:pathData="M15.0304,9.9697 C14.7374,9.6767 14.2624,9.6767 13.9694,9.9697 L10.7504,13.1897 L10.7504,0.7387 C10.7504,0.3307 10.4144,-0.0003 10.0004,-0.0003 C9.5864,-0.0003 9.2504,0.3307 9.2504,0.7387 L9.2504,13.1897 L6.0304,9.9697 C5.7374,9.6767 5.2624,9.6767 4.9694,9.9697 C4.6764,10.2627 4.6764,10.7377 4.9694,11.0307 L9.4694,15.5307 C9.6164,15.6767 9.8074,15.7497 10.0004,15.7497 C10.1924,15.7497 10.3844,15.6767 10.5304,15.5307 L15.0304,11.0307 C15.3234,10.7377 15.3234,10.2627 15.0304,9.9697" + android:strokeWidth="1" /> + </group> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml new file mode 100644 index 000000000000..e9a07cc3b988 --- /dev/null +++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2019 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="24dp" + android:tint="?android:attr/colorControlNormal" + android:viewportHeight="24" + android:viewportWidth="24" + android:width="24dp" > + <group + android:translateX="3.000000" + android:translateY="3.000000" > + <path + android:fillColor="@android:color/white" + android:fillType="evenOdd" + android:pathData="M16.7178,12.626 C17.2378,11.522 17.5288,10.291 17.5288,9 C17.5288,6.119 16.1088,3.539 13.8488,2 L15.7588,2 C16.1578,2 16.4988,1.659 16.4988,1.25 C16.4988,0.84 16.1578,0.5 15.7488,0.5 L10.7488,0.5 C10.3388,0.5 9.9988,0.84 9.9988,1.25 L9.9988,6.25 C9.9988,6.659 10.3388,7 10.7488,7 C11.1578,7 11.4988,6.659 11.4988,6.25 L11.4988,2.47 C14.1978,3.489 16.0188,6.039 16.0188,9 C16.0188,9.785 15.8828,10.542 15.6438,11.252 C15.0498,10.788 14.3108,10.5 13.4988,10.5 C11.5658,10.5 9.9988,12.066 9.9988,14 C9.9988,15.933 11.5658,17.5 13.4988,17.5 C15.4318,17.5 16.9988,15.933 16.9988,14 C16.9988,13.512 16.8978,13.048 16.7178,12.626 L16.7178,12.626 Z M13.4988,16.5 C13.2228,16.5 12.9988,16.275 12.9988,16 C12.9988,15.723 13.2228,15.5 13.4988,15.5 C13.7748,15.5 13.9988,15.723 13.9988,16 C13.9988,16.275 13.7748,16.5 13.4988,16.5 L13.4988,16.5 Z M13.9988,14 C13.9988,14.275 13.7748,14.5 13.4988,14.5 C13.2228,14.5 12.9988,14.275 12.9988,14 L12.9988,12 C12.9988,11.723 13.2228,11.5 13.4988,11.5 C13.7748,11.5 13.9988,11.723 13.9988,12 L13.9988,14 Z" + android:strokeWidth="1" /> + <path + android:fillColor="@android:color/white" + android:fillType="evenOdd" + android:pathData="M7.0811,0.7197 C3.1901,1.6097 0.4801,5.0097 0.4801,8.9997 C0.4801,11.8797 1.9011,14.4587 4.1611,15.9987 L2.2511,15.9987 C1.8411,15.9987 1.5011,16.3397 1.5011,16.7497 C1.5011,17.1577 1.8411,17.4997 2.2511,17.4997 L7.2511,17.4997 C7.6621,17.4997 8.0011,17.1577 8.0011,16.7497 L8.0011,11.7487 C8.0011,11.3397 7.6621,10.9997 7.2511,10.9997 C6.8411,10.9997 6.5021,11.3397 6.5021,11.7487 L6.5021,15.5287 C3.8011,14.5107 1.9811,11.9587 1.9811,8.9997 C1.9811,5.7197 4.2111,2.9097 7.4211,2.1807 C7.8221,2.0907 8.0811,1.6797 7.9801,1.2797 C7.9041,0.9347 7.5961,0.7017 7.2491,0.7017 C7.1941,0.7017 7.1381,0.7067 7.0811,0.7197" + android:strokeWidth="1" /> + </group> +</vector>
\ No newline at end of file diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 3764ca4b7906..988db6a87100 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -2924,6 +2924,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState if (sVerbose) { Slog.v(TAG, "Adding autofillable view with id " + id + " and state " + state); } + viewState.setCurrentValue(findValueLocked(id)); mViewStates.put(id, viewState); } if ((state & ViewState.STATE_AUTOFILLED) != 0) { diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java index e1b089cf28b2..84886f83027d 100644 --- a/services/autofill/java/com/android/server/autofill/ViewState.java +++ b/services/autofill/java/com/android/server/autofill/ViewState.java @@ -227,6 +227,7 @@ final class ViewState { if (mVirtualBounds != null) { builder.append(", virtualBounds:" ).append(mVirtualBounds); } + builder.append("]"); return builder.toString(); } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index f0321c190b5f..4f7900eefee2 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -2579,8 +2579,8 @@ public class ConnectivityService extends IConnectivityManager.Stub if (nai.everConnected) { loge("ERROR: cannot call explicitlySelected on already-connected network"); } - nai.networkMisc.explicitlySelected = (msg.arg1 == 1); - nai.networkMisc.acceptUnvalidated = (msg.arg1 == 1) && (msg.arg2 == 1); + nai.networkMisc.explicitlySelected = toBool(msg.arg1); + nai.networkMisc.acceptUnvalidated = toBool(msg.arg1) && toBool(msg.arg2); // Mark the network as temporarily accepting partial connectivity so that it // will be validated (and possibly become default) even if it only provides // partial internet access. Note that if user connects to partial connectivity @@ -2588,7 +2588,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // out of wifi coverage) and if the same wifi is available again, the device // will auto connect to this wifi even though the wifi has "no internet". // TODO: Evaluate using a separate setting in IpMemoryStore. - nai.networkMisc.acceptPartialConnectivity = (msg.arg2 == 1); + nai.networkMisc.acceptPartialConnectivity = toBool(msg.arg2); break; } case NetworkAgent.EVENT_SOCKET_KEEPALIVE: { diff --git a/services/core/java/com/android/server/appop/HistoricalRegistry.java b/services/core/java/com/android/server/appop/HistoricalRegistry.java index 35fbfe1d4044..9cf342c0e4fb 100644 --- a/services/core/java/com/android/server/appop/HistoricalRegistry.java +++ b/services/core/java/com/android/server/appop/HistoricalRegistry.java @@ -150,11 +150,9 @@ final class HistoricalRegistry { /** * Whether history is enabled. - * - * <p>The feature is permanently disabled in Android Q */ @GuardedBy("mInMemoryLock") - private final int mMode = AppOpsManager.HISTORICAL_MODE_DISABLED; + private int mMode = AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE; /** * This granularity has been chosen to allow clean delineation for intervals @@ -453,7 +451,6 @@ final class HistoricalRegistry { void setHistoryParameters(@HistoricalMode int mode, long baseSnapshotInterval, long intervalCompressionMultiplier) { - /* synchronized (mOnDiskLock) { synchronized (mInMemoryLock) { // NOTE: We allow this call if persistence is not initialized as @@ -482,7 +479,6 @@ final class HistoricalRegistry { } } } - */ } void offsetHistory(long offsetMillis) { diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java index 3a74798a2ad8..03224d1939b9 100644 --- a/services/core/java/com/android/server/pm/ApexManager.java +++ b/services/core/java/com/android/server/pm/ApexManager.java @@ -117,7 +117,7 @@ class ApexManager { for (ApexInfo ai : allPkgs) { // If the device is using flattened APEX, don't report any APEX // packages since they won't be managed or updated by PackageManager. - if ((new File(ai.packagePath)).isDirectory()) { + if ((new File(ai.modulePath)).isDirectory()) { break; } try { @@ -131,7 +131,7 @@ class ApexManager { "Two active packages have the same name: " + pkg.packageName); } - activePackagesSet.add(ai.packageName); + activePackagesSet.add(pkg.packageName); } if (ai.isFactory) { if (factoryPackagesSet.contains(pkg.packageName)) { @@ -139,7 +139,7 @@ class ApexManager { "Two factory packages have the same name: " + pkg.packageName); } - factoryPackagesSet.add(ai.packageName); + factoryPackagesSet.add(pkg.packageName); } } catch (PackageParserException pe) { throw new IllegalStateException("Unable to parse: " + ai, pe); diff --git a/services/core/java/com/android/server/pm/ShareTargetInfo.java b/services/core/java/com/android/server/pm/ShareTargetInfo.java index 9e8b73e36f69..fdfee773ea74 100644 --- a/services/core/java/com/android/server/pm/ShareTargetInfo.java +++ b/services/core/java/com/android/server/pm/ShareTargetInfo.java @@ -15,12 +15,36 @@ */ package com.android.server.pm; +import android.annotation.NonNull; import android.text.TextUtils; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlSerializer; + +import java.io.IOException; +import java.util.ArrayList; + /** * Represents a Share Target definition, read from the application's manifest (shortcuts.xml) */ class ShareTargetInfo { + + private static final String TAG_SHARE_TARGET = "share-target"; + private static final String ATTR_TARGET_CLASS = "targetClass"; + + private static final String TAG_DATA = "data"; + private static final String ATTR_SCHEME = "scheme"; + private static final String ATTR_HOST = "host"; + private static final String ATTR_PORT = "port"; + private static final String ATTR_PATH = "path"; + private static final String ATTR_PATH_PATTERN = "pathPattern"; + private static final String ATTR_PATH_PREFIX = "pathPrefix"; + private static final String ATTR_MIME_TYPE = "mimeType"; + + private static final String TAG_CATEGORY = "category"; + private static final String ATTR_NAME = "name"; + static class TargetData { final String mScheme; final String mHost; @@ -98,4 +122,72 @@ class ShareTargetInfo { return strBuilder.toString(); } + + void saveToXml(@NonNull XmlSerializer out) throws IOException { + out.startTag(null, TAG_SHARE_TARGET); + + ShortcutService.writeAttr(out, ATTR_TARGET_CLASS, mTargetClass); + + for (int i = 0; i < mTargetData.length; i++) { + out.startTag(null, TAG_DATA); + ShortcutService.writeAttr(out, ATTR_SCHEME, mTargetData[i].mScheme); + ShortcutService.writeAttr(out, ATTR_HOST, mTargetData[i].mHost); + ShortcutService.writeAttr(out, ATTR_PORT, mTargetData[i].mPort); + ShortcutService.writeAttr(out, ATTR_PATH, mTargetData[i].mPath); + ShortcutService.writeAttr(out, ATTR_PATH_PATTERN, mTargetData[i].mPathPattern); + ShortcutService.writeAttr(out, ATTR_PATH_PREFIX, mTargetData[i].mPathPrefix); + ShortcutService.writeAttr(out, ATTR_MIME_TYPE, mTargetData[i].mMimeType); + out.endTag(null, TAG_DATA); + } + + for (int i = 0; i < mCategories.length; i++) { + out.startTag(null, TAG_CATEGORY); + ShortcutService.writeAttr(out, ATTR_NAME, mCategories[i]); + out.endTag(null, TAG_CATEGORY); + } + + out.endTag(null, TAG_SHARE_TARGET); + } + + static ShareTargetInfo loadFromXml(XmlPullParser parser) + throws IOException, XmlPullParserException { + final String targetClass = ShortcutService.parseStringAttribute(parser, ATTR_TARGET_CLASS); + final ArrayList<ShareTargetInfo.TargetData> targetData = new ArrayList<>(); + final ArrayList<String> categories = new ArrayList<>(); + + int type; + while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) { + if (type == XmlPullParser.START_TAG) { + switch (parser.getName()) { + case TAG_DATA: + targetData.add(parseTargetData(parser)); + break; + case TAG_CATEGORY: + categories.add(ShortcutService.parseStringAttribute(parser, ATTR_NAME)); + break; + } + } else if (type == XmlPullParser.END_TAG && parser.getName().equals(TAG_SHARE_TARGET)) { + break; + } + } + if (targetData.isEmpty() || targetClass == null || categories.isEmpty()) { + return null; + } + return new ShareTargetInfo( + targetData.toArray(new ShareTargetInfo.TargetData[targetData.size()]), + targetClass, categories.toArray(new String[categories.size()])); + } + + private static ShareTargetInfo.TargetData parseTargetData(XmlPullParser parser) { + final String scheme = ShortcutService.parseStringAttribute(parser, ATTR_SCHEME); + final String host = ShortcutService.parseStringAttribute(parser, ATTR_HOST); + final String port = ShortcutService.parseStringAttribute(parser, ATTR_PORT); + final String path = ShortcutService.parseStringAttribute(parser, ATTR_PATH); + final String pathPattern = ShortcutService.parseStringAttribute(parser, ATTR_PATH_PATTERN); + final String pathPrefix = ShortcutService.parseStringAttribute(parser, ATTR_PATH_PREFIX); + final String mimeType = ShortcutService.parseStringAttribute(parser, ATTR_MIME_TYPE); + + return new ShareTargetInfo.TargetData(scheme, host, port, path, pathPattern, pathPrefix, + mimeType); + } } diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java index d6e87aab35fe..06c71baade42 100644 --- a/services/core/java/com/android/server/pm/ShortcutPackage.java +++ b/services/core/java/com/android/server/pm/ShortcutPackage.java @@ -73,6 +73,7 @@ class ShortcutPackage extends ShortcutPackageItem { private static final String TAG_INTENT = "intent"; private static final String TAG_EXTRAS = "extras"; private static final String TAG_SHORTCUT = "shortcut"; + private static final String TAG_SHARE_TARGET = "share-target"; private static final String TAG_CATEGORIES = "categories"; private static final String TAG_PERSON = "person"; @@ -1453,8 +1454,9 @@ class ShortcutPackage extends ShortcutPackageItem { public void saveToXml(@NonNull XmlSerializer out, boolean forBackup) throws IOException, XmlPullParserException { final int size = mShortcuts.size(); + final int shareTargetSize = mShareTargets.size(); - if (size == 0 && mApiCallCount == 0) { + if (size == 0 && shareTargetSize == 0 && mApiCallCount == 0) { return; // nothing to write. } @@ -1470,6 +1472,12 @@ class ShortcutPackage extends ShortcutPackageItem { getPackageInfo().isBackupAllowed()); } + if (!forBackup) { + for (int j = 0; j < shareTargetSize; j++) { + mShareTargets.get(j).saveToXml(out); + } + } + out.endTag(null, TAG_ROOT); } @@ -1627,6 +1635,9 @@ class ShortcutPackage extends ShortcutPackageItem { // Don't use addShortcut(), we don't need to save the icon. ret.mShortcuts.put(si.getId(), si); continue; + case TAG_SHARE_TARGET: + ret.mShareTargets.add(ShareTargetInfo.loadFromXml(parser)); + continue; } } ShortcutService.warnForInvalidTag(depth, tag); diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java index 18bbfed3364f..f9a019703f4d 100644 --- a/services/core/java/com/android/server/pm/StagingManager.java +++ b/services/core/java/com/android/server/pm/StagingManager.java @@ -170,7 +170,7 @@ public class StagingManager { PackageManager.GET_META_DATA); } catch (PackageParserException e) { throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED, - "Failed to parse APEX package " + newPackage.packagePath, e); + "Failed to parse APEX package " + newPackage.modulePath, e); } final PackageInfo activePackage = mApexManager.getPackageInfo(pkg.packageName, ApexManager.MATCH_ACTIVE_PACKAGE); diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 602cc553f870..ab531899b496 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -2524,11 +2524,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { } final int resource; - if (onWallpaper) { - resource = R.anim.lock_screen_behind_enter_wallpaper; - } else if (subtleAnimation) { + if (subtleAnimation) { resource = R.anim.lock_screen_behind_enter_subtle; - } else { + } else if (onWallpaper) { + resource = R.anim.lock_screen_behind_enter_wallpaper; + } else { resource = R.anim.lock_screen_behind_enter; } diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java index 6127303141f4..553b0ffa6999 100644 --- a/services/core/java/com/android/server/wm/DragState.java +++ b/services/core/java/com/android/server/wm/DragState.java @@ -176,6 +176,8 @@ class DragState { mTransaction.transferTouchFocus(mTransferTouchFromToken, h.token); mTransferTouchFromToken = null; + // syncInputWindows here to ensure the input channel isn't removed before the transfer. + mTransaction.syncInputWindows(); mTransaction.apply(); } diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 3ec8b2efa8a2..47539d3adcb8 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -1893,6 +1893,10 @@ public final class SystemServer { mSystemServiceManager.startService(IncidentCompanionService.class); t.traceEnd(); + if (safeMode) { + mActivityManagerService.enterSafeMode(); + } + // MMS service broker t.traceBegin("StartMmsService"); mmsService = mSystemServiceManager.startService(MmsServiceBroker.class); diff --git a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java index 504d981af53f..06366cf7d143 100644 --- a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java @@ -63,7 +63,6 @@ import com.android.server.LocalServices; import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.quality.Strictness; @@ -234,7 +233,6 @@ public class AppOpsServiceTest { assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED); } - @Ignore("Historical appops are disabled in Android Q") @Test public void testGetOpsForPackage() { mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED); @@ -276,7 +274,7 @@ public class AppOpsServiceTest { assertThat(getLoggedOps()).isNull(); } - @Ignore("Historical appops are disabled in Android Q") + @Test public void testPackageRemovedHistoricalOps() throws InterruptedException { mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED); diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java index 7e6b7da4a058..6c917b7f8636 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java +++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java @@ -97,16 +97,25 @@ import android.os.UserHandle; import android.test.suitebuilder.annotation.SmallTest; import android.util.Log; import android.util.SparseArray; +import android.util.Xml; import com.android.frameworks.servicestests.R; +import com.android.internal.util.FastXmlSerializer; import com.android.server.pm.ShortcutService.ConfigConstants; import com.android.server.pm.ShortcutService.FileOutputStreamWithPath; import com.android.server.pm.ShortcutUser.PackageWithUser; import org.mockito.ArgumentCaptor; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlSerializer; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.Locale; @@ -8089,4 +8098,70 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { } } } + + public void testShareTargetInfo_saveToXml() throws IOException, XmlPullParserException { + List<ShareTargetInfo> expectedValues = new ArrayList<>(); + expectedValues.add(new ShareTargetInfo( + new ShareTargetInfo.TargetData[]{new ShareTargetInfo.TargetData( + "http", "www.google.com", "1234", "somePath", "somePathPattern", + "somePathPrefix", "text/plain")}, "com.test.directshare.TestActivity1", + new String[]{"com.test.category.CATEGORY1", "com.test.category.CATEGORY2"})); + expectedValues.add(new ShareTargetInfo(new ShareTargetInfo.TargetData[]{ + new ShareTargetInfo.TargetData(null, null, null, null, null, null, "video/mp4"), + new ShareTargetInfo.TargetData("content", null, null, null, null, null, "video/*")}, + "com.test.directshare.TestActivity5", + new String[]{"com.test.category.CATEGORY5", "com.test.category.CATEGORY6"})); + + // Write ShareTargets to Xml + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + final XmlSerializer outXml = new FastXmlSerializer(); + outXml.setOutput(outStream, StandardCharsets.UTF_8.name()); + outXml.startDocument(null, true); + for (int i = 0; i < expectedValues.size(); i++) { + expectedValues.get(i).saveToXml(outXml); + } + outXml.endDocument(); + outXml.flush(); + + // Read ShareTargets from Xml + ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray()); + XmlPullParser parser = Xml.newPullParser(); + parser.setInput(new InputStreamReader(inStream)); + List<ShareTargetInfo> shareTargets = new ArrayList<>(); + int type; + while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) { + if (type == XmlPullParser.START_TAG && parser.getName().equals("share-target")) { + shareTargets.add(ShareTargetInfo.loadFromXml(parser)); + } + } + + // Assert two lists are equal + assertNotNull(shareTargets); + assertEquals(expectedValues.size(), shareTargets.size()); + + for (int i = 0; i < expectedValues.size(); i++) { + ShareTargetInfo expected = expectedValues.get(i); + ShareTargetInfo actual = shareTargets.get(i); + + assertEquals(expected.mTargetData.length, actual.mTargetData.length); + for (int j = 0; j < expected.mTargetData.length; j++) { + assertEquals(expected.mTargetData[j].mScheme, actual.mTargetData[j].mScheme); + assertEquals(expected.mTargetData[j].mHost, actual.mTargetData[j].mHost); + assertEquals(expected.mTargetData[j].mPort, actual.mTargetData[j].mPort); + assertEquals(expected.mTargetData[j].mPath, actual.mTargetData[j].mPath); + assertEquals(expected.mTargetData[j].mPathPrefix, + actual.mTargetData[j].mPathPrefix); + assertEquals(expected.mTargetData[j].mPathPattern, + actual.mTargetData[j].mPathPattern); + assertEquals(expected.mTargetData[j].mMimeType, actual.mTargetData[j].mMimeType); + } + + assertEquals(expected.mTargetClass, actual.mTargetClass); + + assertEquals(expected.mCategories.length, actual.mCategories.length); + for (int j = 0; j < expected.mCategories.length; j++) { + assertEquals(expected.mCategories[j], actual.mCategories[j]); + } + } + } } diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 484fd3b17c02..4a9b174cedbb 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -2121,24 +2121,27 @@ public class SubscriptionManager { * @hide */ @UnsupportedAppUsage - public @NonNull int[] getActiveSubscriptionIdList() { - int[] subId = null; + public static @NonNull int[] getActiveSubscriptionIdList() { + return getActiveSubscriptionIdList(true); + } + /** + * @return a non-null list of subId's that are active. + * + * @hide + */ + public static @NonNull int[] getActiveSubscriptionIdList(boolean visibleOnly) { try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); if (iSub != null) { - subId = iSub.getActiveSubIdList(/*visibleOnly*/true); + int[] subId = iSub.getActiveSubIdList(visibleOnly); + if (subId != null) return subId; } } catch (RemoteException ex) { // ignore it } - if (subId == null) { - subId = new int[0]; - } - - return subId; - + return new int[0]; } /** diff --git a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java index 7a0ab9ca6a28..5b57c9d7554c 100644 --- a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java +++ b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java @@ -605,15 +605,11 @@ public final class TelephonyPermissions { */ private static boolean checkCarrierPrivilegeForAnySubId(Context context, Supplier<ITelephony> telephonySupplier, int uid) { - SubscriptionManager sm = (SubscriptionManager) context.getSystemService( - Context.TELEPHONY_SUBSCRIPTION_SERVICE); - int[] activeSubIds = sm.getActiveSubscriptionIdList(); - if (activeSubIds != null) { - for (int activeSubId : activeSubIds) { - if (getCarrierPrivilegeStatus(telephonySupplier, activeSubId, uid) - == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { - return true; - } + int[] activeSubIds = SubscriptionManager.getActiveSubscriptionIdList(/*visibleOnly*/ false); + for (int activeSubId : activeSubIds) { + if (getCarrierPrivilegeStatus(telephonySupplier, activeSubId, uid) + == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { + return true; } } return false; diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 42328baf5265..1b2a12887aa5 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -652,8 +652,8 @@ public class ConnectivityServiceTest { return mScore; } - public void explicitlySelected(boolean acceptUnvalidated) { - mNetworkAgent.explicitlySelected(acceptUnvalidated); + public void explicitlySelected(boolean explicitlySelected, boolean acceptUnvalidated) { + mNetworkAgent.explicitlySelected(explicitlySelected, acceptUnvalidated); } public void addCapability(int capability) { @@ -756,6 +756,11 @@ public class ConnectivityServiceTest { connect(false); } + public void connectWithPartialValidConnectivity() { + setNetworkPartialValid(); + connect(false); + } + public void suspend() { mNetworkInfo.setDetailedState(DetailedState.SUSPENDED, null, null); mNetworkAgent.sendNetworkInfo(mNetworkInfo); @@ -2389,7 +2394,7 @@ public class ConnectivityServiceTest { // Bring up unvalidated wifi with explicitlySelected=true. mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); - mWiFiNetworkAgent.explicitlySelected(false); + mWiFiNetworkAgent.explicitlySelected(true, false); mWiFiNetworkAgent.connect(false); callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); @@ -2412,7 +2417,7 @@ public class ConnectivityServiceTest { mWiFiNetworkAgent.disconnect(); callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent); mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); - mWiFiNetworkAgent.explicitlySelected(false); + mWiFiNetworkAgent.explicitlySelected(true, false); mWiFiNetworkAgent.connect(false); callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); @@ -2423,7 +2428,7 @@ public class ConnectivityServiceTest { // Reconnect, again with explicitlySelected=true, but this time validate. mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); - mWiFiNetworkAgent.explicitlySelected(false); + mWiFiNetworkAgent.explicitlySelected(true, false); mWiFiNetworkAgent.connect(true); callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent); @@ -2438,14 +2443,36 @@ public class ConnectivityServiceTest { assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork()); callback.assertNoCallback(); + // Disconnect wifi, and then reconnect as if the user had selected "yes, don't ask again" + // (i.e., with explicitlySelected=true and acceptUnvalidated=true). Expect to switch to + // wifi immediately. + mWiFiNetworkAgent.disconnect(); + callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent); + mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); + mWiFiNetworkAgent.explicitlySelected(true, true); + mWiFiNetworkAgent.connect(false); + callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); + callback.expectCallback(CallbackState.LOSING, mEthernetNetworkAgent); + assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); + mEthernetNetworkAgent.disconnect(); + callback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent); + + // Disconnect and reconnect with explicitlySelected=false and acceptUnvalidated=true. + // Check that the network is not scored specially and that the device prefers cell data. + mWiFiNetworkAgent.disconnect(); + callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent); + mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); + mWiFiNetworkAgent.explicitlySelected(false, true); + mWiFiNetworkAgent.connect(false); + callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); + assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); + // Clean up. mWiFiNetworkAgent.disconnect(); mCellNetworkAgent.disconnect(); - mEthernetNetworkAgent.disconnect(); callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent); callback.expectCallback(CallbackState.LOST, mCellNetworkAgent); - callback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent); } private int[] makeIntArray(final int size, final int value) { @@ -2690,6 +2717,7 @@ public class ConnectivityServiceTest { // NetworkMonitor#setAcceptPartialConnectivity() should be called too. waitForIdle(); verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); + // Need a trigger point to let NetworkMonitor tell ConnectivityService that network is // validated. mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); @@ -2720,8 +2748,10 @@ public class ConnectivityServiceTest { // NET_CAPABILITY_PARTIAL_CONNECTIVITY. mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); // acceptUnvalidated is also used as setting for accepting partial networks. - mWiFiNetworkAgent.explicitlySelected(true /* acceptUnvalidated */); + mWiFiNetworkAgent.explicitlySelected(true /* explicitlySelected */, + true /* acceptUnvalidated */); mWiFiNetworkAgent.connect(true); + // If user accepted partial connectivity network before, // NetworkMonitor#setAcceptPartialConnectivity() will be called in // ConnectivityService#updateNetworkInfo(). @@ -2731,20 +2761,18 @@ public class ConnectivityServiceTest { callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent); nc = callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); assertFalse(nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); + // Wifi should be the default network. assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); mWiFiNetworkAgent.disconnect(); callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent); - // If user accepted partial connectivity before, and now the device reconnects to the - // partial connectivity network. The network should be valid and contain - // NET_CAPABILITY_PARTIAL_CONNECTIVITY. + // The user accepted partial connectivity and selected "don't ask again". Now the user + // reconnects to the partial connectivity network. Switch to wifi as soon as partial + // connectivity is detected. mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); - mWiFiNetworkAgent.explicitlySelected(true /* acceptUnvalidated */); - // Current design cannot send multi-testResult from NetworkMonitor to ConnectivityService. - // So, if user accepts partial connectivity, NetworkMonitor will send PARTIAL_CONNECTIVITY - // to ConnectivityService first then send VALID. Once NetworkMonitor support - // multi-testResult, this test case also need to be changed to meet the new design. + mWiFiNetworkAgent.explicitlySelected(true /* explicitlySelected */, + true /* acceptUnvalidated */); mWiFiNetworkAgent.connectWithPartialConnectivity(); // If user accepted partial connectivity network before, // NetworkMonitor#setAcceptPartialConnectivity() will be called in @@ -2753,17 +2781,35 @@ public class ConnectivityServiceTest { verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent); - // TODO: If the user accepted partial connectivity, we shouldn't switch to wifi until - // NetworkMonitor detects partial connectivity assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); callback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, mWiFiNetworkAgent); mWiFiNetworkAgent.setNetworkValid(); + // Need a trigger point to let NetworkMonitor tell ConnectivityService that network is // validated. mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); mWiFiNetworkAgent.disconnect(); callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent); + + // If the user accepted partial connectivity, and the device auto-reconnects to the partial + // connectivity network, it should contain both PARTIAL_CONNECTIVITY and VALIDATED. + mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); + mWiFiNetworkAgent.explicitlySelected(false /* explicitlySelected */, + true /* acceptUnvalidated */); + + // NetworkMonitor will immediately (once the HTTPS probe fails...) report the network as + // valid, because ConnectivityService calls setAcceptPartialConnectivity before it calls + // notifyNetworkConnected. + mWiFiNetworkAgent.connectWithPartialValidConnectivity(); + waitForIdle(); + verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); + callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); + callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent); + callback.expectCapabilitiesWith( + NET_CAPABILITY_PARTIAL_CONNECTIVITY | NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); + mWiFiNetworkAgent.disconnect(); + callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent); } @Test |