diff options
586 files changed, 13872 insertions, 8390 deletions
diff --git a/Android.mk b/Android.mk index 749242d78bd2..08ef6f59fe7b 100644 --- a/Android.mk +++ b/Android.mk @@ -140,8 +140,8 @@ LOCAL_SRC_FILES += \ core/java/android/bluetooth/IBluetoothInputHost.aidl \ core/java/android/bluetooth/IBluetoothHidDeviceCallback.aidl \ core/java/android/bluetooth/IBluetoothGatt.aidl \ - core/java/android/bluetooth/IBluetoothGattCallbackExt.aidl \ - core/java/android/bluetooth/IBluetoothGattServerCallbackExt.aidl \ + core/java/android/bluetooth/IBluetoothGattCallback.aidl \ + core/java/android/bluetooth/IBluetoothGattServerCallback.aidl \ core/java/android/bluetooth/le/IAdvertiserCallback.aidl \ core/java/android/bluetooth/le/IAdvertisingSetCallback.aidl \ core/java/android/bluetooth/le/IPeriodicAdvertisingCallback.aidl \ @@ -223,6 +223,7 @@ LOCAL_SRC_FILES += \ core/java/android/net/IEthernetManager.aidl \ core/java/android/net/IEthernetServiceListener.aidl \ core/java/android/net/INetdEventCallback.aidl \ + core/java/android/net/IIpSecService.aidl \ core/java/android/net/INetworkManagementEventObserver.aidl \ core/java/android/net/INetworkPolicyListener.aidl \ core/java/android/net/INetworkPolicyManager.aidl \ @@ -319,6 +320,8 @@ LOCAL_SRC_FILES += \ core/java/android/service/wallpaper/IWallpaperService.aidl \ core/java/android/service/chooser/IChooserTargetService.aidl \ core/java/android/service/chooser/IChooserTargetResult.aidl \ + core/java/android/service/resolver/IResolverRankerService.aidl \ + core/java/android/service/resolver/IResolverRankerResult.aidl \ core/java/android/text/ITextClassificationService.aidl \ core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl\ core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl\ @@ -567,8 +570,9 @@ LOCAL_JAVA_LIBRARIES := core-oj core-libart conscrypt okhttp bouncycastle ext LOCAL_STATIC_JAVA_LIBRARIES := \ framework-protos \ - android.hardware.thermal@1.0-java-constants \ android.hardware.health@1.0-java-constants \ + android.hardware.thermal@1.0-java-constants \ + android.hardware.tv.input@1.0-java-constants \ android.hardware.usb@1.0-java-constants \ android.hardware.vibrator@1.0-java-constants \ @@ -727,6 +731,7 @@ aidl_files := \ frameworks/base/core/java/android/service/notification/SnoozeCriterion.aidl \ frameworks/base/core/java/android/service/notification/StatusBarNotification.aidl \ frameworks/base/core/java/android/service/chooser/ChooserTarget.aidl \ + frameworks/base/core/java/android/service/resolver/ResolverTarget.aidl \ frameworks/base/core/java/android/speech/tts/Voice.aidl \ frameworks/base/core/java/android/app/usage/CacheQuotaHint.aidl \ frameworks/base/core/java/android/app/usage/ExternalStorageStats.aidl \ @@ -1459,7 +1464,8 @@ LOCAL_PROTOC_FLAGS := \ LOCAL_SRC_FILES := \ $(call all-proto-files-under, core/proto) \ $(call all-proto-files-under, libs/incident/proto) -include $(BUILD_STATIC_LIBRARY) +LOCAL_SHARED_LIBRARIES := libprotobuf-cpp-full +include $(BUILD_SHARED_LIBRARY) # ==== c++ proto host library ============================== include $(CLEAR_VARS) diff --git a/api/current.txt b/api/current.txt index 8f969c1efb02..f4db2817c0a3 100644 --- a/api/current.txt +++ b/api/current.txt @@ -696,6 +696,7 @@ package android { field public static final int hyphenationFrequency = 16843998; // 0x10104de field public static final int icon = 16842754; // 0x1010002 field public static final int iconPreview = 16843337; // 0x1010249 + field public static final int iconSpaceReserved = 16844132; // 0x1010564 field public static final int iconTint = 16844129; // 0x1010561 field public static final int iconTintMode = 16844130; // 0x1010562 field public static final int iconifiedByDefault = 16843514; // 0x10102fa @@ -3673,7 +3674,7 @@ package android.app { method public void onLowMemory(); method public boolean onMenuItemSelected(int, android.view.MenuItem); method public boolean onMenuOpened(int, android.view.Menu); - method public void onMovedToDisplay(int); + method public void onMovedToDisplay(int, android.content.res.Configuration); method public void onMultiWindowModeChanged(boolean); method public boolean onNavigateUp(); method public boolean onNavigateUpFromChild(android.app.Activity); @@ -4609,6 +4610,7 @@ package android.app { method public void onDestroyOptionsMenu(); method public void onDestroyView(); method public void onDetach(); + method public android.view.LayoutInflater onGetLayoutInflater(android.os.Bundle); method public void onHiddenChanged(boolean); method public deprecated void onInflate(android.util.AttributeSet, android.os.Bundle); method public void onInflate(android.content.Context, android.util.AttributeSet, android.os.Bundle); @@ -4763,6 +4765,7 @@ package android.app { method public abstract android.app.FragmentManager.BackStackEntry getBackStackEntryAt(int); method public abstract int getBackStackEntryCount(); method public abstract android.app.Fragment getFragment(android.os.Bundle, java.lang.String); + method public abstract java.util.Collection<android.app.Fragment> getFragments(); method public abstract android.app.Fragment getPrimaryNavigationFragment(); method public void invalidateOptionsMenu(); method public abstract boolean isDestroyed(); @@ -5583,7 +5586,7 @@ package android.app { method public boolean removeAutomaticZenRule(java.lang.String); method public final void setInterruptionFilter(int); method public void setNotificationPolicy(android.app.NotificationManager.Policy); - method public android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification); + method public deprecated android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification); method public boolean updateAutomaticZenRule(java.lang.String, android.app.AutomaticZenRule); field public static final java.lang.String ACTION_INTERRUPTION_FILTER_CHANGED = "android.app.action.INTERRUPTION_FILTER_CHANGED"; field public static final java.lang.String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED"; @@ -5638,6 +5641,7 @@ package android.app { method public java.lang.String getCreatorPackage(); method public int getCreatorUid(); method public android.os.UserHandle getCreatorUserHandle(); + method public static android.app.PendingIntent getForegroundService(android.content.Context, int, android.content.Intent, int); method public android.content.IntentSender getIntentSender(); method public static android.app.PendingIntent getService(android.content.Context, int, android.content.Intent, int); method public deprecated java.lang.String getTargetPackage(); @@ -7138,7 +7142,6 @@ package android.bluetooth { method public static synchronized android.bluetooth.BluetoothAdapter getDefaultAdapter(); method public int getLeMaximumAdvertisingDataLength(); method public java.lang.String getName(); - method public android.bluetooth.le.PeriodicAdvertisingManager getPeriodicAdvertisingManager(); method public int getProfileConnectionState(int); method public boolean getProfileProxy(android.content.Context, android.bluetooth.BluetoothProfile.ServiceListener, int); method public android.bluetooth.BluetoothDevice getRemoteDevice(java.lang.String); @@ -8027,21 +8030,6 @@ package android.bluetooth.le { method public void stopScan(android.bluetooth.le.ScanCallback); } - public abstract class PeriodicAdvertisingCallback { - ctor public PeriodicAdvertisingCallback(); - method public void onPeriodicAdvertisingReport(android.bluetooth.le.PeriodicAdvertisingReport); - method public void onSyncEstablished(int, android.bluetooth.BluetoothDevice, int, int, int, int); - method public void onSyncLost(int); - field public static final int SYNC_NO_RESOURCES = 2; // 0x2 - field public static final int SYNC_NO_RESPONSE = 1; // 0x1 - } - - public final class PeriodicAdvertisingManager { - method public void registerSync(android.bluetooth.le.ScanResult, int, int, android.bluetooth.le.PeriodicAdvertisingCallback); - method public void registerSync(android.bluetooth.le.ScanResult, int, int, android.bluetooth.le.PeriodicAdvertisingCallback, android.os.Handler); - method public void unregisterSync(android.bluetooth.le.PeriodicAdvertisingCallback); - } - public final class PeriodicAdvertisingParameters implements android.os.Parcelable { method public int describeContents(); method public boolean getEnable(); @@ -8059,21 +8047,6 @@ package android.bluetooth.le { method public android.bluetooth.le.PeriodicAdvertisingParameters.Builder setInterval(int); } - public final class PeriodicAdvertisingReport implements android.os.Parcelable { - ctor public PeriodicAdvertisingReport(int, int, int, int, android.bluetooth.le.ScanRecord); - method public int describeContents(); - method public android.bluetooth.le.ScanRecord getData(); - method public int getDataStatus(); - method public int getRssi(); - method public int getSyncHandle(); - method public long getTimestampNanos(); - method public int getTxPower(); - method public void writeToParcel(android.os.Parcel, int); - field public static final android.os.Parcelable.Creator<android.bluetooth.le.PeriodicAdvertisingReport> CREATOR; - field public static final int DATA_COMPLETE = 0; // 0x0 - field public static final int DATA_INCOMPLETE_TRUNCATED = 2; // 0x2 - } - public abstract class ScanCallback { ctor public ScanCallback(); method public void onBatchScanResults(java.util.List<android.bluetooth.le.ScanResult>); @@ -8855,6 +8828,7 @@ package android.content { method public abstract void startActivities(android.content.Intent[], android.os.Bundle); method public abstract void startActivity(android.content.Intent); method public abstract void startActivity(android.content.Intent, android.os.Bundle); + method public abstract android.content.ComponentName startForegroundService(android.content.Intent); method public abstract boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle); method public abstract void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException; method public abstract void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException; @@ -9046,6 +9020,7 @@ package android.content { method public void startActivities(android.content.Intent[], android.os.Bundle); method public void startActivity(android.content.Intent); method public void startActivity(android.content.Intent, android.os.Bundle); + method public android.content.ComponentName startForegroundService(android.content.Intent); method public boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle); method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException; method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException; @@ -12695,7 +12670,7 @@ package android.graphics { enum_constant public static final android.graphics.Canvas.VertexMode TRIANGLE_STRIP; } - public class Color { + public final class Color { ctor public Color(); method public static int HSVToColor(float[]); method public static int HSVToColor(int, float[]); @@ -12720,6 +12695,7 @@ package android.graphics { method public float getComponent(int); method public int getComponentCount(); method public float[] getComponents(); + method public float[] getComponents(float[]); method public android.graphics.ColorSpace.Model getModel(); method public float green(); method public static float green(long); @@ -20889,7 +20865,8 @@ package android.media { method public int getContentType(); method public int getFlags(); method public int getUsage(); - method public static int getVolumeControlStream(android.media.AudioAttributes); + method public static deprecated int getVolumeControlStream(android.media.AudioAttributes); + method public int getVolumeControlStream(); method public void writeToParcel(android.os.Parcel, int); field public static final int CONTENT_TYPE_MOVIE = 3; // 0x3 field public static final int CONTENT_TYPE_MUSIC = 2; // 0x2 @@ -21818,23 +21795,23 @@ package android.media { } public final class MediaCas { - ctor public MediaCas(int) throws android.media.UnsupportedCasException; + ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException; method public void closeSession(byte[]); method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins(); method public static boolean isSystemIdSupported(int); - method public byte[] openSession(int); - method public byte[] openSession(int, int); - method public void processEcm(byte[], byte[], int, int); - method public void processEcm(byte[], byte[]); - method public void processEmm(byte[], int, int); - method public void processEmm(byte[]); - method public void provision(java.lang.String); - method public void refreshEntitlements(int, byte[]); + method public byte[] openSession(int) throws android.media.MediaCasException; + method public byte[] openSession(int, int) throws android.media.MediaCasException; + method public void processEcm(byte[], byte[], int, int) throws android.media.MediaCasException; + method public void processEcm(byte[], byte[]) throws android.media.MediaCasException; + method public void processEmm(byte[], int, int) throws android.media.MediaCasException; + method public void processEmm(byte[]) throws android.media.MediaCasException; + method public void provision(java.lang.String) throws android.media.MediaCasException; + method public void refreshEntitlements(int, byte[]) throws android.media.MediaCasException; method public void release(); - method public void sendEvent(int, int, byte[]); + method public void sendEvent(int, int, byte[]) throws android.media.MediaCasException; method public void setEventListener(android.media.MediaCas.EventListener, android.os.Handler); - method public void setPrivateData(byte[]); - method public void setSessionPrivateData(byte[], byte[]); + method public void setPrivateData(byte[]) throws android.media.MediaCasException; + method public void setSessionPrivateData(byte[], byte[]) throws android.media.MediaCasException; } public static abstract interface MediaCas.EventListener { @@ -21847,7 +21824,22 @@ package android.media { } public class MediaCasException extends java.lang.Exception { - ctor public MediaCasException(java.lang.String); + } + + public static final class MediaCasException.DeniedByServerException extends android.media.MediaCasException { + } + + public static final class MediaCasException.NotProvisionedException extends android.media.MediaCasException { + } + + public static final class MediaCasException.ResourceBusyException extends android.media.MediaCasException { + } + + public static final class MediaCasException.UnsupportedCasException extends android.media.MediaCasException { + } + + public class MediaCasStateException extends java.lang.IllegalStateException { + method public java.lang.String getDiagnosticInfo(); } public final class MediaCodec { @@ -22275,7 +22267,7 @@ package android.media { } public final class MediaDescrambler { - ctor public MediaDescrambler(int) throws android.media.UnsupportedCasException; + ctor public MediaDescrambler(int) throws android.media.MediaCasException.UnsupportedCasException; method public final int descramble(java.nio.ByteBuffer, int, java.nio.ByteBuffer, int, android.media.MediaCodec.CryptoInfo); method public final void release(); method public final boolean requiresSecureDecoderComponent(java.lang.String); @@ -23586,10 +23578,6 @@ package android.media { field public static final int TONE_SUP_RINGTONE = 23; // 0x17 } - public final class UnsupportedCasException extends android.media.MediaCasException { - ctor public UnsupportedCasException(java.lang.String); - } - public final class UnsupportedSchemeException extends android.media.MediaDrmException { ctor public UnsupportedSchemeException(java.lang.String); } @@ -24326,9 +24314,9 @@ package android.media.session { method public void setRepeatMode(int); method public void setSessionActivity(android.app.PendingIntent); method public void setShuffleModeEnabled(boolean); - field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1 + field public static final deprecated int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1 field public static final int FLAG_HANDLES_QUEUE_COMMANDS = 4; // 0x4 - field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2 + field public static final deprecated int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2 } public static abstract class MediaSession.Callback { @@ -24548,6 +24536,7 @@ package android.media.tv { field public static final java.lang.String COLUMN_REVIEW_RATING_STYLE = "review_rating_style"; field public static final java.lang.String COLUMN_STARTING_PRICE = "starting_price"; field public static final java.lang.String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio"; + field public static final java.lang.String COLUMN_TRANSIENT = "transient"; field public static final java.lang.String COLUMN_TYPE = "type"; field public static final java.lang.String INTERACTION_TYPE_FANS = "INTERACTION_TYPE_FANS"; field public static final java.lang.String INTERACTION_TYPE_FOLLOWERS = "INTERACTION_TYPE_FOLLOWERS"; @@ -24625,6 +24614,7 @@ package android.media.tv { field public static final java.lang.String COLUMN_SEARCHABLE = "searchable"; field public static final java.lang.String COLUMN_SERVICE_ID = "service_id"; field public static final java.lang.String COLUMN_SERVICE_TYPE = "service_type"; + field public static final java.lang.String COLUMN_TRANSIENT = "transient"; field public static final java.lang.String COLUMN_TRANSPORT_STREAM_ID = "transport_stream_id"; field public static final java.lang.String COLUMN_TYPE = "type"; field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number"; @@ -25408,7 +25398,7 @@ package android.net { method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket() throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException; method public void removeTransportModeTransform(java.net.Socket, android.net.IpSecTransform); method public void removeTransportModeTransform(java.net.DatagramSocket, android.net.IpSecTransform); - method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException; + method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(int, java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException; field public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; // 0x0 } @@ -26659,7 +26649,6 @@ package android.net.wifi.aware { ctor public PublishConfig.Builder(); method public android.net.wifi.aware.PublishConfig build(); method public android.net.wifi.aware.PublishConfig.Builder setMatchFilter(java.util.List<byte[]>); - method public android.net.wifi.aware.PublishConfig.Builder setPublishCount(int); method public android.net.wifi.aware.PublishConfig.Builder setPublishType(int); method public android.net.wifi.aware.PublishConfig.Builder setServiceName(java.lang.String); method public android.net.wifi.aware.PublishConfig.Builder setServiceSpecificInfo(byte[]); @@ -26688,7 +26677,6 @@ package android.net.wifi.aware { method public android.net.wifi.aware.SubscribeConfig.Builder setMatchStyle(int); method public android.net.wifi.aware.SubscribeConfig.Builder setServiceName(java.lang.String); method public android.net.wifi.aware.SubscribeConfig.Builder setServiceSpecificInfo(byte[]); - method public android.net.wifi.aware.SubscribeConfig.Builder setSubscribeCount(int); method public android.net.wifi.aware.SubscribeConfig.Builder setSubscribeType(int); method public android.net.wifi.aware.SubscribeConfig.Builder setTerminateNotificationEnabled(boolean); method public android.net.wifi.aware.SubscribeConfig.Builder setTtlSec(int); @@ -31884,6 +31872,7 @@ package android.os.storage { method public boolean isObbMounted(java.lang.String); method public boolean mountObb(java.lang.String, java.lang.String, android.os.storage.OnObbStateChangeListener); method public android.os.ParcelFileDescriptor openProxyFileDescriptor(int, android.os.ProxyFileDescriptorCallback) throws java.io.IOException; + method public android.os.ParcelFileDescriptor openProxyFileDescriptor(int, android.os.ProxyFileDescriptorCallback, android.os.Handler) throws java.io.IOException; method public void setCacheBehaviorGroup(java.io.File, boolean) throws java.io.IOException; method public void setCacheBehaviorTombstone(java.io.File, boolean) throws java.io.IOException; method public boolean unmountObb(java.lang.String, boolean, android.os.storage.OnObbStateChangeListener); @@ -32032,6 +32021,7 @@ package android.preference { method public int getWidgetLayoutResource(); method public boolean hasKey(); method public boolean isEnabled(); + method public boolean isIconSpaceReserved(); method public boolean isPersistent(); method public boolean isRecycleEnabled(); method public boolean isSelectable(); @@ -32066,6 +32056,7 @@ package android.preference { method public void setFragment(java.lang.String); method public void setIcon(android.graphics.drawable.Drawable); method public void setIcon(int); + method public void setIconSpaceReserved(boolean); method public void setIntent(android.content.Intent); method public void setKey(java.lang.String); method public void setLayoutResource(int); @@ -34858,7 +34849,7 @@ package android.provider { field public static final java.lang.String WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN = "wifi_device_owner_configs_lockdown"; field public static final java.lang.String WIFI_MAX_DHCP_RETRY_COUNT = "wifi_max_dhcp_retry_count"; field public static final java.lang.String WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS = "wifi_mobile_data_transition_wakelock_timeout_ms"; - field public static final java.lang.String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = "wifi_networks_available_notification_on"; + field public static final deprecated java.lang.String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = "wifi_networks_available_notification_on"; field public static final java.lang.String WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY = "wifi_networks_available_repeat_delay"; field public static final java.lang.String WIFI_NUM_OPEN_NETWORKS_KEPT = "wifi_num_open_networks_kept"; field public static final java.lang.String WIFI_ON = "wifi_on"; @@ -37842,6 +37833,7 @@ package android.speech.tts { method public void onRangeStart(java.lang.String, int, int, int); method public abstract void onStart(java.lang.String); method public void onStop(java.lang.String, boolean); + method public deprecated void onUtteranceRangeStart(java.lang.String, int, int); } public class Voice implements android.os.Parcelable { @@ -39363,6 +39355,7 @@ package android.telephony { field public static final java.lang.String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array"; field public static final java.lang.String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool"; field public static final java.lang.String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool"; + field public static final java.lang.String KEY_HIDE_ENHANCED_4G_LTE_BOOL = "hide_enhanced_4g_lte_bool"; field public static final java.lang.String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool"; field public static final java.lang.String KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL = "hide_preferred_network_type_bool"; field public static final java.lang.String KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool"; @@ -40659,6 +40652,7 @@ package android.test.mock { method public void startActivities(android.content.Intent[], android.os.Bundle); method public void startActivity(android.content.Intent); method public void startActivity(android.content.Intent, android.os.Bundle); + method public android.content.ComponentName startForegroundService(android.content.Intent); method public boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle); method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException; method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException; @@ -41062,9 +41056,9 @@ package android.text { public static final class FontConfig.Font implements android.os.Parcelable { method public int describeContents(); method public android.text.FontConfig.Axis[] getAxes(); - method public android.os.ParcelFileDescriptor getFd(); method public java.lang.String getFontName(); method public int getTtcIndex(); + method public android.net.Uri getUri(); method public int getWeight(); method public boolean isItalic(); method public void writeToParcel(android.os.Parcel, int); @@ -45141,8 +45135,8 @@ package android.view { method public void addTouchables(java.util.ArrayList<android.view.View>); method public android.view.ViewPropertyAnimator animate(); method public void announceForAccessibility(java.lang.CharSequence); - method public boolean autofill(android.view.autofill.AutofillValue); - method public boolean autofill(android.util.SparseArray<android.view.autofill.AutofillValue>); + method public void autofill(android.view.autofill.AutofillValue); + method public void autofill(android.util.SparseArray<android.view.autofill.AutofillValue>); method protected boolean awakenScrollBars(); method protected boolean awakenScrollBars(int); method protected boolean awakenScrollBars(int, boolean); @@ -45476,7 +45470,7 @@ package android.view { method public boolean onKeyUp(int, android.view.KeyEvent); method protected void onLayout(boolean, int, int, int, int); method protected void onMeasure(int, int); - method public void onMovedToDisplay(int); + method public void onMovedToDisplay(int, android.content.res.Configuration); method protected void onOverScrolled(int, int, boolean, boolean); method public void onPointerCaptureChange(boolean); method public void onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent); @@ -45977,6 +45971,7 @@ package android.view { method public static deprecated int getEdgeSlop(); method public static deprecated int getFadingEdgeLength(); method public static deprecated long getGlobalActionKeyTimeout(); + method public float getScaledHorizontalScrollFactor(); method public static int getJumpTapTimeout(); method public static int getKeyRepeatDelay(); method public static int getKeyRepeatTimeout(); @@ -45995,7 +45990,6 @@ package android.view { method public int getScaledOverscrollDistance(); method public int getScaledPagingTouchSlop(); method public int getScaledScrollBarSize(); - method public int getScaledScrollFactor(); method public int getScaledTouchSlop(); method public int getScaledWindowTouchSlop(); method public static int getScrollBarFadeDuration(); @@ -46004,6 +45998,7 @@ package android.view { method public static float getScrollFriction(); method public static int getTapTimeout(); method public static deprecated int getTouchSlop(); + method public float getScaledVerticalScrollFactor(); method public static deprecated int getWindowTouchSlop(); method public static long getZoomControlsTimeout(); method public boolean hasPermanentMenuKey(); @@ -48811,6 +48806,7 @@ package android.webkit { method public int getRendererRequestedPriority(); method public deprecated float getScale(); method public android.webkit.WebSettings getSettings(); + method public android.view.textclassifier.TextClassifier getTextClassifier(); method public java.lang.String getTitle(); method public java.lang.String getUrl(); method public android.webkit.WebChromeClient getWebChromeClient(); @@ -48857,6 +48853,7 @@ package android.webkit { method public void setNetworkAvailable(boolean); method public deprecated void setPictureListener(android.webkit.WebView.PictureListener); method public void setRendererPriorityPolicy(int, boolean); + method public void setTextClassifier(android.view.textclassifier.TextClassifier); method public deprecated void setVerticalScrollbarOverlay(boolean); method public void setWebChromeClient(android.webkit.WebChromeClient); method public static void setWebContentsDebuggingEnabled(boolean); diff --git a/api/removed.txt b/api/removed.txt index 75da976d1b64..fa62e056757c 100644 --- a/api/removed.txt +++ b/api/removed.txt @@ -374,6 +374,10 @@ package android.view { method protected void initializeScrollbars(android.content.res.TypedArray); } + public class ViewConfiguration { + method public int getScaledScrollFactor(); + } + public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable { field public static final int TYPE_KEYGUARD = 2004; // 0x7d4 } diff --git a/api/system-current.txt b/api/system-current.txt index 48b878ec699f..fd2140b1c32e 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -53,6 +53,7 @@ package android { field public static final java.lang.String BIND_PRINT_SERVICE = "android.permission.BIND_PRINT_SERVICE"; field public static final java.lang.String BIND_QUICK_SETTINGS_TILE = "android.permission.BIND_QUICK_SETTINGS_TILE"; field public static final java.lang.String BIND_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS"; + field public static final java.lang.String BIND_RESOLVER_RANKER_SERVICE = "android.permission.BIND_RESOLVER_RANKER_SERVICE"; field public static final java.lang.String BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE = "android.permission.BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE"; field public static final java.lang.String BIND_SCREENING_SERVICE = "android.permission.BIND_SCREENING_SERVICE"; field public static final java.lang.String BIND_TELECOM_CONNECTION_SERVICE = "android.permission.BIND_TELECOM_CONNECTION_SERVICE"; @@ -93,6 +94,7 @@ package android { field public static final java.lang.String CLEAR_APP_CACHE = "android.permission.CLEAR_APP_CACHE"; field public static final java.lang.String CLEAR_APP_USER_DATA = "android.permission.CLEAR_APP_USER_DATA"; field public static final java.lang.String CONNECTIVITY_INTERNAL = "android.permission.CONNECTIVITY_INTERNAL"; + field public static final java.lang.String CONNECTIVITY_USE_RESTRICTED_NETWORKS = "android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS"; field public static final java.lang.String CONTROL_INCALL_EXPERIENCE = "android.permission.CONTROL_INCALL_EXPERIENCE"; field public static final java.lang.String CONTROL_LOCATION_UPDATES = "android.permission.CONTROL_LOCATION_UPDATES"; field public static final java.lang.String CONTROL_VPN = "android.permission.CONTROL_VPN"; @@ -809,6 +811,7 @@ package android { field public static final int hyphenationFrequency = 16843998; // 0x10104de field public static final int icon = 16842754; // 0x1010002 field public static final int iconPreview = 16843337; // 0x1010249 + field public static final int iconSpaceReserved = 16844132; // 0x1010564 field public static final int iconTint = 16844129; // 0x1010561 field public static final int iconTintMode = 16844130; // 0x1010562 field public static final int iconifiedByDefault = 16843514; // 0x10102fa @@ -3798,7 +3801,7 @@ package android.app { method public void onLowMemory(); method public boolean onMenuItemSelected(int, android.view.MenuItem); method public boolean onMenuOpened(int, android.view.Menu); - method public void onMovedToDisplay(int); + method public void onMovedToDisplay(int, android.content.res.Configuration); method public void onMultiWindowModeChanged(boolean); method public boolean onNavigateUp(); method public boolean onNavigateUpFromChild(android.app.Activity); @@ -4767,6 +4770,7 @@ package android.app { method public void onDestroyOptionsMenu(); method public void onDestroyView(); method public void onDetach(); + method public android.view.LayoutInflater onGetLayoutInflater(android.os.Bundle); method public void onHiddenChanged(boolean); method public deprecated void onInflate(android.util.AttributeSet, android.os.Bundle); method public void onInflate(android.content.Context, android.util.AttributeSet, android.os.Bundle); @@ -4921,6 +4925,7 @@ package android.app { method public abstract android.app.FragmentManager.BackStackEntry getBackStackEntryAt(int); method public abstract int getBackStackEntryCount(); method public abstract android.app.Fragment getFragment(android.os.Bundle, java.lang.String); + method public abstract java.util.Collection<android.app.Fragment> getFragments(); method public abstract android.app.Fragment getPrimaryNavigationFragment(); method public void invalidateOptionsMenu(); method public abstract boolean isDestroyed(); @@ -5308,6 +5313,7 @@ package android.app { field public static final int DEFAULT_LIGHTS = 4; // 0x4 field public static final int DEFAULT_SOUND = 1; // 0x1 field public static final int DEFAULT_VIBRATE = 2; // 0x2 + field public static final java.lang.String EXTRA_ALLOW_DURING_SETUP = "android.allowDuringSetup"; field public static final java.lang.String EXTRA_AUDIO_CONTENTS_URI = "android.audioContents"; field public static final java.lang.String EXTRA_BACKGROUND_IMAGE_URI = "android.backgroundImageUri"; field public static final java.lang.String EXTRA_BIG_TEXT = "android.bigText"; @@ -5775,7 +5781,7 @@ package android.app { method public boolean removeAutomaticZenRule(java.lang.String); method public final void setInterruptionFilter(int); method public void setNotificationPolicy(android.app.NotificationManager.Policy); - method public android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification); + method public deprecated android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification); method public boolean updateAutomaticZenRule(java.lang.String, android.app.AutomaticZenRule); field public static final java.lang.String ACTION_INTERRUPTION_FILTER_CHANGED = "android.app.action.INTERRUPTION_FILTER_CHANGED"; field public static final java.lang.String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED"; @@ -5830,6 +5836,7 @@ package android.app { method public java.lang.String getCreatorPackage(); method public int getCreatorUid(); method public android.os.UserHandle getCreatorUserHandle(); + method public static android.app.PendingIntent getForegroundService(android.content.Context, int, android.content.Intent, int); method public android.content.IntentSender getIntentSender(); method public static android.app.PendingIntent getService(android.content.Context, int, android.content.Intent, int); method public deprecated java.lang.String getTargetPackage(); @@ -7596,7 +7603,6 @@ package android.bluetooth { method public static synchronized android.bluetooth.BluetoothAdapter getDefaultAdapter(); method public int getLeMaximumAdvertisingDataLength(); method public java.lang.String getName(); - method public android.bluetooth.le.PeriodicAdvertisingManager getPeriodicAdvertisingManager(); method public int getProfileConnectionState(int); method public boolean getProfileProxy(android.content.Context, android.bluetooth.BluetoothProfile.ServiceListener, int); method public android.bluetooth.BluetoothDevice getRemoteDevice(java.lang.String); @@ -8494,21 +8500,6 @@ package android.bluetooth.le { method public void stopScan(android.bluetooth.le.ScanCallback); } - public abstract class PeriodicAdvertisingCallback { - ctor public PeriodicAdvertisingCallback(); - method public void onPeriodicAdvertisingReport(android.bluetooth.le.PeriodicAdvertisingReport); - method public void onSyncEstablished(int, android.bluetooth.BluetoothDevice, int, int, int, int); - method public void onSyncLost(int); - field public static final int SYNC_NO_RESOURCES = 2; // 0x2 - field public static final int SYNC_NO_RESPONSE = 1; // 0x1 - } - - public final class PeriodicAdvertisingManager { - method public void registerSync(android.bluetooth.le.ScanResult, int, int, android.bluetooth.le.PeriodicAdvertisingCallback); - method public void registerSync(android.bluetooth.le.ScanResult, int, int, android.bluetooth.le.PeriodicAdvertisingCallback, android.os.Handler); - method public void unregisterSync(android.bluetooth.le.PeriodicAdvertisingCallback); - } - public final class PeriodicAdvertisingParameters implements android.os.Parcelable { method public int describeContents(); method public boolean getEnable(); @@ -8526,21 +8517,6 @@ package android.bluetooth.le { method public android.bluetooth.le.PeriodicAdvertisingParameters.Builder setInterval(int); } - public final class PeriodicAdvertisingReport implements android.os.Parcelable { - ctor public PeriodicAdvertisingReport(int, int, int, int, android.bluetooth.le.ScanRecord); - method public int describeContents(); - method public android.bluetooth.le.ScanRecord getData(); - method public int getDataStatus(); - method public int getRssi(); - method public int getSyncHandle(); - method public long getTimestampNanos(); - method public int getTxPower(); - method public void writeToParcel(android.os.Parcel, int); - field public static final android.os.Parcelable.Creator<android.bluetooth.le.PeriodicAdvertisingReport> CREATOR; - field public static final int DATA_COMPLETE = 0; // 0x0 - field public static final int DATA_INCOMPLETE_TRUNCATED = 2; // 0x2 - } - public final class ResultStorageDescriptor implements android.os.Parcelable { ctor public ResultStorageDescriptor(int, int, int); method public int describeContents(); @@ -9348,6 +9324,7 @@ package android.content { method public abstract void startActivities(android.content.Intent[], android.os.Bundle); method public abstract void startActivity(android.content.Intent); method public abstract void startActivity(android.content.Intent, android.os.Bundle); + method public abstract android.content.ComponentName startForegroundService(android.content.Intent); method public abstract boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle); method public abstract void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException; method public abstract void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException; @@ -9553,6 +9530,7 @@ package android.content { method public void startActivities(android.content.Intent[], android.os.Bundle); method public void startActivity(android.content.Intent); method public void startActivity(android.content.Intent, android.os.Bundle); + method public android.content.ComponentName startForegroundService(android.content.Intent); method public boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle); method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException; method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException; @@ -11171,6 +11149,7 @@ package android.content.pm { method public abstract byte[] getInstantAppCookie(); method public abstract int getInstantAppCookieMaxSize(); method public abstract android.graphics.drawable.Drawable getInstantAppIcon(java.lang.String); + method public abstract android.content.ComponentName getInstantAppResolverSettingsComponent(); method public abstract java.util.List<android.content.pm.InstantAppInfo> getInstantApps(); method public abstract android.content.pm.InstrumentationInfo getInstrumentationInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException; method public abstract java.util.List<android.content.pm.IntentFilterVerificationInfo> getIntentFilterVerifications(java.lang.String); @@ -11420,6 +11399,7 @@ package android.content.pm { field public static final int MATCH_DIRECT_BOOT_UNAWARE = 262144; // 0x40000 field public static final int MATCH_DISABLED_COMPONENTS = 512; // 0x200 field public static final int MATCH_DISABLED_UNTIL_USED_COMPONENTS = 32768; // 0x8000 + field public static final int MATCH_FACTORY_ONLY = 2097152; // 0x200000 field public static final int MATCH_INSTANT = 8388608; // 0x800000 field public static final int MATCH_SYSTEM_ONLY = 1048576; // 0x100000 field public static final int MATCH_UNINSTALLED_PACKAGES = 8192; // 0x2000 @@ -13420,7 +13400,7 @@ package android.graphics { enum_constant public static final android.graphics.Canvas.VertexMode TRIANGLE_STRIP; } - public class Color { + public final class Color { ctor public Color(); method public static int HSVToColor(float[]); method public static int HSVToColor(int, float[]); @@ -13445,6 +13425,7 @@ package android.graphics { method public float getComponent(int); method public int getComponentCount(); method public float[] getComponents(); + method public float[] getComponents(float[]); method public android.graphics.ColorSpace.Model getModel(); method public float green(); method public static float green(long); @@ -22622,7 +22603,8 @@ package android.media { method public int getContentType(); method public int getFlags(); method public int getUsage(); - method public static int getVolumeControlStream(android.media.AudioAttributes); + method public static deprecated int getVolumeControlStream(android.media.AudioAttributes); + method public int getVolumeControlStream(); method public void writeToParcel(android.os.Parcel, int); field public static final int CONTENT_TYPE_MOVIE = 3; // 0x3 field public static final int CONTENT_TYPE_MUSIC = 2; // 0x2 @@ -23604,23 +23586,23 @@ package android.media { } public final class MediaCas { - ctor public MediaCas(int) throws android.media.UnsupportedCasException; + ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException; method public void closeSession(byte[]); method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins(); method public static boolean isSystemIdSupported(int); - method public byte[] openSession(int); - method public byte[] openSession(int, int); - method public void processEcm(byte[], byte[], int, int); - method public void processEcm(byte[], byte[]); - method public void processEmm(byte[], int, int); - method public void processEmm(byte[]); - method public void provision(java.lang.String); - method public void refreshEntitlements(int, byte[]); + method public byte[] openSession(int) throws android.media.MediaCasException; + method public byte[] openSession(int, int) throws android.media.MediaCasException; + method public void processEcm(byte[], byte[], int, int) throws android.media.MediaCasException; + method public void processEcm(byte[], byte[]) throws android.media.MediaCasException; + method public void processEmm(byte[], int, int) throws android.media.MediaCasException; + method public void processEmm(byte[]) throws android.media.MediaCasException; + method public void provision(java.lang.String) throws android.media.MediaCasException; + method public void refreshEntitlements(int, byte[]) throws android.media.MediaCasException; method public void release(); - method public void sendEvent(int, int, byte[]); + method public void sendEvent(int, int, byte[]) throws android.media.MediaCasException; method public void setEventListener(android.media.MediaCas.EventListener, android.os.Handler); - method public void setPrivateData(byte[]); - method public void setSessionPrivateData(byte[], byte[]); + method public void setPrivateData(byte[]) throws android.media.MediaCasException; + method public void setSessionPrivateData(byte[], byte[]) throws android.media.MediaCasException; } public static abstract interface MediaCas.EventListener { @@ -23633,7 +23615,22 @@ package android.media { } public class MediaCasException extends java.lang.Exception { - ctor public MediaCasException(java.lang.String); + } + + public static final class MediaCasException.DeniedByServerException extends android.media.MediaCasException { + } + + public static final class MediaCasException.NotProvisionedException extends android.media.MediaCasException { + } + + public static final class MediaCasException.ResourceBusyException extends android.media.MediaCasException { + } + + public static final class MediaCasException.UnsupportedCasException extends android.media.MediaCasException { + } + + public class MediaCasStateException extends java.lang.IllegalStateException { + method public java.lang.String getDiagnosticInfo(); } public final class MediaCodec { @@ -24061,7 +24058,7 @@ package android.media { } public final class MediaDescrambler { - ctor public MediaDescrambler(int) throws android.media.UnsupportedCasException; + ctor public MediaDescrambler(int) throws android.media.MediaCasException.UnsupportedCasException; method public final int descramble(java.nio.ByteBuffer, int, java.nio.ByteBuffer, int, android.media.MediaCodec.CryptoInfo); method public final void release(); method public final boolean requiresSecureDecoderComponent(java.lang.String); @@ -25383,10 +25380,6 @@ package android.media { field public static final int TONE_SUP_RINGTONE = 23; // 0x17 } - public final class UnsupportedCasException extends android.media.MediaCasException { - ctor public UnsupportedCasException(java.lang.String); - } - public final class UnsupportedSchemeException extends android.media.MediaDrmException { ctor public UnsupportedSchemeException(java.lang.String); } @@ -26195,9 +26188,9 @@ package android.media.session { method public void setRepeatMode(int); method public void setSessionActivity(android.app.PendingIntent); method public void setShuffleModeEnabled(boolean); - field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1 + field public static final deprecated int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1 field public static final int FLAG_HANDLES_QUEUE_COMMANDS = 4; // 0x4 - field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2 + field public static final deprecated int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2 } public static abstract class MediaSession.Callback { @@ -27536,7 +27529,7 @@ package android.net { method public void removeTransportModeTransform(java.net.Socket, android.net.IpSecTransform); method public void removeTransportModeTransform(java.net.DatagramSocket, android.net.IpSecTransform); method public void removeTunnelModeTransform(android.net.Network, android.net.IpSecTransform); - method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException; + method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(int, java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException; field public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; // 0x0 } @@ -29350,7 +29343,6 @@ package android.net.wifi.aware { ctor public PublishConfig.Builder(); method public android.net.wifi.aware.PublishConfig build(); method public android.net.wifi.aware.PublishConfig.Builder setMatchFilter(java.util.List<byte[]>); - method public android.net.wifi.aware.PublishConfig.Builder setPublishCount(int); method public android.net.wifi.aware.PublishConfig.Builder setPublishType(int); method public android.net.wifi.aware.PublishConfig.Builder setServiceName(java.lang.String); method public android.net.wifi.aware.PublishConfig.Builder setServiceSpecificInfo(byte[]); @@ -29379,7 +29371,6 @@ package android.net.wifi.aware { method public android.net.wifi.aware.SubscribeConfig.Builder setMatchStyle(int); method public android.net.wifi.aware.SubscribeConfig.Builder setServiceName(java.lang.String); method public android.net.wifi.aware.SubscribeConfig.Builder setServiceSpecificInfo(byte[]); - method public android.net.wifi.aware.SubscribeConfig.Builder setSubscribeCount(int); method public android.net.wifi.aware.SubscribeConfig.Builder setSubscribeType(int); method public android.net.wifi.aware.SubscribeConfig.Builder setTerminateNotificationEnabled(boolean); method public android.net.wifi.aware.SubscribeConfig.Builder setTtlSec(int); @@ -34716,6 +34707,7 @@ package android.os.storage { method public boolean isObbMounted(java.lang.String); method public boolean mountObb(java.lang.String, java.lang.String, android.os.storage.OnObbStateChangeListener); method public android.os.ParcelFileDescriptor openProxyFileDescriptor(int, android.os.ProxyFileDescriptorCallback) throws java.io.IOException; + method public android.os.ParcelFileDescriptor openProxyFileDescriptor(int, android.os.ProxyFileDescriptorCallback, android.os.Handler) throws java.io.IOException; method public void setCacheBehaviorGroup(java.io.File, boolean) throws java.io.IOException; method public void setCacheBehaviorTombstone(java.io.File, boolean) throws java.io.IOException; method public boolean unmountObb(java.lang.String, boolean, android.os.storage.OnObbStateChangeListener); @@ -34876,6 +34868,7 @@ package android.preference { method public int getWidgetLayoutResource(); method public boolean hasKey(); method public boolean isEnabled(); + method public boolean isIconSpaceReserved(); method public boolean isPersistent(); method public boolean isRecycleEnabled(); method public boolean isSelectable(); @@ -34910,6 +34903,7 @@ package android.preference { method public void setFragment(java.lang.String); method public void setIcon(android.graphics.drawable.Drawable); method public void setIcon(int); + method public void setIconSpaceReserved(boolean); method public void setIntent(android.content.Intent); method public void setKey(java.lang.String); method public void setLayoutResource(int); @@ -37748,7 +37742,6 @@ package android.provider { field public static final java.lang.String ACTION_CAPTIONING_SETTINGS = "android.settings.CAPTIONING_SETTINGS"; field public static final java.lang.String ACTION_CAST_SETTINGS = "android.settings.CAST_SETTINGS"; field public static final java.lang.String ACTION_CHANNEL_NOTIFICATION_SETTINGS = "android.settings.CHANNEL_NOTIFICATION_SETTINGS"; - field public static final java.lang.String ACTION_CONFIGURE_WIFI_SETTINGS = "android.settings.CONFIGURE_WIFI_SETTINGS"; field public static final java.lang.String ACTION_DATA_ROAMING_SETTINGS = "android.settings.DATA_ROAMING_SETTINGS"; field public static final java.lang.String ACTION_DATE_SETTINGS = "android.settings.DATE_SETTINGS"; field public static final java.lang.String ACTION_DEVICE_INFO_SETTINGS = "android.settings.DEVICE_INFO_SETTINGS"; @@ -37798,7 +37791,6 @@ package android.provider { field public static final java.lang.String ACTION_VR_LISTENER_SETTINGS = "android.settings.VR_LISTENER_SETTINGS"; field public static final java.lang.String ACTION_WEBVIEW_SETTINGS = "android.settings.WEBVIEW_SETTINGS"; field public static final java.lang.String ACTION_WIFI_IP_SETTINGS = "android.settings.WIFI_IP_SETTINGS"; - field public static final java.lang.String ACTION_WIFI_SAVED_NETWORK_SETTINGS = "android.settings.WIFI_SAVED_NETWORK_SETTINGS"; field public static final java.lang.String ACTION_WIFI_SETTINGS = "android.settings.WIFI_SETTINGS"; field public static final java.lang.String ACTION_WIRELESS_SETTINGS = "android.settings.WIRELESS_SETTINGS"; field public static final java.lang.String ACTION_ZEN_MODE_PRIORITY_SETTINGS = "android.settings.ZEN_MODE_PRIORITY_SETTINGS"; @@ -37871,7 +37863,7 @@ package android.provider { field public static final java.lang.String WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN = "wifi_device_owner_configs_lockdown"; field public static final java.lang.String WIFI_MAX_DHCP_RETRY_COUNT = "wifi_max_dhcp_retry_count"; field public static final java.lang.String WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS = "wifi_mobile_data_transition_wakelock_timeout_ms"; - field public static final java.lang.String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = "wifi_networks_available_notification_on"; + field public static final deprecated java.lang.String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = "wifi_networks_available_notification_on"; field public static final java.lang.String WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY = "wifi_networks_available_repeat_delay"; field public static final java.lang.String WIFI_NUM_OPEN_NETWORKS_KEPT = "wifi_num_open_networks_kept"; field public static final java.lang.String WIFI_ON = "wifi_on"; @@ -40430,6 +40422,36 @@ package android.service.quicksettings { } +package android.service.resolver { + + public abstract class ResolverRankerService extends android.app.Service { + ctor public ResolverRankerService(); + method public android.os.IBinder onBind(android.content.Intent); + method public void onPredictSharingProbabilities(java.util.List<android.service.resolver.ResolverTarget>); + method public void onTrainRankingModel(java.util.List<android.service.resolver.ResolverTarget>, int); + field public static final java.lang.String BIND_PERMISSION = "android.permission.BIND_RESOLVER_RANKER_SERVICE"; + field public static final java.lang.String SERVICE_INTERFACE = "android.service.resolver.ResolverRankerService"; + } + + public final class ResolverTarget implements android.os.Parcelable { + ctor public ResolverTarget(); + method public int describeContents(); + method public float getChooserScore(); + method public float getLaunchScore(); + method public float getRecencyScore(); + method public float getSelectProbability(); + method public float getTimeSpentScore(); + method public void setChooserScore(float); + method public void setLaunchScore(float); + method public void setRecencyScore(float); + method public void setSelectProbability(float); + method public void setTimeSpentScore(float); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.service.resolver.ResolverTarget> CREATOR; + } + +} + package android.service.restrictions { public abstract class RestrictionsReceiver extends android.content.BroadcastReceiver { @@ -40976,6 +40998,7 @@ package android.speech.tts { method public void onRangeStart(java.lang.String, int, int, int); method public abstract void onStart(java.lang.String); method public void onStop(java.lang.String, boolean); + method public deprecated void onUtteranceRangeStart(java.lang.String, int, int); } public class Voice implements android.os.Parcelable { @@ -42717,6 +42740,7 @@ package android.telephony { field public static final java.lang.String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array"; field public static final java.lang.String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool"; field public static final java.lang.String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool"; + field public static final java.lang.String KEY_HIDE_ENHANCED_4G_LTE_BOOL = "hide_enhanced_4g_lte_bool"; field public static final java.lang.String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool"; field public static final java.lang.String KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL = "hide_preferred_network_type_bool"; field public static final java.lang.String KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool"; @@ -44097,6 +44121,7 @@ package android.test.mock { method public void startActivities(android.content.Intent[], android.os.Bundle); method public void startActivity(android.content.Intent); method public void startActivity(android.content.Intent, android.os.Bundle); + method public android.content.ComponentName startForegroundService(android.content.Intent); method public boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle); method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException; method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException; @@ -44203,6 +44228,7 @@ package android.test.mock { method public byte[] getInstantAppCookie(); method public int getInstantAppCookieMaxSize(); method public android.graphics.drawable.Drawable getInstantAppIcon(java.lang.String); + method public android.content.ComponentName getInstantAppResolverSettingsComponent(); method public java.util.List<android.content.pm.InstantAppInfo> getInstantApps(); method public android.content.pm.InstrumentationInfo getInstrumentationInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException; method public java.util.List<android.content.pm.IntentFilterVerificationInfo> getIntentFilterVerifications(java.lang.String); @@ -44516,9 +44542,9 @@ package android.text { public static final class FontConfig.Font implements android.os.Parcelable { method public int describeContents(); method public android.text.FontConfig.Axis[] getAxes(); - method public android.os.ParcelFileDescriptor getFd(); method public java.lang.String getFontName(); method public int getTtcIndex(); + method public android.net.Uri getUri(); method public int getWeight(); method public boolean isItalic(); method public void writeToParcel(android.os.Parcel, int); @@ -48596,8 +48622,8 @@ package android.view { method public void addTouchables(java.util.ArrayList<android.view.View>); method public android.view.ViewPropertyAnimator animate(); method public void announceForAccessibility(java.lang.CharSequence); - method public boolean autofill(android.view.autofill.AutofillValue); - method public boolean autofill(android.util.SparseArray<android.view.autofill.AutofillValue>); + method public void autofill(android.view.autofill.AutofillValue); + method public void autofill(android.util.SparseArray<android.view.autofill.AutofillValue>); method protected boolean awakenScrollBars(); method protected boolean awakenScrollBars(int); method protected boolean awakenScrollBars(int, boolean); @@ -48931,7 +48957,7 @@ package android.view { method public boolean onKeyUp(int, android.view.KeyEvent); method protected void onLayout(boolean, int, int, int, int); method protected void onMeasure(int, int); - method public void onMovedToDisplay(int); + method public void onMovedToDisplay(int, android.content.res.Configuration); method protected void onOverScrolled(int, int, boolean, boolean); method public void onPointerCaptureChange(boolean); method public void onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent); @@ -49432,6 +49458,7 @@ package android.view { method public static deprecated int getEdgeSlop(); method public static deprecated int getFadingEdgeLength(); method public static deprecated long getGlobalActionKeyTimeout(); + method public float getScaledHorizontalScrollFactor(); method public static int getJumpTapTimeout(); method public static int getKeyRepeatDelay(); method public static int getKeyRepeatTimeout(); @@ -49450,7 +49477,6 @@ package android.view { method public int getScaledOverscrollDistance(); method public int getScaledPagingTouchSlop(); method public int getScaledScrollBarSize(); - method public int getScaledScrollFactor(); method public int getScaledTouchSlop(); method public int getScaledWindowTouchSlop(); method public static int getScrollBarFadeDuration(); @@ -49459,6 +49485,7 @@ package android.view { method public static float getScrollFriction(); method public static int getTapTimeout(); method public static deprecated int getTouchSlop(); + method public float getScaledVerticalScrollFactor(); method public static deprecated int getWindowTouchSlop(); method public static long getZoomControlsTimeout(); method public boolean hasPermanentMenuKey(); @@ -52362,6 +52389,7 @@ package android.webkit { method public int getRendererRequestedPriority(); method public deprecated float getScale(); method public android.webkit.WebSettings getSettings(); + method public android.view.textclassifier.TextClassifier getTextClassifier(); method public java.lang.String getTitle(); method public java.lang.String getUrl(); method public android.webkit.WebChromeClient getWebChromeClient(); @@ -52409,6 +52437,7 @@ package android.webkit { method public void setNetworkAvailable(boolean); method public deprecated void setPictureListener(android.webkit.WebView.PictureListener); method public void setRendererPriorityPolicy(int, boolean); + method public void setTextClassifier(android.view.textclassifier.TextClassifier); method public deprecated void setVerticalScrollbarOverlay(boolean); method public void setWebChromeClient(android.webkit.WebChromeClient); method public static void setWebContentsDebuggingEnabled(boolean); @@ -52650,6 +52679,7 @@ package android.webkit { method public abstract float getScale(); method public abstract android.webkit.WebViewProvider.ScrollDelegate getScrollDelegate(); method public abstract android.webkit.WebSettings getSettings(); + method public default android.view.textclassifier.TextClassifier getTextClassifier(); method public abstract java.lang.String getTitle(); method public abstract java.lang.String getTouchIconUrl(); method public abstract java.lang.String getUrl(); @@ -52702,6 +52732,7 @@ package android.webkit { method public abstract void setNetworkAvailable(boolean); method public abstract void setPictureListener(android.webkit.WebView.PictureListener); method public abstract void setRendererPriorityPolicy(int, boolean); + method public default void setTextClassifier(android.view.textclassifier.TextClassifier); method public abstract void setVerticalScrollbarOverlay(boolean); method public abstract void setWebChromeClient(android.webkit.WebChromeClient); method public abstract void setWebViewClient(android.webkit.WebViewClient); diff --git a/api/system-removed.txt b/api/system-removed.txt index 3aa93982fc94..1244103ee62d 100644 --- a/api/system-removed.txt +++ b/api/system-removed.txt @@ -368,6 +368,10 @@ package android.view { method protected void initializeScrollbars(android.content.res.TypedArray); } + public class ViewConfiguration { + method public int getScaledScrollFactor(); + } + public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable { field public static final int TYPE_KEYGUARD = 2004; // 0x7d4 } diff --git a/api/test-current.txt b/api/test-current.txt index 4d8d7f2d5f84..bee9cb31efb5 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -696,6 +696,7 @@ package android { field public static final int hyphenationFrequency = 16843998; // 0x10104de field public static final int icon = 16842754; // 0x1010002 field public static final int iconPreview = 16843337; // 0x1010249 + field public static final int iconSpaceReserved = 16844132; // 0x1010564 field public static final int iconTint = 16844129; // 0x1010561 field public static final int iconTintMode = 16844130; // 0x1010562 field public static final int iconifiedByDefault = 16843514; // 0x10102fa @@ -3675,7 +3676,7 @@ package android.app { method public void onLowMemory(); method public boolean onMenuItemSelected(int, android.view.MenuItem); method public boolean onMenuOpened(int, android.view.Menu); - method public void onMovedToDisplay(int); + method public void onMovedToDisplay(int, android.content.res.Configuration); method public void onMultiWindowModeChanged(boolean); method public boolean onNavigateUp(); method public boolean onNavigateUpFromChild(android.app.Activity); @@ -4031,6 +4032,8 @@ package android.app { method public android.app.ActivityOptions setLaunchBounds(android.graphics.Rect); method public android.app.ActivityOptions setLaunchDisplayId(int); method public void setLaunchStackId(int); + method public void setLaunchTaskId(int); + method public void setTaskOverlay(boolean, boolean); method public android.os.Bundle toBundle(); method public void update(android.app.ActivityOptions); field public static final java.lang.String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time"; @@ -4619,6 +4622,7 @@ package android.app { method public void onDestroyOptionsMenu(); method public void onDestroyView(); method public void onDetach(); + method public android.view.LayoutInflater onGetLayoutInflater(android.os.Bundle); method public void onHiddenChanged(boolean); method public deprecated void onInflate(android.util.AttributeSet, android.os.Bundle); method public void onInflate(android.content.Context, android.util.AttributeSet, android.os.Bundle); @@ -4773,6 +4777,7 @@ package android.app { method public abstract android.app.FragmentManager.BackStackEntry getBackStackEntryAt(int); method public abstract int getBackStackEntryCount(); method public abstract android.app.Fragment getFragment(android.os.Bundle, java.lang.String); + method public abstract java.util.Collection<android.app.Fragment> getFragments(); method public abstract android.app.Fragment getPrimaryNavigationFragment(); method public void invalidateOptionsMenu(); method public abstract boolean isDestroyed(); @@ -5594,7 +5599,7 @@ package android.app { method public boolean removeAutomaticZenRule(java.lang.String); method public final void setInterruptionFilter(int); method public void setNotificationPolicy(android.app.NotificationManager.Policy); - method public android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification); + method public deprecated android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification); method public boolean updateAutomaticZenRule(java.lang.String, android.app.AutomaticZenRule); field public static final java.lang.String ACTION_INTERRUPTION_FILTER_CHANGED = "android.app.action.INTERRUPTION_FILTER_CHANGED"; field public static final java.lang.String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED"; @@ -5649,6 +5654,7 @@ package android.app { method public java.lang.String getCreatorPackage(); method public int getCreatorUid(); method public android.os.UserHandle getCreatorUserHandle(); + method public static android.app.PendingIntent getForegroundService(android.content.Context, int, android.content.Intent, int); method public android.content.IntentSender getIntentSender(); method public static android.app.PendingIntent getService(android.content.Context, int, android.content.Intent, int); method public deprecated java.lang.String getTargetPackage(); @@ -7166,7 +7172,6 @@ package android.bluetooth { method public static synchronized android.bluetooth.BluetoothAdapter getDefaultAdapter(); method public int getLeMaximumAdvertisingDataLength(); method public java.lang.String getName(); - method public android.bluetooth.le.PeriodicAdvertisingManager getPeriodicAdvertisingManager(); method public int getProfileConnectionState(int); method public boolean getProfileProxy(android.content.Context, android.bluetooth.BluetoothProfile.ServiceListener, int); method public android.bluetooth.BluetoothDevice getRemoteDevice(java.lang.String); @@ -8055,21 +8060,6 @@ package android.bluetooth.le { method public void stopScan(android.bluetooth.le.ScanCallback); } - public abstract class PeriodicAdvertisingCallback { - ctor public PeriodicAdvertisingCallback(); - method public void onPeriodicAdvertisingReport(android.bluetooth.le.PeriodicAdvertisingReport); - method public void onSyncEstablished(int, android.bluetooth.BluetoothDevice, int, int, int, int); - method public void onSyncLost(int); - field public static final int SYNC_NO_RESOURCES = 2; // 0x2 - field public static final int SYNC_NO_RESPONSE = 1; // 0x1 - } - - public final class PeriodicAdvertisingManager { - method public void registerSync(android.bluetooth.le.ScanResult, int, int, android.bluetooth.le.PeriodicAdvertisingCallback); - method public void registerSync(android.bluetooth.le.ScanResult, int, int, android.bluetooth.le.PeriodicAdvertisingCallback, android.os.Handler); - method public void unregisterSync(android.bluetooth.le.PeriodicAdvertisingCallback); - } - public final class PeriodicAdvertisingParameters implements android.os.Parcelable { method public int describeContents(); method public boolean getEnable(); @@ -8087,21 +8077,6 @@ package android.bluetooth.le { method public android.bluetooth.le.PeriodicAdvertisingParameters.Builder setInterval(int); } - public final class PeriodicAdvertisingReport implements android.os.Parcelable { - ctor public PeriodicAdvertisingReport(int, int, int, int, android.bluetooth.le.ScanRecord); - method public int describeContents(); - method public android.bluetooth.le.ScanRecord getData(); - method public int getDataStatus(); - method public int getRssi(); - method public int getSyncHandle(); - method public long getTimestampNanos(); - method public int getTxPower(); - method public void writeToParcel(android.os.Parcel, int); - field public static final android.os.Parcelable.Creator<android.bluetooth.le.PeriodicAdvertisingReport> CREATOR; - field public static final int DATA_COMPLETE = 0; // 0x0 - field public static final int DATA_INCOMPLETE_TRUNCATED = 2; // 0x2 - } - public abstract class ScanCallback { ctor public ScanCallback(); method public void onBatchScanResults(java.util.List<android.bluetooth.le.ScanResult>); @@ -8885,6 +8860,7 @@ package android.content { method public abstract void startActivities(android.content.Intent[], android.os.Bundle); method public abstract void startActivity(android.content.Intent); method public abstract void startActivity(android.content.Intent, android.os.Bundle); + method public abstract android.content.ComponentName startForegroundService(android.content.Intent); method public abstract boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle); method public abstract void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException; method public abstract void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException; @@ -9077,6 +9053,7 @@ package android.content { method public void startActivities(android.content.Intent[], android.os.Bundle); method public void startActivity(android.content.Intent); method public void startActivity(android.content.Intent, android.os.Bundle); + method public android.content.ComponentName startForegroundService(android.content.Intent); method public boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle); method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException; method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException; @@ -11750,7 +11727,7 @@ package android.database { } public final class PageViewCursor extends android.database.CursorWrapper implements android.database.CrossProcessCursor { - ctor public PageViewCursor(android.database.Cursor, int, int); + ctor public PageViewCursor(android.database.Cursor, android.os.Bundle); method public void fillWindow(int, android.database.CursorWindow); method public android.database.CursorWindow getWindow(); method public boolean onMove(int, int); @@ -12743,7 +12720,7 @@ package android.graphics { enum_constant public static final android.graphics.Canvas.VertexMode TRIANGLE_STRIP; } - public class Color { + public final class Color { ctor public Color(); method public static int HSVToColor(float[]); method public static int HSVToColor(int, float[]); @@ -12768,6 +12745,7 @@ package android.graphics { method public float getComponent(int); method public int getComponentCount(); method public float[] getComponents(); + method public float[] getComponents(float[]); method public android.graphics.ColorSpace.Model getModel(); method public float green(); method public static float green(long); @@ -21000,7 +20978,8 @@ package android.media { method public int getContentType(); method public int getFlags(); method public int getUsage(); - method public static int getVolumeControlStream(android.media.AudioAttributes); + method public static deprecated int getVolumeControlStream(android.media.AudioAttributes); + method public int getVolumeControlStream(); method public void writeToParcel(android.os.Parcel, int); field public static final int CONTENT_TYPE_MOVIE = 3; // 0x3 field public static final int CONTENT_TYPE_MUSIC = 2; // 0x2 @@ -21929,23 +21908,23 @@ package android.media { } public final class MediaCas { - ctor public MediaCas(int) throws android.media.UnsupportedCasException; + ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException; method public void closeSession(byte[]); method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins(); method public static boolean isSystemIdSupported(int); - method public byte[] openSession(int); - method public byte[] openSession(int, int); - method public void processEcm(byte[], byte[], int, int); - method public void processEcm(byte[], byte[]); - method public void processEmm(byte[], int, int); - method public void processEmm(byte[]); - method public void provision(java.lang.String); - method public void refreshEntitlements(int, byte[]); + method public byte[] openSession(int) throws android.media.MediaCasException; + method public byte[] openSession(int, int) throws android.media.MediaCasException; + method public void processEcm(byte[], byte[], int, int) throws android.media.MediaCasException; + method public void processEcm(byte[], byte[]) throws android.media.MediaCasException; + method public void processEmm(byte[], int, int) throws android.media.MediaCasException; + method public void processEmm(byte[]) throws android.media.MediaCasException; + method public void provision(java.lang.String) throws android.media.MediaCasException; + method public void refreshEntitlements(int, byte[]) throws android.media.MediaCasException; method public void release(); - method public void sendEvent(int, int, byte[]); + method public void sendEvent(int, int, byte[]) throws android.media.MediaCasException; method public void setEventListener(android.media.MediaCas.EventListener, android.os.Handler); - method public void setPrivateData(byte[]); - method public void setSessionPrivateData(byte[], byte[]); + method public void setPrivateData(byte[]) throws android.media.MediaCasException; + method public void setSessionPrivateData(byte[], byte[]) throws android.media.MediaCasException; } public static abstract interface MediaCas.EventListener { @@ -21958,7 +21937,22 @@ package android.media { } public class MediaCasException extends java.lang.Exception { - ctor public MediaCasException(java.lang.String); + } + + public static final class MediaCasException.DeniedByServerException extends android.media.MediaCasException { + } + + public static final class MediaCasException.NotProvisionedException extends android.media.MediaCasException { + } + + public static final class MediaCasException.ResourceBusyException extends android.media.MediaCasException { + } + + public static final class MediaCasException.UnsupportedCasException extends android.media.MediaCasException { + } + + public class MediaCasStateException extends java.lang.IllegalStateException { + method public java.lang.String getDiagnosticInfo(); } public final class MediaCodec { @@ -22386,7 +22380,7 @@ package android.media { } public final class MediaDescrambler { - ctor public MediaDescrambler(int) throws android.media.UnsupportedCasException; + ctor public MediaDescrambler(int) throws android.media.MediaCasException.UnsupportedCasException; method public final int descramble(java.nio.ByteBuffer, int, java.nio.ByteBuffer, int, android.media.MediaCodec.CryptoInfo); method public final void release(); method public final boolean requiresSecureDecoderComponent(java.lang.String); @@ -23697,10 +23691,6 @@ package android.media { field public static final int TONE_SUP_RINGTONE = 23; // 0x17 } - public final class UnsupportedCasException extends android.media.MediaCasException { - ctor public UnsupportedCasException(java.lang.String); - } - public final class UnsupportedSchemeException extends android.media.MediaDrmException { ctor public UnsupportedSchemeException(java.lang.String); } @@ -24437,9 +24427,9 @@ package android.media.session { method public void setRepeatMode(int); method public void setSessionActivity(android.app.PendingIntent); method public void setShuffleModeEnabled(boolean); - field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1 + field public static final deprecated int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1 field public static final int FLAG_HANDLES_QUEUE_COMMANDS = 4; // 0x4 - field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2 + field public static final deprecated int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2 } public static abstract class MediaSession.Callback { @@ -24659,6 +24649,7 @@ package android.media.tv { field public static final java.lang.String COLUMN_REVIEW_RATING_STYLE = "review_rating_style"; field public static final java.lang.String COLUMN_STARTING_PRICE = "starting_price"; field public static final java.lang.String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio"; + field public static final java.lang.String COLUMN_TRANSIENT = "transient"; field public static final java.lang.String COLUMN_TYPE = "type"; field public static final java.lang.String INTERACTION_TYPE_FANS = "INTERACTION_TYPE_FANS"; field public static final java.lang.String INTERACTION_TYPE_FOLLOWERS = "INTERACTION_TYPE_FOLLOWERS"; @@ -24736,6 +24727,7 @@ package android.media.tv { field public static final java.lang.String COLUMN_SEARCHABLE = "searchable"; field public static final java.lang.String COLUMN_SERVICE_ID = "service_id"; field public static final java.lang.String COLUMN_SERVICE_TYPE = "service_type"; + field public static final java.lang.String COLUMN_TRANSIENT = "transient"; field public static final java.lang.String COLUMN_TRANSPORT_STREAM_ID = "transport_stream_id"; field public static final java.lang.String COLUMN_TYPE = "type"; field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number"; @@ -25519,7 +25511,7 @@ package android.net { method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket() throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException; method public void removeTransportModeTransform(java.net.Socket, android.net.IpSecTransform); method public void removeTransportModeTransform(java.net.DatagramSocket, android.net.IpSecTransform); - method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException; + method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(int, java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException; field public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; // 0x0 } @@ -26770,7 +26762,6 @@ package android.net.wifi.aware { ctor public PublishConfig.Builder(); method public android.net.wifi.aware.PublishConfig build(); method public android.net.wifi.aware.PublishConfig.Builder setMatchFilter(java.util.List<byte[]>); - method public android.net.wifi.aware.PublishConfig.Builder setPublishCount(int); method public android.net.wifi.aware.PublishConfig.Builder setPublishType(int); method public android.net.wifi.aware.PublishConfig.Builder setServiceName(java.lang.String); method public android.net.wifi.aware.PublishConfig.Builder setServiceSpecificInfo(byte[]); @@ -26799,7 +26790,6 @@ package android.net.wifi.aware { method public android.net.wifi.aware.SubscribeConfig.Builder setMatchStyle(int); method public android.net.wifi.aware.SubscribeConfig.Builder setServiceName(java.lang.String); method public android.net.wifi.aware.SubscribeConfig.Builder setServiceSpecificInfo(byte[]); - method public android.net.wifi.aware.SubscribeConfig.Builder setSubscribeCount(int); method public android.net.wifi.aware.SubscribeConfig.Builder setSubscribeType(int); method public android.net.wifi.aware.SubscribeConfig.Builder setTerminateNotificationEnabled(boolean); method public android.net.wifi.aware.SubscribeConfig.Builder setTtlSec(int); @@ -32019,6 +32009,7 @@ package android.os.storage { method public boolean isObbMounted(java.lang.String); method public boolean mountObb(java.lang.String, java.lang.String, android.os.storage.OnObbStateChangeListener); method public android.os.ParcelFileDescriptor openProxyFileDescriptor(int, android.os.ProxyFileDescriptorCallback) throws java.io.IOException; + method public android.os.ParcelFileDescriptor openProxyFileDescriptor(int, android.os.ProxyFileDescriptorCallback, android.os.Handler) throws java.io.IOException; method public void setCacheBehaviorGroup(java.io.File, boolean) throws java.io.IOException; method public void setCacheBehaviorTombstone(java.io.File, boolean) throws java.io.IOException; method public boolean unmountObb(java.lang.String, boolean, android.os.storage.OnObbStateChangeListener); @@ -32167,6 +32158,7 @@ package android.preference { method public int getWidgetLayoutResource(); method public boolean hasKey(); method public boolean isEnabled(); + method public boolean isIconSpaceReserved(); method public boolean isPersistent(); method public boolean isRecycleEnabled(); method public boolean isSelectable(); @@ -32201,6 +32193,7 @@ package android.preference { method public void setFragment(java.lang.String); method public void setIcon(android.graphics.drawable.Drawable); method public void setIcon(int); + method public void setIconSpaceReserved(boolean); method public void setIntent(android.content.Intent); method public void setKey(java.lang.String); method public void setLayoutResource(int); @@ -34997,7 +34990,7 @@ package android.provider { field public static final java.lang.String WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN = "wifi_device_owner_configs_lockdown"; field public static final java.lang.String WIFI_MAX_DHCP_RETRY_COUNT = "wifi_max_dhcp_retry_count"; field public static final java.lang.String WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS = "wifi_mobile_data_transition_wakelock_timeout_ms"; - field public static final java.lang.String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = "wifi_networks_available_notification_on"; + field public static final deprecated java.lang.String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = "wifi_networks_available_notification_on"; field public static final java.lang.String WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY = "wifi_networks_available_repeat_delay"; field public static final java.lang.String WIFI_NUM_OPEN_NETWORKS_KEPT = "wifi_num_open_networks_kept"; field public static final java.lang.String WIFI_ON = "wifi_on"; @@ -38043,6 +38036,7 @@ package android.speech.tts { method public void onRangeStart(java.lang.String, int, int, int); method public abstract void onStart(java.lang.String); method public void onStop(java.lang.String, boolean); + method public deprecated void onUtteranceRangeStart(java.lang.String, int, int); } public class Voice implements android.os.Parcelable { @@ -39564,6 +39558,7 @@ package android.telephony { field public static final java.lang.String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array"; field public static final java.lang.String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool"; field public static final java.lang.String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool"; + field public static final java.lang.String KEY_HIDE_ENHANCED_4G_LTE_BOOL = "hide_enhanced_4g_lte_bool"; field public static final java.lang.String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool"; field public static final java.lang.String KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL = "hide_preferred_network_type_bool"; field public static final java.lang.String KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool"; @@ -40861,6 +40856,7 @@ package android.test.mock { method public void startActivities(android.content.Intent[], android.os.Bundle); method public void startActivity(android.content.Intent); method public void startActivity(android.content.Intent, android.os.Bundle); + method public android.content.ComponentName startForegroundService(android.content.Intent); method public boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle); method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException; method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException; @@ -41267,9 +41263,9 @@ package android.text { public static final class FontConfig.Font implements android.os.Parcelable { method public int describeContents(); method public android.text.FontConfig.Axis[] getAxes(); - method public android.os.ParcelFileDescriptor getFd(); method public java.lang.String getFontName(); method public int getTtcIndex(); + method public android.net.Uri getUri(); method public int getWeight(); method public boolean isItalic(); method public void writeToParcel(android.os.Parcel, int); @@ -45513,8 +45509,8 @@ package android.view { method public void addTouchables(java.util.ArrayList<android.view.View>); method public android.view.ViewPropertyAnimator animate(); method public void announceForAccessibility(java.lang.CharSequence); - method public boolean autofill(android.view.autofill.AutofillValue); - method public boolean autofill(android.util.SparseArray<android.view.autofill.AutofillValue>); + method public void autofill(android.view.autofill.AutofillValue); + method public void autofill(android.util.SparseArray<android.view.autofill.AutofillValue>); method protected boolean awakenScrollBars(); method protected boolean awakenScrollBars(int); method protected boolean awakenScrollBars(int, boolean); @@ -45849,7 +45845,7 @@ package android.view { method public boolean onKeyUp(int, android.view.KeyEvent); method protected void onLayout(boolean, int, int, int, int); method protected void onMeasure(int, int); - method public void onMovedToDisplay(int); + method public void onMovedToDisplay(int, android.content.res.Configuration); method protected void onOverScrolled(int, int, boolean, boolean); method public void onPointerCaptureChange(boolean); method public void onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent); @@ -46352,6 +46348,7 @@ package android.view { method public static deprecated int getEdgeSlop(); method public static deprecated int getFadingEdgeLength(); method public static deprecated long getGlobalActionKeyTimeout(); + method public float getScaledHorizontalScrollFactor(); method public static int getHoverTooltipHideShortTimeout(); method public static int getHoverTooltipHideTimeout(); method public static int getHoverTooltipShowTimeout(); @@ -46374,7 +46371,6 @@ package android.view { method public int getScaledOverscrollDistance(); method public int getScaledPagingTouchSlop(); method public int getScaledScrollBarSize(); - method public int getScaledScrollFactor(); method public int getScaledTouchSlop(); method public int getScaledWindowTouchSlop(); method public static int getScrollBarFadeDuration(); @@ -46383,6 +46379,7 @@ package android.view { method public static float getScrollFriction(); method public static int getTapTimeout(); method public static deprecated int getTouchSlop(); + method public float getScaledVerticalScrollFactor(); method public static deprecated int getWindowTouchSlop(); method public static long getZoomControlsTimeout(); method public boolean hasPermanentMenuKey(); @@ -49192,6 +49189,7 @@ package android.webkit { method public int getRendererRequestedPriority(); method public deprecated float getScale(); method public android.webkit.WebSettings getSettings(); + method public android.view.textclassifier.TextClassifier getTextClassifier(); method public java.lang.String getTitle(); method public java.lang.String getUrl(); method public android.webkit.WebChromeClient getWebChromeClient(); @@ -49238,6 +49236,7 @@ package android.webkit { method public void setNetworkAvailable(boolean); method public deprecated void setPictureListener(android.webkit.WebView.PictureListener); method public void setRendererPriorityPolicy(int, boolean); + method public void setTextClassifier(android.view.textclassifier.TextClassifier); method public deprecated void setVerticalScrollbarOverlay(boolean); method public void setWebChromeClient(android.webkit.WebChromeClient); method public static void setWebContentsDebuggingEnabled(boolean); diff --git a/api/test-removed.txt b/api/test-removed.txt index 75da976d1b64..fa62e056757c 100644 --- a/api/test-removed.txt +++ b/api/test-removed.txt @@ -374,6 +374,10 @@ package android.view { method protected void initializeScrollbars(android.content.res.TypedArray); } + public class ViewConfiguration { + method public int getScaledScrollFactor(); + } + public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable { field public static final int TYPE_KEYGUARD = 2004; // 0x7d4 } diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index fa1de030e729..147b5d034fd1 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -1990,27 +1990,32 @@ public class Activity extends ContextThemeWrapper } } - void dispatchMovedToDisplay(int displayId) { + void dispatchMovedToDisplay(int displayId, Configuration config) { updateDisplay(displayId); - onMovedToDisplay(displayId); + onMovedToDisplay(displayId, config); } /** * Called by the system when the activity is moved from one display to another without * recreation. This means that this activity is declared to handle all changes to configuration * that happened when it was switched to another display, so it wasn't destroyed and created - * again. This call will be followed by {@link #onConfigurationChanged(Configuration)} if the - * applied configuration actually changed. + * again. + * + * <p>This call will be followed by {@link #onConfigurationChanged(Configuration)} if the + * applied configuration actually changed. It is up to app developer to choose whether to handle + * the change in this method or in the following {@link #onConfigurationChanged(Configuration)} + * call. * * <p>Use this callback to track changes to the displays if some activity functionality relies * on an association with some display properties. * * @param displayId The id of the display to which activity was moved. + * @param config Configuration of the activity resources on new display after move. * * @see #onConfigurationChanged(Configuration) - * @see View#onMovedToDisplay(int) + * @see View#onMovedToDisplay(int, Configuration) */ - public void onMovedToDisplay(int displayId) { + public void onMovedToDisplay(int displayId, Configuration config) { } /** @@ -2735,6 +2740,10 @@ public class Activity extends ContextThemeWrapper return true; } return false; + } else if (keyCode == KeyEvent.KEYCODE_TAB) { + // Don't consume TAB here since it's used for navigation. Arrow keys + // aren't considered "typing keys" so they already won't get consumed. + return false; } else { // Common code for DEFAULT_KEYS_DIALER & DEFAULT_KEYS_SEARCH_* boolean clearSpannable = false; diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 9f2f669b64c8..4004bd6686b1 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -405,6 +405,13 @@ public class ActivityManager { */ public static final int INTENT_SENDER_SERVICE = 4; + /** + * Type for IActivityManaqer.getIntentSender: this PendingIntent is + * for a startForegroundService operation. + * @hide + */ + public static final int INTENT_SENDER_FOREGROUND_SERVICE = 5; + /** @hide User operation call: success! */ public static final int USER_OP_SUCCESS = 0; diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index 0b9479d8b52e..aa7cdf7b475e 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -1068,6 +1068,7 @@ public class ActivityOptions { * Sets the task the activity will be launched in. * @hide */ + @TestApi public void setLaunchTaskId(int taskId) { mLaunchTaskId = taskId; } @@ -1085,6 +1086,7 @@ public class ActivityOptions { * the task will also not be moved to the front of the stack. * @hide */ + @TestApi public void setTaskOverlay(boolean taskOverlay, boolean canResume) { mTaskOverlay = taskOverlay; mTaskOverlayCanResume = canResume; diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index b4e6bd5856c7..b5d1fa8550df 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -808,11 +808,6 @@ public final class ActivityThread { public final void scheduleReceiver(Intent intent, ActivityInfo info, CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras, boolean sync, int sendingUser, int processState) { - // TODO: Debugging added for bug:36406078 . Remove when done - if (Log.isLoggable("36406078", Log.DEBUG)) { - Log.d(TAG, "scheduleReceiver"); - } - updateProcessState(processState, false); ReceiverData r = new ReceiverData(intent, resultCode, data, extras, sync, false, mAppThread.asBinder(), sendingUser); @@ -899,11 +894,6 @@ public final class ActivityThread { CompatibilityInfo compatInfo, Map services, Bundle coreSettings, String buildSerial) { - // TODO: Debugging added for bug:36406078 . Remove when done - if (Log.isLoggable("36406078", Log.DEBUG)) { - Log.d(TAG, "bindApplication: " + processName); - } - if (services != null) { // Setup the service cache in the ServiceManager ServiceManager.initServiceCache(services); @@ -3239,10 +3229,6 @@ public final class ActivityThread { if (receiver.getPendingResult() != null) { data.finish(); } - // TODO: Debugging added for bug:36406078 . Remove when done - if (Log.isLoggable("36406078", Log.DEBUG)) { - Log.d(TAG, "handleReceiver done"); - } } // Instantiate a BackupAgent and tell it that it's alive @@ -4815,16 +4801,18 @@ public final class ActivityThread { * {@link ActivityClientRecord#overrideConfig}. * @param displayId The id of the display where the Activity currently resides. * @param movedToDifferentDisplay Indicates if the activity was moved to different display. + * @return {@link Configuration} instance sent to client, null if not sent. */ - private void performConfigurationChangedForActivity(ActivityClientRecord r, + private Configuration performConfigurationChangedForActivity(ActivityClientRecord r, Configuration newBaseConfig, int displayId, boolean movedToDifferentDisplay) { r.tmpConfig.setTo(newBaseConfig); if (r.overrideConfig != null) { r.tmpConfig.updateFrom(r.overrideConfig); } - performActivityConfigurationChanged(r.activity, r.tmpConfig, r.overrideConfig, displayId, - movedToDifferentDisplay); + final Configuration reportedConfig = performActivityConfigurationChanged(r.activity, + r.tmpConfig, r.overrideConfig, displayId, movedToDifferentDisplay); freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig)); + return reportedConfig; } /** @@ -4878,9 +4866,11 @@ public final class ActivityThread { * ActivityManager. * @param displayId Id of the display where activity currently resides. * @param movedToDifferentDisplay Indicates if the activity was moved to different display. + * @return Configuration sent to client, null if no changes and not moved to different display. */ - private void performActivityConfigurationChanged(Activity activity, Configuration newConfig, - Configuration amOverrideConfig, int displayId, boolean movedToDifferentDisplay) { + private Configuration performActivityConfigurationChanged(Activity activity, + Configuration newConfig, Configuration amOverrideConfig, int displayId, + boolean movedToDifferentDisplay) { if (activity == null) { throw new IllegalArgumentException("No activity provided."); } @@ -4911,7 +4901,7 @@ public final class ActivityThread { } if (!shouldChangeConfig && !movedToDifferentDisplay) { // Nothing significant, don't proceed with updating and reporting. - return; + return null; } // Propagate the configuration change to ResourcesManager and Activity. @@ -4934,22 +4924,22 @@ public final class ActivityThread { activity.mConfigChangeFlags = 0; activity.mCurrentConfig = new Configuration(newConfig); + // Apply the ContextThemeWrapper override if necessary. + // NOTE: Make sure the configurations are not modified, as they are treated as immutable + // in many places. + final Configuration configToReport = createNewConfigAndUpdateIfNotNull(newConfig, + contextThemeWrapperOverrideConfig); + if (!REPORT_TO_ACTIVITY) { // Not configured to report to activity. - return; + return configToReport; } if (movedToDifferentDisplay) { - activity.dispatchMovedToDisplay(displayId); + activity.dispatchMovedToDisplay(displayId, configToReport); } if (shouldChangeConfig) { - // Apply the ContextThemeWrapper override if necessary. - // NOTE: Make sure the configurations are not modified, as they are treated as immutable - // in many places. - final Configuration configToReport = createNewConfigAndUpdateIfNotNull( - newConfig, contextThemeWrapperOverrideConfig); - activity.mCalled = false; activity.onConfigurationChanged(configToReport); if (!activity.mCalled) { @@ -4957,6 +4947,8 @@ public final class ActivityThread { " did not call through to super.onConfigurationChanged()"); } } + + return configToReport; } public final void applyConfigurationToResources(Configuration config) { @@ -5129,10 +5121,10 @@ public final class ActivityThread { + r.activityInfo.name + ", displayId=" + displayId + ", config=" + data.overrideConfig); - performConfigurationChangedForActivity(r, mCompatConfiguration, displayId, - true /* movedToDifferentDisplay */); + final Configuration reportedConfig = performConfigurationChangedForActivity(r, + mCompatConfiguration, displayId, true /* movedToDifferentDisplay */); if (viewRoot != null) { - viewRoot.onMovedToDisplay(displayId); + viewRoot.onMovedToDisplay(displayId, reportedConfig); } } else { if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: " @@ -5142,7 +5134,7 @@ public final class ActivityThread { // Notify the ViewRootImpl instance about configuration changes. It may have initiated this // update to make sure that resources are updated before updating itself. if (viewRoot != null) { - viewRoot.updateConfiguration(); + viewRoot.updateConfiguration(displayId); } mSomeActivitiesChanged = true; } @@ -5778,10 +5770,6 @@ public final class ActivityThread { } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } - // TODO: Debugging added for bug:36406078 . Remove when done - if (Log.isLoggable("36406078", Log.DEBUG)) { - Log.d(TAG, "handleBindApplication done"); - } } /*package*/ final void finishInstrumentation(int resultCode, Bundle results) { diff --git a/core/java/android/app/ApplicationLoaders.java b/core/java/android/app/ApplicationLoaders.java index ef2db4a0d795..2062930929a2 100644 --- a/core/java/android/app/ApplicationLoaders.java +++ b/core/java/android/app/ApplicationLoaders.java @@ -18,6 +18,7 @@ package android.app; import android.os.Build; import android.os.Trace; +import android.text.TextUtils; import android.util.ArrayMap; import com.android.internal.os.PathClassLoaderFactory; import dalvik.system.PathClassLoader; @@ -29,8 +30,16 @@ public class ApplicationLoaders { } ClassLoader getClassLoader(String zip, int targetSdkVersion, boolean isBundled, - String librarySearchPath, String libraryPermittedPath, - ClassLoader parent) { + String librarySearchPath, String libraryPermittedPath, + ClassLoader parent) { + // For normal usage the cache key used is the same as the zip path. + return getClassLoader(zip, targetSdkVersion, isBundled, librarySearchPath, + libraryPermittedPath, parent, zip); + } + + private ClassLoader getClassLoader(String zip, int targetSdkVersion, boolean isBundled, + String librarySearchPath, String libraryPermittedPath, + ClassLoader parent, String cacheKey) { /* * This is the parent we use if they pass "null" in. In theory * this should be the "system" class loader; in practice we @@ -50,7 +59,7 @@ public class ApplicationLoaders { * new ClassLoader for the zip archive. */ if (parent == baseParent) { - ClassLoader loader = mLoaders.get(zip); + ClassLoader loader = mLoaders.get(cacheKey); if (loader != null) { return loader; } @@ -71,7 +80,7 @@ public class ApplicationLoaders { setupVulkanLayerPath(pathClassloader, librarySearchPath); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); - mLoaders.put(zip, pathClassloader); + mLoaders.put(cacheKey, pathClassloader); return pathClassloader; } @@ -87,12 +96,16 @@ public class ApplicationLoaders { * by this class. This is used in the WebView zygote, where its presence in the cache speeds up * startup and enables memory sharing. */ - public ClassLoader createAndCacheWebViewClassLoader(String packagePath, String libsPath) { - // The correct paths are calculated by WebViewZygote in the system server and passed to - // us here. We hardcode the other parameters: WebView always targets the current SDK, - // does not need to use non-public system libraries, and uses the base classloader as its - // parent to permit usage of the cache. - return getClassLoader(packagePath, Build.VERSION.SDK_INT, false, libsPath, null, null); + public ClassLoader createAndCacheWebViewClassLoader(String packagePath, String libsPath, + String cacheKey) { + // The correct paths are calculated by WebViewZygote in the system server and passed to + // us here. We hardcode the other parameters: WebView always targets the current SDK, + // does not need to use non-public system libraries, and uses the base classloader as its + // parent to permit usage of the cache. + // The cache key is passed separately to enable the stub WebView to be cached under the + // stub's APK path, when the actual package path is the donor APK. + return getClassLoader(packagePath, Build.VERSION.SDK_INT, false, libsPath, null, null, + cacheKey); } private static native void setupVulkanLayerPath(ClassLoader classLoader, String librarySearchPath); diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 286f8570f55c..461f9cc35125 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -2630,4 +2630,13 @@ public class ApplicationPackageManager extends PackageManager { throw e.rethrowAsRuntimeException(); } } + + @Override + public ComponentName getInstantAppResolverSettingsComponent() { + try { + return mPM.getInstantAppResolverSettingsComponent(); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } } diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 4c080c9e6a95..467ba996ad4f 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -1447,14 +1447,21 @@ class ContextImpl extends Context { @Override public ComponentName startService(Intent service) { warnIfCallingFromSystemProcess(); - return startServiceCommon(service, -1, null, mUser); + return startServiceCommon(service, -1, null, false, mUser); } @Override + public ComponentName startForegroundService(Intent service) { + warnIfCallingFromSystemProcess(); + return startServiceCommon(service, -1, null, true, mUser); + } + + // STOPSHIP: remove when NotificationManager.startServiceInForeground() is retired + @Override public ComponentName startServiceInForeground(Intent service, int id, Notification notification) { warnIfCallingFromSystemProcess(); - return startServiceCommon(service, id, notification, mUser); + return startServiceCommon(service, id, notification, false, mUser); } @Override @@ -1465,24 +1472,30 @@ class ContextImpl extends Context { @Override public ComponentName startServiceAsUser(Intent service, UserHandle user) { - return startServiceCommon(service, -1, null, user); + return startServiceCommon(service, -1, null, false, user); } @Override + public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) { + return startServiceCommon(service, -1, null, true, user); + } + + // STOPSHIP: remove when NotificationManager.startServiceInForeground() is retired + @Override public ComponentName startServiceInForegroundAsUser(Intent service, int id, Notification notification, UserHandle user) { - return startServiceCommon(service, id, notification, user); + return startServiceCommon(service, id, notification, false, user); } private ComponentName startServiceCommon(Intent service, int id, Notification notification, - UserHandle user) { + boolean requireForeground, UserHandle user) { try { validateServiceIntent(service); service.prepareToLeaveProcess(this); ComponentName cn = ActivityManager.getService().startService( mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded( - getContentResolver()), id, notification, getOpPackageName(), - user.getIdentifier()); + getContentResolver()), id, notification, requireForeground, + getOpPackageName(), user.getIdentifier()); if (cn != null) { if (cn.getPackageName().equals("!")) { throw new SecurityException( diff --git a/core/java/android/app/DialogFragment.java b/core/java/android/app/DialogFragment.java index 3198c7c086d1..7e0e4d827477 100644 --- a/core/java/android/app/DialogFragment.java +++ b/core/java/android/app/DialogFragment.java @@ -398,9 +398,9 @@ public class DialogFragment extends Fragment /** @hide */ @Override - public LayoutInflater getLayoutInflater(Bundle savedInstanceState) { + public LayoutInflater onGetLayoutInflater(Bundle savedInstanceState) { if (!mShowsDialog) { - return super.getLayoutInflater(savedInstanceState); + return super.onGetLayoutInflater(savedInstanceState); } mDialog = onCreateDialog(savedInstanceState); diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java index 44fefd38048c..02fe101c9152 100644 --- a/core/java/android/app/Fragment.java +++ b/core/java/android/app/Fragment.java @@ -31,7 +31,6 @@ import android.content.res.TypedArray; import android.os.Build; import android.os.Build.VERSION_CODES; import android.os.Bundle; -import android.os.Handler; import android.os.Looper; import android.os.Parcel; import android.os.Parcelable; @@ -1357,11 +1356,16 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene } /** - * @hide Hack so that DialogFragment can make its Dialog before creating - * its views, and the view construction can use the dialog's context for - * inflation. Maybe this should become a public API. Note sure. + * Returns the LayoutInflater used to inflate Views of this Fragment. The default + * implementation will throw an exception if the Fragment is not attached. + * + * @return The LayoutInflater used to inflate Views of this Fragment. */ - public LayoutInflater getLayoutInflater(Bundle savedInstanceState) { + public LayoutInflater onGetLayoutInflater(Bundle savedInstanceState) { + if (mHost == null) { + throw new IllegalStateException("onGetLayoutInflater() cannot be executed until the " + + "Fragment is attached to the FragmentManager."); + } final LayoutInflater result = mHost.onGetLayoutInflater(); if (mHost.onUseFragmentManagerInflaterFactory()) { getChildFragmentManager(); // Init if needed; use raw implementation below. diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java index d710d8bb6221..0c1be07ab231 100644 --- a/core/java/android/app/FragmentManager.java +++ b/core/java/android/app/FragmentManager.java @@ -54,6 +54,8 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; @@ -312,6 +314,16 @@ public abstract class FragmentManager { public abstract Fragment getFragment(Bundle bundle, String key); /** + * Get a collection of all fragments that are currently added to the FragmentManager. + * This may include those that are hidden as well as those that are shown. + * This will not include any fragments only in the back stack, or fragments that + * are detached or removed. + * + * @return A collection of all fragments that are added to the FragmentManager. + */ + public abstract Collection<Fragment> getFragments(); + + /** * Save the current instance state of the given Fragment. This can be * used later when creating a new instance of the Fragment and adding * it to the fragment manager, to have it create itself to match the @@ -895,6 +907,16 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate } @Override + public Collection<Fragment> getFragments() { + if (mAdded == null) { + return Collections.EMPTY_LIST; + } + synchronized (mAdded) { + return (Collection<Fragment>) mAdded.clone(); + } + } + + @Override public Fragment.SavedState saveFragmentInstanceState(Fragment fragment) { if (fragment.mIndex < 0) { throwException(new IllegalStateException("Fragment " + fragment @@ -1226,7 +1248,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate } } f.mContainer = container; - f.mView = f.performCreateView(f.getLayoutInflater( + f.mView = f.performCreateView(f.onGetLayoutInflater( f.mSavedFragmentState), container, f.mSavedFragmentState); if (f.mView != null) { f.mView.setSaveFromParentEnabled(false); @@ -1398,7 +1420,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate void ensureInflatedFragmentView(Fragment f) { if (f.mFromLayout && !f.mPerformedCreateView) { - f.mView = f.performCreateView(f.getLayoutInflater( + f.mView = f.performCreateView(f.onGetLayoutInflater( f.mSavedFragmentState), null, f.mSavedFragmentState); if (f.mView != null) { f.mView.setSaveFromParentEnabled(false); @@ -1620,7 +1642,9 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate if (mAdded.contains(fragment)) { throw new IllegalStateException("Fragment already added: " + fragment); } - mAdded.add(fragment); + synchronized (mAdded) { + mAdded.add(fragment); + } fragment.mAdded = true; fragment.mRemoving = false; if (fragment.mView == null) { @@ -1648,7 +1672,9 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate } } if (mAdded != null) { - mAdded.remove(fragment); + synchronized (mAdded) { + mAdded.remove(fragment); + } } if (fragment.mHasMenu && fragment.mMenuVisible) { mNeedMenuInvalidate = true; @@ -1698,7 +1724,9 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate // We are not already in back stack, so need to remove the fragment. if (mAdded != null) { if (DEBUG) Log.v(TAG, "remove from detach: " + fragment); - mAdded.remove(fragment); + synchronized (mAdded) { + mAdded.remove(fragment); + } } if (fragment.mHasMenu && fragment.mMenuVisible) { mNeedMenuInvalidate = true; @@ -1720,7 +1748,9 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate throw new IllegalStateException("Fragment already added: " + fragment); } if (DEBUG) Log.v(TAG, "add from attach: " + fragment); - mAdded.add(fragment); + synchronized (mAdded) { + mAdded.add(fragment); + } fragment.mAdded = true; if (fragment.mHasMenu && fragment.mMenuVisible) { mNeedMenuInvalidate = true; @@ -2695,7 +2725,15 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate for (int i = 0; i < count; i++) { Fragment f = nonConfigFragments.get(i); if (DEBUG) Log.v(TAG, "restoreAllState: re-attaching retained " + f); - FragmentState fs = fms.mActive[f.mIndex]; + int index = 0; // index of f in fms.mActive + while (index < fms.mActive.length && fms.mActive[index].mIndex != f.mIndex) { + index++; + } + if (index == fms.mActive.length) { + throwException(new IllegalStateException("Could not find active fragment " + + "with index " + f.mIndex)); + } + FragmentState fs = fms.mActive[index]; fs.mInstance = f; f.mSavedViewState = null; f.mBackStackNesting = 0; @@ -2762,7 +2800,9 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate if (mAdded.contains(f)) { throw new IllegalStateException("Already added!"); } - mAdded.add(f); + synchronized (mAdded) { + mAdded.add(f); + } } } else { mAdded = null; diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 82229d5b1bc8..0a5e4bef8dca 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -130,7 +130,7 @@ interface IActivityManager { PendingIntent getRunningServiceControlPanel(in ComponentName service); ComponentName startService(in IApplicationThread caller, in Intent service, in String resolvedType, int id, in Notification notification, - in String callingPackage, int userId); + boolean requireForeground, in String callingPackage, int userId); int stopService(in IApplicationThread caller, in Intent service, in String resolvedType, int userId); int bindService(in IApplicationThread caller, in IBinder token, in Intent service, @@ -629,6 +629,11 @@ interface IActivityManager { */ void setDisablePreviewScreenshots(IBinder token, boolean disable); + /** + * Return the user id of last resumed activity. + */ + int getLastResumedActivityUserId(); + // WARNING: when these transactions are updated, check if they are any callers on the native // side. If so, make sure they are using the correct transaction ids and arguments. // If a transaction which will also be used on the native side is being inserted, add it diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index c78b3cde6fbe..4bbc003cfdfa 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -971,6 +971,7 @@ public class Notification implements Parcelable * Only available to notifications coming from the android package. * @hide */ + @SystemApi public static final String EXTRA_ALLOW_DURING_SETUP = "android.allowDuringSetup"; /** diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index 75998f2eb36d..72c59781ae80 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -1171,8 +1171,11 @@ public class NotificationManager * @return If the service is being started or is already running, the * {@link ComponentName} of the actual service that was started is * returned; else if the service does not exist null is returned. + * + * @deprecated STOPSHIP transition away from this for O */ @Nullable + @Deprecated public ComponentName startServiceInForeground(Intent service, int id, Notification notification) { return mContext.startServiceInForeground(service, id, notification); diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java index 7d1a16ab1045..dc432afb5c06 100644 --- a/core/java/android/app/PendingIntent.java +++ b/core/java/android/app/PendingIntent.java @@ -596,6 +596,42 @@ public final class PendingIntent implements Parcelable { */ public static PendingIntent getService(Context context, int requestCode, @NonNull Intent intent, @Flags int flags) { + return buildServicePendingIntent(context, requestCode, intent, flags, + ActivityManager.INTENT_SENDER_SERVICE); + } + + /** + * Retrieve a PendingIntent that will start a foreground service, like calling + * {@link Context#startService Context.startForegroundService()}. The start + * arguments given to the service will come from the extras of the Intent. + * + * <p class="note">For security reasons, the {@link android.content.Intent} + * you supply here should almost always be an <em>explicit intent</em>, + * that is specify an explicit component to be delivered to through + * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p> + * + * @param context The Context in which this PendingIntent should start + * the service. + * @param requestCode Private request code for the sender + * @param intent An Intent describing the service to be started. + * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE}, + * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT}, + * {@link #FLAG_IMMUTABLE} or any of the flags as supported by + * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts + * of the intent that can be supplied when the actual send happens. + * + * @return Returns an existing or new PendingIntent matching the given + * parameters. May return null only if {@link #FLAG_NO_CREATE} has been + * supplied. + */ + public static PendingIntent getForegroundService(Context context, int requestCode, + @NonNull Intent intent, @Flags int flags) { + return buildServicePendingIntent(context, requestCode, intent, flags, + ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE); + } + + private static PendingIntent buildServicePendingIntent(Context context, int requestCode, + Intent intent, int flags, int serviceKind) { String packageName = context.getPackageName(); String resolvedType = intent != null ? intent.resolveTypeIfNeeded( context.getContentResolver()) : null; @@ -603,7 +639,7 @@ public final class PendingIntent implements Parcelable { intent.prepareToLeaveProcess(context); IIntentSender target = ActivityManager.getService().getIntentSender( - ActivityManager.INTENT_SENDER_SERVICE, packageName, + serviceKind, packageName, null, null, requestCode, new Intent[] { intent }, resolvedType != null ? new String[] { resolvedType } : null, flags, null, UserHandle.myUserId()); diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 124749a43d61..9b349dd85614 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -74,7 +74,9 @@ import android.net.ConnectivityThread; import android.net.EthernetManager; import android.net.IConnectivityManager; import android.net.IEthernetManager; +import android.net.IIpSecService; import android.net.INetworkPolicyManager; +import android.net.IpSecManager; import android.net.NetworkPolicyManager; import android.net.NetworkScoreManager; import android.net.nsd.INsdManager; @@ -93,6 +95,7 @@ import android.nfc.NfcManager; import android.os.BatteryManager; import android.os.BatteryStats; import android.os.Build; +import android.os.Debug; import android.os.DropBoxManager; import android.os.HardwarePropertiesManager; import android.os.IBatteryPropertiesRegistrar; @@ -262,6 +265,15 @@ final class SystemServiceRegistry { return new ConnectivityManager(context, service); }}); + registerService(Context.IPSEC_SERVICE, IpSecManager.class, + new StaticServiceFetcher<IpSecManager>() { + @Override + public IpSecManager createService() { + IBinder b = ServiceManager.getService(Context.IPSEC_SERVICE); + IIpSecService service = IIpSecService.Stub.asInterface(b); + return new IpSecManager(service); + }}); + registerService(Context.COUNTRY_DETECTOR, CountryDetector.class, new StaticServiceFetcher<CountryDetector>() { @Override diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java index 6e31d807a044..1ca2be5b2a1f 100644 --- a/core/java/android/bluetooth/BluetoothA2dp.java +++ b/core/java/android/bluetooth/BluetoothA2dp.java @@ -612,6 +612,51 @@ public final class BluetoothA2dp implements BluetoothProfile { } /** + * Enables the optional codecs. + * + * @hide + */ + public void enableOptionalCodecs() { + if (DBG) Log.d(TAG, "enableOptionalCodecs"); + enableDisableOptionalCodecs(true); + } + + /** + * Disables the optional codecs. + * + * @hide + */ + public void disableOptionalCodecs() { + if (DBG) Log.d(TAG, "disableOptionalCodecs"); + enableDisableOptionalCodecs(false); + } + + /** + * Enables or disables the optional codecs. + * + * @param enable if true, enable the optional codecs, other disable them + */ + private void enableDisableOptionalCodecs(boolean enable) { + try { + mServiceLock.readLock().lock(); + if (mService != null && isEnabled()) { + if (enable) { + mService.enableOptionalCodecs(); + } else { + mService.disableOptionalCodecs(); + } + } + if (mService == null) Log.w(TAG, "Proxy not attached to service"); + return; + } catch (RemoteException e) { + Log.e(TAG, "Error talking to BT service in enableDisableOptionalCodecs()", e); + return; + } finally { + mServiceLock.readLock().unlock(); + } + } + + /** * Helper for converting a state to a string. * * For debug use only - strings are not internationalized. diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 4e1e42da4fe7..845a47d99842 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -638,6 +638,7 @@ public final class BluetoothAdapter { * <p> * Use {@link #isLePeriodicAdvertisingSupported()} to check whether LE Periodic Advertising is * supported on this device before calling this method. + * @hide */ public PeriodicAdvertisingManager getPeriodicAdvertisingManager() { if (!getLeAccess()) diff --git a/core/java/android/bluetooth/BluetoothCodecConfig.java b/core/java/android/bluetooth/BluetoothCodecConfig.java index 176e48fb6e08..d5e142981013 100644 --- a/core/java/android/bluetooth/BluetoothCodecConfig.java +++ b/core/java/android/bluetooth/BluetoothCodecConfig.java @@ -63,7 +63,7 @@ public final class BluetoothCodecConfig implements Parcelable { public static final int CHANNEL_MODE_STEREO = 0x1 << 1; private final int mCodecType; - private final int mCodecPriority; + private int mCodecPriority; private final int mSampleRate; private final int mBitsPerSample; private final int mChannelMode; @@ -280,6 +280,15 @@ public final class BluetoothCodecConfig implements Parcelable { } /** + * Checks whether the codec is mandatory. + * + * @return true if the codec is mandatory, otherwise false. + */ + public boolean isMandatoryCodec() { + return mCodecType == SOURCE_CODEC_TYPE_SBC; + } + + /** * Gets the codec selection priority. * The codec selection priority is relative to other codecs: larger value * means higher priority. If 0, reset to default. @@ -291,6 +300,17 @@ public final class BluetoothCodecConfig implements Parcelable { } /** + * Sets the codec selection priority. + * The codec selection priority is relative to other codecs: larger value + * means higher priority. If 0, reset to default. + * + * @param codecPriority the codec priority + */ + public void setCodecPriority(int codecPriority) { + mCodecPriority = codecPriority; + } + + /** * Gets the codec sample rate. The value can be a bitmask with all * supported sample rates: * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_NONE} or diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java index 9e2eb84b13f9..5d1e8ec58ceb 100644 --- a/core/java/android/bluetooth/BluetoothGatt.java +++ b/core/java/android/bluetooth/BluetoothGatt.java @@ -135,8 +135,8 @@ public final class BluetoothGatt implements BluetoothProfile { /** * Bluetooth GATT callbacks. Overrides the default BluetoothGattCallback implementation. */ - private final IBluetoothGattCallbackExt mBluetoothGattCallback = - new IBluetoothGattCallbackExt.Stub() { + private final IBluetoothGattCallback mBluetoothGattCallback = + new IBluetoothGattCallback.Stub() { /** * Application interface registered - app is ready to go * @hide @@ -778,7 +778,7 @@ public final class BluetoothGatt implements BluetoothProfile { /** * Set the preferred connection PHY for this app. Please note that this is just a - * recommendation, wether the PHY change will happen depends on other applications peferences, + * recommendation, whether the PHY change will happen depends on other applications peferences, * local and remote controller capabilities. Controller can override these settings. * <p> * {@link BluetoothGattCallback#onPhyUpdate} will be triggered as a result of this call, even diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java index c991e2f71bb8..2df2ed8ff86f 100644 --- a/core/java/android/bluetooth/BluetoothGattServer.java +++ b/core/java/android/bluetooth/BluetoothGattServer.java @@ -59,8 +59,8 @@ public final class BluetoothGattServer implements BluetoothProfile { /** * Bluetooth GATT interface callbacks */ - private final IBluetoothGattServerCallbackExt mBluetoothGattServerCallback = - new IBluetoothGattServerCallbackExt.Stub() { + private final IBluetoothGattServerCallback mBluetoothGattServerCallback = + new IBluetoothGattServerCallback.Stub() { /** * Application interface registered - app is ready to go * @hide @@ -550,7 +550,7 @@ public final class BluetoothGattServer implements BluetoothProfile { /** * Set the preferred connection PHY for this app. Please note that this is just a - * recommendation, wether the PHY change will happen depends on other applications peferences, + * recommendation, whether the PHY change will happen depends on other applications peferences, * local and remote controller capabilities. Controller can override these settings. * <p> * {@link BluetoothGattServerCallback#onPhyUpdate} will be triggered as a result of this call, even diff --git a/core/java/android/bluetooth/IBluetoothA2dp.aidl b/core/java/android/bluetooth/IBluetoothA2dp.aidl index dbb5b7d7944b..a775a1f90b8e 100644 --- a/core/java/android/bluetooth/IBluetoothA2dp.aidl +++ b/core/java/android/bluetooth/IBluetoothA2dp.aidl @@ -40,4 +40,6 @@ interface IBluetoothA2dp { boolean isA2dpPlaying(in BluetoothDevice device); BluetoothCodecStatus getCodecStatus(); oneway void setCodecConfigPreference(in BluetoothCodecConfig codecConfig); + oneway void enableOptionalCodecs(); + oneway void disableOptionalCodecs(); } diff --git a/core/java/android/bluetooth/IBluetoothGatt.aidl b/core/java/android/bluetooth/IBluetoothGatt.aidl index 652a1c6098f2..0825ee88a456 100644 --- a/core/java/android/bluetooth/IBluetoothGatt.aidl +++ b/core/java/android/bluetooth/IBluetoothGatt.aidl @@ -29,8 +29,8 @@ import android.bluetooth.le.ResultStorageDescriptor; import android.os.ParcelUuid; import android.os.WorkSource; -import android.bluetooth.IBluetoothGattCallbackExt; -import android.bluetooth.IBluetoothGattServerCallbackExt; +import android.bluetooth.IBluetoothGattCallback; +import android.bluetooth.IBluetoothGattServerCallback; import android.bluetooth.le.IAdvertiserCallback; import android.bluetooth.le.IAdvertisingSetCallback; import android.bluetooth.le.IPeriodicAdvertisingCallback; @@ -66,7 +66,7 @@ interface IBluetoothGatt { void registerSync(in ScanResult scanResult, in int skip, in int timeout, in IPeriodicAdvertisingCallback callback); void unregisterSync(in IPeriodicAdvertisingCallback callback); - void registerClient(in ParcelUuid appId, in IBluetoothGattCallbackExt callback); + void registerClient(in ParcelUuid appId, in IBluetoothGattCallback callback); void unregisterClient(in int clientIf); void clientConnect(in int clientIf, in String address, in boolean isDirect, in int transport, in int phy); @@ -88,7 +88,7 @@ interface IBluetoothGatt { void configureMTU(in int clientIf, in String address, in int mtu); void connectionParameterUpdate(in int clientIf, in String address, in int connectionPriority); - void registerServer(in ParcelUuid appId, in IBluetoothGattServerCallbackExt callback); + void registerServer(in ParcelUuid appId, in IBluetoothGattServerCallback callback); void unregisterServer(in int serverIf); void serverConnect(in int serverIf, in String address, in boolean isDirect, in int transport); void serverDisconnect(in int serverIf, in String address); diff --git a/core/java/android/bluetooth/IBluetoothGattCallbackExt.aidl b/core/java/android/bluetooth/IBluetoothGattCallback.aidl index ed69e54671ca..4f85cdda87f7 100644 --- a/core/java/android/bluetooth/IBluetoothGattCallbackExt.aidl +++ b/core/java/android/bluetooth/IBluetoothGattCallback.aidl @@ -22,7 +22,7 @@ import android.bluetooth.BluetoothGattService; * Callback definitions for interacting with BLE / GATT * @hide */ -oneway interface IBluetoothGattCallbackExt { +oneway interface IBluetoothGattCallback { void onClientRegistered(in int status, in int clientIf); void onClientConnectionState(in int status, in int clientIf, in boolean connected, in String address); diff --git a/core/java/android/bluetooth/IBluetoothGattServerCallbackExt.aidl b/core/java/android/bluetooth/IBluetoothGattServerCallback.aidl index 267e8824439d..74ee11fbd321 100644 --- a/core/java/android/bluetooth/IBluetoothGattServerCallbackExt.aidl +++ b/core/java/android/bluetooth/IBluetoothGattServerCallback.aidl @@ -21,7 +21,7 @@ import android.bluetooth.BluetoothGattService; * Callback definitions for interacting with BLE / GATT * @hide */ -oneway interface IBluetoothGattServerCallbackExt { +oneway interface IBluetoothGattServerCallback { void onServerRegistered(in int status, in int serverIf); void onServerConnectionState(in int status, in int serverIf, in boolean connected, in String address); diff --git a/core/java/android/bluetooth/le/AdvertisingSetParameters.java b/core/java/android/bluetooth/le/AdvertisingSetParameters.java index fe1f425c4fc1..3e13ad34f019 100644 --- a/core/java/android/bluetooth/le/AdvertisingSetParameters.java +++ b/core/java/android/bluetooth/le/AdvertisingSetParameters.java @@ -253,10 +253,10 @@ public final class AdvertisingSetParameters implements Parcelable { /** * Set whether the advertisement type should be connectable or * non-connectable. - * Legacy advertisements can be both connectable and scannable. Other - * advertisements can be connectable only if not scannable. + * Legacy advertisements must be both connectable and scannable. Nonlegacy + * advertisements can be only scannable or only connectable. * @param connectable Controls whether the advertisment type will be - * connectable (true) or non-connectable (false). + * connectable (true) or nonconnectable (false). */ public Builder setConnectable(boolean connectable) { this.connectable = connectable; @@ -264,11 +264,11 @@ public final class AdvertisingSetParameters implements Parcelable { } /** - * Set whether the advertisement type should be scannable - * Legacy advertisements can be both connectable and scannable. Other - * advertisements can be scannable only if not connectable. + * Set whether the advertisement type should be scannable. + * Legacy advertisements must be both connectable and scannable. Nonlegacy + * advertisements can be only scannable or only connectable. * @param scannable Controls whether the advertisment type will be - * scannable (true) or non-scannable (false). + * scannable (true) or nonscannable (false). */ public Builder setScannable(boolean scannable) { this.scannable = scannable; @@ -279,7 +279,7 @@ public final class AdvertisingSetParameters implements Parcelable { * When set to true, advertising set will advertise 4.x Spec compliant * advertisements. * - * @param isLegacy wether legacy advertising mode should be used. + * @param isLegacy whether legacy advertising mode should be used. */ public Builder setLegacyMode(boolean isLegacy) { this.isLegacy = isLegacy; @@ -287,12 +287,12 @@ public final class AdvertisingSetParameters implements Parcelable { } /** - * Set wether advertiser address should be ommited from all packets. If this + * Set whether advertiser address should be ommited from all packets. If this * mode is used, periodic advertising can't be enabled for this set. * * This is used only if legacy mode is not used. * - * @param isAnonymous wether anonymous advertising should be used. + * @param isAnonymous whether anonymous advertising should be used. */ public Builder setAnonymous(boolean isAnonymous) { this.isAnonymous = isAnonymous; @@ -300,11 +300,11 @@ public final class AdvertisingSetParameters implements Parcelable { } /** - * Set wether TX power should be included in the extended header. + * Set whether TX power should be included in the extended header. * * This is used only if legacy mode is not used. * - * @param includeTxPower wether TX power should be included in extended + * @param includeTxPower whether TX power should be included in extended * header */ public Builder setIncludeTxPower(boolean includeTxPower) { diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java b/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java index 6616231bcdf8..364b575b4d8d 100644 --- a/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java +++ b/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java @@ -23,6 +23,7 @@ import android.bluetooth.BluetoothDevice; * advertising operation status. * * @see PeriodicAdvertisingManager#createSync + * @hide */ public abstract class PeriodicAdvertisingCallback { diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java b/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java index 12c8a8c8ffd4..d9c2d8819a33 100644 --- a/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java +++ b/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java @@ -37,6 +37,7 @@ import java.util.Map; * <p> * <b>Note:</b> Most of the methods here require * {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. + * @hide */ public final class PeriodicAdvertisingManager { diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java b/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java index ebc92bd0bcf8..149540ce0dab 100644 --- a/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java +++ b/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java @@ -93,7 +93,7 @@ public final class PeriodicAdvertisingParameters implements Parcelable { private int interval = INTERVAL_MAX; /** - * Set wether the Periodic Advertising should be enabled for this set. + * Set whether the Periodic Advertising should be enabled for this set. */ public Builder setEnable(boolean enable) { this.enable = enable; diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java b/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java index 3ff4ca580069..51b93cbd64dc 100644 --- a/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java +++ b/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java @@ -24,6 +24,7 @@ import java.util.Objects; /** * PeriodicAdvertisingReport for Bluetooth LE synchronized advertising. + * @hide */ public final class PeriodicAdvertisingReport implements Parcelable { diff --git a/core/java/android/companion/AssociationRequest.java b/core/java/android/companion/AssociationRequest.java index bb844a327168..919f4baf3b86 100644 --- a/core/java/android/companion/AssociationRequest.java +++ b/core/java/android/companion/AssociationRequest.java @@ -27,6 +27,7 @@ import com.android.internal.util.CollectionUtils; import java.util.ArrayList; import java.util.List; +import java.util.Objects; /** * A request for the user to select a companion device to associate with. @@ -69,6 +70,20 @@ public final class AssociationRequest implements Parcelable { } @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + AssociationRequest that = (AssociationRequest) o; + return mSingleDevice == that.mSingleDevice && + Objects.equals(mDeviceFilters, that.mDeviceFilters); + } + + @Override + public int hashCode() { + return Objects.hash(mSingleDevice, mDeviceFilters); + } + + @Override public void writeToParcel(Parcel dest, int flags) { dest.writeByte((byte) (mSingleDevice ? 1 : 0)); dest.writeParcelableList(mDeviceFilters, flags); diff --git a/core/java/android/companion/BluetoothDeviceFilter.java b/core/java/android/companion/BluetoothDeviceFilter.java index 1d8df7f26f6e..84e15364c191 100644 --- a/core/java/android/companion/BluetoothDeviceFilter.java +++ b/core/java/android/companion/BluetoothDeviceFilter.java @@ -35,6 +35,7 @@ import com.android.internal.util.CollectionUtils; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.regex.Pattern; /** @@ -123,6 +124,22 @@ public final class BluetoothDeviceFilter implements DeviceFilter<BluetoothDevice } @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + BluetoothDeviceFilter that = (BluetoothDeviceFilter) o; + return Objects.equals(mNamePattern, that.mNamePattern) && + Objects.equals(mAddress, that.mAddress) && + Objects.equals(mServiceUuids, that.mServiceUuids) && + Objects.equals(mServiceUuidMasks, that.mServiceUuidMasks); + } + + @Override + public int hashCode() { + return Objects.hash(mNamePattern, mAddress, mServiceUuids, mServiceUuidMasks); + } + + @Override public int describeContents() { return 0; } diff --git a/core/java/android/companion/BluetoothDeviceFilterUtils.java b/core/java/android/companion/BluetoothDeviceFilterUtils.java index 8a316f19af8e..3665d1b85bcb 100644 --- a/core/java/android/companion/BluetoothDeviceFilterUtils.java +++ b/core/java/android/companion/BluetoothDeviceFilterUtils.java @@ -37,7 +37,7 @@ public class BluetoothDeviceFilterUtils { private BluetoothDeviceFilterUtils() {} private static final boolean DEBUG = false; - private static final String LOG_TAG = "BluetoothDeviceFilterUtil"; + private static final String LOG_TAG = "BluetoothDeviceFilterUtils"; @Nullable static String patternToString(@Nullable Pattern p) { @@ -50,8 +50,10 @@ public class BluetoothDeviceFilterUtils { } static boolean matches(ScanFilter filter, BluetoothDevice device) { - return matchesAddress(filter.getDeviceAddress(), device) + boolean result = matchesAddress(filter.getDeviceAddress(), device) && matchesServiceUuid(filter.getServiceUuid(), filter.getServiceUuidMask(), device); + if (DEBUG) debugLogMatchResult(result, device, filter); + return result; } static boolean matchesAddress(String deviceAddress, BluetoothDevice device) { diff --git a/core/java/android/companion/BluetoothLEDeviceFilter.java b/core/java/android/companion/BluetoothLEDeviceFilter.java index e057fbcc901a..5a1b29d63e10 100644 --- a/core/java/android/companion/BluetoothLEDeviceFilter.java +++ b/core/java/android/companion/BluetoothLEDeviceFilter.java @@ -31,11 +31,14 @@ import android.bluetooth.le.ScanResult; import android.os.Parcel; import android.provider.OneTimeUseBuilder; import android.text.TextUtils; +import android.util.Log; import com.android.internal.util.BitUtils; import com.android.internal.util.ObjectUtils; import com.android.internal.util.Preconditions; +import java.util.Arrays; +import java.util.Objects; import java.util.regex.Pattern; /** @@ -45,6 +48,9 @@ import java.util.regex.Pattern; */ public final class BluetoothLEDeviceFilter implements DeviceFilter<ScanResult> { + private static final boolean DEBUG = false; + private static final String LOG_TAG = "BluetoothLEDeviceFilter"; + private static final int RENAME_PREFIX_LENGTH_LIMIT = 10; private final Pattern mNamePattern; @@ -143,9 +149,13 @@ public final class BluetoothLEDeviceFilter implements DeviceFilter<ScanResult> { /** @hide */ @Override public boolean matches(ScanResult device) { - return matches(device.getDevice()) - && BitUtils.maskedEquals(device.getScanRecord().getBytes(), - mRawDataFilter, mRawDataFilterMask); + boolean result = matches(device.getDevice()) + && (mRawDataFilter == null + || BitUtils.maskedEquals(device.getScanRecord().getBytes(), + mRawDataFilter, mRawDataFilterMask)); + if (DEBUG) Log.i(LOG_TAG, "matches(this = " + this + ", device = " + device + + ") -> " + result); + return result; } private boolean matches(BluetoothDevice device) { @@ -160,9 +170,39 @@ public final class BluetoothLEDeviceFilter implements DeviceFilter<ScanResult> { } @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + BluetoothLEDeviceFilter that = (BluetoothLEDeviceFilter) o; + return mRenameBytesFrom == that.mRenameBytesFrom && + mRenameBytesTo == that.mRenameBytesTo && + mRenameBytesReverseOrder == that.mRenameBytesReverseOrder && + Objects.equals(mNamePattern, that.mNamePattern) && + Objects.equals(mScanFilter, that.mScanFilter) && + Arrays.equals(mRawDataFilter, that.mRawDataFilter) && + Arrays.equals(mRawDataFilterMask, that.mRawDataFilterMask) && + Objects.equals(mRenamePrefix, that.mRenamePrefix) && + Objects.equals(mRenameSuffix, that.mRenameSuffix); + } + + @Override + public int hashCode() { + return Objects.hash(mNamePattern, mScanFilter, mRawDataFilter, mRawDataFilterMask, + mRenamePrefix, mRenameSuffix, mRenameBytesFrom, mRenameBytesTo, + mRenameBytesReverseOrder); + } + + @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(patternToString(getNamePattern())); dest.writeParcelable(mScanFilter, flags); + dest.writeByteArray(mRawDataFilter); + dest.writeByteArray(mRawDataFilterMask); + dest.writeString(mRenamePrefix); + dest.writeString(mRenameSuffix); + dest.writeInt(mRenameBytesFrom); + dest.writeInt(mRenameBytesTo); + dest.writeBoolean(mRenameBytesReverseOrder); } @Override @@ -174,13 +214,23 @@ public final class BluetoothLEDeviceFilter implements DeviceFilter<ScanResult> { = new Creator<BluetoothLEDeviceFilter>() { @Override public BluetoothLEDeviceFilter createFromParcel(Parcel in) { - return new BluetoothLEDeviceFilter.Builder() + Builder builder = new Builder() .setNamePattern(patternFromString(in.readString())) - .setScanFilter(in.readParcelable(null)) - .setRawDataFilter(in.readBlob(), in.readBlob()) - .setRename(in.readString(), in.readString(), - in.readInt(), in.readInt(), in.readBoolean()) - .build(); + .setScanFilter(in.readParcelable(null)); + byte[] rawDataFilter = in.createByteArray(); + byte[] rawDataFilterMask = in.createByteArray(); + if (rawDataFilter != null) { + builder.setRawDataFilter(rawDataFilter, rawDataFilterMask); + } + String renamePrefix = in.readString(); + String suffix = in.readString(); + int bytesFrom = in.readInt(); + int bytesTo = in.readInt(); + boolean bytesReverseOrder = in.readBoolean(); + if (renamePrefix != null) { + builder.setRename(renamePrefix, suffix, bytesFrom, bytesTo, bytesReverseOrder); + } + return builder.build(); } @Override @@ -240,12 +290,14 @@ public final class BluetoothLEDeviceFilter implements DeviceFilter<ScanResult> { */ @NonNull public Builder setRawDataFilter(@NonNull byte[] rawDataFilter, - @NonNull byte[] rawDataFilterMask) { + @Nullable byte[] rawDataFilterMask) { checkNotUsed(); - checkArgument(rawDataFilter.length == rawDataFilterMask.length, + Preconditions.checkNotNull(rawDataFilter); + checkArgument(rawDataFilterMask == null || + rawDataFilter.length == rawDataFilterMask.length, "Mask and filter should be the same length"); - mRawDataFilter = Preconditions.checkNotNull(rawDataFilter); - mRawDataFilterMask = Preconditions.checkNotNull(rawDataFilterMask); + mRawDataFilter = rawDataFilter; + mRawDataFilterMask = rawDataFilterMask; return this; } diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java index 78e3de47df06..7b38863c9cc6 100644 --- a/core/java/android/companion/CompanionDeviceManager.java +++ b/core/java/android/companion/CompanionDeviceManager.java @@ -17,6 +17,8 @@ package android.companion; +import static com.android.internal.util.Preconditions.checkNotNull; + import android.annotation.NonNull; import android.annotation.Nullable; import android.app.PendingIntent; @@ -24,7 +26,6 @@ import android.content.Context; import android.content.IntentSender; import android.content.pm.PackageManager; import android.os.Handler; -import android.os.Looper; import android.os.RemoteException; import android.util.Log; @@ -43,7 +44,7 @@ import java.util.List; */ public final class CompanionDeviceManager { - private static final boolean DEBUG = false; //TODO + private static final boolean DEBUG = false; private static final String LOG_TAG = "CompanionDeviceManager"; /** @@ -129,10 +130,9 @@ public final class CompanionDeviceManager { if (!checkFeaturePresent()) { return; } - - final Handler finalHandler = handler != null - ? handler - : new Handler(Looper.getMainLooper()); + checkNotNull(request, "Request cannot be null"); + checkNotNull(callback, "Callback cannot be null"); + final Handler finalHandler = Handler.mainIfNull(handler); try { mService.associate( request, diff --git a/core/java/android/companion/WifiDeviceFilter.java b/core/java/android/companion/WifiDeviceFilter.java index 1ab9ce11cb0f..b6e704c39998 100644 --- a/core/java/android/companion/WifiDeviceFilter.java +++ b/core/java/android/companion/WifiDeviceFilter.java @@ -29,6 +29,7 @@ import android.net.wifi.ScanResult; import android.os.Parcel; import android.provider.OneTimeUseBuilder; +import java.util.Objects; import java.util.regex.Pattern; /** @@ -75,6 +76,19 @@ public final class WifiDeviceFilter implements DeviceFilter<ScanResult> { } @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + WifiDeviceFilter that = (WifiDeviceFilter) o; + return Objects.equals(mNamePattern, that.mNamePattern); + } + + @Override + public int hashCode() { + return Objects.hash(mNamePattern); + } + + @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(patternToString(getNamePattern())); } diff --git a/core/java/android/content/ClipboardManager.java b/core/java/android/content/ClipboardManager.java index c28172c6347c..f1c2f342eb3e 100644 --- a/core/java/android/content/ClipboardManager.java +++ b/core/java/android/content/ClipboardManager.java @@ -150,7 +150,7 @@ public class ClipboardManager extends android.text.ClipboardManager { public void addPrimaryClipChangedListener(OnPrimaryClipChangedListener what) { synchronized (mPrimaryClipChangedListeners) { - if (mPrimaryClipChangedListeners.size() == 0) { + if (mPrimaryClipChangedListeners.isEmpty()) { try { mService.addPrimaryClipChangedListener( mPrimaryClipChangedServiceListener, mContext.getOpPackageName()); @@ -165,7 +165,7 @@ public class ClipboardManager extends android.text.ClipboardManager { public void removePrimaryClipChangedListener(OnPrimaryClipChangedListener what) { synchronized (mPrimaryClipChangedListeners) { mPrimaryClipChangedListeners.remove(what); - if (mPrimaryClipChangedListeners.size() == 0) { + if (mPrimaryClipChangedListeners.isEmpty()) { try { mService.removePrimaryClipChangedListener( mPrimaryClipChangedServiceListener); diff --git a/core/java/android/content/ContentProviderOperation.java b/core/java/android/content/ContentProviderOperation.java index fd1e24a48da5..8f3a31746266 100644 --- a/core/java/android/content/ContentProviderOperation.java +++ b/core/java/android/content/ContentProviderOperation.java @@ -508,14 +508,14 @@ public class ContentProviderOperation implements Parcelable { /** Create a ContentProviderOperation from this {@link Builder}. */ public ContentProviderOperation build() { if (mType == TYPE_UPDATE) { - if ((mValues == null || mValues.size() == 0) - && (mValuesBackReferences == null || mValuesBackReferences.size() == 0)) { + if ((mValues == null || mValues.isEmpty()) + && (mValuesBackReferences == null || mValuesBackReferences.isEmpty())) { throw new IllegalArgumentException("Empty values"); } } if (mType == TYPE_ASSERT) { - if ((mValues == null || mValues.size() == 0) - && (mValuesBackReferences == null || mValuesBackReferences.size() == 0) + if ((mValues == null || mValues.isEmpty()) + && (mValuesBackReferences == null || mValuesBackReferences.isEmpty()) && (mExpectedCount == null)) { throw new IllegalArgumentException("Empty values"); } diff --git a/core/java/android/content/ContentValues.java b/core/java/android/content/ContentValues.java index 3a87cb3e7a29..6f9379890a3a 100644 --- a/core/java/android/content/ContentValues.java +++ b/core/java/android/content/ContentValues.java @@ -204,6 +204,17 @@ public final class ContentValues implements Parcelable { } /** + * Indicates whether this collection is empty. + * + * @return true iff size == 0 + * {@hide} + * TODO: consider exposing this new method publicly + */ + public boolean isEmpty() { + return mValues.isEmpty(); + } + + /** * Remove a single value. * * @param key the name of the value to remove diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 3a8a4206e105..1803bbe24610 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -2576,7 +2576,7 @@ public abstract class Context { * {@link ComponentName} of the actual service that was started is * returned; else if the service does not exist null is returned. * - * @throws SecurityException If the caller does not permission to access the service + * @throws SecurityException If the caller does not have permission to access the service * or the service can not be found. * @throws IllegalStateException If the application is in a state where the service * can not be started (such as not in the foreground in a state when services are allowed). @@ -2588,11 +2588,47 @@ public abstract class Context { public abstract ComponentName startService(Intent service); /** + * Similar to {@link #startService(Intent)}, but with an implicit promise that the + * Service will call {@link android.app.Service#startForeground(int, Notification) + * startForeground(int, Notification)} once it begins running. The service is given + * an amount of time comparable to the ANR interval to do this, otherwise the system + * will automatically stop the service and declare the app ANR. + * + * <p>Unlike the ordinary {@link #startService(Intent)}, this method can be used + * at any time, regardless of whether the app hosting the service is in a foreground + * state. + * + * @param service Identifies the service to be started. The Intent must be + * fully explicit (supplying a component name). Additional values + * may be included in the Intent extras to supply arguments along with + * this specific start call. + * + * @return If the service is being started or is already running, the + * {@link ComponentName} of the actual service that was started is + * returned; else if the service does not exist null is returned. + * + * @throws SecurityException If the caller does not have permission to access the service + * or the service can not be found. + * + * @see #stopService + * @see android.app.Service#startForeground(int, Notification) + */ + @Nullable + public abstract ComponentName startForegroundService(Intent service); + + /** + * @hide like {@link #startForegroundService(Intent)} but for a specific user. + */ + @Nullable + public abstract ComponentName startForegroundServiceAsUser(Intent service, UserHandle user); + + /** * Start a service directly into the "foreground service" state. Unlike {@link #startService}, * this method can be used from within background operations like broadcast receivers * or scheduled jobs. The API entry point for this is in NotificationManager in order to * preserve appropriate public package layering. * @hide + * @deprecated STOPSHIP remove in favor of two-step startForegroundService() + startForeground() */ @Nullable public abstract ComponentName startServiceInForeground(Intent service, @@ -2620,7 +2656,7 @@ public abstract class Context { * @return If there is a service matching the given Intent that is already * running, then it is stopped and {@code true} is returned; else {@code false} is returned. * - * @throws SecurityException If the caller does not permission to access the service + * @throws SecurityException If the caller does not have permission to access the service * or the service can not be found. * @throws IllegalStateException If the application is in a state where the service * can not be started (such as not in the foreground in a state when services are allowed). @@ -2638,7 +2674,9 @@ public abstract class Context { /** * @hide like {@link #startServiceInForeground(Intent, int, Notification)} * but for a specific user. + * @deprecated STOPSHIP remove when trial API is turned off */ + @Deprecated @Nullable public abstract ComponentName startServiceInForegroundAsUser(Intent service, int id, Notification notification, UserHandle user); @@ -2685,7 +2723,7 @@ public abstract class Context { * {@code false} is returned if the connection is not made so you will not * receive the service object. * - * @throws SecurityException If the caller does not permission to access the service + * @throws SecurityException If the caller does not have permission to access the service * or the service can not be found. * * @see #unbindService diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index 6b0bbfaedc3e..75784a69c74c 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -644,7 +644,12 @@ public class ContextWrapper extends Context { return mBase.startService(service); } - /** @hide */ + @Override + public ComponentName startForegroundService(Intent service) { + return mBase.startForegroundService(service); + } + + /** @hide STOPSHIP remove when trial API is turned down */ @Override public ComponentName startServiceInForeground(Intent service, int id, Notification notification) { @@ -664,6 +669,12 @@ public class ContextWrapper extends Context { /** @hide */ @Override + public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) { + return mBase.startForegroundServiceAsUser(service, user); + } + + /** @hide STOPSHIP removed when trial API is turned down */ + @Override public ComponentName startServiceInForegroundAsUser(Intent service, int id, Notification notification, UserHandle user) { return mBase.startServiceInForegroundAsUser(service, id, notification, user); diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index fb86791a509c..7890a9607932 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1532,6 +1532,19 @@ public class Intent implements Parcelable, Cloneable { = "android.intent.action.RESOLVE_EPHEMERAL_PACKAGE"; /** + * Activity Action: Launch ephemeral settings. + * + * <p class="note"> + * This is a protected intent that can only be sent by the system. + * </p> + * + * @hide + */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_EPHEMERAL_RESOLVER_SETTINGS + = "android.intent.action.EPHEMERAL_RESOLVER_SETTINGS"; + + /** * Used as a string extra field with {@link #ACTION_INSTALL_PACKAGE} to install a * package. Specifies the installer package name; this package will receive the * {@link #ACTION_APP_ERROR} intent. diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 59b022ded9bf..147df763fce2 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -630,4 +630,6 @@ interface IPackageManager { boolean canRequestPackageInstalls(String packageName, int userId); void deletePreloadsFileCache(); + + ComponentName getInstantAppResolverSettingsComponent(); } diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 71db5d311bd6..136c13b6f37d 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -153,6 +153,7 @@ public abstract class PackageManager { MATCH_UNINSTALLED_PACKAGES, MATCH_SYSTEM_ONLY, MATCH_DEBUG_TRIAGED_MISSING, + MATCH_DISABLED_COMPONENTS, MATCH_DISABLED_UNTIL_USED_COMPONENTS, MATCH_INSTANT, GET_DISABLED_UNTIL_USED_COMPONENTS, @@ -431,6 +432,7 @@ public abstract class PackageManager { * This will not return information on any unbundled update to system components. * @hide */ + @SystemApi public static final int MATCH_FACTORY_ONLY = 0x00200000; /** @@ -3730,6 +3732,7 @@ public abstract class PackageManager { * * @param flags Additional option flags. Use any combination of * {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES}, + * {@link #MATCH_DISABLED_COMPONENTS}, {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS} * {@link #MATCH_SYSTEM_ONLY}, {@link #MATCH_UNINSTALLED_PACKAGES} * to modify the data returned. * @@ -3743,6 +3746,7 @@ public abstract class PackageManager { * * @see #GET_META_DATA * @see #GET_SHARED_LIBRARY_FILES + * @see #MATCH_DISABLED_COMPONENTS * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS * @see #MATCH_SYSTEM_ONLY * @see #MATCH_UNINSTALLED_PACKAGES @@ -3757,6 +3761,7 @@ public abstract class PackageManager { * * @param flags Additional option flags. Use any combination of * {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES}, + * {@link #MATCH_DISABLED_COMPONENTS}, {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS} * {@link #MATCH_SYSTEM_ONLY}, {@link #MATCH_UNINSTALLED_PACKAGES} * to modify the data returned. * @param userId The user for whom the installed applications are to be listed @@ -3772,6 +3777,7 @@ public abstract class PackageManager { * * @see #GET_META_DATA * @see #GET_SHARED_LIBRARY_FILES + * @see #MATCH_DISABLED_COMPONENTS * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS * @see #MATCH_SYSTEM_ONLY * @see #MATCH_UNINSTALLED_PACKAGES @@ -6233,4 +6239,14 @@ public abstract class PackageManager { * @see {@link android.provider.Settings#ACTION_MANAGE_EXTERNAL_SOURCES} */ public abstract boolean canRequestPackageInstalls(); + + /** + * Return the {@link ComponentName} of the activity providing Settings for the Instant App + * resolver. + * + * @see {@link android.content.intent#ACTION_EPHEMERAL_RESOLVER_SETTINGS} + * @hide + */ + @SystemApi + public abstract ComponentName getInstantAppResolverSettingsComponent(); } diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java index 6272822ac308..16d582efb730 100644 --- a/core/java/android/content/pm/PackageManagerInternal.java +++ b/core/java/android/content/pm/PackageManagerInternal.java @@ -172,6 +172,7 @@ public abstract class PackageManagerInternal { * @param packageName The package name. * @param userId The user for which to check. * @return Whether was launched. + * @throws IllegalArgumentException if the package is not found */ public abstract boolean wasPackageEverLaunched(String packageName, int userId); @@ -241,6 +242,7 @@ public abstract class PackageManagerInternal { public abstract void grantEphemeralAccess(int userId, Intent intent, int targetAppId, int ephemeralAppId); + public abstract boolean isInstantAppInstallerComponent(ComponentName component); /** * Prunes instant apps and state associated with uninstalled * instant apps according to the current platform policy. @@ -312,4 +314,17 @@ public abstract class PackageManagerInternal { */ public abstract ResolveInfo resolveIntent(Intent intent, String resolvedType, int flags, int userId); + + /** + * Track the creator of a new isolated uid. + * @param isolatedUid The newly created isolated uid. + * @param ownerUid The uid of the app that created the isolated process. + */ + public abstract void addIsolatedUid(int isolatedUid, int ownerUid); + + /** + * Track removal of an isolated uid. + * @param isolatedUid isolated uid that is no longer being used. + */ + public abstract void removeIsolatedUid(int isolatedUid); } diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 1fafe6534077..d264e094ca3f 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -4400,8 +4400,12 @@ public class PackageParser { defaultMaxAspectRatio = owner.applicationInfo.maxAspectRatio; } - aInfo.maxAspectRatio = Math.max(1.0f, sa.getFloat( - R.styleable.AndroidManifestActivity_maxAspectRatio, defaultMaxAspectRatio)); + aInfo.maxAspectRatio = sa.getFloat( + R.styleable.AndroidManifestActivity_maxAspectRatio, defaultMaxAspectRatio); + if (aInfo.maxAspectRatio < 1.0f && aInfo.maxAspectRatio != 0) { + // Ignore any value lesser than 1.0. + aInfo.maxAspectRatio = 0; + } } /** diff --git a/core/java/android/content/pm/ShortcutManager.java b/core/java/android/content/pm/ShortcutManager.java index 7a0158a8d9af..b992d29eb32f 100644 --- a/core/java/android/content/pm/ShortcutManager.java +++ b/core/java/android/content/pm/ShortcutManager.java @@ -242,6 +242,7 @@ import java.util.List; * You can provide multiple intents for a single shortcut so that the last defined activity is launched * with the other activities in the <a href="/guide/components/tasks-and-back-stack.html">back stack</a>. * See {@link android.app.TaskStackBuilder} for details. + * <p><b>Note:</b> String resources may not be used within an {@code <intent>} element. * </dd> * <dt>{@code categories}</dt> * <dd>Specify shortcut categories. Currently only diff --git a/core/java/android/database/PageViewCursor.java b/core/java/android/database/PageViewCursor.java index 44727a0d300e..4569a2765f51 100644 --- a/core/java/android/database/PageViewCursor.java +++ b/core/java/android/database/PageViewCursor.java @@ -15,6 +15,7 @@ */ package android.database; +import static com.android.internal.util.ArrayUtils.contains; import static com.android.internal.util.Preconditions.checkArgument; import android.annotation.Nullable; @@ -25,7 +26,7 @@ import android.os.Bundle; import android.util.Log; import android.util.MathUtils; -import com.android.internal.util.ArrayUtils; +import java.util.Arrays; /** * Cursor wrapper that provides visibility into a subset of a wrapped cursor. @@ -40,11 +41,12 @@ public final class PageViewCursor extends CursorWrapper implements CrossProcessC /** An extra added to results that are auto-paged using the wrapper. */ public static final String EXTRA_AUTO_PAGED = "android.content.extra.AUTO_PAGED"; + private static final String[] EMPTY_ARGS = new String[0]; private static final String TAG = "PageViewCursor"; private static final boolean DEBUG = Build.IS_DEBUGGABLE; private static final boolean VERBOSE = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.VERBOSE); - private final int mOffset; // aka first index + private final int mOffset; // aka first index private final int mCount; private final Bundle mExtras; @@ -55,12 +57,17 @@ public final class PageViewCursor extends CursorWrapper implements CrossProcessC /** * @see PageViewCursor#wrap(Cursor, Bundle) */ - public PageViewCursor(Cursor cursor, int offset, int limit) { + public PageViewCursor(Cursor cursor, Bundle queryArgs) { super(cursor); + int offset = queryArgs.getInt(ContentResolver.QUERY_ARG_OFFSET, 0); + int limit = queryArgs.getInt(ContentResolver.QUERY_ARG_LIMIT, Integer.MAX_VALUE); + checkArgument(offset > -1); checkArgument(limit > -1); + int count = mCursor.getCount(); + mOffset = offset; mExtras = new Bundle(); @@ -68,26 +75,47 @@ public final class PageViewCursor extends CursorWrapper implements CrossProcessC if (extras != null) { mExtras.putAll(extras); } - mExtras.putBoolean(EXTRA_AUTO_PAGED, true); - - // We need a mutable bundle so we can add QUERY_RESULT_SIZE. - // Direct equality check is correct here. Bundle.EMPTY is a specific instance - // of Bundle that is immutable by way of implementation. - // mExtras = (extras == Bundle.EMPTY) ? new Bundle() : extras; // When we're wrapping another cursor, it should not already be "paged". - checkArgument(!mExtras.containsKey(ContentResolver.EXTRA_TOTAL_SIZE)); + checkArgument(!hasPagedResponseDetails(mExtras)); - int count = mCursor.getCount(); + mExtras.putBoolean(EXTRA_AUTO_PAGED, true); mExtras.putInt(ContentResolver.EXTRA_TOTAL_SIZE, count); + // Ensure we retain any extra args supplied in cursor extras, and add + // offset and/or limit. + String[] existingArgs = mExtras.getStringArray(ContentResolver.EXTRA_HONORED_ARGS); + existingArgs = existingArgs != null ? existingArgs : EMPTY_ARGS; + + int size = existingArgs.length; + + // copy the array with space for the extra query args we'll be adding. + String[] newArgs = Arrays.copyOf(existingArgs, size + 2); + + if (queryArgs.containsKey(ContentResolver.QUERY_ARG_OFFSET)) { + newArgs[size++] = ContentResolver.QUERY_ARG_OFFSET; + } + if (queryArgs.containsKey(ContentResolver.QUERY_ARG_LIMIT)) { + newArgs[size++] = ContentResolver.QUERY_ARG_LIMIT; + } + + assert(size > existingArgs.length); // must add at least one arg. + + // At this point there may be a null element at the end of + // the array because our pre-sizing didn't match the actualy + // number of args we added. So we trim. + if (size == newArgs.length - 1) { + newArgs = Arrays.copyOf(newArgs, size); + } + mExtras.putStringArray(ContentResolver.EXTRA_HONORED_ARGS, newArgs); + mCount = MathUtils.constrain(count - offset, 0, limit); if (DEBUG) Log.d(TAG, "Wrapped cursor" - + " offset: " + mOffset - + ", limit: " + limit - + ", delegate_size: " + count - + ", paged_count: " + mCount); + + " offset: " + mOffset + + ", limit: " + limit + + ", delegate_size: " + count + + ", paged_count: " + mCount); } @Override @@ -155,9 +183,9 @@ public final class PageViewCursor extends CursorWrapper implements CrossProcessC public boolean moveToPosition(int position) { if (position >= mCount) { if (VERBOSE) Log.v(TAG, "Invalid Positon: " + position + " >= count: " + mCount - + ". Moving to last record."); + + ". Moving to last record."); mPos = mCount; - super.moveToPosition(mOffset + mPos); // move into "after last" state. + super.moveToPosition(mOffset + mPos); // move into "after last" state. return false; } @@ -198,15 +226,15 @@ public final class PageViewCursor extends CursorWrapper implements CrossProcessC @Override public boolean getWantsAllOnMoveCalls() { - return false; // we want bulk cursor adapter to lift data into a CursorWindow. + return false; // we want bulk cursor adapter to lift data into a CursorWindow. } @Override public CursorWindow getWindow() { assert(mPos == -1 || mPos == 0); if (mWindow == null) { - mWindow = new CursorWindow("PageViewCursorWindow"); - fillWindow(0, mWindow); + mWindow = new CursorWindow("PageViewCursorWindow"); + fillWindow(0, mWindow); } return mWindow; @@ -224,17 +252,16 @@ public final class PageViewCursor extends CursorWrapper implements CrossProcessC } /** - * Wraps the cursor such that it will honor paging args (if present), AND if the cursor - * does not report paging size. - * - * <p>No-op if cursor already contains paging or is less than specified page size. + * Wraps the cursor such that it will honor paging args (if present), AND if the cursor does + * not report paging size. + * <p> + * No-op if cursor already contains paging or is less than specified page size. */ public static Cursor wrap(Cursor cursor, @Nullable Bundle queryArgs) { - boolean hasPagingArgs = - queryArgs != null + boolean hasPagingArgs = queryArgs != null && (queryArgs.containsKey(ContentResolver.QUERY_ARG_OFFSET) - || queryArgs.containsKey(ContentResolver.QUERY_ARG_LIMIT)); + || queryArgs.containsKey(ContentResolver.QUERY_ARG_LIMIT)); if (!hasPagingArgs) { if (VERBOSE) Log.v(TAG, "No-wrap: No paging args in request."); @@ -253,25 +280,26 @@ public final class PageViewCursor extends CursorWrapper implements CrossProcessC return cursor; } - return new PageViewCursor( - cursor, - queryArgs.getInt(ContentResolver.QUERY_ARG_OFFSET, 0), - queryArgs.getInt(ContentResolver.QUERY_ARG_LIMIT, Integer.MAX_VALUE)); + return new PageViewCursor(cursor, queryArgs); } /** - * @return true if the extras contains information indicating the associated - * cursor is paged. + * @return true if the extras contains information indicating the associated cursor is + * paged. */ private static boolean hasPagedResponseDetails(@Nullable Bundle extras) { - if (extras != null && extras.containsKey(ContentResolver.EXTRA_TOTAL_SIZE)) { + if (extras == null) { + return false; + } + + if (extras.containsKey(ContentResolver.EXTRA_TOTAL_SIZE)) { return true; } String[] honoredArgs = extras.getStringArray(ContentResolver.EXTRA_HONORED_ARGS); - if (honoredArgs != null && ( - ArrayUtils.contains(honoredArgs, ContentResolver.QUERY_ARG_OFFSET) - || ArrayUtils.contains(honoredArgs, ContentResolver.QUERY_ARG_LIMIT))) { + if (honoredArgs != null + && (contains(honoredArgs, ContentResolver.QUERY_ARG_OFFSET) + || contains(honoredArgs, ContentResolver.QUERY_ARG_LIMIT))) { return true; } diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java index 8e178320d66d..fe849b8a99cf 100644 --- a/core/java/android/database/sqlite/SQLiteDatabase.java +++ b/core/java/android/database/sqlite/SQLiteDatabase.java @@ -1449,7 +1449,7 @@ public final class SQLiteDatabase extends SQLiteClosable { sql.append('('); Object[] bindArgs = null; - int size = (initialValues != null && initialValues.size() > 0) + int size = (initialValues != null && !initialValues.isEmpty()) ? initialValues.size() : 0; if (size > 0) { bindArgs = new Object[size]; @@ -1541,7 +1541,7 @@ public final class SQLiteDatabase extends SQLiteClosable { */ public int updateWithOnConflict(String table, ContentValues values, String whereClause, String[] whereArgs, int conflictAlgorithm) { - if (values == null || values.size() == 0) { + if (values == null || values.isEmpty()) { throw new IllegalArgumentException("Empty values"); } diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java index dcd069d335e0..da771e48d85e 100644 --- a/core/java/android/hardware/camera2/CameraCaptureSession.java +++ b/core/java/android/hardware/camera2/CameraCaptureSession.java @@ -118,6 +118,11 @@ public abstract class CameraCaptureSession implements AutoCloseable { * the Surface provided to prepare must not be used as a target of a CaptureRequest submitted * to this session.</p> * + * <p>Note that if 2 surfaces share the same stream via {@link + * OutputConfiguration#enableSurfaceSharing} and {@link OutputConfiguration#addSurface}, + * prepare() only needs to be called on one surface, and {link + * StateCallback#onSurfacePrepared} will be triggered for both surfaces.</p> + * * <p>{@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY} * devices cannot pre-allocate output buffers; for those devices, * {@link StateCallback#onSurfacePrepared} will be immediately called, and no preallocation is diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java index e3b97e82f6c8..e75b3758a31e 100644 --- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java @@ -708,7 +708,8 @@ public class CameraDeviceImpl extends CameraDevice synchronized(mInterfaceLock) { int streamId = -1; for (int i = 0; i < mConfiguredOutputs.size(); i++) { - if (surface == mConfiguredOutputs.valueAt(i).getSurface()) { + final List<Surface> surfaces = mConfiguredOutputs.valueAt(i).getSurfaces(); + if (surfaces.contains(surface)) { streamId = mConfiguredOutputs.keyAt(i); break; } @@ -2020,9 +2021,10 @@ public class CameraDeviceImpl extends CameraDevice Log.w(TAG, "onPrepared invoked for unknown output Surface"); return; } - final Surface surface = output.getSurface(); - - sessionCallback.onSurfacePrepared(surface); + final List<Surface> surfaces = output.getSurfaces(); + for (Surface surface : surfaces) { + sessionCallback.onSurfacePrepared(surface); + } } @Override diff --git a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java index dbe1394e20ee..00e047db98c0 100644 --- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java +++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java @@ -1112,6 +1112,8 @@ public final class StreamConfigurationMap { return ImageFormat.DEPTH_POINT_CLOUD; case HAL_PIXEL_FORMAT_Y16: return ImageFormat.DEPTH16; + case HAL_PIXEL_FORMAT_RAW16: + return ImageFormat.RAW_DEPTH; case ImageFormat.JPEG: throw new IllegalArgumentException( "ImageFormat.JPEG is an unknown internal format"); @@ -1179,6 +1181,8 @@ public final class StreamConfigurationMap { return HAL_PIXEL_FORMAT_BLOB; case ImageFormat.DEPTH16: return HAL_PIXEL_FORMAT_Y16; + case ImageFormat.RAW_DEPTH: + return HAL_PIXEL_FORMAT_RAW16; default: return format; } @@ -1220,6 +1224,7 @@ public final class StreamConfigurationMap { return HAL_DATASPACE_V0_JFIF; case ImageFormat.DEPTH_POINT_CLOUD: case ImageFormat.DEPTH16: + case ImageFormat.RAW_DEPTH: return HAL_DATASPACE_DEPTH; default: return HAL_DATASPACE_UNKNOWN; @@ -1609,6 +1614,8 @@ public final class StreamConfigurationMap { return "DEPTH16"; case ImageFormat.DEPTH_POINT_CLOUD: return "DEPTH_POINT_CLOUD"; + case ImageFormat.RAW_DEPTH: + return "RAW_DEPTH"; case ImageFormat.PRIVATE: return "PRIVATE"; default: diff --git a/core/java/android/hardware/radio/RadioManager.java b/core/java/android/hardware/radio/RadioManager.java index 14bb923767ed..0e59a2dfe6bb 100644 --- a/core/java/android/hardware/radio/RadioManager.java +++ b/core/java/android/hardware/radio/RadioManager.java @@ -196,6 +196,19 @@ public class RadioManager { return mIsCaptureSupported; } + /** + * {@code true} if the module supports background scanning. At the given time it may not + * be available though, see {@link RadioTuner#startBackgroundScan()}. + * + * @return {@code true} if background scanning is supported (not necessary available + * at a given time), {@code false} otherwise. + * + * @hide FutureFeature + */ + public boolean isBackgroundScanningSupported() { + return false; + } + /** List of descriptors for all bands supported by this module. * @return an array of {@link BandDescriptor}. */ @@ -1136,21 +1149,27 @@ public class RadioManager { * {@link RadioTuner#getProgramInformation(RadioManager.ProgramInfo[])} */ public static class ProgramInfo implements Parcelable { + // sourced from hardware/interfaces/broadcastradio/1.1/types.hal + private final static int FLAG_LIVE = 1 << 0; + private final static int FLAG_MUTED = 1 << 1; + private final int mChannel; private final int mSubChannel; private final boolean mTuned; private final boolean mStereo; private final boolean mDigital; + private final int mFlags; private final int mSignalStrength; private final RadioMetadata mMetadata; ProgramInfo(int channel, int subChannel, boolean tuned, boolean stereo, - boolean digital, int signalStrength, RadioMetadata metadata) { + boolean digital, int signalStrength, RadioMetadata metadata, int flags) { mChannel = channel; mSubChannel = subChannel; mTuned = tuned; mStereo = stereo; mDigital = digital; + mFlags = flags; mSignalStrength = signalStrength; mMetadata = metadata; } @@ -1186,6 +1205,30 @@ public class RadioManager { public boolean isDigital() { return mDigital; } + + /** + * {@code true} if the program is currently playing live stream. + * This may result in a slightly altered reception parameters, + * usually targetted at reduced latency. + * + * @hide FutureFeature + */ + public boolean isLive() { + return (mFlags & FLAG_LIVE) != 0; + } + + /** + * {@code true} if radio stream is not playing, ie. due to bad reception + * conditions or buffering. In this state volume knob MAY be disabled to + * prevent user increasing volume too much. + * It does NOT mean the user has muted audio. + * + * @hide FutureFeature + */ + public boolean isMuted() { + return (mFlags & FLAG_MUTED) != 0; + } + /** Signal strength indicator from 0 (no signal) to 100 (excellent) * @return the signal strength indication. */ @@ -1212,6 +1255,7 @@ public class RadioManager { } else { mMetadata = null; } + mFlags = in.readInt(); } public static final Parcelable.Creator<ProgramInfo> CREATOR @@ -1239,6 +1283,7 @@ public class RadioManager { dest.writeByte((byte)1); mMetadata.writeToParcel(dest, flags); } + dest.writeInt(mFlags); } @Override @@ -1250,7 +1295,7 @@ public class RadioManager { public String toString() { return "ProgramInfo [mChannel=" + mChannel + ", mSubChannel=" + mSubChannel + ", mTuned=" + mTuned + ", mStereo=" + mStereo + ", mDigital=" + mDigital - + ", mSignalStrength=" + mSignalStrength + + ", mFlags=" + mFlags + ", mSignalStrength=" + mSignalStrength + ((mMetadata == null) ? "" : (", mMetadata=" + mMetadata.toString())) + "]"; } @@ -1264,6 +1309,7 @@ public class RadioManager { result = prime * result + (mTuned ? 1 : 0); result = prime * result + (mStereo ? 1 : 0); result = prime * result + (mDigital ? 1 : 0); + result = prime * result + mFlags; result = prime * result + mSignalStrength; result = prime * result + ((mMetadata == null) ? 0 : mMetadata.hashCode()); return result; @@ -1286,6 +1332,8 @@ public class RadioManager { return false; if (mDigital != other.isDigital()) return false; + if (mFlags != other.mFlags) + return false; if (mSignalStrength != other.getSignalStrength()) return false; if (mMetadata == null) { diff --git a/core/java/android/hardware/radio/RadioModule.java b/core/java/android/hardware/radio/RadioModule.java index 89648931fd53..c0df0f386b09 100644 --- a/core/java/android/hardware/radio/RadioModule.java +++ b/core/java/android/hardware/radio/RadioModule.java @@ -79,8 +79,14 @@ public class RadioModule extends RadioTuner { public native int getProgramInformation(RadioManager.ProgramInfo[] info); + public native boolean startBackgroundScan(); + public native @NonNull List<RadioManager.ProgramInfo> getProgramList(@Nullable String filter); + public native boolean isAnalogForced(); + + public native void setAnalogForced(boolean isForced); + public native boolean isAntennaConnected(); public native boolean hasControl(); diff --git a/core/java/android/hardware/radio/RadioTuner.java b/core/java/android/hardware/radio/RadioTuner.java index c8034eb94992..6e1232d84481 100644 --- a/core/java/android/hardware/radio/RadioTuner.java +++ b/core/java/android/hardware/radio/RadioTuner.java @@ -212,6 +212,23 @@ public abstract class RadioTuner { public abstract int getProgramInformation(RadioManager.ProgramInfo[] info); /** + * Initiates a background scan to update internally cached program list. + * + * It may not be necessary to initiate the scan explicitly - the scan MAY be performed on boot. + * + * The operation is asynchronous and {@link Callback} backgroundScanComplete or onError will + * be called if the return value of this call was {@code true}. As result of this call + * programListChanged may be triggered (if the scanned list differs). + * + * @return {@code true} if the scan was properly scheduled, {@code false} if the scan feature + * is unavailable; ie. temporarily due to ongoing foreground playback in single-tuner device + * or permanently if the feature is not supported + * (see ModuleProperties#isBackgroundScanningSupported()). + * @hide FutureFeature + */ + public abstract boolean startBackgroundScan(); + + /** * Get the list of discovered radio stations. * * To get the full list, set filter to null or empty string. Otherwise, client application @@ -219,13 +236,40 @@ public abstract class RadioTuner { * * @param filter vendor-specific selector for radio stations. * @return a list of radio stations. - * @throws IllegalStateException if the scan is in progress or has not been started. + * @throws IllegalStateException if the scan is in progress or has not been started, + * startBackgroundScan() call may fix it. * @throws IllegalArgumentException if the filter argument is not valid. * @hide FutureFeature */ public abstract @NonNull List<RadioManager.ProgramInfo> getProgramList(@Nullable String filter); /** + * Checks, if the analog playback is forced, see setAnalogForced. + * + * @throws IllegalStateException if the switch is not supported at current + * configuration. + * @return {@code true} if analog is forced, {@code false} otherwise. + * @hide FutureFeature + */ + public abstract boolean isAnalogForced(); + + /** + * Forces the analog playback for the supporting radio technology. + * + * User may disable digital playback for FM HD Radio or hybrid FM/DAB with + * this option. This is purely user choice, ie. does not reflect digital- + * analog handover managed from the HAL implementation side. + * + * Some radio technologies may not support this, ie. DAB. + * + * @param isForced {@code true} to force analog, {@code false} for a default behaviour. + * @throws IllegalStateException if the switch is not supported at current + * configuration. + * @hide FutureFeature + */ + public abstract void setAnalogForced(boolean isForced); + + /** * Get current antenna connection state for current configuration. * Only valid if a configuration has been applied. * @return {@code true} if the antenna is connected, {@code false} otherwise. @@ -317,6 +361,32 @@ public abstract class RadioTuner { * with control set to {@code true}. */ public void onControlChanged(boolean control) {} + + /** + * onBackgroundScanAvailabilityChange() is called when background scan + * feature becomes available or not. + * + * @param isAvailable true, if the tuner turned temporarily background- + * capable, false in the other case. + * @hide FutureFeature + */ + public void onBackgroundScanAvailabilityChange(boolean isAvailable) {} + + /** + * Called when a background scan completes successfully. + * + * @hide FutureFeature + */ + public void onBackgroundScanComplete() {} + + /** + * Called when available program list changed. + * + * Use getProgramList() to get the actual list. + * + * @hide FutureFeature + */ + public void onProgramListChanged() {} } } diff --git a/core/java/android/metrics/LogMaker.java b/core/java/android/metrics/LogMaker.java index 60b27b47960f..04482210c088 100644 --- a/core/java/android/metrics/LogMaker.java +++ b/core/java/android/metrics/LogMaker.java @@ -16,6 +16,7 @@ package android.metrics; import android.annotation.SystemApi; +import android.content.ComponentName; import android.util.Log; import android.util.SparseArray; @@ -118,6 +119,16 @@ public class LogMaker { return this; } + /** + * @param component to replace the existing setting. + * @hide + */ + public LogMaker setComponentName(ComponentName component) { + entries.put(MetricsEvent.RESERVED_FOR_LOGBUILDER_PACKAGENAME, component.getPackageName()); + entries.put(MetricsEvent.FIELD_CLASS_NAME, component.getClassName()); + return this; + } + /** Remove the package name property. */ public LogMaker clearPackageName() { entries.remove(MetricsEvent.RESERVED_FOR_LOGBUILDER_PACKAGENAME); diff --git a/core/java/android/net/IIpSecService.aidl b/core/java/android/net/IIpSecService.aidl new file mode 100644 index 000000000000..b8737fef72e2 --- /dev/null +++ b/core/java/android/net/IIpSecService.aidl @@ -0,0 +1,24 @@ +/* +** Copyright 2017, 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 android.net; + +/** + * @hide + */ +interface IIpSecService +{ +} diff --git a/core/java/android/net/IpSecManager.java b/core/java/android/net/IpSecManager.java index 2c544e9b9bfe..83f4cc97b8fa 100644 --- a/core/java/android/net/IpSecManager.java +++ b/core/java/android/net/IpSecManager.java @@ -18,8 +18,6 @@ package android.net; import static com.android.internal.util.Preconditions.checkNotNull; import android.annotation.SystemApi; -import android.content.Context; -import android.os.INetworkManagementService; import android.os.ParcelFileDescriptor; import android.util.AndroidException; import dalvik.system.CloseGuard; @@ -79,12 +77,11 @@ public final class IpSecManager { } } - private final Context mContext; - private final INetworkManagementService mService; + private final IIpSecService mService; public static final class SecurityParameterIndex implements AutoCloseable { - private final Context mContext; - private final InetAddress mDestinationAddress; + private final IIpSecService mService; + private final InetAddress mRemoteAddress; private final CloseGuard mCloseGuard = CloseGuard.get(); private int mSpi; @@ -93,10 +90,11 @@ public final class IpSecManager { return mSpi; } - private SecurityParameterIndex(Context context, InetAddress destinationAddress, int spi) + private SecurityParameterIndex( + IIpSecService service, int direction, InetAddress remoteAddress, int spi) throws ResourceUnavailableException, SpiUnavailableException { - mContext = context; - mDestinationAddress = destinationAddress; + mService = service; + mRemoteAddress = remoteAddress; mSpi = spi; mCloseGuard.open("open"); } @@ -104,13 +102,9 @@ public final class IpSecManager { /** * Release an SPI that was previously reserved. * - * <p>Release an SPI for use by other users in the system. This will fail if the SPI is - * currently in use by an IpSecTransform. - * - * @param destinationAddress SPIs must be unique for each combination of SPI and destination - * address. Thus, the destinationAddress to which the SPI will communicate must be - * supplied. - * @param spi the previously reserved SPI to be freed. + * <p>Release an SPI for use by other users in the system. If a SecurityParameterIndex is + * applied to an IpSecTransform, it will become unusable for future transforms but should + * still be closed to ensure system resources are released. */ @Override public void close() { @@ -136,13 +130,13 @@ public final class IpSecManager { public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; /** - * Reserve an SPI for traffic bound towards the specified destination address. + * Reserve an SPI for traffic bound towards the specified remote address. * * <p>If successful, this SPI is guaranteed available until released by a call to {@link * SecurityParameterIndex#close()}. * - * @param destinationAddress SPIs must be unique for each combination of SPI and destination - * address. + * @param direction {@link IpSecTransform#DIRECTION_IN} or {@link IpSecTransform#DIRECTION_OUT} + * @param remoteAddress address of the remote. SPIs must be unique for each remoteAddress. * @param requestedSpi the requested SPI, or '0' to allocate a random SPI. * @return the reserved SecurityParameterIndex * @throws ResourceUnavailableException indicating that too many SPIs are currently allocated @@ -150,9 +144,9 @@ public final class IpSecManager { * @throws SpiUnavailableException indicating that a particular SPI cannot be reserved */ public SecurityParameterIndex reserveSecurityParameterIndex( - InetAddress destinationAddress, int requestedSpi) + int direction, InetAddress remoteAddress, int requestedSpi) throws SpiUnavailableException, ResourceUnavailableException { - return new SecurityParameterIndex(mContext, destinationAddress, requestedSpi); + return new SecurityParameterIndex(mService, direction, remoteAddress, requestedSpi); } /** @@ -260,19 +254,19 @@ public final class IpSecManager { */ public static final class UdpEncapsulationSocket implements AutoCloseable { private final FileDescriptor mFd; - private final Context mContext; + private final IIpSecService mService; private final CloseGuard mCloseGuard = CloseGuard.get(); - private UdpEncapsulationSocket(Context context, int port) + private UdpEncapsulationSocket(IIpSecService service, int port) throws ResourceUnavailableException { - mContext = context; + mService = service; mCloseGuard.open("constructor"); // TODO: go down to the kernel and get a socket on the specified mFd = new FileDescriptor(); } - private UdpEncapsulationSocket(Context context) throws ResourceUnavailableException { - mContext = context; + private UdpEncapsulationSocket(IIpSecService service) throws ResourceUnavailableException { + mService = service; mCloseGuard.open("constructor"); // TODO: go get a random socket on a random port mFd = new FileDescriptor(); @@ -339,7 +333,7 @@ public final class IpSecManager { public UdpEncapsulationSocket openUdpEncapsulationSocket(int port) throws IOException, ResourceUnavailableException { // Temporary code - return new UdpEncapsulationSocket(mContext, port); + return new UdpEncapsulationSocket(mService, port); } /** @@ -363,7 +357,7 @@ public final class IpSecManager { public UdpEncapsulationSocket openUdpEncapsulationSocket() throws IOException, ResourceUnavailableException { // Temporary code - return new UdpEncapsulationSocket(mContext); + return new UdpEncapsulationSocket(mService); } /** @@ -372,8 +366,7 @@ public final class IpSecManager { * @param context the application context for this manager * @hide */ - public IpSecManager(Context context, INetworkManagementService service) { - mContext = checkNotNull(context, "missing context"); + public IpSecManager(IIpSecService service) { mService = checkNotNull(service, "missing service"); } } diff --git a/core/java/android/net/IpSecTransform.java b/core/java/android/net/IpSecTransform.java index d6dd28bec390..5c0bbe6a1437 100644 --- a/core/java/android/net/IpSecTransform.java +++ b/core/java/android/net/IpSecTransform.java @@ -307,7 +307,7 @@ public final class IpSecTransform implements AutoCloseable { * <p>Care should be chosen when selecting an SPI to ensure that is is as unique as * possible. Random number generation is a reasonable approach to selecting an SPI. For * outbound SPIs, they must be reserved by calling {@link - * IpSecManager#reserveSecurityParameterIndex(InetAddress, int)}. Otherwise, Transforms will + * IpSecManager#reserveSecurityParameterIndex(int, InetAddress, int)}. Otherwise, Transforms will * fail to build. * * <p>Unless an SPI is set for a given direction, traffic in that direction will be @@ -329,7 +329,7 @@ public final class IpSecTransform implements AutoCloseable { * <p>Care should be chosen when selecting an SPI to ensure that is is as unique as * possible. Random number generation is a reasonable approach to selecting an SPI. For * outbound SPIs, they must be reserved by calling {@link - * IpSecManager#reserveSecurityParameterIndex(InetAddress, int)}. Otherwise, Transforms will + * IpSecManager#reserveSecurityParameterIndex(int, InetAddress, int)}. Otherwise, Transforms will * fail to activate. * * <p>Unless an SPI is set for a given direction, traffic in that direction will be diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java index 70ecf89dc155..29483cd98bd1 100644 --- a/core/java/android/net/NetworkScoreManager.java +++ b/core/java/android/net/NetworkScoreManager.java @@ -120,6 +120,14 @@ public class NetworkScoreManager { "android.net.wifi.use_open_wifi_package"; /** + * Meta-data specified on a {@link NetworkRecommendationProvider} that specifies the + * {@link android.app.NotificationChannel} ID used to post open network notifications. + * @hide + */ + public static final String NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID_META_DATA = + "android.net.wifi.notification_channel_id_network_available"; + + /** * Broadcast action: the active scorer has been changed. Scorer apps may listen to this to * perform initialization once selected as the active scorer, or clean up unneeded resources * if another scorer has been selected. This is an explicit broadcast only sent to the diff --git a/core/java/android/net/NetworkScorerAppData.java b/core/java/android/net/NetworkScorerAppData.java index 5bf1e103a2de..1734b347ab9c 100644 --- a/core/java/android/net/NetworkScorerAppData.java +++ b/core/java/android/net/NetworkScorerAppData.java @@ -23,13 +23,20 @@ public final class NetworkScorerAppData implements Parcelable { * wifi networks automatically" feature. */ private final ComponentName mEnableUseOpenWifiActivity; + /** + * The {@link android.app.NotificationChannel} ID used by {@link #mRecommendationService} to + * post open network notifications. + */ + private final String mNetworkAvailableNotificationChannelId; public NetworkScorerAppData(int packageUid, ComponentName recommendationServiceComp, - String recommendationServiceLabel, ComponentName enableUseOpenWifiActivity) { + String recommendationServiceLabel, ComponentName enableUseOpenWifiActivity, + String networkAvailableNotificationChannelId) { this.packageUid = packageUid; this.mRecommendationService = recommendationServiceComp; this.mRecommendationServiceLabel = recommendationServiceLabel; this.mEnableUseOpenWifiActivity = enableUseOpenWifiActivity; + this.mNetworkAvailableNotificationChannelId = networkAvailableNotificationChannelId; } protected NetworkScorerAppData(Parcel in) { @@ -37,6 +44,7 @@ public final class NetworkScorerAppData implements Parcelable { mRecommendationService = ComponentName.readFromParcel(in); mRecommendationServiceLabel = in.readString(); mEnableUseOpenWifiActivity = ComponentName.readFromParcel(in); + mNetworkAvailableNotificationChannelId = in.readString(); } @Override @@ -45,6 +53,7 @@ public final class NetworkScorerAppData implements Parcelable { ComponentName.writeToParcel(mRecommendationService, dest); dest.writeString(mRecommendationServiceLabel); ComponentName.writeToParcel(mEnableUseOpenWifiActivity, dest); + dest.writeString(mNetworkAvailableNotificationChannelId); } @Override @@ -83,6 +92,11 @@ public final class NetworkScorerAppData implements Parcelable { return mRecommendationServiceLabel; } + @Nullable + public String getNetworkAvailableNotificationChannelId() { + return mNetworkAvailableNotificationChannelId; + } + @Override public String toString() { return "NetworkScorerAppData{" + @@ -90,6 +104,8 @@ public final class NetworkScorerAppData implements Parcelable { ", mRecommendationService=" + mRecommendationService + ", mRecommendationServiceLabel=" + mRecommendationServiceLabel + ", mEnableUseOpenWifiActivity=" + mEnableUseOpenWifiActivity + + ", mNetworkAvailableNotificationChannelId=" + + mNetworkAvailableNotificationChannelId + '}'; } @@ -101,12 +117,14 @@ public final class NetworkScorerAppData implements Parcelable { return packageUid == that.packageUid && Objects.equals(mRecommendationService, that.mRecommendationService) && Objects.equals(mRecommendationServiceLabel, that.mRecommendationServiceLabel) && - Objects.equals(mEnableUseOpenWifiActivity, that.mEnableUseOpenWifiActivity); + Objects.equals(mEnableUseOpenWifiActivity, that.mEnableUseOpenWifiActivity) && + Objects.equals(mNetworkAvailableNotificationChannelId, + that.mNetworkAvailableNotificationChannelId); } @Override public int hashCode() { return Objects.hash(packageUid, mRecommendationService, mRecommendationServiceLabel, - mEnableUseOpenWifiActivity); + mEnableUseOpenWifiActivity, mNetworkAvailableNotificationChannelId); } } diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java index 3c7c962eaa12..8678d95db17d 100644 --- a/core/java/android/os/Handler.java +++ b/core/java/android/os/Handler.java @@ -16,6 +16,8 @@ package android.os; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.util.Log; import android.util.Printer; @@ -69,6 +71,7 @@ public class Handler { */ private static final boolean FIND_POTENTIAL_LEAKS = false; private static final String TAG = "Handler"; + private static Handler MAIN_THREAD_HANDLER = null; /** * Callback interface you can use when instantiating a Handler to avoid @@ -231,6 +234,21 @@ public class Handler { mAsynchronous = async; } + /** @hide */ + @NonNull + public static Handler getMain() { + if (MAIN_THREAD_HANDLER == null) { + MAIN_THREAD_HANDLER = new Handler(Looper.getMainLooper()); + } + return MAIN_THREAD_HANDLER; + } + + /** @hide */ + @NonNull + public static Handler mainIfNull(@Nullable Handler handler) { + return handler == null ? getMain() : handler; + } + /** {@hide} */ public String getTraceName(Message message) { final StringBuilder sb = new StringBuilder(); diff --git a/core/java/android/os/HidlSupport.java b/core/java/android/os/HidlSupport.java new file mode 100644 index 000000000000..7dec4d724f15 --- /dev/null +++ b/core/java/android/os/HidlSupport.java @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2017 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 android.os; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.IntStream; + +/** @hide */ +public class HidlSupport { + /** + * Similar to Objects.deepEquals, but also take care of lists. + * Two objects of HIDL types are considered equal if: + * 1. Both null + * 2. Both non-null, and of the same class, and: + * 2.1 Both are primitive arrays / enum arrays, elements are equal using == check + * 2.2 Both are object arrays, elements are checked recursively + * 2.3 Both are Lists, elements are checked recursively + * 2.4 (If both are collections other than lists or maps, throw an error) + * 2.5 lft.equals(rgt) returns true + */ + public static boolean deepEquals(Object lft, Object rgt) { + if (lft == rgt) { + return true; + } + if (lft == null || rgt == null) { + return false; + } + + Class<?> lftClazz = lft.getClass(); + Class<?> rgtClazz = rgt.getClass(); + if (lftClazz != rgtClazz) { + return false; + } + + if (lftClazz.isArray()) { + Class<?> lftElementType = lftClazz.getComponentType(); + if (lftElementType != rgtClazz.getComponentType()) { + return false; + } + + if (lftElementType.isPrimitive()) { + return Objects.deepEquals(lft, rgt); + } + + Object[] lftArray = (Object[])lft; + Object[] rgtArray = (Object[])rgt; + return (lftArray.length == rgtArray.length) && + IntStream.range(0, lftArray.length).allMatch( + i -> deepEquals(lftArray[i], rgtArray[i])); + } + + if (lft instanceof List<?>) { + List<Object> lftList = (List<Object>)lft; + List<Object> rgtList = (List<Object>)rgt; + if (lftList.size() != rgtList.size()) { + return false; + } + + Iterator<Object> lftIter = lftList.iterator(); + return rgtList.stream() + .allMatch(rgtElement -> deepEquals(lftIter.next(), rgtElement)); + } + + throwErrorIfUnsupportedType(lft); + + return lft.equals(rgt); + } + + /** + * Similar to Arrays.deepHashCode, but also take care of lists. + */ + public static int deepHashCode(Object o) { + if (o == null) { + return 0; + } + Class<?> clazz = o.getClass(); + if (clazz.isArray()) { + Class<?> elementType = clazz.getComponentType(); + if (elementType.isPrimitive()) { + return primitiveArrayHashCode(o); + } + return Arrays.hashCode(Arrays.stream((Object[])o) + .mapToInt(element -> deepHashCode(element)) + .toArray()); + } + + if (o instanceof List<?>) { + return Arrays.hashCode(((List<Object>)o).stream() + .mapToInt(element -> deepHashCode(element)) + .toArray()); + } + + throwErrorIfUnsupportedType(o); + + return o.hashCode(); + } + + private static void throwErrorIfUnsupportedType(Object o) { + if (o instanceof Collection<?> && !(o instanceof List<?>)) { + throw new UnsupportedOperationException( + "Cannot check equality on collections other than lists: " + + o.getClass().getName()); + } + + if (o instanceof Map<?, ?>) { + throw new UnsupportedOperationException( + "Cannot check equality on maps"); + } + } + + private static int primitiveArrayHashCode(Object o) { + Class<?> elementType = o.getClass().getComponentType(); + if (elementType == boolean.class) { + return Arrays.hashCode(((boolean[])o)); + } + if (elementType == byte.class) { + return Arrays.hashCode(((byte[])o)); + } + if (elementType == char.class) { + return Arrays.hashCode(((char[])o)); + } + if (elementType == double.class) { + return Arrays.hashCode(((double[])o)); + } + if (elementType == float.class) { + return Arrays.hashCode(((float[])o)); + } + if (elementType == int.class) { + return Arrays.hashCode(((int[])o)); + } + if (elementType == long.class) { + return Arrays.hashCode(((long[])o)); + } + if (elementType == short.class) { + return Arrays.hashCode(((short[])o)); + } + // Should not reach here. + throw new UnsupportedOperationException(); + } +} diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java index 63d3e7ad2135..44dbcfb09582 100644 --- a/core/java/android/os/Looper.java +++ b/core/java/android/os/Looper.java @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.os.LooperProto; import android.util.Log; import android.util.Printer; +import android.util.Slog; import android.util.proto.ProtoOutputStream; /** @@ -76,6 +77,9 @@ public final class Looper { private Printer mLogging; private long mTraceTag; + /* If set, the looper will show a warning log if a message dispatch takes longer than time. */ + private long mSlowDispatchThresholdMs; + /** Initialize the current thread as a looper. * This gives you a chance to create handlers that then reference * this looper, before actually starting the loop. Be sure to call @@ -148,17 +152,30 @@ public final class Looper { msg.callback + ": " + msg.what); } + final long slowDispatchThresholdMs = me.mSlowDispatchThresholdMs; + final long traceTag = me.mTraceTag; if (traceTag != 0 && Trace.isTagEnabled(traceTag)) { Trace.traceBegin(traceTag, msg.target.getTraceName(msg)); } + final long start = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis(); + final long end; try { msg.target.dispatchMessage(msg); + end = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis(); } finally { if (traceTag != 0) { Trace.traceEnd(traceTag); } } + if (slowDispatchThresholdMs > 0) { + final long time = end - start; + if (time > slowDispatchThresholdMs) { + Slog.w(TAG, "Dispatch took " + time + "ms on " + + Thread.currentThread().getName() + ", h=" + + msg.target + " cb=" + msg.callback + " msg=" + msg.what); + } + } if (logging != null) { logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); @@ -226,6 +243,11 @@ public final class Looper { mTraceTag = traceTag; } + /** {@hide} */ + public void setSlowDispatchThresholdMs(long slowDispatchThresholdMs) { + mSlowDispatchThresholdMs = slowDispatchThresholdMs; + } + /** * Quits the looper. * <p> diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java index ef5bc5cf9075..5f66abd58d8b 100644 --- a/core/java/android/os/RecoverySystem.java +++ b/core/java/android/os/RecoverySystem.java @@ -483,7 +483,7 @@ public class RecoverySystem { } final String filenameArg = "--update_package=" + filename + "\n"; - final String localeArg = "--locale=" + Locale.getDefault().toString() + "\n"; + final String localeArg = "--locale=" + Locale.getDefault().toLanguageTag() + "\n"; final String securityArg = "--security\n"; String command = filenameArg + localeArg; @@ -531,7 +531,7 @@ public class RecoverySystem { } final String filenameArg = "--update_package=" + filename + "\n"; - final String localeArg = "--locale=" + Locale.getDefault().toString() + "\n"; + final String localeArg = "--locale=" + Locale.getDefault().toLanguageTag() + "\n"; final String securityArg = "--security\n"; String command = filenameArg + localeArg; @@ -647,7 +647,7 @@ public class RecoverySystem { reasonArg = "--reason=" + sanitizeArg(reason); } - final String localeArg = "--locale=" + Locale.getDefault().toString(); + final String localeArg = "--locale=" + Locale.getDefault().toLanguageTag() ; bootCommand(context, shutdownArg, "--wipe_data", reasonArg, localeArg); } @@ -678,7 +678,7 @@ public class RecoverySystem { reasonArg = "--reason=" + sanitizeArg(reason); } - final String localeArg = "--locale=" + Locale.getDefault().toString(); + final String localeArg = "--locale=" + Locale.getDefault().toLanguageTag() ; bootCommand(context, "--wipe_cache", reasonArg, localeArg); } @@ -703,7 +703,7 @@ public class RecoverySystem { final String filename = packageFile.getCanonicalPath(); final String filenameArg = "--wipe_package=" + filename; - final String localeArg = "--locale=" + Locale.getDefault().toString(); + final String localeArg = "--locale=" + Locale.getDefault().toLanguageTag() ; bootCommand(context, "--wipe_ab", filenameArg, reasonArg, localeArg); } @@ -741,6 +741,10 @@ public class RecoverySystem { int timeTotal = -1; int uncryptTime = -1; int sourceVersion = -1; + int temperature_start = -1; + int temperature_end = -1; + int temperature_max = -1; + while ((line = in.readLine()) != null) { // Here is an example of lines in last_install: // ... @@ -785,6 +789,12 @@ public class RecoverySystem { } else if (line.startsWith("bytes_stashed")) { bytesStashedInMiB = (bytesStashedInMiB == -1) ? scaled : bytesStashedInMiB + scaled; + } else if (line.startsWith("temperature_start")) { + temperature_start = scaled; + } else if (line.startsWith("temperature_end")) { + temperature_end = scaled; + } else if (line.startsWith("temperature_max")) { + temperature_max = scaled; } } @@ -804,6 +814,15 @@ public class RecoverySystem { if (bytesStashedInMiB != -1) { MetricsLogger.histogram(context, "ota_stashed_in_MiBs", bytesStashedInMiB); } + if (temperature_start != -1) { + MetricsLogger.histogram(context, "ota_temperature_start", temperature_start); + } + if (temperature_end != -1) { + MetricsLogger.histogram(context, "ota_temperature_end", temperature_end); + } + if (temperature_max != -1) { + MetricsLogger.histogram(context, "ota_temperature_max", temperature_max); + } } catch (IOException e) { Log.e(TAG, "Failed to read lines in last_install", e); diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java index b3366d883fc6..8208438dc62a 100644 --- a/core/java/android/os/ZygoteProcess.java +++ b/core/java/android/os/ZygoteProcess.java @@ -487,11 +487,11 @@ public class ZygoteProcess { * Instructs the zygote to pre-load the classes and native libraries at the given paths * for the specified abi. Not all zygotes support this function. */ - public void preloadPackageForAbi(String packagePath, String libsPath, String abi) - throws ZygoteStartFailedEx, IOException { + public void preloadPackageForAbi(String packagePath, String libsPath, String cacheKey, + String abi) throws ZygoteStartFailedEx, IOException { synchronized(mLock) { ZygoteState state = openZygoteSocketIfNeeded(abi); - state.writer.write("3"); + state.writer.write("4"); state.writer.newLine(); state.writer.write("--preload-package"); @@ -503,6 +503,9 @@ public class ZygoteProcess { state.writer.write(libsPath); state.writer.newLine(); + state.writer.write(cacheKey); + state.writer.newLine(); + state.writer.flush(); } } diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index 7e1b5abf8112..e5d73e04bda6 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -59,6 +59,8 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.os.AppFuseMount; import com.android.internal.os.FuseAppLoop; +import com.android.internal.os.FuseAppLoop.UnmountedException; +import com.android.internal.os.FuseUnavailableMountException; import com.android.internal.os.RoSystemProperties; import com.android.internal.os.SomeArgs; import com.android.internal.util.Preconditions; @@ -82,6 +84,7 @@ import java.util.List; import java.util.Objects; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicInteger; +import libcore.io.IoUtils; /** * StorageManager is the interface to the systems storage service. The storage @@ -1390,53 +1393,52 @@ public class StorageManager { /** {@hide} */ @VisibleForTesting public @NonNull ParcelFileDescriptor openProxyFileDescriptor( - int mode, ProxyFileDescriptorCallback callback, ThreadFactory factory) + int mode, ProxyFileDescriptorCallback callback, Handler handler, ThreadFactory factory) throws IOException { MetricsLogger.count(mContext, "storage_open_proxy_file_descriptor", 1); // Retry is needed because the mount point mFuseAppLoop is using may be unmounted before // invoking StorageManagerService#openProxyFileDescriptor. In this case, we need to re-mount // the bridge by calling mountProxyFileDescriptorBridge. - int retry = 3; - while (retry-- > 0) { + while (true) { try { synchronized (mFuseAppLoopLock) { + boolean newlyCreated = false; if (mFuseAppLoop == null) { final AppFuseMount mount = mStorageManager.mountProxyFileDescriptorBridge(); if (mount == null) { - Log.e(TAG, "Failed to open proxy file bridge."); - throw new IOException("Failed to open proxy file bridge."); + throw new IOException("Failed to mount proxy bridge"); } - mFuseAppLoop = FuseAppLoop.open(mount.mountPointId, mount.fd, factory); + mFuseAppLoop = new FuseAppLoop(mount.mountPointId, mount.fd, factory); + newlyCreated = true; + } + if (handler == null) { + handler = new Handler(Looper.getMainLooper()); } - try { - final int fileId = mFuseAppLoop.registerCallback(callback); - final ParcelFileDescriptor pfd = - mStorageManager.openProxyFileDescriptor( - mFuseAppLoop.getMountPointId(), fileId, mode); - if (pfd != null) { - return pfd; + final int fileId = mFuseAppLoop.registerCallback(callback, handler); + final ParcelFileDescriptor pfd = mStorageManager.openProxyFileDescriptor( + mFuseAppLoop.getMountPointId(), fileId, mode); + if (pfd == null) { + mFuseAppLoop.unregisterCallback(fileId); + throw new FuseUnavailableMountException( + mFuseAppLoop.getMountPointId()); + } + return pfd; + } catch (FuseUnavailableMountException exception) { + // The bridge is being unmounted. Tried to recreate it unless the bridge was + // just created. + if (newlyCreated) { + throw new IOException(exception); } - // Probably the bridge is being unmounted but mFuseAppLoop has not been - // noticed it yet. - mFuseAppLoop.unregisterCallback(fileId); - } catch (FuseAppLoop.UnmountedException error) { - Log.d(TAG, "mFuseAppLoop has been already unmounted."); mFuseAppLoop = null; continue; } } - try { - Thread.sleep(100); - } catch (InterruptedException e) { - break; - } } catch (RemoteException e) { - e.rethrowFromSystemServer(); + // Cannot recover from remote exception. + throw new IOException(e); } } - - throw new IOException("Failed to mount bridge."); } /** @@ -1448,16 +1450,37 @@ public class StorageManager { * {@link ParcelFileDescriptor#MODE_WRITE_ONLY}, or * {@link ParcelFileDescriptor#MODE_READ_WRITE} * @param callback Callback to process file operation requests issued on returned file - * descriptor. The callback is invoked on a thread managed by the framework. + * descriptor. * @return Seekable ParcelFileDescriptor. * @throws IOException */ public @NonNull ParcelFileDescriptor openProxyFileDescriptor( int mode, ProxyFileDescriptorCallback callback) throws IOException { - return openProxyFileDescriptor(mode, callback, null); + return openProxyFileDescriptor(mode, callback, null, null); } + /** + * Opens seekable ParcelFileDescriptor that routes file operation requests to + * ProxyFileDescriptorCallback. + * + * @param mode The desired access mode, must be one of + * {@link ParcelFileDescriptor#MODE_READ_ONLY}, + * {@link ParcelFileDescriptor#MODE_WRITE_ONLY}, or + * {@link ParcelFileDescriptor#MODE_READ_WRITE} + * @param callback Callback to process file operation requests issued on returned file + * descriptor. + * @param handler Handler that invokes callback methods. + * @return Seekable ParcelFileDescriptor. + * @throws IOException + */ + public @NonNull ParcelFileDescriptor openProxyFileDescriptor( + int mode, ProxyFileDescriptorCallback callback, Handler handler) + throws IOException { + return openProxyFileDescriptor(mode, callback, handler, null); + } + + /** {@hide} */ @VisibleForTesting public int getProxyFileDescriptorMountPointId() { diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java index 4d14277be9c1..d3adce73582e 100644 --- a/core/java/android/preference/Preference.java +++ b/core/java/android/preference/Preference.java @@ -83,6 +83,7 @@ import java.util.Set; * @attr ref android.R.styleable#Preference_shouldDisableView * @attr ref android.R.styleable#Preference_recycleEnabled * @attr ref android.R.styleable#Preference_singleLineTitle + * @attr ref android.R.styleable#Preference_iconSpaceReserved */ public class Preference implements Comparable<Preference> { /** @@ -135,6 +136,7 @@ public class Preference implements Comparable<Preference> { private boolean mParentDependencyMet = true; private boolean mRecycleEnabled = true; private boolean mSingleLineTitle = true; + private boolean mIconSpaceReserved; /** * @see #setShouldDisableView(boolean) @@ -302,7 +304,11 @@ public class Preference implements Comparable<Preference> { case com.android.internal.R.styleable.Preference_singleLineTitle: mSingleLineTitle = a.getBoolean(attr, mSingleLineTitle); break; - } + + case com.android.internal.R.styleable.Preference_iconSpaceReserved: + mIconSpaceReserved = a.getBoolean(attr, mIconSpaceReserved); + break; + } } a.recycle(); } @@ -631,7 +637,11 @@ public class Preference implements Comparable<Preference> { imageView.setImageDrawable(mIcon); } } - imageView.setVisibility(mIcon != null ? View.VISIBLE : View.GONE); + if (mIcon != null) { + imageView.setVisibility(View.VISIBLE); + } else { + imageView.setVisibility(mIconSpaceReserved ? View.INVISIBLE : View.GONE); + } } final View imageFrame = view.findViewById(com.android.internal.R.id.icon_frame); @@ -931,6 +941,25 @@ public class Preference implements Comparable<Preference> { } /** + * Sets whether to reserve the space of this Preference icon view when no icon is provided. + * + * @param iconSpaceReserved set {@code true} if the space for the icon view should be reserved + */ + public void setIconSpaceReserved(boolean iconSpaceReserved) { + mIconSpaceReserved = iconSpaceReserved; + notifyChanged(); + } + + /** + * Gets whether the space this preference icon view is reserved. + * + * @see #setIconSpaceReserved(boolean) + * @return {@code true} if the space of this preference icon view is reserved + */ + public boolean isIconSpaceReserved() { + return mIconSpaceReserved; + } + /** * Returns a unique ID for this Preference. This ID should be unique across all * Preference objects in a hierarchy. * diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 7005d44ee08a..e2100bd43898 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -396,38 +396,6 @@ public final class Settings { "android.settings.WIFI_IP_SETTINGS"; /** - * Activity Action: Show settings to allow the configuration of Wi-Fi features. - * <p> - * In some cases, a matching Activity may not exist, so ensure you - * safeguard against this. - * <p> - * Input: Nothing. - * <p> - * Output: Nothing. - * @hide - */ - @SystemApi - @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) - public static final String ACTION_CONFIGURE_WIFI_SETTINGS = - "android.settings.CONFIGURE_WIFI_SETTINGS"; - - /** - * Activity Action: Show settings to allow configuration of Wi-Fi saved networks. - * <p> - * In some cases, a matching Activity may not exist, so ensure you - * safeguard against this. - * <p> - * Input: Nothing. - * <p> - * Output: Nothing. - * @hide - */ - @SystemApi - @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) - public static final String ACTION_WIFI_SAVED_NETWORK_SETTINGS = - "android.settings.WIFI_SAVED_NETWORK_SETTINGS"; - - /** * Activity Action: Show settings to allow configuration of Bluetooth. * <p> * In some cases, a matching Activity may not exist, so ensure you @@ -7109,6 +7077,15 @@ public final class Settings { INSTANT_APP_SETTINGS.add(ENABLED_ACCESSIBILITY_SERVICES); INSTANT_APP_SETTINGS.add(ACCESSIBILITY_SPEAK_PASSWORD); INSTANT_APP_SETTINGS.add(ACCESSIBILITY_DISPLAY_INVERSION_ENABLED); + INSTANT_APP_SETTINGS.add(ACCESSIBILITY_CAPTIONING_ENABLED); + INSTANT_APP_SETTINGS.add(ACCESSIBILITY_CAPTIONING_PRESET); + INSTANT_APP_SETTINGS.add(ACCESSIBILITY_CAPTIONING_EDGE_TYPE); + INSTANT_APP_SETTINGS.add(ACCESSIBILITY_CAPTIONING_EDGE_COLOR); + INSTANT_APP_SETTINGS.add(ACCESSIBILITY_CAPTIONING_LOCALE); + INSTANT_APP_SETTINGS.add(ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR); + INSTANT_APP_SETTINGS.add(ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR); + INSTANT_APP_SETTINGS.add(ACCESSIBILITY_CAPTIONING_TYPEFACE); + INSTANT_APP_SETTINGS.add(ACCESSIBILITY_CAPTIONING_FONT_SCALE); INSTANT_APP_SETTINGS.add(DEFAULT_INPUT_METHOD); INSTANT_APP_SETTINGS.add(ENABLED_INPUT_METHODS); @@ -8232,9 +8209,14 @@ public final class Settings { * the open network(s) disappear, we remove the notification. When we * show the notification, we will not show it again for * {@link android.provider.Settings.Secure#WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY} time. + * + * @deprecated This feature is no longer controlled by this setting in + * {@link android.os.Build.VERSION_CODES#O}. */ + @Deprecated public static final String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = "wifi_networks_available_notification_on"; + /** * {@hide} */ diff --git a/core/java/android/provider/VoicemailContract.java b/core/java/android/provider/VoicemailContract.java index a8b094eab0a2..4c61c2f755a0 100644 --- a/core/java/android/provider/VoicemailContract.java +++ b/core/java/android/provider/VoicemailContract.java @@ -112,7 +112,7 @@ public class VoicemailContract { /** @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_VOICEMAIL_SMS_RECEIVED = - "android.intent.action.VOICEMAIL_SMS_RECEIVED"; + "com.android.internal.provider.action.VOICEMAIL_SMS_RECEIVED"; /** * Extra in {@link #ACTION_VOICEMAIL_SMS_RECEIVED} indicating the content of the SMS. diff --git a/core/java/android/service/quicksettings/TileService.java b/core/java/android/service/quicksettings/TileService.java index 21168475adf7..8e0103078a42 100644 --- a/core/java/android/service/quicksettings/TileService.java +++ b/core/java/android/service/quicksettings/TileService.java @@ -433,6 +433,7 @@ public class TileService extends Service { public static final void requestListeningState(Context context, ComponentName component) { Intent intent = new Intent(ACTION_REQUEST_LISTENING); intent.putExtra(EXTRA_COMPONENT, component); + intent.setPackage("com.android.systemui"); context.sendBroadcast(intent, Manifest.permission.BIND_QUICK_SETTINGS_TILE); } } diff --git a/core/java/android/service/resolver/IResolverRankerResult.aidl b/core/java/android/service/resolver/IResolverRankerResult.aidl new file mode 100644 index 000000000000..bda315420b7b --- /dev/null +++ b/core/java/android/service/resolver/IResolverRankerResult.aidl @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2017 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 android.service.resolver; + +import android.service.resolver.ResolverTarget; + +/** + * @hide + */ +oneway interface IResolverRankerResult +{ + void sendResult(in List<ResolverTarget> results); +}
\ No newline at end of file diff --git a/core/java/android/service/resolver/IResolverRankerService.aidl b/core/java/android/service/resolver/IResolverRankerService.aidl new file mode 100644 index 000000000000..f0d747d974a7 --- /dev/null +++ b/core/java/android/service/resolver/IResolverRankerService.aidl @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2017 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 android.service.resolver; + +import android.service.resolver.IResolverRankerResult; +import android.service.resolver.ResolverTarget; + +/** + * @hide + */ +oneway interface IResolverRankerService +{ + void predict(in List<ResolverTarget> targets, IResolverRankerResult result); + void train(in List<ResolverTarget> targets, int selectedPosition); +}
\ No newline at end of file diff --git a/core/java/android/service/resolver/ResolverRankerService.java b/core/java/android/service/resolver/ResolverRankerService.java new file mode 100644 index 000000000000..05067479bf45 --- /dev/null +++ b/core/java/android/service/resolver/ResolverRankerService.java @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2017 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 android.service.resolver; + +import android.annotation.SdkConstant; +import android.annotation.SystemApi; +import android.app.Service; +import android.content.ComponentName; +import android.content.Intent; +import android.os.IBinder; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.RemoteException; +import android.service.resolver.ResolverTarget; +import android.util.Log; + +import java.util.List; +import java.util.Map; + +/** + * A service to rank apps according to usage stats of apps, when the system is resolving targets for + * an Intent. + * + * <p>To extend this class, you must declare the service in your manifest file with the + * {@link android.Manifest.permission#BIND_RESOLVER_RANKER_SERVICE} permission, and include an + * intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p> + * <pre> + * <service android:name=".MyResolverRankerService" + * android:exported="true" + * android:priority="100" + * android:permission="android.permission.BIND_RESOLVER_RANKER_SERVICE"> + * <intent-filter> + * <action android:name="android.service.resolver.ResolverRankerService" /> + * </intent-filter> + * </service> + * </pre> + * @hide + */ +@SystemApi +public abstract class ResolverRankerService extends Service { + + private static final String TAG = "ResolverRankerService"; + + private static final boolean DEBUG = false; + + /** + * The Intent action that a service must respond to. Add it to the intent filter of the service + * in its manifest. + */ + @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) + public static final String SERVICE_INTERFACE = "android.service.resolver.ResolverRankerService"; + + /** + * The permission that a service must require to ensure that only Android system can bind to it. + * If this permission is not enforced in the AndroidManifest of the service, the system will + * skip that service. + */ + public static final String BIND_PERMISSION = "android.permission.BIND_RESOLVER_RANKER_SERVICE"; + + private ResolverRankerServiceWrapper mWrapper = null; + + /** + * Called by the system to retrieve a list of probabilities to rank apps/options. To implement + * it, set selectProbability of each input {@link ResolverTarget}. The higher the + * selectProbability is, the more likely the {@link ResolverTarget} will be selected by the + * user. Override this function to provide prediction results. + * + * @param targets a list of {@link ResolverTarget}, for the list of apps to be ranked. + * + * @throws Exception when the prediction task fails. + */ + public void onPredictSharingProbabilities(final List<ResolverTarget> targets) {} + + /** + * Called by the system to train/update a ranking service, after the user makes a selection from + * the ranked list of apps. Override this function to enable model updates. + * + * @param targets a list of {@link ResolverTarget}, for the list of apps to be ranked. + * @param selectedPosition the position of the selected app in the list. + * + * @throws Exception when the training task fails. + */ + public void onTrainRankingModel( + final List<ResolverTarget> targets, final int selectedPosition) {} + + private static final String HANDLER_THREAD_NAME = "RESOLVER_RANKER_SERVICE"; + private volatile Handler mHandler; + private HandlerThread mHandlerThread; + + @Override + public IBinder onBind(Intent intent) { + if (DEBUG) Log.d(TAG, "onBind " + intent); + if (!SERVICE_INTERFACE.equals(intent.getAction())) { + if (DEBUG) Log.d(TAG, "bad intent action " + intent.getAction() + "; returning null"); + return null; + } + if (mHandlerThread == null) { + mHandlerThread = new HandlerThread(HANDLER_THREAD_NAME); + mHandlerThread.start(); + mHandler = new Handler(mHandlerThread.getLooper()); + } + if (mWrapper == null) { + mWrapper = new ResolverRankerServiceWrapper(); + } + return mWrapper; + } + + @Override + public void onDestroy() { + mHandler = null; + if (mHandlerThread != null) { + mHandlerThread.quitSafely(); + } + super.onDestroy(); + } + + private static void sendResult(List<ResolverTarget> targets, IResolverRankerResult result) { + try { + result.sendResult(targets); + } catch (Exception e) { + Log.e(TAG, "failed to send results: " + e); + } + } + + private class ResolverRankerServiceWrapper extends IResolverRankerService.Stub { + + @Override + public void predict(final List<ResolverTarget> targets, final IResolverRankerResult result) + throws RemoteException { + Runnable predictRunnable = new Runnable() { + @Override + public void run() { + try { + if (DEBUG) { + Log.d(TAG, "predict calls onPredictSharingProbabilities."); + } + onPredictSharingProbabilities(targets); + sendResult(targets, result); + } catch (Exception e) { + Log.e(TAG, "onPredictSharingProbabilities failed; send null results: " + e); + sendResult(null, result); + } + } + }; + final Handler h = mHandler; + if (h != null) { + h.post(predictRunnable); + } + } + + @Override + public void train(final List<ResolverTarget> targets, final int selectedPosition) + throws RemoteException { + Runnable trainRunnable = new Runnable() { + @Override + public void run() { + try { + if (DEBUG) { + Log.d(TAG, "train calls onTranRankingModel"); + } + onTrainRankingModel(targets, selectedPosition); + } catch (Exception e) { + Log.e(TAG, "onTrainRankingModel failed; skip train: " + e); + } + } + }; + final Handler h = mHandler; + if (h != null) { + h.post(trainRunnable); + } + } + } +} diff --git a/core/java/android/service/resolver/ResolverTarget.aidl b/core/java/android/service/resolver/ResolverTarget.aidl new file mode 100644 index 000000000000..6cab2d4df908 --- /dev/null +++ b/core/java/android/service/resolver/ResolverTarget.aidl @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2017 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 android.service.resolver; + +/** + * @hide + */ +parcelable ResolverTarget; diff --git a/core/java/android/service/resolver/ResolverTarget.java b/core/java/android/service/resolver/ResolverTarget.java new file mode 100644 index 000000000000..fb3e2d738469 --- /dev/null +++ b/core/java/android/service/resolver/ResolverTarget.java @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2017 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 android.service.resolver; + +import android.annotation.SystemApi; +import android.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.ArrayMap; + +import java.util.Map; + +/** + * A ResolverTarget contains features by which an app or option will be ranked, in + * {@link ResolverRankerService}. + * @hide + */ +@SystemApi +public final class ResolverTarget implements Parcelable { + private static final String TAG = "ResolverTarget"; + + /** + * a float score for recency of last use. + */ + private float mRecencyScore; + + /** + * a float score for total time spent. + */ + private float mTimeSpentScore; + + /** + * a float score for number of launches. + */ + private float mLaunchScore; + + /** + * a float score for number of selected. + */ + private float mChooserScore; + + /** + * a float score for the probability to be selected. + */ + private float mSelectProbability; + + // constructor for the class. + public ResolverTarget() {} + + ResolverTarget(Parcel in) { + mRecencyScore = in.readFloat(); + mTimeSpentScore = in.readFloat(); + mLaunchScore = in.readFloat(); + mChooserScore = in.readFloat(); + mSelectProbability = in.readFloat(); + } + + /** + * Gets the score for how recently the target was used in the foreground. + * + * @return a float score whose range is [0, 1]. The higher the score is, the more recently the + * target was used. + */ + public float getRecencyScore() { + return mRecencyScore; + } + + /** + * Sets the score for how recently the target was used in the foreground. + * + * @param recencyScore a float score whose range is [0, 1]. The higher the score is, the more + * recently the target was used. + */ + public void setRecencyScore(float recencyScore) { + this.mRecencyScore = recencyScore; + } + + /** + * Gets the score for how long the target has been used in the foreground. + * + * @return a float score whose range is [0, 1]. The higher the score is, the longer the target + * has been used for. + */ + public float getTimeSpentScore() { + return mTimeSpentScore; + } + + /** + * Sets the score for how long the target has been used in the foreground. + * + * @param timeSpentScore a float score whose range is [0, 1]. The higher the score is, the + * longer the target has been used for. + */ + public void setTimeSpentScore(float timeSpentScore) { + this.mTimeSpentScore = timeSpentScore; + } + + /** + * Gets the score for how many times the target has been launched to the foreground. + * + * @return a float score whose range is [0, 1]. The higher the score is, the more times the + * target has been launched. + */ + public float getLaunchScore() { + return mLaunchScore; + } + + /** + * Sets the score for how many times the target has been launched to the foreground. + * + * @param launchScore a float score whose range is [0, 1]. The higher the score is, the more + * times the target has been launched. + */ + public void setLaunchScore(float launchScore) { + this.mLaunchScore = launchScore; + } + + /** + * Gets the score for how many times the target has been selected by the user to share the same + * types of content. + * + * @return a float score whose range is [0, 1]. The higher the score is, the + * more times the target has been selected by the user to share the same types of content for. + */ + public float getChooserScore() { + return mChooserScore; + } + + /** + * Sets the score for how many times the target has been selected by the user to share the same + * types of content. + * + * @param chooserScore a float score whose range is [0, 1]. The higher the score is, the more + * times the target has been selected by the user to share the same types + * of content for. + */ + public void setChooserScore(float chooserScore) { + this.mChooserScore = chooserScore; + } + + /** + * Gets the probability of how likely this target will be selected by the user. + * + * @return a float score whose range is [0, 1]. The higher the score is, the more likely the + * user is going to select this target. + */ + public float getSelectProbability() { + return mSelectProbability; + } + + /** + * Sets the probability for how like this target will be selected by the user. + * + * @param selectProbability a float score whose range is [0, 1]. The higher the score is, the + * more likely tht user is going to select this target. + */ + public void setSelectProbability(float selectProbability) { + this.mSelectProbability = selectProbability; + } + + // serialize the class to a string. + @Override + public String toString() { + return "ResolverTarget{" + + mRecencyScore + ", " + + mTimeSpentScore + ", " + + mLaunchScore + ", " + + mChooserScore + ", " + + mSelectProbability + "}"; + } + + // describes the kinds of special objects contained in this Parcelable instance's marshaled + // representation. + @Override + public int describeContents() { + return 0; + } + + // flattens this object in to a Parcel. + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeFloat(mRecencyScore); + dest.writeFloat(mTimeSpentScore); + dest.writeFloat(mLaunchScore); + dest.writeFloat(mChooserScore); + dest.writeFloat(mSelectProbability); + } + + // creator definition for the class. + public static final Creator<ResolverTarget> CREATOR + = new Creator<ResolverTarget>() { + @Override + public ResolverTarget createFromParcel(Parcel source) { + return new ResolverTarget(source); + } + + @Override + public ResolverTarget[] newArray(int size) { + return new ResolverTarget[size]; + } + }; +} diff --git a/core/java/android/speech/tts/UtteranceProgressListener.java b/core/java/android/speech/tts/UtteranceProgressListener.java index e59ec080e2c0..59ee8f360c12 100644 --- a/core/java/android/speech/tts/UtteranceProgressListener.java +++ b/core/java/android/speech/tts/UtteranceProgressListener.java @@ -137,7 +137,15 @@ public abstract class UtteranceProgressListener { * @param end The end index of the range (exclusive) in the utterance text. * @param frame The position in frames in the audio of the request where this range is spoken. */ - public void onRangeStart(String utteranceId, int start, int end, int frame) {} + public void onRangeStart(String utteranceId, int start, int end, int frame) { + onUtteranceRangeStart(utteranceId, start, end); + } + + /** + * @deprecated Due to internal API changes. Remove when apps catch up. + */ + public void onUtteranceRangeStart(String utteranceId, int start, int end) { + } /** * Wraps an old deprecated OnUtteranceCompletedListener with a shiny new progress listener. diff --git a/core/java/android/text/FontConfig.java b/core/java/android/text/FontConfig.java index 70f9bdd9193b..14d3ad790b1d 100644 --- a/core/java/android/text/FontConfig.java +++ b/core/java/android/text/FontConfig.java @@ -22,13 +22,11 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.FontListParser; +import android.net.Uri; import android.os.Parcel; -import android.os.ParcelFileDescriptor; import android.os.Parcelable; -import java.io.IOException; import java.lang.annotation.Retention; -import java.util.Arrays; /** @@ -44,20 +42,6 @@ public final class FontConfig implements Parcelable { } /** - * For duplicating file descriptors. - * - * Note that this copy constructor can not be usable for deep copy. - * @hide - */ - public FontConfig(@NonNull FontConfig config) { - mFamilies = new Family[config.mFamilies.length]; - for (int i = 0; i < config.mFamilies.length; ++i) { - mFamilies[i] = new Family(config.mFamilies[i]); - } - mAliases = Arrays.copyOf(config.mAliases, config.mAliases.length); - } - - /** * Returns the ordered list of families included in the system fonts. */ public @NonNull Family[] getFamilies() { @@ -174,7 +158,7 @@ public final class FontConfig implements Parcelable { private final @NonNull Axis[] mAxes; private final int mWeight; private final boolean mIsItalic; - private @Nullable ParcelFileDescriptor mFd; + private Uri mUri; /** * @hide @@ -186,29 +170,6 @@ public final class FontConfig implements Parcelable { mAxes = axes; mWeight = weight; mIsItalic = isItalic; - mFd = null; - } - - /** - * This is for duplicating FileDescriptors. - * - * Note that this copy ctor doesn't deep copy the members. - * - * @hide - */ - public Font(Font origin) { - mFontName = origin.mFontName; - mTtcIndex = origin.mTtcIndex; - mAxes = origin.mAxes; - mWeight = origin.mWeight; - mIsItalic = origin.mIsItalic; - if (origin.mFd != null) { - try { - mFd = origin.mFd.dup(); - } catch (IOException e) { - e.printStackTrace(); - } - } } /** @@ -247,17 +208,20 @@ public final class FontConfig implements Parcelable { } /** - * Returns a file descriptor to access the specified font. This should be closed after use. + * Returns the content uri associated to this font. + * + * You can reach to the font contents by calling {@link + * android.content.ContentResolver#openInputStream}. */ - public @Nullable ParcelFileDescriptor getFd() { - return mFd; + public @Nullable Uri getUri() { + return mUri; } /** * @hide */ - public void setFd(@NonNull ParcelFileDescriptor fd) { - mFd = fd; + public void setUri(@NonNull Uri uri) { + mUri = uri; } /** @@ -269,11 +233,7 @@ public final class FontConfig implements Parcelable { mAxes = in.createTypedArray(Axis.CREATOR); mWeight = in.readInt(); mIsItalic = in.readInt() == 1; - if (in.readInt() == 1) { /* has FD */ - mFd = ParcelFileDescriptor.CREATOR.createFromParcel(in); - } else { - mFd = null; - } + mUri = in.readTypedObject(Uri.CREATOR); } @Override @@ -283,10 +243,7 @@ public final class FontConfig implements Parcelable { out.writeTypedArray(mAxes, flag); out.writeInt(mWeight); out.writeInt(mIsItalic ? 1 : 0); - out.writeInt(mFd == null ? 0 : 1); - if (mFd != null) { - mFd.writeToParcel(out, flag); - } + out.writeTypedObject(mUri, flag); } @Override @@ -425,22 +382,6 @@ public final class FontConfig implements Parcelable { } /** - * For duplicating file descriptor underlying Font object. - * - * This copy constructor is not for deep copying. - * @hide - */ - public Family(Family origin) { - mName = origin.mName; - mLanguage = origin.mLanguage; - mVariant = origin.mVariant; - mFonts = new Font[origin.mFonts.length]; - for (int i = 0; i < origin.mFonts.length; ++i) { - mFonts[i] = new Font(origin.mFonts[i]); - } - } - - /** * Returns the name given by the system to this font family. */ public @Nullable String getName() { diff --git a/core/java/android/util/ExceptionUtils.java b/core/java/android/util/ExceptionUtils.java index 87231e106ca3..44019c32560d 100644 --- a/core/java/android/util/ExceptionUtils.java +++ b/core/java/android/util/ExceptionUtils.java @@ -17,6 +17,7 @@ package android.util; import android.annotation.NonNull; +import android.annotation.Nullable; import android.os.ParcelableException; import com.android.internal.util.Preconditions; @@ -55,10 +56,26 @@ public class ExceptionUtils { return getCompleteMessage(null, t); } + public static <E extends Throwable> void propagateIfInstanceOf( + @Nullable Throwable t, Class<E> c) throws E { + if (t != null && c.isInstance(t)) { + throw c.cast(t); + } + } + + /** + * @param <E> a checked exception that is ok to throw without wrapping + */ + public static <E extends Exception> RuntimeException propagate(@NonNull Throwable t, Class<E> c) + throws E { + propagateIfInstanceOf(t, c); + return propagate(t); + } + public static RuntimeException propagate(@NonNull Throwable t) { Preconditions.checkNotNull(t); - if (t instanceof Error) throw (Error)t; - if (t instanceof RuntimeException) throw (RuntimeException)t; + propagateIfInstanceOf(t, Error.class); + propagateIfInstanceOf(t, RuntimeException.class); throw new RuntimeException(t); } } diff --git a/core/java/android/view/ContextThemeWrapper.java b/core/java/android/view/ContextThemeWrapper.java index 86318e91b885..d3cc175d3e1c 100644 --- a/core/java/android/view/ContextThemeWrapper.java +++ b/core/java/android/view/ContextThemeWrapper.java @@ -36,8 +36,8 @@ public class ContextThemeWrapper extends ContextWrapper { /** * Creates a new context wrapper with no theme and no base context. - * <p> - * <stong>Note:</strong> A base context <strong>must</strong> be attached + * <p class="note"> + * <strong>Note:</strong> A base context <strong>must</strong> be attached * using {@link #attachBaseContext(Context)} before calling any other * method on the newly constructed context wrapper. */ diff --git a/core/java/android/view/FocusFinder.java b/core/java/android/view/FocusFinder.java index 61c92018a406..ae1ee42c8720 100644 --- a/core/java/android/view/FocusFinder.java +++ b/core/java/android/view/FocusFinder.java @@ -18,6 +18,7 @@ package android.view; import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.pm.PackageManager; import android.graphics.Rect; import android.util.ArrayMap; import android.util.SparseArray; @@ -88,8 +89,9 @@ public class FocusFinder { private View findNextFocus(ViewGroup root, View focused, Rect focusedRect, int direction) { View next = null; + ViewGroup effectiveRoot = getEffectiveRoot(root, focused); if (focused != null) { - next = findNextUserSpecifiedFocus(root, focused, direction); + next = findNextUserSpecifiedFocus(effectiveRoot, focused, direction); } if (next != null) { return next; @@ -97,9 +99,9 @@ public class FocusFinder { ArrayList<View> focusables = mTempList; try { focusables.clear(); - root.addFocusables(focusables, direction); + effectiveRoot.addFocusables(focusables, direction); if (!focusables.isEmpty()) { - next = findNextFocus(root, focused, focusedRect, direction, focusables); + next = findNextFocus(effectiveRoot, focused, focusedRect, direction, focusables); } } finally { focusables.clear(); @@ -108,6 +110,35 @@ public class FocusFinder { } /** + * Returns the "effective" root of a view. The "effective" root is the closest ancestor + * within-which focus should cycle. + * <p> + * For example: normal focus navigation would stay within a ViewGroup marked as + * touchscreenBlocksFocus and keyboardNavigationCluster until a cluster-jump out. + * @return the "effective" root of {@param focused} + */ + private ViewGroup getEffectiveRoot(ViewGroup root, View focused) { + if (focused == null) { + return root; + } + ViewParent effective = focused.getParent(); + do { + if (effective == root) { + return root; + } + ViewGroup vg = (ViewGroup) effective; + if (vg.getTouchscreenBlocksFocus() + && focused.getContext().getPackageManager().hasSystemFeature( + PackageManager.FEATURE_TOUCHSCREEN) + && vg.isKeyboardNavigationCluster()) { + return vg; + } + effective = effective.getParent(); + } while (effective != null); + return root; + } + + /** * Find the root of the next keyboard navigation cluster after the current one. * @param root The view tree to look inside. Cannot be null * @param currentCluster The starting point of the search. Null means the default cluster diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index e59073999683..076b33cc9d6a 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -137,7 +137,10 @@ public class SurfaceView extends View { } break; case DRAW_FINISHED_MSG: { mDrawFinished = true; - invalidate(); + if (mAttachedToWindow) { + notifyDrawFinished(); + invalidate(); + } } break; } } @@ -188,9 +191,12 @@ public class SurfaceView extends View { private Translator mTranslator; private boolean mGlobalListenersAdded; + private boolean mAttachedToWindow; private int mSurfaceFlags = SurfaceControl.HIDDEN; + private int mPendingReportDraws; + public SurfaceView(Context context) { this(context, null); } @@ -227,6 +233,7 @@ public class SurfaceView extends View { mViewVisibility = getVisibility() == VISIBLE; mRequestedVisible = mViewVisibility && mWindowVisibility; + mAttachedToWindow = true; if (!mGlobalListenersAdded) { ViewTreeObserver observer = getViewTreeObserver(); observer.addOnScrollChangedListener(mScrollChangedListener); @@ -261,8 +268,17 @@ public class SurfaceView extends View { updateSurface(); } + void notifyDrawFinished() { + ViewRootImpl viewRoot = getViewRootImpl(); + if (viewRoot != null) { + viewRoot.pendingDrawFinished(); + } + mPendingReportDraws--; + } + @Override protected void onDetachedFromWindow() { + mAttachedToWindow = false; if (mGlobalListenersAdded) { ViewTreeObserver observer = getViewTreeObserver(); observer.removeOnScrollChangedListener(mScrollChangedListener); @@ -270,6 +286,10 @@ public class SurfaceView extends View { mGlobalListenersAdded = false; } + while (mPendingReportDraws > 0) { + notifyDrawFinished(); + } + mRequestedVisible = false; updateSurface(); @@ -618,6 +638,9 @@ public class SurfaceView extends View { if (callbacks == null) { callbacks = getSurfaceCallbacks(); } + + mPendingReportDraws++; + viewRoot.drawPending(); SurfaceCallbackHelper sch = new SurfaceCallbackHelper(this::onDrawFinished); sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 6c73b9b5ecef..23fcb553ddbd 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -61,6 +61,7 @@ import android.graphics.Shader; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.hardware.display.DisplayManagerGlobal; +import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Handler; @@ -4170,14 +4171,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * When this flag is used with {@link #DRAG_FLAG_GLOBAL}, the drag recipient will be able to * request read access to the content URI(s) contained in the {@link ClipData} object. - * @see android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION + * @see android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION */ public static final int DRAG_FLAG_GLOBAL_URI_READ = Intent.FLAG_GRANT_READ_URI_PERMISSION; /** * When this flag is used with {@link #DRAG_FLAG_GLOBAL}, the drag recipient will be able to * request write access to the content URI(s) contained in the {@link ClipData} object. - * @see android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION + * @see android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION */ public static final int DRAG_FLAG_GLOBAL_URI_WRITE = Intent.FLAG_GRANT_WRITE_URI_PERMISSION; @@ -4185,8 +4186,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * When this flag is used with {@link #DRAG_FLAG_GLOBAL_URI_READ} and/or {@link * #DRAG_FLAG_GLOBAL_URI_WRITE}, the URI permission grant can be persisted across device * reboots until explicitly revoked with - * {@link android.content.Context#revokeUriPermission(Uri,int) Context.revokeUriPermission}. - * @see android.content.Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION + * {@link android.content.Context#revokeUriPermission(Uri, int)} Context.revokeUriPermission}. + * @see android.content.Intent#FLAG_GRANT_PERSISTABLE_URI_PERMISSION */ public static final int DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION = Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION; @@ -4195,7 +4196,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * When this flag is used with {@link #DRAG_FLAG_GLOBAL_URI_READ} and/or {@link * #DRAG_FLAG_GLOBAL_URI_WRITE}, the URI permission grant applies to any URI that is a prefix * match against the original granted URI. - * @see android.content.Intent.FLAG_GRANT_PREFIX_URI_PERMISSION + * @see android.content.Intent#FLAG_GRANT_PREFIX_URI_PERMISSION */ public static final int DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION = Intent.FLAG_GRANT_PREFIX_URI_PERMISSION; @@ -7446,11 +7447,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * </pre> * * @param value value to be autofilled. - * - * @return {@code true} if the view was successfully autofilled, {@code false} otherwise */ - public boolean autofill(@SuppressWarnings("unused") AutofillValue value) { - return false; + public void autofill(@SuppressWarnings("unused") AutofillValue value) { } /** @@ -7460,12 +7458,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * {@link #onProvideAutofillVirtualStructure(ViewStructure, int)} for more info. * * @param values map of values to be autofilled, keyed by virtual child id. - * - * @return {@code true} if the view was successfully autofilled, {@code false} otherwise */ - public boolean autofill( - @NonNull @SuppressWarnings("unused") SparseArray<AutofillValue>values) { - return false; + public void autofill(@NonNull @SuppressWarnings("unused") SparseArray<AutofillValue> values) { } /** @@ -7895,7 +7889,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @param arguments A {@link Bundle} holding any arguments relevant for this request. May be * {@code null} if the service provided no arguments. * - * @see AccessibilityNodeInfo#setExtraAvailableData + * @see AccessibilityNodeInfo#setAvailableExtraData(List) */ public void addExtraDataToAccessibilityNodeInfo( @NonNull AccessibilityNodeInfo info, @NonNull String extraDataKey, @@ -9839,7 +9833,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * Focus gets restored for a view hierarchy when the root of the hierarchy gets added to a * window or serves as a target of cluster navigation. * - * @see #restoreDefaultFocus(int) + * @see #restoreDefaultFocus() * * @return {@code true} if this view is the default-focus view, {@code false} otherwise * @attr ref android.R.styleable#View_focusedByDefault @@ -9859,7 +9853,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @param isFocusedByDefault {@code true} to set this view as the default-focus view, * {@code false} otherwise. * - * @see #restoreDefaultFocus(int) + * @see #restoreDefaultFocus() * * @attr ref android.R.styleable#View_focusedByDefault */ @@ -16457,29 +16451,34 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * @see #onMovedToDisplay(int) + * @see #onMovedToDisplay(int, Configuration) */ - void dispatchMovedToDisplay(Display display) { + void dispatchMovedToDisplay(Display display, Configuration config) { mAttachInfo.mDisplay = display; mAttachInfo.mDisplayState = display.getState(); - onMovedToDisplay(display.getDisplayId()); + onMovedToDisplay(display.getDisplayId(), config); } /** * Called by the system when the hosting activity is moved from one display to another without * recreation. This means that the activity is declared to handle all changes to configuration * that happened when it was switched to another display, so it wasn't destroyed and created - * again. This call will be followed by {@link #onConfigurationChanged(Configuration)} if the - * applied configuration actually changed. + * again. + * + * <p>This call will be followed by {@link #onConfigurationChanged(Configuration)} if the + * applied configuration actually changed. It is up to app developer to choose whether to handle + * the change in this method or in the following {@link #onConfigurationChanged(Configuration)} + * call. * * <p>Use this callback to track changes to the displays if some functionality relies on an * association with some display properties. * * @param displayId The id of the display to which the view was moved. + * @param config Configuration of the resources on new display after move. * * @see #onConfigurationChanged(Configuration) */ - public void onMovedToDisplay(int displayId) { + public void onMovedToDisplay(int displayId, Configuration config) { } /** diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java index f16fcc933b70..574137b30f1e 100644 --- a/core/java/android/view/ViewConfiguration.java +++ b/core/java/android/view/ViewConfiguration.java @@ -232,10 +232,16 @@ public class ViewConfiguration { private static final int OVERFLING_DISTANCE = 6; /** - * Amount to scroll in response to a {@link MotionEvent#ACTION_SCROLL} event, in dips per - * axis value. + * Amount to scroll in response to a horizontal {@link MotionEvent#ACTION_SCROLL} event, + * in dips per axis value. */ - private static final int SCROLL_FACTOR = 64; + private static final float HORIZONTAL_SCROLL_FACTOR = 64; + + /** + * Amount to scroll in response to a vertical {@link MotionEvent#ACTION_SCROLL} event, + * in dips per axis value. + */ + private static final float VERTICAL_SCROLL_FACTOR = 64; /** * Default duration to hide an action mode for. @@ -289,7 +295,8 @@ public class ViewConfiguration { private final int mOverflingDistance; private final boolean mFadingMarqueeEnabled; private final long mGlobalActionsKeyTimeout; - private final int mScrollFactor; + private final float mVerticalScrollFactor; + private final float mHorizontalScrollFactor; private boolean sHasPermanentMenuKey; private boolean sHasPermanentMenuKeySet; @@ -319,7 +326,8 @@ public class ViewConfiguration { mOverflingDistance = OVERFLING_DISTANCE; mFadingMarqueeEnabled = true; mGlobalActionsKeyTimeout = GLOBAL_ACTIONS_KEY_TIMEOUT; - mScrollFactor = SCROLL_FACTOR; + mHorizontalScrollFactor = HORIZONTAL_SCROLL_FACTOR; + mVerticalScrollFactor = VERTICAL_SCROLL_FACTOR; } /** @@ -406,8 +414,11 @@ public class ViewConfiguration { com.android.internal.R.dimen.config_viewMaxFlingVelocity); mGlobalActionsKeyTimeout = res.getInteger( com.android.internal.R.integer.config_globalActionsKeyTimeout); - mScrollFactor = res.getDimensionPixelSize( - com.android.internal.R.dimen.config_scrollFactor); + + mHorizontalScrollFactor = res.getDimensionPixelSize( + com.android.internal.R.dimen.config_horizontalScrollFactor); + mVerticalScrollFactor = res.getDimensionPixelSize( + com.android.internal.R.dimen.config_verticalScrollFactor); } /** @@ -730,9 +741,27 @@ public class ViewConfiguration { /** * @return Amount to scroll in response to a {@link MotionEvent#ACTION_SCROLL} event. Multiply * this by the event's axis value to obtain the number of pixels to be scrolled. + * + * @removed */ public int getScaledScrollFactor() { - return mScrollFactor; + return (int) mVerticalScrollFactor; + } + + /** + * @return Amount to scroll in response to a horizontal {@link MotionEvent#ACTION_SCROLL} event. + * Multiply this by the event's axis value to obtain the number of pixels to be scrolled. + */ + public float getScaledHorizontalScrollFactor() { + return mHorizontalScrollFactor; + } + + /** + * @return Amount to scroll in response to a vertical {@link MotionEvent#ACTION_SCROLL} event. + * Multiply this by the event's axis value to obtain the number of pixels to be scrolled. + */ + public float getScaledVerticalScrollFactor() { + return mVerticalScrollFactor; } /** diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index de0ec40ac97b..c250226ae713 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -1190,7 +1190,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager final int focusableCount = views.size(); final int descendantFocusability = getDescendantFocusability(); - final boolean focusSelf = (isFocusableInTouchMode() || !shouldBlockFocusForTouchscreen()); + final boolean blockFocusForTouchscreen = shouldBlockFocusForTouchscreen(); + final boolean focusSelf = (isFocusableInTouchMode() || !blockFocusForTouchscreen); if (descendantFocusability == FOCUS_BLOCK_DESCENDANTS) { if (focusSelf) { @@ -1199,7 +1200,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager return; } - if (shouldBlockFocusForTouchscreen()) { + if (blockFocusForTouchscreen) { focusableMode |= FOCUSABLES_TOUCH_MODE; } @@ -1234,7 +1235,19 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager public void addKeyboardNavigationClusters(Collection<View> views, int direction) { final int focusableCount = views.size(); - super.addKeyboardNavigationClusters(views, direction); + if (isKeyboardNavigationCluster()) { + // Cluster-navigation can enter a touchscreenBlocksFocus cluster, so temporarily + // disable touchscreenBlocksFocus to evaluate whether it contains focusables. + final boolean blockedFocus = getTouchscreenBlocksFocus(); + try { + setTouchscreenBlocksFocusNoRefocus(false); + super.addKeyboardNavigationClusters(views, direction); + } finally { + setTouchscreenBlocksFocusNoRefocus(blockedFocus); + } + } else { + super.addKeyboardNavigationClusters(views, direction); + } if (focusableCount != views.size()) { // No need to look for groups inside a group. @@ -1280,6 +1293,14 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } } + private void setTouchscreenBlocksFocusNoRefocus(boolean touchscreenBlocksFocus) { + if (touchscreenBlocksFocus) { + mGroupFlags |= FLAG_TOUCHSCREEN_BLOCKS_FOCUS; + } else { + mGroupFlags &= ~FLAG_TOUCHSCREEN_BLOCKS_FOCUS; + } + } + /** * Check whether this ViewGroup should ignore focus requests for itself and its children. */ @@ -1288,8 +1309,12 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } boolean shouldBlockFocusForTouchscreen() { + // There is a special case for keyboard-navigation clusters. We allow cluster navigation + // to jump into blockFocusForTouchscreen ViewGroups which are clusters. Once in the + // cluster, focus is free to move around within it. return getTouchscreenBlocksFocus() && - mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN); + mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN) + && (!hasFocus() || !isKeyboardNavigationCluster()); } @Override @@ -3175,6 +3200,21 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager @TestApi @Override public boolean restoreFocusInCluster(@FocusRealDirection int direction) { + // Allow cluster-navigation to enter touchscreenBlocksFocus ViewGroups. + if (isKeyboardNavigationCluster()) { + final boolean blockedFocus = getTouchscreenBlocksFocus(); + try { + setTouchscreenBlocksFocusNoRefocus(false); + return restoreFocusInClusterInternal(direction); + } finally { + setTouchscreenBlocksFocusNoRefocus(blockedFocus); + } + } else { + return restoreFocusInClusterInternal(direction); + } + } + + private boolean restoreFocusInClusterInternal(@FocusRealDirection int direction) { if (mFocusedInCluster != null && !mFocusedInCluster.isKeyboardNavigationCluster() && getDescendantFocusability() != FOCUS_BLOCK_DESCENDANTS && (mFocusedInCluster.mViewFlags & VISIBILITY_MASK) == VISIBLE @@ -3281,13 +3321,13 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } @Override - void dispatchMovedToDisplay(Display display) { - super.dispatchMovedToDisplay(display); + void dispatchMovedToDisplay(Display display, Configuration config) { + super.dispatchMovedToDisplay(display, config); final int count = mChildrenCount; final View[] children = mChildren; for (int i = 0; i < count; i++) { - children[i].dispatchMovedToDisplay(display); + children[i].dispatchMovedToDisplay(display, config); } } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 168178702ebf..a43b13e659a0 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -28,6 +28,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY; import android.Manifest; import android.animation.LayoutTransition; import android.annotation.NonNull; +import android.annotation.TestApi; import android.app.ActivityManager; import android.app.ActivityThread; import android.app.ResourcesManager; @@ -210,8 +211,11 @@ public final class ViewRootImpl implements ViewParent, /** * Always assign focus if a focusable View is available. + * + * @hide */ - private static boolean sAlwaysAssignFocus; + @TestApi + public static boolean sAlwaysAssignFocus; /** * This list must only be modified by the main thread, so a lock is only needed when changing @@ -1106,10 +1110,11 @@ public final class ViewRootImpl implements ViewParent, /** * Notify about move to a different display. * @param displayId The id of the display where this view root is moved to. + * @param config Configuration of the resources on new display after move. * * @hide */ - public void onMovedToDisplay(int displayId) { + public void onMovedToDisplay(int displayId, Configuration config) { if (mDisplay.getDisplayId() == displayId) { return; } @@ -1120,7 +1125,7 @@ public final class ViewRootImpl implements ViewParent, mView.getResources()); mAttachInfo.mDisplayState = mDisplay.getState(); // Internal state updated, now notify the view hierarchy. - mView.dispatchMovedToDisplay(mDisplay); + mView.dispatchMovedToDisplay(mDisplay, config); } void pokeDrawLockIfNeeded() { @@ -2703,8 +2708,40 @@ public final class ViewRootImpl implements ViewParent, } } - private void onDrawFinished() { + /** + * A count of the number of calls to pendingDrawFinished we + * require to notify the WM drawing is complete. + * + * This starts at 1, for the ViewRootImpl surface itself. + * Subsurfaces may debt the value with drawPending. + */ + int mDrawsNeededToReport = 1; + + /** + * Delay notifying WM of draw finished until + * a balanced call to pendingDrawFinished. + */ + void drawPending() { + mDrawsNeededToReport++; + } + + void pendingDrawFinished() { + if (mDrawsNeededToReport == 0) { + throw new RuntimeException("Unbalanced drawPending/pendingDrawFinished calls"); + } + mDrawsNeededToReport--; + if (mDrawsNeededToReport == 0) { + reportDrawFinished(); + } + } + + private void postDrawFinished() { + mHandler.sendEmptyMessage(MSG_DRAW_FINISHED); + } + + private void reportDrawFinished() { try { + mDrawsNeededToReport = 1; mWindowSession.finishDrawing(mWindow); } catch (RemoteException e) { // Have fun! @@ -2761,15 +2798,12 @@ public final class ViewRootImpl implements ViewParent, } if (mSurfaceHolder != null && mSurface.isValid()) { - SurfaceCallbackHelper sch = new SurfaceCallbackHelper(this::onDrawFinished); + SurfaceCallbackHelper sch = new SurfaceCallbackHelper(this::postDrawFinished); SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks(); sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks); } else { - try { - mWindowSession.finishDrawing(mWindow); - } catch (RemoteException e) { - } + pendingDrawFinished(); } } } @@ -3485,15 +3519,16 @@ public final class ViewRootImpl implements ViewParent, mActivityConfigCallback.onConfigurationChanged(overrideConfig, newDisplayId); } else { // There is no activity callback - update the configuration right away. - updateConfiguration(); + updateConfiguration(newDisplayId); } mForceNextConfigUpdate = false; } /** * Update display and views if last applied merged configuration changed. + * @param newDisplayId Id of new display if moved, {@link Display#INVALID_DISPLAY} otherwise. */ - public void updateConfiguration() { + public void updateConfiguration(int newDisplayId) { if (mView == null) { return; } @@ -3503,6 +3538,13 @@ public final class ViewRootImpl implements ViewParent, // the one in them which may be newer. final Resources localResources = mView.getResources(); final Configuration config = localResources.getConfiguration(); + + // Handle move to display. + if (newDisplayId != INVALID_DISPLAY) { + onMovedToDisplay(newDisplayId, config); + } + + // Handle configuration change. if (mForceNextConfigUpdate || mLastConfigurationFromResources.diff(config) != 0) { // Update the display with new DisplayAdjustments. mDisplay = ResourcesManager.getInstance().getAdjustedDisplay( @@ -3567,6 +3609,7 @@ public final class ViewRootImpl implements ViewParent, private final static int MSG_REQUEST_KEYBOARD_SHORTCUTS = 26; private final static int MSG_UPDATE_POINTER_ICON = 27; private final static int MSG_POINTER_CAPTURE_CHANGED = 28; + private final static int MSG_DRAW_FINISHED = 29; final class ViewRootHandler extends Handler { @Override @@ -3618,6 +3661,8 @@ public final class ViewRootImpl implements ViewParent, return "MSG_UPDATE_POINTER_ICON"; case MSG_POINTER_CAPTURE_CHANGED: return "MSG_POINTER_CAPTURE_CHANGED"; + case MSG_DRAW_FINISHED: + return "MSG_DRAW_FINISHED"; } return super.getMessageName(message); } @@ -3674,15 +3719,17 @@ public final class ViewRootImpl implements ViewParent, SomeArgs args = (SomeArgs) msg.obj; final int displayId = args.argi3; + final MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg4; final boolean displayChanged = mDisplay.getDisplayId() != displayId; - if (displayChanged) { - onMovedToDisplay(displayId); - } - final MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg4; if (mergedConfiguration != null) { + // If configuration changed - notify about that and, maybe, about move to + // display. performConfigurationChange(mergedConfiguration, false /* force */, displayChanged ? displayId : INVALID_DISPLAY /* same display */); + } else if (displayChanged) { + // Moved to display without config change - report last applied one. + onMovedToDisplay(displayId, mLastConfigurationFromResources); } final boolean framesChanged = !mWinFrame.equals(args.arg1) @@ -3891,6 +3938,9 @@ public final class ViewRootImpl implements ViewParent, final boolean hasCapture = msg.arg1 != 0; handlePointerCaptureChanged(hasCapture); } break; + case MSG_DRAW_FINISHED: { + pendingDrawFinished(); + } break; } } } diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index b4d2c6bfe016..37ca5b3f6941 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -554,9 +554,8 @@ public final class AutofillManager { } valuesByParent.put(id.getVirtualChildId(), value); } else { - if (view.autofill(value)) { - numApplied++; - } + view.autofill(value); + numApplied++; } } @@ -564,9 +563,8 @@ public final class AutofillManager { for (int i = 0; i < virtualValues.size(); i++) { final View parent = virtualValues.keyAt(i); final SparseArray<AutofillValue> childrenValues = virtualValues.valueAt(i); - if (parent.autofill(childrenValues)) { - numApplied += childrenValues.size(); - } + parent.autofill(childrenValues); + numApplied += childrenValues.size(); } } diff --git a/core/java/android/view/inputmethod/InputMethodSubtype.java b/core/java/android/view/inputmethod/InputMethodSubtype.java index 44309a7b68c2..28c2d016f6db 100644 --- a/core/java/android/view/inputmethod/InputMethodSubtype.java +++ b/core/java/android/view/inputmethod/InputMethodSubtype.java @@ -520,27 +520,27 @@ public final class InputMethodSubtype implements Parcelable { } private HashMap<String, String> getExtraValueHashMap() { - if (mExtraValueHashMapCache == null) { - synchronized(this) { - if (mExtraValueHashMapCache == null) { - mExtraValueHashMapCache = new HashMap<String, String>(); - final String[] pairs = mSubtypeExtraValue.split(EXTRA_VALUE_PAIR_SEPARATOR); - final int N = pairs.length; - for (int i = 0; i < N; ++i) { - final String[] pair = pairs[i].split(EXTRA_VALUE_KEY_VALUE_SEPARATOR); - if (pair.length == 1) { - mExtraValueHashMapCache.put(pair[0], null); - } else if (pair.length > 1) { - if (pair.length > 2) { - Slog.w(TAG, "ExtraValue has two or more '='s"); - } - mExtraValueHashMapCache.put(pair[0], pair[1]); - } + synchronized (this) { + HashMap<String, String> extraValueMap = mExtraValueHashMapCache; + if (extraValueMap != null) { + return extraValueMap; + } + extraValueMap = new HashMap<>(); + final String[] pairs = mSubtypeExtraValue.split(EXTRA_VALUE_PAIR_SEPARATOR); + for (int i = 0; i < pairs.length; ++i) { + final String[] pair = pairs[i].split(EXTRA_VALUE_KEY_VALUE_SEPARATOR); + if (pair.length == 1) { + extraValueMap.put(pair[0], null); + } else if (pair.length > 1) { + if (pair.length > 2) { + Slog.w(TAG, "ExtraValue has two or more '='s"); } + extraValueMap.put(pair[0], pair[1]); } } + mExtraValueHashMapCache = extraValueMap; + return extraValueMap; } - return mExtraValueHashMapCache; } /** diff --git a/core/java/android/view/textclassifier/SmartSelection.java b/core/java/android/view/textclassifier/SmartSelection.java index 9397a4163e97..f0f39b683fbd 100644 --- a/core/java/android/view/textclassifier/SmartSelection.java +++ b/core/java/android/view/textclassifier/SmartSelection.java @@ -26,6 +26,11 @@ final class SmartSelection { System.loadLibrary("textclassifier"); } + /** Hints the classifier that this may be a url. */ + static final int HINT_FLAG_URL = 0x01; + /** Hints the classifier that this may be an email. */ + static final int HINT_FLAG_EMAIL = 0x02; + private final long mCtx; /** @@ -59,8 +64,8 @@ final class SmartSelection { * scores for different collections. */ public ClassificationResult[] classifyText( - String context, int selectionBegin, int selectionEnd) { - return nativeClassifyText(mCtx, context, selectionBegin, selectionEnd); + String context, int selectionBegin, int selectionEnd, int hintFlags) { + return nativeClassifyText(mCtx, context, selectionBegin, selectionEnd, hintFlags); } /** @@ -76,7 +81,7 @@ final class SmartSelection { long context, String text, int selectionBegin, int selectionEnd); private static native ClassificationResult[] nativeClassifyText( - long context, String text, int selectionBegin, int selectionEnd); + long context, String text, int selectionBegin, int selectionEnd, int hintFlags); private static native void nativeClose(long context); diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java index 35c9a294d273..548796584dc8 100644 --- a/core/java/android/view/textclassifier/TextClassificationManager.java +++ b/core/java/android/view/textclassifier/TextClassificationManager.java @@ -44,8 +44,6 @@ public final class TextClassificationManager { private final Object mLangIdLock = new Object(); private final Context mContext; - // TODO: Implement a way to close the file descriptors. - private ParcelFileDescriptor mSmartSelectionFd; private ParcelFileDescriptor mLangIdFd; private TextClassifier mDefault; private LangId mLangId; @@ -61,15 +59,7 @@ public final class TextClassificationManager { public TextClassifier getDefaultTextClassifier() { synchronized (mTextClassifierLock) { if (mDefault == null) { - try { - mSmartSelectionFd = ParcelFileDescriptor.open( - new File("/etc/textclassifier/textclassifier.smartselection.en.model"), - ParcelFileDescriptor.MODE_READ_ONLY); - mDefault = new TextClassifierImpl(mContext, mSmartSelectionFd); - } catch (FileNotFoundException e) { - Log.e(LOG_TAG, "Error accessing 'text classifier selection' model file.", e); - mDefault = TextClassifier.NO_OP; - } + mDefault = new TextClassifierImpl(mContext); } return mDefault; } diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java index be12f5702129..f634a1b52675 100644 --- a/core/java/android/view/textclassifier/TextClassifierImpl.java +++ b/core/java/android/view/textclassifier/TextClassifierImpl.java @@ -35,19 +35,27 @@ import android.text.method.WordIterator; import android.text.style.ClickableSpan; import android.text.util.Linkify; import android.util.Log; +import android.util.Patterns; import android.view.View; +import com.android.internal.annotations.GuardedBy; import com.android.internal.util.Preconditions; +import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; +import java.util.StringJoiner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Default implementation of the {@link TextClassifier} interface. @@ -61,16 +69,21 @@ import java.util.Map; final class TextClassifierImpl implements TextClassifier { private static final String LOG_TAG = "TextClassifierImpl"; - - private final Object mSmartSelectionLock = new Object(); + private static final String MODEL_DIR = "/etc/textclassifier/"; + private static final String MODEL_FILE_REGEX = "textclassifier\\.smartselection\\.(.*)\\.model"; private final Context mContext; - private final ParcelFileDescriptor mFd; + + private final Object mSmartSelectionLock = new Object(); + @GuardedBy("mSmartSelectionLock") // Do not access outside this lock. + private Map<Locale, String> mModelFilePaths; + @GuardedBy("mSmartSelectionLock") // Do not access outside this lock. + private Locale mLocale; + @GuardedBy("mSmartSelectionLock") // Do not access outside this lock. private SmartSelection mSmartSelection; - TextClassifierImpl(Context context, ParcelFileDescriptor fd) { + TextClassifierImpl(Context context) { mContext = Preconditions.checkNotNull(context); - mFd = Preconditions.checkNotNull(fd); } @Override @@ -80,15 +93,18 @@ final class TextClassifierImpl implements TextClassifier { validateInput(text, selectionStartIndex, selectionEndIndex); try { if (text.length() > 0) { + final SmartSelection smartSelection = getSmartSelection(defaultLocales); final String string = text.toString(); - final int[] startEnd = getSmartSelection() - .suggest(string, selectionStartIndex, selectionEndIndex); + final int[] startEnd = smartSelection.suggest( + string, selectionStartIndex, selectionEndIndex); final int start = startEnd[0]; final int end = startEnd[1]; if (start >= 0 && end <= string.length() && start <= end) { final TextSelection.Builder tsBuilder = new TextSelection.Builder(start, end); final SmartSelection.ClassificationResult[] results = - getSmartSelection().classifyText(string, start, end); + smartSelection.classifyText( + string, start, end, + getHintFlags(string, start, end)); final int size = results.length; for (int i = 0; i < size; i++) { tsBuilder.setEntityType(results[i].mCollection, results[i].mScore); @@ -116,12 +132,14 @@ final class TextClassifierImpl implements TextClassifier { validateInput(text, startIndex, endIndex); try { if (text.length() > 0) { - final CharSequence classified = text.subSequence(startIndex, endIndex); - SmartSelection.ClassificationResult[] results = getSmartSelection() - .classifyText(text.toString(), startIndex, endIndex); + final String string = text.toString(); + SmartSelection.ClassificationResult[] results = getSmartSelection(defaultLocales) + .classifyText(string, startIndex, endIndex, + getHintFlags(string, startIndex, endIndex)); if (results.length > 0) { final TextClassificationResult classificationResult = - createClassificationResult(results, classified); + createClassificationResult( + results, string.subSequence(startIndex, endIndex)); // TODO: Added this log for debug only. Remove before release. Log.d(LOG_TAG, String.format( "Classification type: %s", classificationResult)); @@ -142,7 +160,7 @@ final class TextClassifierImpl implements TextClassifier { Preconditions.checkArgument(text != null); try { return LinksInfoFactory.create( - mContext, getSmartSelection(), text.toString(), linkMask); + mContext, getSmartSelection(defaultLocales), text.toString(), linkMask); } catch (Throwable t) { // Avoid throwing from this method. Log the error. Log.e(LOG_TAG, "Error getting links info.", t); @@ -151,15 +169,69 @@ final class TextClassifierImpl implements TextClassifier { return TextClassifier.NO_OP.getLinks(text, linkMask, defaultLocales); } - private SmartSelection getSmartSelection() throws FileNotFoundException { + private SmartSelection getSmartSelection(LocaleList localeList) throws FileNotFoundException { synchronized (mSmartSelectionLock) { - if (mSmartSelection == null) { - mSmartSelection = new SmartSelection(mFd.getFd()); + localeList = localeList == null ? LocaleList.getEmptyLocaleList() : localeList; + final Locale locale = findBestSupportedLocaleLocked(localeList); + if (mSmartSelection == null || !Objects.equals(mLocale, locale)) { + destroySmartSelectionIfExistsLocked(); + mSmartSelection = new SmartSelection( + ParcelFileDescriptor.open( + // findBestSupportedLocaleLocked should have initialized + // mModelFilePaths + new File(mModelFilePaths.get(locale)), + ParcelFileDescriptor.MODE_READ_ONLY) + .getFd()); + mLocale = locale; } return mSmartSelection; } } + @GuardedBy("mSmartSelectionLock") // Do not call outside this lock. + private void destroySmartSelectionIfExistsLocked() { + if (mSmartSelection != null) { + mSmartSelection.close(); + mSmartSelection = null; + } + } + + @GuardedBy("mSmartSelectionLock") // Do not call outside this lock. + @Nullable + private Locale findBestSupportedLocaleLocked(LocaleList localeList) { + final List<Locale.LanguageRange> languageRangeList = Locale.LanguageRange.parse( + new StringJoiner(",") + // Specified localeList takes priority over the system default + .add(localeList.toLanguageTags()) + .add(LocaleList.getDefault().toLanguageTags()) + .toString()); + return Locale.lookup(languageRangeList, loadModelFilePathsLocked().keySet()); + } + + @GuardedBy("mSmartSelectionLock") // Do not call outside this lock. + private Map<Locale, String> loadModelFilePathsLocked() { + if (mModelFilePaths == null) { + final Map<Locale, String> modelFilePaths = new HashMap<>(); + final File modelsDir = new File(MODEL_DIR); + if (modelsDir.exists() && modelsDir.isDirectory()) { + final File[] models = modelsDir.listFiles(); + final Pattern modelFilenamePattern = Pattern.compile(MODEL_FILE_REGEX); + final int size = models.length; + for (int i = 0; i < size; i++) { + final File modelFile = models[i]; + final Matcher matcher = modelFilenamePattern.matcher(modelFile.getName()); + if (matcher.matches() && modelFile.isFile()) { + final String language = matcher.group(1); + final Locale locale = Locale.forLanguageTag(language); + modelFilePaths.put(locale, modelFile.getAbsolutePath()); + } + } + } + mModelFilePaths = modelFilePaths; + } + return mModelFilePaths; + } + private TextClassificationResult createClassificationResult( SmartSelection.ClassificationResult[] classifications, CharSequence text) { final TextClassificationResult.Builder builder = new TextClassificationResult.Builder() @@ -208,6 +280,24 @@ final class TextClassifierImpl implements TextClassifier { return builder.build(); } + private static int getHintFlags(CharSequence text, int start, int end) { + int flag = 0; + final CharSequence subText = text.subSequence(start, end); + if (Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(subText).matches()) { + flag |= SmartSelection.HINT_FLAG_EMAIL; + } + if (Patterns.AUTOLINK_WEB_URL.matcher(subText).matches() + && Linkify.sUrlMatchFilter.acceptMatch(text, start, end)) { + flag |= SmartSelection.HINT_FLAG_URL; + } + // TODO: Added this log for debug only. Remove before release. + Log.d(LOG_TAG, String.format("Email hint: %b", + (flag & SmartSelection.HINT_FLAG_EMAIL) != 0)); + Log.d(LOG_TAG, String.format("Url hint: %b", + (flag & SmartSelection.HINT_FLAG_URL) != 0)); + return flag; + } + private static String getHighestScoringType(SmartSelection.ClassificationResult[] types) { if (types.length < 1) { return ""; @@ -262,7 +352,9 @@ final class TextClassifierImpl implements TextClassifier { if (selectionStart >= 0 && selectionEnd <= text.length() && selectionStart <= selectionEnd) { final SmartSelection.ClassificationResult[] results = - smartSelection.classifyText(text, selectionStart, selectionEnd); + smartSelection.classifyText( + text, selectionStart, selectionEnd, + getHintFlags(text, selectionStart, selectionEnd)); if (results.length > 0) { final String type = getHighestScoringType(results); if (matches(type, linkMask)) { diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index c2b4138b90db..bc491230aa60 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -18,6 +18,7 @@ package android.webkit; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.Widget; import android.content.Context; @@ -58,6 +59,7 @@ import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeProvider; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; +import android.view.textclassifier.TextClassifier; import android.widget.AbsoluteLayout; import java.io.BufferedWriter; @@ -2249,6 +2251,23 @@ public class WebView extends AbsoluteLayout public boolean getRendererPriorityWaivedWhenNotVisible() { return mProvider.getRendererPriorityWaivedWhenNotVisible(); } + + /** + * Sets the {@link TextClassifier} for this WebView. + */ + public void setTextClassifier(@Nullable TextClassifier textClassifier) { + mProvider.setTextClassifier(textClassifier); + } + + /** + * Returns the {@link TextClassifier} used by this WebView. + * If no TextClassifier has been set, this WebView uses the default set by the system. + */ + @NonNull + public TextClassifier getTextClassifier() { + return mProvider.getTextClassifier(); + } + //------------------------------------------------------------------------- // Interface for WebView providers //------------------------------------------------------------------------- diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java index 81c2f5d5ef4c..71db6b141ca9 100644 --- a/core/java/android/webkit/WebViewFactory.java +++ b/core/java/android/webkit/WebViewFactory.java @@ -280,6 +280,44 @@ public final class WebViewFactory { } } + /** + * If the ApplicationInfo provided is for a stub WebView, fix up the object to include the + * required values from the donor package. If the ApplicationInfo is for a full WebView, + * leave it alone. Throws MissingWebViewPackageException if the donor is missing. + */ + private static void fixupStubApplicationInfo(ApplicationInfo ai, PackageManager pm) { + String donorPackageName = null; + if (ai.metaData != null) { + donorPackageName = ai.metaData.getString("com.android.webview.WebViewDonorPackage"); + } + if (donorPackageName != null) { + PackageInfo donorPackage; + try { + donorPackage = pm.getPackageInfo( + donorPackageName, + PackageManager.GET_SHARED_LIBRARY_FILES + | PackageManager.MATCH_DEBUG_TRIAGED_MISSING + | PackageManager.MATCH_UNINSTALLED_PACKAGES + | PackageManager.MATCH_FACTORY_ONLY); + } catch (PackageManager.NameNotFoundException e) { + throw new MissingWebViewPackageException("Failed to find donor package: " + + donorPackageName); + } + ApplicationInfo donorInfo = donorPackage.applicationInfo; + + // Replace the stub's code locations with the donor's. + ai.sourceDir = donorInfo.sourceDir; + ai.splitSourceDirs = donorInfo.splitSourceDirs; + ai.nativeLibraryDir = donorInfo.nativeLibraryDir; + ai.secondaryNativeLibraryDir = donorInfo.secondaryNativeLibraryDir; + + // Copy the donor's primary and secondary ABIs, since the stub doesn't have native code + // and so they are unset. + ai.primaryCpuAbi = donorInfo.primaryCpuAbi; + ai.secondaryCpuAbi = donorInfo.secondaryCpuAbi; + } + } + private static Context getWebViewContextAndSetProvider() { Application initialApplication = AppGlobals.getInitialApplication(); try { @@ -307,9 +345,10 @@ public final class WebViewFactory { } // Fetch package info and verify it against the chosen package PackageInfo newPackageInfo = null; + PackageManager pm = initialApplication.getPackageManager(); Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "PackageManager.getPackageInfo()"); try { - newPackageInfo = initialApplication.getPackageManager().getPackageInfo( + newPackageInfo = pm.getPackageInfo( response.packageInfo.packageName, PackageManager.GET_SHARED_LIBRARY_FILES | PackageManager.MATCH_DEBUG_TRIAGED_MISSING @@ -328,12 +367,15 @@ public final class WebViewFactory { // failure verifyPackageInfo(response.packageInfo, newPackageInfo); + ApplicationInfo ai = newPackageInfo.applicationInfo; + fixupStubApplicationInfo(ai, pm); + Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "initialApplication.createApplicationContext"); try { // Construct an app context to load the Java code into the current app. Context webViewContext = initialApplication.createApplicationContext( - newPackageInfo.applicationInfo, + ai, Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY); sPackageInfo = newPackageInfo; return webViewContext; @@ -449,7 +491,11 @@ public final class WebViewFactory { */ public static int onWebViewProviderChanged(PackageInfo packageInfo) { String[] nativeLibs = null; + String originalSourceDir = packageInfo.applicationInfo.sourceDir; try { + fixupStubApplicationInfo(packageInfo.applicationInfo, + AppGlobals.getInitialApplication().getPackageManager()); + nativeLibs = WebViewFactory.getWebViewNativeLibraryPaths(packageInfo); if (nativeLibs != null) { long newVmSize = 0L; @@ -498,7 +544,7 @@ public final class WebViewFactory { Log.e(LOGTAG, "error preparing webview native library", t); } - WebViewZygote.onWebViewProviderChanged(packageInfo); + WebViewZygote.onWebViewProviderChanged(packageInfo, originalSourceDir); return prepareWebViewInSystemServer(nativeLibs); } diff --git a/core/java/android/webkit/WebViewProvider.java b/core/java/android/webkit/WebViewProvider.java index 5724a9b24052..aa1ffa25931d 100644 --- a/core/java/android/webkit/WebViewProvider.java +++ b/core/java/android/webkit/WebViewProvider.java @@ -16,6 +16,8 @@ package android.webkit; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.SystemApi; import android.content.res.Configuration; import android.content.Intent; @@ -41,6 +43,7 @@ import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeProvider; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; +import android.view.textclassifier.TextClassifier; import android.webkit.WebView.HitTestResult; import android.webkit.WebView.PictureListener; import android.webkit.WebView.VisualStateCallback; @@ -275,6 +278,12 @@ public interface WebViewProvider { public boolean getRendererPriorityWaivedWhenNotVisible(); + @SuppressWarnings("unused") + public default void setTextClassifier(@Nullable TextClassifier textClassifier) {} + + @NonNull + public default TextClassifier getTextClassifier() { return TextClassifier.NO_OP; } + //------------------------------------------------------------------------- // Provider internal methods //------------------------------------------------------------------------- diff --git a/core/java/android/webkit/WebViewZygote.java b/core/java/android/webkit/WebViewZygote.java index f78d62250029..2123debfeb67 100644 --- a/core/java/android/webkit/WebViewZygote.java +++ b/core/java/android/webkit/WebViewZygote.java @@ -67,6 +67,13 @@ public class WebViewZygote { private static PackageInfo sPackage; /** + * Cache key for the selected WebView package's classloader. This is set from + * #onWebViewProviderChanged(). + */ + @GuardedBy("sLock") + private static String sPackageCacheKey; + + /** * Flag for whether multi-process WebView is enabled. If this is false, the zygote * will not be started. */ @@ -118,9 +125,10 @@ public class WebViewZygote { } } - public static void onWebViewProviderChanged(PackageInfo packageInfo) { + public static void onWebViewProviderChanged(PackageInfo packageInfo, String cacheKey) { synchronized (sLock) { sPackage = packageInfo; + sPackageCacheKey = cacheKey; // If multi-process is not enabled, then do not start the zygote service. if (!sMultiprocessEnabled) { @@ -210,7 +218,8 @@ public class WebViewZygote { TextUtils.join(File.pathSeparator, zipPaths); Log.d(LOGTAG, "Preloading package " + zip + " " + librarySearchPath); - sZygote.preloadPackageForAbi(zip, librarySearchPath, Build.SUPPORTED_ABIS[0]); + sZygote.preloadPackageForAbi(zip, librarySearchPath, sPackageCacheKey, + Build.SUPPORTED_ABIS[0]); } catch (Exception e) { Log.e(LOGTAG, "Error connecting to " + serviceName, e); sZygote = null; diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 1937187defed..1c87726b3ca9 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -618,7 +618,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te private int mTouchSlop; private float mDensityScale; - private float mScrollFactor; + private float mVerticalScrollFactor; private InputConnection mDefInputConnection; private InputConnectionWrapper mPublicInputConnection; @@ -877,7 +877,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te final ViewConfiguration configuration = ViewConfiguration.get(mContext); mTouchSlop = configuration.getScaledTouchSlop(); - mScrollFactor = configuration.getScaledScrollFactor(); + mVerticalScrollFactor = configuration.getScaledVerticalScrollFactor(); mMinimumVelocity = configuration.getScaledMinimumFlingVelocity(); mMaximumVelocity = configuration.getScaledMaximumFlingVelocity(); mOverscrollDistance = configuration.getScaledOverscrollDistance(); @@ -4225,7 +4225,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te axisValue = 0; } - final int delta = Math.round(axisValue * mScrollFactor); + final int delta = Math.round(axisValue * mVerticalScrollFactor); if (delta != 0) { if (!trackMotionScroll(delta, delta)) { return true; @@ -6873,9 +6873,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mTransientStateViews.put(position, scrap); } else { // Otherwise, we'll have to remove the view and start over. + clearScrapForRebind(scrap); getSkippedScrap().add(scrap); } } else { + clearScrapForRebind(scrap); if (mViewTypeCount == 1) { mCurrentScrap.add(scrap); } else { @@ -7098,12 +7100,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } else if (params.scrappedFromPosition == position) { final View scrap = scrapViews.remove(i); - clearAccessibilityFromScrap(scrap); + clearScrapForRebind(scrap); return scrap; } } final View scrap = scrapViews.remove(size - 1); - clearAccessibilityFromScrap(scrap); + clearScrapForRebind(scrap); return scrap; } else { return null; @@ -7117,7 +7119,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } - private void clearAccessibilityFromScrap(View view) { + private void clearScrapForRebind(View view) { view.clearAccessibilityFocus(); view.setAccessibilityDelegate(null); } diff --git a/core/java/android/widget/AbsSpinner.java b/core/java/android/widget/AbsSpinner.java index 8f662ba79d5f..352e7de967dd 100644 --- a/core/java/android/widget/AbsSpinner.java +++ b/core/java/android/widget/AbsSpinner.java @@ -526,15 +526,15 @@ public abstract class AbsSpinner extends AdapterView<SpinnerAdapter> { } @Override - public boolean autofill(AutofillValue value) { - if (!isEnabled()) return false; + public void autofill(AutofillValue value) { + if (!isEnabled()) return; - if (value.isList()) { - setSelection(value.getListValue()); - } else { + if (!value.isList()) { Log.w(LOG_TAG, value + " could not be autofilled into " + this); + return; } - return true; + + setSelection(value.getListValue()); } @Override diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java index 9dc61ab56b34..c7ba7b5d5a48 100644 --- a/core/java/android/widget/CompoundButton.java +++ b/core/java/android/widget/CompoundButton.java @@ -584,16 +584,15 @@ public abstract class CompoundButton extends Button implements Checkable { } @Override - public boolean autofill(AutofillValue value) { - if (!isEnabled()) return false; + public void autofill(AutofillValue value) { + if (!isEnabled()) return; - if (value.isToggle()) { - setChecked(value.getToggleValue()); - } else { + if (!value.isToggle()) { Log.w(LOG_TAG, value + " could not be autofilled into " + this); + return; } - return true; + setChecked(value.getToggleValue()); } @Override diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java index 7d04f355f251..463ff587466a 100644 --- a/core/java/android/widget/DatePicker.java +++ b/core/java/android/widget/DatePicker.java @@ -775,16 +775,15 @@ public class DatePicker extends FrameLayout { } @Override - public boolean autofill(AutofillValue value) { - if (!isEnabled()) return false; + public void autofill(AutofillValue value) { + if (!isEnabled()) return; - if (value.isDate()) { - mDelegate.updateDate(value.getDateValue()); - } else { + if (!value.isDate()) { Log.w(LOG_TAG, value + " could not be autofilled into " + this); + return; } - return true; + mDelegate.updateDate(value.getDateValue()); } @Override diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java index 918b6c0d65ff..da00d9c970b1 100644 --- a/core/java/android/widget/HorizontalScrollView.java +++ b/core/java/android/widget/HorizontalScrollView.java @@ -129,7 +129,7 @@ public class HorizontalScrollView extends FrameLayout { private int mOverscrollDistance; private int mOverflingDistance; - private float mScrollFactor; + private float mHorizontalScrollFactor; /** * ID of the active pointer. This is used to retain consistency during @@ -224,7 +224,7 @@ public class HorizontalScrollView extends FrameLayout { mMaximumVelocity = configuration.getScaledMaximumFlingVelocity(); mOverscrollDistance = configuration.getScaledOverscrollDistance(); mOverflingDistance = configuration.getScaledOverflingDistance(); - mScrollFactor = configuration.getScaledScrollFactor(); + mHorizontalScrollFactor = configuration.getScaledHorizontalScrollFactor(); } @Override @@ -743,7 +743,7 @@ public class HorizontalScrollView extends FrameLayout { axisValue = 0; } - final int delta = Math.round(axisValue * mScrollFactor); + final int delta = Math.round(axisValue * mHorizontalScrollFactor); if (delta != 0) { final int range = getScrollRange(); int oldScrollX = mScrollX; diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java index 78d18fdbca5f..ab4cce479005 100644 --- a/core/java/android/widget/ListPopupWindow.java +++ b/core/java/android/widget/ListPopupWindow.java @@ -523,9 +523,17 @@ public class ListPopupWindow implements ShowableListMenu { /** * Sets the height of the popup window in pixels. Can also be {@link #MATCH_PARENT}. * - * @param height Height of the popup window. + * @param height Height of the popup window must be a positive value, + * {@link #MATCH_PARENT}, or {@link #WRAP_CONTENT}. + * + * @throws IllegalArgumentException if height is set to negative value */ public void setHeight(int height) { + if (height < 0 && ViewGroup.LayoutParams.WRAP_CONTENT != height + && ViewGroup.LayoutParams.MATCH_PARENT != height) { + throw new IllegalArgumentException( + "Invalid height. Must be a positive value, MATCH_PARENT, or WRAP_CONTENT."); + } mDropDownHeight = height; } diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java index 1c0c4ef7cba7..12e35a14e381 100644 --- a/core/java/android/widget/ListView.java +++ b/core/java/android/widget/ListView.java @@ -1639,7 +1639,7 @@ public class ListView extends AbsListView { final View focusChild = getAccessibilityFocusedChild(focusHost); if (focusChild != null) { if (!dataChanged || isDirectChildHeaderOrFooter(focusChild) - || focusChild.hasTransientState() || mAdapterHasStableIds) { + || (focusChild.hasTransientState() && mAdapterHasStableIds)) { // The views won't be changing, so try to maintain // focus on the current host and virtual view. accessibilityFocusLayoutRestoreView = focusHost; diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java index b63b899d5c92..59fb02d353bb 100644 --- a/core/java/android/widget/PopupWindow.java +++ b/core/java/android/widget/PopupWindow.java @@ -2064,7 +2064,7 @@ public class PopupWindow { } if (update) { - update(mAnchor.get(), p); + update(mAnchor != null ? mAnchor.get() : null, p); } } @@ -2178,9 +2178,14 @@ public class PopupWindow { update = true; } - final View anchor = mAnchor.get(); - final int newAccessibilityIdOfAnchor = (anchor != null) - ? anchor.getAccessibilityViewId() : -1; + View anchor = null; + int newAccessibilityIdOfAnchor = -1; + + if (mAnchor != null && mAnchor.get() != null) { + anchor = mAnchor.get(); + newAccessibilityIdOfAnchor = anchor.getAccessibilityViewId(); + } + if (newAccessibilityIdOfAnchor != p.accessibilityIdOfAnchor) { p.accessibilityIdOfAnchor = newAccessibilityIdOfAnchor; update = true; @@ -2366,7 +2371,8 @@ public class PopupWindow { } private class PopupDecorView extends FrameLayout { - private TransitionListenerAdapter mPendingExitListener; + /** Runnable used to clean up listeners after exit transition. */ + private Runnable mCleanupAfterExit; public PopupDecorView(Context context) { super(context); @@ -2477,7 +2483,7 @@ public class PopupWindow { * <p> * <strong>Note:</strong> The transition listener is guaranteed to have * its {@code onTransitionEnd} method called even if the transition - * never starts; however, it may be called with a {@code null} argument. + * never starts. */ public void startExitTransition(@NonNull Transition transition, @Nullable final View anchorRoot, @Nullable final Rect epicenter, @@ -2493,25 +2499,32 @@ public class PopupWindow { anchorRoot.addOnAttachStateChangeListener(mOnAnchorRootDetachedListener); } - // The exit listener MUST be called for cleanup, even if the - // transition never starts or ends. Stash it for later. - mPendingExitListener = new TransitionListenerAdapter() { - @Override - public void onTransitionEnd(Transition t) { - if (anchorRoot != null) { - anchorRoot.removeOnAttachStateChangeListener(mOnAnchorRootDetachedListener); - } - - listener.onTransitionEnd(t); + // The cleanup runnable MUST be called even if the transition is + // canceled before it starts (and thus can't call onTransitionEnd). + mCleanupAfterExit = () -> { + listener.onTransitionEnd(transition); - // The listener was called. Our job here is done. - mPendingExitListener = null; - t.removeListener(this); + if (anchorRoot != null) { + anchorRoot.removeOnAttachStateChangeListener(mOnAnchorRootDetachedListener); } + + // The listener was called. Our job here is done. + mCleanupAfterExit = null; }; final Transition exitTransition = transition.clone(); - exitTransition.addListener(mPendingExitListener); + exitTransition.addListener(new TransitionListenerAdapter() { + @Override + public void onTransitionEnd(Transition t) { + t.removeListener(this); + + // This null check shouldn't be necessary, but it's easier + // to check here than it is to test every possible case. + if (mCleanupAfterExit != null) { + mCleanupAfterExit.run(); + } + } + }); exitTransition.setEpicenterCallback(new EpicenterCallback() { @Override public Rect onGetEpicenter(Transition transition) { @@ -2539,8 +2552,10 @@ public class PopupWindow { public void cancelTransitions() { TransitionManager.endTransitions(this); - if (mPendingExitListener != null) { - mPendingExitListener.onTransitionEnd(null); + // If the cleanup runnable is still around, that means the + // transition never started. We should run it now to clean up. + if (mCleanupAfterExit != null) { + mCleanupAfterExit.run(); } } diff --git a/core/java/android/widget/RadioGroup.java b/core/java/android/widget/RadioGroup.java index a7574c7a45ae..08e657559e17 100644 --- a/core/java/android/widget/RadioGroup.java +++ b/core/java/android/widget/RadioGroup.java @@ -426,24 +426,22 @@ public class RadioGroup extends LinearLayout { } @Override - public boolean autofill(AutofillValue value) { - if (!isEnabled()) return false; + public void autofill(AutofillValue value) { + if (!isEnabled()) return; - int index; - if (value.isList()) { - index = value.getListValue(); - } else { + if (!value.isList()) { Log.w(LOG_TAG, value + " could not be autofilled into " + this); - return false; + return; } + final int index = value.getListValue(); final View child = getChildAt(index); if (child == null) { Log.w(VIEW_LOG_TAG, "RadioGroup.autoFill(): no child with index " + index); - return false; + return; } + check(child.getId()); - return true; } @Override diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java index d8f337926073..0a9e361a20c4 100644 --- a/core/java/android/widget/ScrollView.java +++ b/core/java/android/widget/ScrollView.java @@ -135,7 +135,7 @@ public class ScrollView extends FrameLayout { private int mOverscrollDistance; private int mOverflingDistance; - private int mScrollFactor; + private float mVerticalScrollFactor; /** * ID of the active pointer. This is used to retain consistency during @@ -250,7 +250,7 @@ public class ScrollView extends FrameLayout { mMaximumVelocity = configuration.getScaledMaximumFlingVelocity(); mOverscrollDistance = configuration.getScaledOverscrollDistance(); mOverflingDistance = configuration.getScaledOverflingDistance(); - mScrollFactor = configuration.getScaledScrollFactor(); + mVerticalScrollFactor = configuration.getScaledVerticalScrollFactor(); } @Override @@ -796,7 +796,7 @@ public class ScrollView extends FrameLayout { axisValue = 0; } - final int delta = Math.round(axisValue * mScrollFactor); + final int delta = Math.round(axisValue * mVerticalScrollFactor); if (delta != 0) { final int range = getScrollRange(); int oldScrollY = mScrollY; @@ -1875,7 +1875,7 @@ public class ScrollView extends FrameLayout { @Override public String toString() { - return "HorizontalScrollView.SavedState{" + return "ScrollView.SavedState{" + Integer.toHexString(System.identityHashCode(this)) + " scrollPosition=" + scrollPosition + "}"; } diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java index a03238374f39..003db061c140 100644 --- a/core/java/android/widget/SelectionActionModeHelper.java +++ b/core/java/android/widget/SelectionActionModeHelper.java @@ -289,7 +289,7 @@ final class SelectionActionModeHelper { */ private static final class TextClassificationHelper { - private static final int TRIM_DELTA = 50; // characters + private static final int TRIM_DELTA = 120; // characters private TextClassifier mTextClassifier; diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index bc7c79d2e701..02afee32153b 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -10050,17 +10050,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } @Override - public boolean autofill(AutofillValue value) { - if (value.isText()) { - if (isTextEditable()) { - setText(value.getTextValue(), mBufferType, true, 0); - return true; - } - } else { + public void autofill(AutofillValue value) { + if (!value.isText() || !isTextEditable()) { Log.w(LOG_TAG, value + " could not be autofilled into " + this); + return; } - return false; + setText(value.getTextValue(), mBufferType, true, 0); } @Override diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java index 1e97e3ba5134..0289dada0fd9 100644 --- a/core/java/android/widget/TimePicker.java +++ b/core/java/android/widget/TimePicker.java @@ -530,16 +530,14 @@ public class TimePicker extends FrameLayout { } @Override - public boolean autofill(AutofillValue value) { - if (!isEnabled()) return false; + public void autofill(AutofillValue value) { + if (!isEnabled()) return; - if (value.isDate()) { - mDelegate.setDate(value.getDateValue()); - } else { + if (!value.isDate()) { Log.w(LOG_TAG, value + " could not be autofilled into " + this); } - return true; + mDelegate.setDate(value.getDateValue()); } @Override diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java index 2eb50e082041..bf3085d6f1d1 100644 --- a/core/java/android/widget/Toolbar.java +++ b/core/java/android/widget/Toolbar.java @@ -343,6 +343,9 @@ public class Toolbar extends ViewGroup { final ViewGroup vgParent = (ViewGroup) parent; if (vgParent.isKeyboardNavigationCluster()) { setKeyboardNavigationCluster(false); + if (vgParent.getTouchscreenBlocksFocus()) { + setTouchscreenBlocksFocus(false); + } break; } parent = vgParent.getParent(); diff --git a/core/java/com/android/internal/app/LRResolverRankerService.java b/core/java/com/android/internal/app/LRResolverRankerService.java new file mode 100644 index 000000000000..1cad7c770b7c --- /dev/null +++ b/core/java/com/android/internal/app/LRResolverRankerService.java @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2017 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.internal.app; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Environment; +import android.os.IBinder; +import android.os.storage.StorageManager; +import android.service.resolver.ResolverRankerService; +import android.service.resolver.ResolverTarget; +import android.util.ArrayMap; +import android.util.Log; + +import java.io.File; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * A Logistic Regression based {@link android.service.resolver.ResolverRankerService}, to be used + * in {@link ResolverComparator}. + */ +public final class LRResolverRankerService extends ResolverRankerService { + private static final String TAG = "LRResolverRankerService"; + + private static final boolean DEBUG = false; + + private static final String PARAM_SHARED_PREF_NAME = "resolver_ranker_params"; + private static final String BIAS_PREF_KEY = "bias"; + private static final String VERSION_PREF_KEY = "version"; + + private static final String LAUNCH_SCORE = "launch"; + private static final String TIME_SPENT_SCORE = "timeSpent"; + private static final String RECENCY_SCORE = "recency"; + private static final String CHOOSER_SCORE = "chooser"; + + // parameters for a pre-trained model, to initialize the app ranker. When updating the + // pre-trained model, please update these params, as well as initModel(). + private static final int CURRENT_VERSION = 1; + private static final float LEARNING_RATE = 0.0001f; + private static final float REGULARIZER_PARAM = 0.0001f; + + private SharedPreferences mParamSharedPref; + private ArrayMap<String, Float> mFeatureWeights; + private float mBias; + + @Override + public IBinder onBind(Intent intent) { + initModel(); + return super.onBind(intent); + } + + @Override + public void onPredictSharingProbabilities(List<ResolverTarget> targets) { + final int size = targets.size(); + for (int i = 0; i < size; ++i) { + ResolverTarget target = targets.get(i); + ArrayMap<String, Float> features = getFeatures(target); + target.setSelectProbability(predict(features)); + } + } + + @Override + public void onTrainRankingModel(List<ResolverTarget> targets, int selectedPosition) { + final int size = targets.size(); + if (selectedPosition < 0 || selectedPosition >= size) { + if (DEBUG) { + Log.d(TAG, "Invalid Position of Selected App " + selectedPosition); + } + return; + } + final ArrayMap<String, Float> positive = getFeatures(targets.get(selectedPosition)); + final float positiveProbability = targets.get(selectedPosition).getSelectProbability(); + final int targetSize = targets.size(); + for (int i = 0; i < targetSize; ++i) { + if (i == selectedPosition) { + continue; + } + final ArrayMap<String, Float> negative = getFeatures(targets.get(i)); + final float negativeProbability = targets.get(i).getSelectProbability(); + if (negativeProbability > positiveProbability) { + update(negative, negativeProbability, false); + update(positive, positiveProbability, true); + } + } + commitUpdate(); + } + + private void initModel() { + mParamSharedPref = getParamSharedPref(); + mFeatureWeights = new ArrayMap<>(4); + if (mParamSharedPref == null || + mParamSharedPref.getInt(VERSION_PREF_KEY, 0) < CURRENT_VERSION) { + // Initializing the app ranker to a pre-trained model. When updating the pre-trained + // model, please increment CURRENT_VERSION, and update LEARNING_RATE and + // REGULARIZER_PARAM. + mBias = -1.6568f; + mFeatureWeights.put(LAUNCH_SCORE, 2.5543f); + mFeatureWeights.put(TIME_SPENT_SCORE, 2.8412f); + mFeatureWeights.put(RECENCY_SCORE, 0.269f); + mFeatureWeights.put(CHOOSER_SCORE, 4.2222f); + } else { + mBias = mParamSharedPref.getFloat(BIAS_PREF_KEY, 0.0f); + mFeatureWeights.put(LAUNCH_SCORE, mParamSharedPref.getFloat(LAUNCH_SCORE, 0.0f)); + mFeatureWeights.put( + TIME_SPENT_SCORE, mParamSharedPref.getFloat(TIME_SPENT_SCORE, 0.0f)); + mFeatureWeights.put(RECENCY_SCORE, mParamSharedPref.getFloat(RECENCY_SCORE, 0.0f)); + mFeatureWeights.put(CHOOSER_SCORE, mParamSharedPref.getFloat(CHOOSER_SCORE, 0.0f)); + } + } + + private ArrayMap<String, Float> getFeatures(ResolverTarget target) { + ArrayMap<String, Float> features = new ArrayMap<>(4); + features.put(RECENCY_SCORE, target.getRecencyScore()); + features.put(TIME_SPENT_SCORE, target.getTimeSpentScore()); + features.put(LAUNCH_SCORE, target.getLaunchScore()); + features.put(CHOOSER_SCORE, target.getChooserScore()); + return features; + } + + private float predict(ArrayMap<String, Float> target) { + if (target == null) { + return 0.0f; + } + final int featureSize = target.size(); + float sum = 0.0f; + for (int i = 0; i < featureSize; i++) { + String featureName = target.keyAt(i); + float weight = mFeatureWeights.getOrDefault(featureName, 0.0f); + sum += weight * target.valueAt(i); + } + return (float) (1.0 / (1.0 + Math.exp(-mBias - sum))); + } + + private void update(ArrayMap<String, Float> target, float predict, boolean isSelected) { + if (target == null) { + return; + } + final int featureSize = target.size(); + float error = isSelected ? 1.0f - predict : -predict; + for (int i = 0; i < featureSize; i++) { + String featureName = target.keyAt(i); + float currentWeight = mFeatureWeights.getOrDefault(featureName, 0.0f); + mBias += LEARNING_RATE * error; + currentWeight = currentWeight - LEARNING_RATE * REGULARIZER_PARAM * currentWeight + + LEARNING_RATE * error * target.valueAt(i); + mFeatureWeights.put(featureName, currentWeight); + } + if (DEBUG) { + Log.d(TAG, "Weights: " + mFeatureWeights + " Bias: " + mBias); + } + } + + private void commitUpdate() { + try { + SharedPreferences.Editor editor = mParamSharedPref.edit(); + editor.putFloat(BIAS_PREF_KEY, mBias); + final int size = mFeatureWeights.size(); + for (int i = 0; i < size; i++) { + editor.putFloat(mFeatureWeights.keyAt(i), mFeatureWeights.valueAt(i)); + } + editor.putInt(VERSION_PREF_KEY, CURRENT_VERSION); + editor.apply(); + } catch (Exception e) { + Log.e(TAG, "Failed to commit update" + e); + } + } + + private SharedPreferences getParamSharedPref() { + // The package info in the context isn't initialized in the way it is for normal apps, + // so the standard, name-based context.getSharedPreferences doesn't work. Instead, we + // build the path manually below using the same policy that appears in ContextImpl. + if (DEBUG) { + Log.d(TAG, "Context Package Name: " + getPackageName()); + } + final File prefsFile = new File(new File( + Environment.getDataUserCePackageDirectory( + StorageManager.UUID_PRIVATE_INTERNAL, getUserId(), getPackageName()), + "shared_prefs"), + PARAM_SHARED_PREF_NAME + ".xml"); + return getSharedPreferences(prefsFile, Context.MODE_PRIVATE); + } +}
\ No newline at end of file diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index 3f1c9adb1b68..622b70843cc2 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -530,6 +530,9 @@ public class ResolverActivity extends Activity { getMainThreadHandler().removeCallbacks(mPostListReadyRunnable); mPostListReadyRunnable = null; } + if (mAdapter != null && mAdapter.mResolverListController != null) { + mAdapter.mResolverListController.destroy(); + } } @Override diff --git a/core/java/com/android/internal/app/ResolverComparator.java b/core/java/com/android/internal/app/ResolverComparator.java index 096fcb83e755..73b62a5fe60d 100644 --- a/core/java/com/android/internal/app/ResolverComparator.java +++ b/core/java/com/android/internal/app/ResolverComparator.java @@ -26,20 +26,34 @@ import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.ComponentInfo; import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.content.SharedPreferences; +import android.content.ServiceConnection; import android.os.Environment; +import android.os.Handler; +import android.os.IBinder; +import android.os.Looper; +import android.os.Message; +import android.os.RemoteException; import android.os.storage.StorageManager; import android.os.UserHandle; +import android.service.resolver.IResolverRankerService; +import android.service.resolver.IResolverRankerResult; +import android.service.resolver.ResolverRankerService; +import android.service.resolver.ResolverTarget; import android.text.TextUtils; import android.util.ArrayMap; import android.util.Log; import com.android.internal.app.ResolverActivity.ResolvedComponentInfo; import java.io.File; +import java.lang.InterruptedException; import java.text.Collator; import java.util.ArrayList; import java.util.Comparator; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -61,11 +75,15 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> { private static final float RECENCY_MULTIPLIER = 2.f; - // feature names used in ranking. - private static final String LAUNCH_SCORE = "launch"; - private static final String TIME_SPENT_SCORE = "timeSpent"; - private static final String RECENCY_SCORE = "recency"; - private static final String CHOOSER_SCORE = "chooser"; + // message types + private static final int RESOLVER_RANKER_SERVICE_RESULT = 0; + private static final int RESOLVER_RANKER_RESULT_TIMEOUT = 1; + + // timeout for establishing connections with a ResolverRankerService. + private static final int CONNECTION_COST_TIMEOUT_MILLIS = 200; + // timeout for establishing connections with a ResolverRankerService, collecting features and + // predicting ranking scores. + private static final int WATCHDOG_TIMEOUT_MILLIS = 500; private final Collator mCollator; private final boolean mHttp; @@ -74,18 +92,74 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> { private final Map<String, UsageStats> mStats; private final long mCurrentTime; private final long mSinceTime; - private final LinkedHashMap<ComponentName, ScoredTarget> mScoredTargets = new LinkedHashMap<>(); + private final LinkedHashMap<ComponentName, ResolverTarget> mTargetsDict = new LinkedHashMap<>(); private final String mReferrerPackage; + private final Object mLock = new Object(); + private ArrayList<ResolverTarget> mTargets; private String mContentType; private String[] mAnnotations; private String mAction; - private LogisticRegressionAppRanker mRanker; + private IResolverRankerService mRanker; + private ResolverRankerServiceConnection mConnection; + private AfterCompute mAfterCompute; + private Context mContext; + private CountDownLatch mConnectSignal; + + private final Handler mHandler = new Handler(Looper.getMainLooper()) { + public void handleMessage(Message msg) { + switch (msg.what) { + case RESOLVER_RANKER_SERVICE_RESULT: + if (DEBUG) { + Log.d(TAG, "RESOLVER_RANKER_SERVICE_RESULT"); + } + if (mHandler.hasMessages(RESOLVER_RANKER_RESULT_TIMEOUT)) { + if (msg.obj != null) { + final List<ResolverTarget> receivedTargets = + (List<ResolverTarget>) msg.obj; + if (receivedTargets != null && mTargets != null + && receivedTargets.size() == mTargets.size()) { + final int size = mTargets.size(); + for (int i = 0; i < size; ++i) { + mTargets.get(i).setSelectProbability( + receivedTargets.get(i).getSelectProbability()); + } + } else { + Log.e(TAG, "Sizes of sent and received ResolverTargets diff."); + } + } else { + Log.e(TAG, "Receiving null prediction results."); + } + mHandler.removeMessages(RESOLVER_RANKER_RESULT_TIMEOUT); + mAfterCompute.afterCompute(); + } + break; + + case RESOLVER_RANKER_RESULT_TIMEOUT: + if (DEBUG) { + Log.d(TAG, "RESOLVER_RANKER_RESULT_TIMEOUT; unbinding services"); + } + mHandler.removeMessages(RESOLVER_RANKER_SERVICE_RESULT); + mAfterCompute.afterCompute(); + break; - public ResolverComparator(Context context, Intent intent, String referrerPackage) { + default: + super.handleMessage(msg); + } + } + }; + + public interface AfterCompute { + public void afterCompute (); + } + + public ResolverComparator(Context context, Intent intent, String referrerPackage, + AfterCompute afterCompute) { mCollator = Collator.getInstance(context.getResources().getConfiguration().locale); String scheme = intent.getScheme(); mHttp = "http".equals(scheme) || "https".equals(scheme); mReferrerPackage = referrerPackage; + mAfterCompute = afterCompute; + mContext = context; mPm = context.getPackageManager(); mUsm = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE); @@ -96,9 +170,9 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> { mContentType = intent.getType(); getContentAnnotations(intent); mAction = intent.getAction(); - mRanker = new LogisticRegressionAppRanker(context); } + // get annotations of content from intent. public void getContentAnnotations(Intent intent) { ArrayList<String> annotations = intent.getStringArrayListExtra( Intent.EXTRA_CONTENT_ANNOTATIONS); @@ -114,20 +188,24 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> { } } + public void setCallBack(AfterCompute afterCompute) { + mAfterCompute = afterCompute; + } + + // compute features for each target according to usage stats of targets. public void compute(List<ResolvedComponentInfo> targets) { - mScoredTargets.clear(); + reset(); final long recentSinceTime = mCurrentTime - RECENCY_TIME_PERIOD; - long mostRecentlyUsedTime = recentSinceTime + 1; - long mostTimeSpent = 1; - int mostLaunched = 1; - int mostSelected = 1; + float mostRecencyScore = 1.0f; + float mostTimeSpentScore = 1.0f; + float mostLaunchScore = 1.0f; + float mostChooserScore = 1.0f; for (ResolvedComponentInfo target : targets) { - final ScoredTarget scoredTarget - = new ScoredTarget(target.getResolveInfoAt(0).activityInfo); - mScoredTargets.put(target.name, scoredTarget); + final ResolverTarget resolverTarget = new ResolverTarget(); + mTargetsDict.put(target.name, resolverTarget); final UsageStats pkStats = mStats.get(target.name.getPackageName()); if (pkStats != null) { // Only count recency for apps that weren't the caller @@ -135,31 +213,33 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> { // Persistent processes muck this up, so omit them too. if (!target.name.getPackageName().equals(mReferrerPackage) && !isPersistentProcess(target)) { - final long lastTimeUsed = pkStats.getLastTimeUsed(); - scoredTarget.lastTimeUsed = lastTimeUsed; - if (lastTimeUsed > mostRecentlyUsedTime) { - mostRecentlyUsedTime = lastTimeUsed; + final float recencyScore = + (float) Math.max(pkStats.getLastTimeUsed() - recentSinceTime, 0); + resolverTarget.setRecencyScore(recencyScore); + if (recencyScore > mostRecencyScore) { + mostRecencyScore = recencyScore; } } - final long timeSpent = pkStats.getTotalTimeInForeground(); - scoredTarget.timeSpent = timeSpent; - if (timeSpent > mostTimeSpent) { - mostTimeSpent = timeSpent; + final float timeSpentScore = (float) pkStats.getTotalTimeInForeground(); + resolverTarget.setTimeSpentScore(timeSpentScore); + if (timeSpentScore > mostTimeSpentScore) { + mostTimeSpentScore = timeSpentScore; } - final int launched = pkStats.mLaunchCount; - scoredTarget.launchCount = launched; - if (launched > mostLaunched) { - mostLaunched = launched; + final float launchScore = (float) pkStats.mLaunchCount; + resolverTarget.setLaunchScore(launchScore); + if (launchScore > mostLaunchScore) { + mostLaunchScore = launchScore; } - int selected = 0; + float chooserScore = 0.0f; if (pkStats.mChooserCounts != null && mAction != null && pkStats.mChooserCounts.get(mAction) != null) { - selected = pkStats.mChooserCounts.get(mAction).getOrDefault(mContentType, 0); + chooserScore = (float) pkStats.mChooserCounts.get(mAction) + .getOrDefault(mContentType, 0); if (mAnnotations != null) { final int size = mAnnotations.length; for (int i = 0; i < size; i++) { - selected += pkStats.mChooserCounts.get(mAction) + chooserScore += (float) pkStats.mChooserCounts.get(mAction) .getOrDefault(mAnnotations[i], 0); } } @@ -169,44 +249,37 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> { Log.d(TAG, "Action type is null"); } else { Log.d(TAG, "Chooser Count of " + mAction + ":" + - target.name.getPackageName() + " is " + Integer.toString(selected)); + target.name.getPackageName() + " is " + + Float.toString(chooserScore)); } } - scoredTarget.chooserCount = selected; - if (selected > mostSelected) { - mostSelected = selected; + resolverTarget.setChooserScore(chooserScore); + if (chooserScore > mostChooserScore) { + mostChooserScore = chooserScore; } } } - if (DEBUG) { - Log.d(TAG, "compute - mostRecentlyUsedTime: " + mostRecentlyUsedTime - + " mostTimeSpent: " + mostTimeSpent - + " recentSinceTime: " + recentSinceTime - + " mostLaunched: " + mostLaunched); + Log.d(TAG, "compute - mostRecencyScore: " + mostRecencyScore + + " mostTimeSpentScore: " + mostTimeSpentScore + + " mostLaunchScore: " + mostLaunchScore + + " mostChooserScore: " + mostChooserScore); } - for (ScoredTarget target : mScoredTargets.values()) { - final float recency = (float) Math.max(target.lastTimeUsed - recentSinceTime, 0) - / (mostRecentlyUsedTime - recentSinceTime); - target.setFeatures((float) target.launchCount / mostLaunched, - (float) target.timeSpent / mostTimeSpent, - recency * recency * RECENCY_MULTIPLIER, - (float) target.chooserCount / mostSelected); - target.selectProb = mRanker.predict(target.getFeatures()); + mTargets = new ArrayList<>(mTargetsDict.values()); + for (ResolverTarget target : mTargets) { + final float recency = target.getRecencyScore() / mostRecencyScore; + setFeatures(target, recency * recency * RECENCY_MULTIPLIER, + target.getLaunchScore() / mostLaunchScore, + target.getTimeSpentScore() / mostTimeSpentScore, + target.getChooserScore() / mostChooserScore); + addDefaultSelectProbability(target); if (DEBUG) { Log.d(TAG, "Scores: " + target); } } - } - - static boolean isPersistentProcess(ResolvedComponentInfo rci) { - if (rci != null && rci.getCount() > 0) { - return (rci.getResolveInfoAt(0).activityInfo.applicationInfo.flags & - ApplicationInfo.FLAG_PERSISTENT) != 0; - } - return false; + predictSelectProbabilities(mTargets); } @Override @@ -245,16 +318,16 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> { // Pinned items stay stable within a normal lexical sort and ignore scoring. if (!lPinned && !rPinned) { if (mStats != null) { - final ScoredTarget lhsTarget = mScoredTargets.get(new ComponentName( + final ResolverTarget lhsTarget = mTargetsDict.get(new ComponentName( lhs.activityInfo.packageName, lhs.activityInfo.name)); - final ScoredTarget rhsTarget = mScoredTargets.get(new ComponentName( + final ResolverTarget rhsTarget = mTargetsDict.get(new ComponentName( rhs.activityInfo.packageName, rhs.activityInfo.name)); - final int selectProbDiff = Float.compare( - rhsTarget.selectProb, lhsTarget.selectProb); + final int selectProbabilityDiff = Float.compare( + rhsTarget.getSelectProbability(), lhsTarget.getSelectProbability()); - if (selectProbDiff != 0) { - return selectProbDiff > 0 ? 1 : -1; + if (selectProbabilityDiff != 0) { + return selectProbabilityDiff > 0 ? 1 : -1; } } } @@ -268,177 +341,234 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> { } public float getScore(ComponentName name) { - final ScoredTarget target = mScoredTargets.get(name); + final ResolverTarget target = mTargetsDict.get(name); if (target != null) { - return target.selectProb; + return target.getSelectProbability(); } return 0; } - static class ScoredTarget { - public final ComponentInfo componentInfo; - public long lastTimeUsed; - public long timeSpent; - public long launchCount; - public long chooserCount; - public ArrayMap<String, Float> features; - public float selectProb; - - public ScoredTarget(ComponentInfo ci) { - componentInfo = ci; - features = new ArrayMap<>(5); + public void updateChooserCounts(String packageName, int userId, String action) { + if (mUsm != null) { + mUsm.reportChooserSelection(packageName, userId, mContentType, mAnnotations, action); } + } - @Override - public String toString() { - return "ScoredTarget{" + componentInfo - + " lastTimeUsed: " + lastTimeUsed - + " timeSpent: " + timeSpent - + " launchCount: " + launchCount - + " chooserCount: " + chooserCount - + " selectProb: " + selectProb - + "}"; + // update ranking model when the connection to it is valid. + public void updateModel(ComponentName componentName) { + synchronized (mLock) { + if (mRanker != null) { + try { + int selectedPos = new ArrayList<ComponentName>(mTargetsDict.keySet()) + .indexOf(componentName); + if (selectedPos > 0) { + mRanker.train(mTargets, selectedPos); + } else { + if (DEBUG) { + Log.d(TAG, "Selected a unknown component: " + componentName); + } + } + } catch (RemoteException e) { + Log.e(TAG, "Error in Train: " + e); + } + } else { + if (DEBUG) { + Log.d(TAG, "Ranker is null; skip updateModel."); + } + } } + } - public void setFeatures(float launchCountScore, float usageTimeScore, float recencyScore, - float chooserCountScore) { - features.put(LAUNCH_SCORE, launchCountScore); - features.put(TIME_SPENT_SCORE, usageTimeScore); - features.put(RECENCY_SCORE, recencyScore); - features.put(CHOOSER_SCORE, chooserCountScore); + // unbind the service and clear unhandled messges. + public void destroy() { + mHandler.removeMessages(RESOLVER_RANKER_SERVICE_RESULT); + mHandler.removeMessages(RESOLVER_RANKER_RESULT_TIMEOUT); + if (mConnection != null) { + mContext.unbindService(mConnection); + mConnection.destroy(); } - - public ArrayMap<String, Float> getFeatures() { - return features; + if (DEBUG) { + Log.d(TAG, "Unbinded Resolver Ranker."); } } - public void updateChooserCounts(String packageName, int userId, String action) { - if (mUsm != null) { - mUsm.reportChooserSelection(packageName, userId, mContentType, mAnnotations, action); + // connect to a ranking service. + private void initRanker(Context context) { + synchronized (mLock) { + if (mConnection != null && mRanker != null) { + if (DEBUG) { + Log.d(TAG, "Ranker still exists; reusing the existing one."); + } + return; + } } - } - - public void updateModel(ComponentName componentName) { - if (mScoredTargets == null || componentName == null || - !mScoredTargets.containsKey(componentName)) { + Intent intent = resolveRankerService(); + if (intent == null) { return; } - ScoredTarget selected = mScoredTargets.get(componentName); - for (ComponentName targetComponent : mScoredTargets.keySet()) { - if (targetComponent.equals(componentName)) { + mConnectSignal = new CountDownLatch(1); + mConnection = new ResolverRankerServiceConnection(mConnectSignal); + context.bindServiceAsUser(intent, mConnection, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM); + } + + // resolve the service for ranking. + private Intent resolveRankerService() { + Intent intent = new Intent(ResolverRankerService.SERVICE_INTERFACE); + final List<ResolveInfo> resolveInfos = mPm.queryIntentServices(intent, 0); + for (ResolveInfo resolveInfo : resolveInfos) { + if (resolveInfo == null || resolveInfo.serviceInfo == null + || resolveInfo.serviceInfo.applicationInfo == null) { + if (DEBUG) { + Log.d(TAG, "Failed to retrieve a ranker: " + resolveInfo); + } continue; } - ScoredTarget target = mScoredTargets.get(targetComponent); - // A potential point of optimization. Save updates or derive a closed form for the - // positive case, to avoid calculating them repeatedly. - if (target.selectProb >= selected.selectProb) { - mRanker.update(target.getFeatures(), target.selectProb, false); - mRanker.update(selected.getFeatures(), selected.selectProb, true); + ComponentName componentName = new ComponentName( + resolveInfo.serviceInfo.applicationInfo.packageName, + resolveInfo.serviceInfo.name); + try { + final String perm = mPm.getServiceInfo(componentName, 0).permission; + if (!ResolverRankerService.BIND_PERMISSION.equals(perm)) { + Log.w(TAG, "ResolverRankerService " + componentName + " does not require" + + " permission " + ResolverRankerService.BIND_PERMISSION + + " - this service will not be queried for ResolverComparator." + + " add android:permission=\"" + + ResolverRankerService.BIND_PERMISSION + "\"" + + " to the <service> tag for " + componentName + + " in the manifest."); + continue; + } + } catch (NameNotFoundException e) { + Log.e(TAG, "Could not look up service " + componentName + + "; component name not found"); + continue; + } + if (DEBUG) { + Log.d(TAG, "Succeeded to retrieve a ranker: " + componentName); } + intent.setComponent(componentName); + return intent; } - mRanker.commitUpdate(); + return null; } - class LogisticRegressionAppRanker { - private static final String PARAM_SHARED_PREF_NAME = "resolver_ranker_params"; - private static final String BIAS_PREF_KEY = "bias"; - private static final String VERSION_PREF_KEY = "version"; - - // parameters for a pre-trained model, to initialize the app ranker. When updating the - // pre-trained model, please update these params, as well as initModel(). - private static final int CURRENT_VERSION = 1; - private static final float LEARNING_RATE = 0.0001f; - private static final float REGULARIZER_PARAM = 0.0001f; + // set a watchdog, to avoid waiting for ranking service for too long. + private void startWatchDog(int timeOutLimit) { + if (DEBUG) Log.d(TAG, "Setting watchdog timer for " + timeOutLimit + "ms"); + if (mHandler == null) { + Log.d(TAG, "Error: Handler is Null; Needs to be initialized."); + } + mHandler.sendEmptyMessageDelayed(RESOLVER_RANKER_RESULT_TIMEOUT, timeOutLimit); + } - private SharedPreferences mParamSharedPref; - private ArrayMap<String, Float> mFeatureWeights; - private float mBias; + private class ResolverRankerServiceConnection implements ServiceConnection { + private final CountDownLatch mConnectSignal; - public LogisticRegressionAppRanker(Context context) { - mParamSharedPref = getParamSharedPref(context); - initModel(); + public ResolverRankerServiceConnection(CountDownLatch connectSignal) { + mConnectSignal = connectSignal; } - public float predict(ArrayMap<String, Float> target) { - if (target == null) { - return 0.0f; - } - final int featureSize = target.size(); - float sum = 0.0f; - for (int i = 0; i < featureSize; i++) { - String featureName = target.keyAt(i); - float weight = mFeatureWeights.getOrDefault(featureName, 0.0f); - sum += weight * target.valueAt(i); + public final IResolverRankerResult resolverRankerResult = + new IResolverRankerResult.Stub() { + @Override + public void sendResult(List<ResolverTarget> targets) throws RemoteException { + if (DEBUG) { + Log.d(TAG, "Sending Result back to Resolver: " + targets); + } + synchronized (mLock) { + final Message msg = Message.obtain(); + msg.what = RESOLVER_RANKER_SERVICE_RESULT; + msg.obj = targets; + mHandler.sendMessage(msg); + } } - return (float) (1.0 / (1.0 + Math.exp(-mBias - sum))); - } + }; - public void update(ArrayMap<String, Float> target, float predict, boolean isSelected) { - if (target == null) { - return; + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + if (DEBUG) { + Log.d(TAG, "onServiceConnected: " + name); } - final int featureSize = target.size(); - float error = isSelected ? 1.0f - predict : -predict; - for (int i = 0; i < featureSize; i++) { - String featureName = target.keyAt(i); - float currentWeight = mFeatureWeights.getOrDefault(featureName, 0.0f); - mBias += LEARNING_RATE * error; - currentWeight = currentWeight - LEARNING_RATE * REGULARIZER_PARAM * currentWeight + - LEARNING_RATE * error * target.valueAt(i); - mFeatureWeights.put(featureName, currentWeight); + synchronized (mLock) { + mRanker = IResolverRankerService.Stub.asInterface(service); + mConnectSignal.countDown(); } + } + + @Override + public void onServiceDisconnected(ComponentName name) { if (DEBUG) { - Log.d(TAG, "Weights: " + mFeatureWeights + " Bias: " + mBias); + Log.d(TAG, "onServiceDisconnected: " + name); + } + synchronized (mLock) { + destroy(); } } - public void commitUpdate() { - SharedPreferences.Editor editor = mParamSharedPref.edit(); - editor.putFloat(BIAS_PREF_KEY, mBias); - final int size = mFeatureWeights.size(); - for (int i = 0; i < size; i++) { - editor.putFloat(mFeatureWeights.keyAt(i), mFeatureWeights.valueAt(i)); + public void destroy() { + synchronized (mLock) { + mRanker = null; } - editor.putInt(VERSION_PREF_KEY, CURRENT_VERSION); - editor.apply(); } + } - private SharedPreferences getParamSharedPref(Context context) { - // The package info in the context isn't initialized in the way it is for normal apps, - // so the standard, name-based context.getSharedPreferences doesn't work. Instead, we - // build the path manually below using the same policy that appears in ContextImpl. + private void reset() { + mTargetsDict.clear(); + mTargets = null; + startWatchDog(WATCHDOG_TIMEOUT_MILLIS); + initRanker(mContext); + } + + // predict select probabilities if ranking service is valid. + private void predictSelectProbabilities(List<ResolverTarget> targets) { + if (mConnection == null) { if (DEBUG) { - Log.d(TAG, "Context Package Name: " + context.getPackageName()); + Log.d(TAG, "Has not found valid ResolverRankerService; Skip Prediction"); + } + return; + } else { + try { + mConnectSignal.await(CONNECTION_COST_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); + synchronized (mLock) { + if (mRanker != null) { + mRanker.predict(targets, mConnection.resolverRankerResult); + return; + } else { + if (DEBUG) { + Log.d(TAG, "Ranker has not been initialized; skip predict."); + } + } + } + } catch (InterruptedException e) { + Log.e(TAG, "Error in Wait for Service Connection."); + } catch (RemoteException e) { + Log.e(TAG, "Error in Predict: " + e); } - final File prefsFile = new File(new File( - Environment.getDataUserCePackageDirectory(StorageManager.UUID_PRIVATE_INTERNAL, - context.getUserId(), context.getPackageName()), - "shared_prefs"), - PARAM_SHARED_PREF_NAME + ".xml"); - return context.getSharedPreferences(prefsFile, Context.MODE_PRIVATE); } + mAfterCompute.afterCompute(); + } - private void initModel() { - mFeatureWeights = new ArrayMap<>(4); - if (mParamSharedPref == null || - mParamSharedPref.getInt(VERSION_PREF_KEY, 0) < CURRENT_VERSION) { - // Initializing the app ranker to a pre-trained model. When updating the pre-trained - // model, please increment CURRENT_VERSION, and update LEARNING_RATE and - // REGULARIZER_PARAM. - mBias = -1.6568f; - mFeatureWeights.put(LAUNCH_SCORE, 2.5543f); - mFeatureWeights.put(TIME_SPENT_SCORE, 2.8412f); - mFeatureWeights.put(RECENCY_SCORE, 0.269f); - mFeatureWeights.put(CHOOSER_SCORE, 4.2222f); - } else { - mBias = mParamSharedPref.getFloat(BIAS_PREF_KEY, 0.0f); - mFeatureWeights.put(LAUNCH_SCORE, mParamSharedPref.getFloat(LAUNCH_SCORE, 0.0f)); - mFeatureWeights.put( - TIME_SPENT_SCORE, mParamSharedPref.getFloat(TIME_SPENT_SCORE, 0.0f)); - mFeatureWeights.put(RECENCY_SCORE, mParamSharedPref.getFloat(RECENCY_SCORE, 0.0f)); - mFeatureWeights.put(CHOOSER_SCORE, mParamSharedPref.getFloat(CHOOSER_SCORE, 0.0f)); - } + // adds select prob as the default values, according to a pre-trained Logistic Regression model. + private void addDefaultSelectProbability(ResolverTarget target) { + float sum = 2.5543f * target.getLaunchScore() + 2.8412f * target.getTimeSpentScore() + + 0.269f * target.getRecencyScore() + 4.2222f * target.getChooserScore(); + target.setSelectProbability((float) (1.0 / (1.0 + Math.exp(1.6568f - sum)))); + } + + // sets features for each target + private void setFeatures(ResolverTarget target, float recencyScore, float launchScore, + float timeSpentScore, float chooserScore) { + target.setRecencyScore(recencyScore); + target.setLaunchScore(launchScore); + target.setTimeSpentScore(timeSpentScore); + target.setChooserScore(chooserScore); + } + + static boolean isPersistentProcess(ResolvedComponentInfo rci) { + if (rci != null && rci.getCount() > 0) { + return (rci.getResolveInfoAt(0).activityInfo.applicationInfo.flags & + ApplicationInfo.FLAG_PERSISTENT) != 0; } + return false; } } diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java index 4071ff4ebd5a..e8bebb74bdd0 100644 --- a/core/java/com/android/internal/app/ResolverListController.java +++ b/core/java/com/android/internal/app/ResolverListController.java @@ -32,8 +32,10 @@ import android.os.RemoteException; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; +import java.lang.InterruptedException; import java.util.ArrayList; import java.util.Collections; +import java.util.concurrent.CountDownLatch; import java.util.List; /** @@ -205,14 +207,42 @@ public class ResolverListController { return listToReturn; } + private class ComputeCallback implements ResolverComparator.AfterCompute { + + private CountDownLatch mFinishComputeSignal; + + public ComputeCallback(CountDownLatch finishComputeSignal) { + mFinishComputeSignal = finishComputeSignal; + } + + public void afterCompute () { + mFinishComputeSignal.countDown(); + } + } + @VisibleForTesting @WorkerThread public void sort(List<ResolverActivity.ResolvedComponentInfo> inputList) { + final CountDownLatch finishComputeSignal = new CountDownLatch(1); + ComputeCallback callback = new ComputeCallback(finishComputeSignal); if (mResolverComparator == null) { - mResolverComparator = new ResolverComparator(mContext, mTargetIntent, mReferrerPackage); + mResolverComparator = + new ResolverComparator(mContext, mTargetIntent, mReferrerPackage, callback); + } else { + mResolverComparator.setCallBack(callback); + } + try { + long beforeRank = System.currentTimeMillis(); + mResolverComparator.compute(inputList); + finishComputeSignal.await(); + Collections.sort(inputList, mResolverComparator); + long afterRank = System.currentTimeMillis(); + if (DEBUG) { + Log.d(TAG, "Time Cost: " + Long.toString(afterRank - beforeRank)); + } + } catch (InterruptedException e) { + Log.e(TAG, "Compute & Sort was interrupted: " + e); } - mResolverComparator.compute(inputList); - Collections.sort(inputList, mResolverComparator); } private static boolean isSameResolvedComponent(ResolveInfo a, @@ -233,7 +263,7 @@ public class ResolverListController { @VisibleForTesting public float getScore(ResolverActivity.DisplayResolveInfo target) { if (mResolverComparator == null) { - mResolverComparator = new ResolverComparator(mContext, mTargetIntent, mReferrerPackage); + return 0.0f; } return mResolverComparator.getScore(target.getResolvedComponentName()); } @@ -249,4 +279,10 @@ public class ResolverListController { mResolverComparator.updateChooserCounts(packageName, userId, action); } } + + public void destroy() { + if (mResolverComparator != null) { + mResolverComparator.destroy(); + } + } } diff --git a/core/java/com/android/internal/app/ToolbarActionBar.java b/core/java/com/android/internal/app/ToolbarActionBar.java index 7ce5fc3103b6..b3904f457708 100644 --- a/core/java/com/android/internal/app/ToolbarActionBar.java +++ b/core/java/com/android/internal/app/ToolbarActionBar.java @@ -477,12 +477,9 @@ public class ToolbarActionBar extends ActionBar { final KeyCharacterMap kmap = KeyCharacterMap.load( event != null ? event.getDeviceId() : KeyCharacterMap.VIRTUAL_KEYBOARD); menu.setQwertyMode(kmap.getKeyboardType() != KeyCharacterMap.NUMERIC); - menu.performShortcut(keyCode, event, 0); + return menu.performShortcut(keyCode, event, 0); } - // This action bar always returns true for handling keyboard shortcuts. - // This will block the window from preparing a temporary panel to handle - // keyboard shortcuts. - return true; + return false; } @Override @@ -525,6 +522,17 @@ public class ToolbarActionBar extends ActionBar { } return result; } + + @Override + public View onCreatePanelView(int featureId) { + if (featureId == Window.FEATURE_OPTIONS_PANEL) { + // This gets called by PhoneWindow.preparePanel. Since this already manages + // its own panel, we return a dummy view here to prevent PhoneWindow from + // preparing a default one. + return new View(mDecorToolbar.getContext()); + } + return super.onCreatePanelView(featureId); + } } private final class ActionMenuPresenterCallback implements MenuPresenter.Callback { diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 3d0d6bf0e3ad..a0dafddc623b 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -10057,6 +10057,9 @@ public class BatteryStatsImpl extends BatteryStats { public void setBatteryStateLocked(int status, int health, int plugType, int level, int temp, int volt, int chargeUAh, int chargeFullUAh) { + // Temperature is encoded without the signed bit, so clamp any negative temperatures to 0. + temp = Math.max(0, temp); + final boolean onBattery = plugType == BATTERY_PLUGGED_NONE; final long uptime = mClocks.uptimeMillis(); final long elapsedRealtime = mClocks.elapsedRealtime(); diff --git a/core/java/com/android/internal/os/FuseAppLoop.java b/core/java/com/android/internal/os/FuseAppLoop.java index 3603b6df11da..8edd637ea814 100644 --- a/core/java/com/android/internal/os/FuseAppLoop.java +++ b/core/java/com/android/internal/os/FuseAppLoop.java @@ -19,16 +19,16 @@ package com.android.internal.os; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.ProxyFileDescriptorCallback; +import android.os.Handler; import android.os.ParcelFileDescriptor; import android.system.ErrnoException; import android.system.OsConstants; import android.util.Log; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; -import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; - -import java.io.IOException; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.ThreadFactory; public class FuseAppLoop { @@ -42,14 +42,21 @@ public class FuseAppLoop { return new Thread(r, TAG); } }; + private static final int FUSE_OK = 0; private final Object mLock = new Object(); private final int mMountPointId; private final Thread mThread; + private final Handler mDefaultHandler; + + private static final int CMD_FSYNC = 1; @GuardedBy("mLock") private final SparseArray<CallbackEntry> mCallbackMap = new SparseArray<>(); + @GuardedBy("mLock") + private final BytesMap mBytesMap = new BytesMap(); + /** * Sequential number can be used as file name and inode in AppFuse. * 0 is regarded as an error, 1 is mount point. So we start the number from 2. @@ -57,38 +64,40 @@ public class FuseAppLoop { @GuardedBy("mLock") private int mNextInode = MIN_INODE; - private FuseAppLoop( + @GuardedBy("mLock") + private long mInstance; + + public FuseAppLoop( int mountPointId, @NonNull ParcelFileDescriptor fd, @Nullable ThreadFactory factory) { mMountPointId = mountPointId; - final int rawFd = fd.detachFd(); if (factory == null) { factory = sDefaultThreadFactory; } - mThread = factory.newThread(new Runnable() { - @Override - public void run() { - // rawFd is closed by native_start_loop. Java code does not need to close it. - native_start_loop(rawFd); + mInstance = native_new(fd.detachFd()); + mThread = factory.newThread(() -> { + native_start(mInstance); + synchronized (mLock) { + native_delete(mInstance); + mInstance = 0; + mBytesMap.clear(); } }); + mThread.start(); + mDefaultHandler = null; } - public static @NonNull FuseAppLoop open(int mountPointId, @NonNull ParcelFileDescriptor fd, - @Nullable ThreadFactory factory) { - Preconditions.checkNotNull(fd); - final FuseAppLoop loop = new FuseAppLoop(mountPointId, fd, factory); - loop.mThread.start(); - return loop; - } - - public int registerCallback(@NonNull ProxyFileDescriptorCallback callback) - throws UnmountedException, IOException { - if (mThread.getState() == Thread.State.TERMINATED) { - throw new UnmountedException(); - } + public int registerCallback(@NonNull ProxyFileDescriptorCallback callback, + @NonNull Handler handler) throws FuseUnavailableMountException { synchronized (mLock) { - if (mCallbackMap.size() >= Integer.MAX_VALUE - MIN_INODE) { - throw new IOException("Too many opened files."); + Preconditions.checkNotNull(callback); + Preconditions.checkNotNull(handler); + Preconditions.checkState( + mCallbackMap.size() < Integer.MAX_VALUE - MIN_INODE, "Too many opened files."); + Preconditions.checkArgument( + Thread.currentThread().getId() != handler.getLooper().getThread().getId(), + "Handler must be different from the current thread"); + if (mInstance == 0) { + throw new FuseUnavailableMountException(mMountPointId); } int id; while (true) { @@ -101,118 +110,171 @@ public class FuseAppLoop { break; } } - mCallbackMap.put(id, new CallbackEntry(callback)); + mCallbackMap.put(id, new CallbackEntry(callback, handler)); return id; } } public void unregisterCallback(int id) { - mCallbackMap.remove(id); + synchronized (mLock) { + mCallbackMap.remove(id); + } } public int getMountPointId() { return mMountPointId; } - private CallbackEntry getCallbackEntryOrThrowLocked(long inode) throws ErrnoException { - final CallbackEntry entry = mCallbackMap.get(checkInode(inode)); - if (entry != null) { - return entry; - } else { - throw new ErrnoException("getCallbackEntry", OsConstants.ENOENT); - } - } + // Defined in fuse.h + private static final int FUSE_LOOKUP = 1; + private static final int FUSE_GETATTR = 3; + private static final int FUSE_OPEN = 14; + private static final int FUSE_READ = 15; + private static final int FUSE_WRITE = 16; + private static final int FUSE_RELEASE = 18; + private static final int FUSE_FSYNC = 20; + + // Defined in FuseBuffer.h + private static final int FUSE_MAX_WRITE = 256 * 1024; // Called by JNI. @SuppressWarnings("unused") - private long onGetSize(long inode) { + private void onCommand(int command, long unique, long inode, long offset, int size, + byte[] data) { synchronized(mLock) { try { - return getCallbackEntryOrThrowLocked(inode).callback.onGetSize(); - } catch (ErrnoException exp) { - return getError(exp); + final CallbackEntry entry = getCallbackEntryOrThrowLocked(inode); + entry.postRunnable(() -> { + try { + switch (command) { + case FUSE_LOOKUP: { + final long fileSize = entry.callback.onGetSize(); + synchronized (mLock) { + if (mInstance != 0) { + native_replyLookup(mInstance, unique, inode, fileSize); + } + } + break; + } + case FUSE_GETATTR: { + final long fileSize = entry.callback.onGetSize(); + synchronized (mLock) { + if (mInstance != 0) { + native_replyGetAttr(mInstance, unique, inode, fileSize); + } + } + break; + } + case FUSE_READ: + final int readSize = entry.callback.onRead(offset, size, data); + synchronized (mLock) { + if (mInstance != 0) { + native_replyRead(mInstance, unique, readSize, data); + } + } + break; + case FUSE_WRITE: + final int writeSize = entry.callback.onWrite(offset, size, data); + synchronized (mLock) { + if (mInstance != 0) { + native_replyWrite(mInstance, unique, writeSize); + } + } + break; + case FUSE_FSYNC: + entry.callback.onFsync(); + synchronized (mLock) { + if (mInstance != 0) { + native_replySimple(mInstance, unique, FUSE_OK); + } + } + break; + case FUSE_RELEASE: + entry.callback.onRelease(); + synchronized (mLock) { + if (mInstance != 0) { + native_replySimple(mInstance, unique, FUSE_OK); + } + mBytesMap.stopUsing(entry.getThreadId()); + } + break; + default: + throw new IllegalArgumentException( + "Unknown FUSE command: " + command); + } + } catch (Exception error) { + Log.e(TAG, "", error); + replySimple(unique, getError(error)); + } + }); + } catch (ErrnoException error) { + Log.e(TAG, "", error); + replySimpleLocked(unique, getError(error)); } } } // Called by JNI. @SuppressWarnings("unused") - private int onOpen(long inode) { - synchronized(mLock) { + private byte[] onOpen(long unique, long inode) { + synchronized (mLock) { try { final CallbackEntry entry = getCallbackEntryOrThrowLocked(inode); if (entry.opened) { throw new ErrnoException("onOpen", OsConstants.EMFILE); } - entry.opened = true; - // Use inode as file handle. It's OK because AppFuse does not allow to open the same - // file twice. - return (int) inode; - } catch (ErrnoException exp) { - return getError(exp); + if (mInstance != 0) { + native_replyOpen(mInstance, unique, /* fh */ inode); + entry.opened = true; + return mBytesMap.startUsing(entry.getThreadId()); + } + } catch (ErrnoException error) { + replySimpleLocked(unique, getError(error)); } + return null; } } - // Called by JNI. - @SuppressWarnings("unused") - private int onFsync(long inode) { - synchronized(mLock) { - try { - getCallbackEntryOrThrowLocked(inode).callback.onFsync(); - return 0; - } catch (ErrnoException exp) { - return getError(exp); + private static int getError(@NonNull Exception error) { + if (error instanceof ErrnoException) { + final int errno = ((ErrnoException) error).errno; + if (errno != OsConstants.ENOSYS) { + return -errno; } } + return -OsConstants.EBADF; } - // Called by JNI. - @SuppressWarnings("unused") - private int onRelease(long inode) { - synchronized(mLock) { - try { - getCallbackEntryOrThrowLocked(inode).callback.onRelease(); - return 0; - } catch (ErrnoException exp) { - return getError(exp); - } finally { - mCallbackMap.remove(checkInode(inode)); - } + private CallbackEntry getCallbackEntryOrThrowLocked(long inode) throws ErrnoException { + final CallbackEntry entry = mCallbackMap.get(checkInode(inode)); + if (entry == null) { + throw new ErrnoException("getCallbackEntryOrThrowLocked", OsConstants.ENOENT); } + return entry; } - // Called by JNI. - @SuppressWarnings("unused") - private int onRead(long inode, long offset, int size, byte[] bytes) { - synchronized(mLock) { - try { - return getCallbackEntryOrThrowLocked(inode).callback.onRead(offset, size, bytes); - } catch (ErrnoException exp) { - return getError(exp); - } + private void replySimple(long unique, int result) { + synchronized (mLock) { + replySimpleLocked(unique, result); } } - // Called by JNI. - @SuppressWarnings("unused") - private int onWrite(long inode, long offset, int size, byte[] bytes) { - synchronized(mLock) { - try { - return getCallbackEntryOrThrowLocked(inode).callback.onWrite(offset, size, bytes); - } catch (ErrnoException exp) { - return getError(exp); - } + private void replySimpleLocked(long unique, int result) { + if (mInstance != 0) { + native_replySimple(mInstance, unique, result); } } - private static int getError(@NonNull ErrnoException exp) { - // Should not return ENOSYS because the kernel stops - // dispatching the FUSE action once FUSE implementation returns ENOSYS for the action. - return exp.errno != OsConstants.ENOSYS ? -exp.errno : -OsConstants.EIO; - } + native long native_new(int fd); + native void native_delete(long ptr); + native void native_start(long ptr); - native boolean native_start_loop(int fd); + native void native_replySimple(long ptr, long unique, int result); + native void native_replyOpen(long ptr, long unique, long fh); + native void native_replyLookup(long ptr, long unique, long inode, long size); + native void native_replyGetAttr(long ptr, long unique, long inode, long size); + native void native_replyWrite(long ptr, long unique, int size); + native void native_replyRead(long ptr, long unique, int size, byte[] bytes); private static int checkInode(long inode) { Preconditions.checkArgumentInRange(inode, MIN_INODE, Integer.MAX_VALUE, "checkInode"); @@ -223,10 +285,61 @@ public class FuseAppLoop { private static class CallbackEntry { final ProxyFileDescriptorCallback callback; + final Handler handler; boolean opened; - CallbackEntry(ProxyFileDescriptorCallback callback) { - Preconditions.checkNotNull(callback); - this.callback = callback; + + CallbackEntry(ProxyFileDescriptorCallback callback, Handler handler) { + this.callback = Preconditions.checkNotNull(callback); + this.handler = Preconditions.checkNotNull(handler); + } + + long getThreadId() { + return handler.getLooper().getThread().getId(); + } + + void postRunnable(Runnable runnable) throws ErrnoException { + final boolean result = handler.post(runnable); + if (!result) { + throw new ErrnoException("postRunnable", OsConstants.EBADF); + } + } + } + + /** + * Entry for bytes map. + */ + private static class BytesMapEntry { + int counter = 0; + byte[] bytes = new byte[FUSE_MAX_WRITE]; + } + + /** + * Map between Thread ID and byte buffer. + */ + private static class BytesMap { + final Map<Long, BytesMapEntry> mEntries = new HashMap<>(); + + byte[] startUsing(long threadId) { + BytesMapEntry entry = mEntries.get(threadId); + if (entry == null) { + entry = new BytesMapEntry(); + mEntries.put(threadId, entry); + } + entry.counter++; + return entry.bytes; + } + + void stopUsing(long threadId) { + final BytesMapEntry entry = mEntries.get(threadId); + Preconditions.checkNotNull(entry); + entry.counter--; + if (entry.counter <= 0) { + mEntries.remove(threadId); + } + } + + void clear() { + mEntries.clear(); } } } diff --git a/media/java/android/media/UnsupportedCasException.java b/core/java/com/android/internal/os/FuseUnavailableMountException.java index 31676373783b..ca3cfb90ae11 100644 --- a/media/java/android/media/UnsupportedCasException.java +++ b/core/java/com/android/internal/os/FuseUnavailableMountException.java @@ -14,14 +14,13 @@ * limitations under the License. */ -package android.media; +package com.android.internal.os; /** - * Exception thrown when an attempt is made to construct a MediaCas object - * using a CA_system_id that is not supported by the device + * Exception occurred when the mount point has already been unavailable. */ -public final class UnsupportedCasException extends MediaCasException { - public UnsupportedCasException(String detailMessage) { - super(detailMessage); +public class FuseUnavailableMountException extends Exception { + public FuseUnavailableMountException(int mountId) { + super("AppFuse mount point " + mountId + " is unavailable"); } } diff --git a/core/java/com/android/internal/os/WebViewZygoteInit.java b/core/java/com/android/internal/os/WebViewZygoteInit.java index f27c0d4df4ce..cc3f58cb0c3d 100644 --- a/core/java/com/android/internal/os/WebViewZygoteInit.java +++ b/core/java/com/android/internal/os/WebViewZygoteInit.java @@ -26,6 +26,7 @@ import android.util.Log; import android.webkit.WebViewFactory; import android.webkit.WebViewFactoryProvider; +import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; @@ -67,16 +68,20 @@ class WebViewZygoteInit { } @Override - protected boolean handlePreloadPackage(String packagePath, String libsPath) { + protected boolean handlePreloadPackage(String packagePath, String libsPath, + String cacheKey) { // Ask ApplicationLoaders to create and cache a classloader for the WebView APK so that // our children will reuse the same classloader instead of creating their own. // This enables us to preload Java and native code in the webview zygote process and // have the preloaded versions actually be used post-fork. ClassLoader loader = ApplicationLoaders.getDefault().createAndCacheWebViewClassLoader( - packagePath, libsPath); + packagePath, libsPath, cacheKey); // Add the APK to the Zygote's list of allowed files for children. - Zygote.nativeAllowFileAcrossFork(packagePath); + String[] packageList = TextUtils.split(packagePath, File.pathSeparator); + for (String packageEntry : packageList) { + Zygote.nativeAllowFileAcrossFork(packageEntry); + } // Once we have the classloader, look up the WebViewFactoryProvider implementation and // call preloadInZygote() on it to give it the opportunity to preload the native library diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java index e2485e90e537..a9bec4123fd2 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java @@ -177,7 +177,7 @@ class ZygoteConnection { if (parsedArgs.preloadPackage != null) { return handlePreloadPackage(parsedArgs.preloadPackage, - parsedArgs.preloadPackageLibs); + parsedArgs.preloadPackageLibs, parsedArgs.preloadPackageCacheKey); } if (parsedArgs.permittedCapabilities != 0 || parsedArgs.effectiveCapabilities != 0) { @@ -314,7 +314,7 @@ class ZygoteConnection { return ZygoteInit.isPreloadComplete(); } - protected boolean handlePreloadPackage(String packagePath, String libsPath) { + protected boolean handlePreloadPackage(String packagePath, String libsPath, String cacheKey) { throw new RuntimeException("Zyogte does not support package preloading"); } @@ -428,6 +428,7 @@ class ZygoteConnection { */ String preloadPackage; String preloadPackageLibs; + String preloadPackageCacheKey; /** * Whether this is a request to start preloading the default resources and classes. @@ -599,6 +600,7 @@ class ZygoteConnection { } else if (arg.equals("--preload-package")) { preloadPackage = args[++curArg]; preloadPackageLibs = args[++curArg]; + preloadPackageCacheKey = args[++curArg]; } else if (arg.equals("--preload-default")) { preloadDefault = true; } else { diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java index d67cef3f0dda..8d9630fe5654 100644 --- a/core/java/com/android/internal/util/StateMachine.java +++ b/core/java/com/android/internal/util/StateMachine.java @@ -2070,8 +2070,6 @@ public class StateMachine { * @param args */ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - // Cannot just invoke pw.println(this.toString()) because if the - // resulting string is to long it won't be displayed. pw.println(getName() + ":"); pw.println(" total records=" + getLogRecCount()); for (int i = 0; i < getLogRecSize(); i++) { @@ -2083,12 +2081,15 @@ public class StateMachine { @Override public String toString() { - StringWriter sr = new StringWriter(); - PrintWriter pr = new PrintWriter(sr); - dump(null, pr, null); - pr.flush(); - pr.close(); - return sr.toString(); + String name = "(null)"; + String state = "(null)"; + try { + name = mName.toString(); + state = mSmHandler.getCurrentState().getName().toString(); + } catch (NullPointerException npe) { + // Will use default(s) initialized above. + } + return "name=" + name + " state=" + state; } /** diff --git a/core/java/com/android/internal/widget/SwipeDismissLayout.java b/core/java/com/android/internal/widget/SwipeDismissLayout.java index 6d814bf14bc0..d2a907222eda 100644 --- a/core/java/com/android/internal/widget/SwipeDismissLayout.java +++ b/core/java/com/android/internal/widget/SwipeDismissLayout.java @@ -26,6 +26,7 @@ import android.content.Context; import android.content.ContextWrapper; import android.content.Intent; import android.content.IntentFilter; +import android.content.ReceiverCallNotAllowedException; import android.content.res.TypedArray; import android.util.AttributeSet; import android.util.Log; @@ -86,24 +87,7 @@ public class SwipeDismissLayout extends FrameLayout { private OnDismissedListener mDismissedListener; private OnSwipeProgressChangedListener mProgressListener; - private BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() { - private Runnable mRunnable = new Runnable() { - @Override - public void run() { - if (mDismissed) { - dismiss(); - } else { - cancel(); - } - resetMembers(); - } - }; - - @Override - public void onReceive(Context context, Intent intent) { - post(mRunnable); - } - }; + private BroadcastReceiver mScreenOffReceiver; private IntentFilter mScreenOffFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF); @@ -146,12 +130,36 @@ public class SwipeDismissLayout extends FrameLayout { @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); - getContext().registerReceiver(mScreenOffReceiver, mScreenOffFilter); + try { + mScreenOffReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + post(() -> { + if (mDismissed) { + dismiss(); + } else { + cancel(); + } + resetMembers(); + }); + } + }; + getContext().registerReceiver(mScreenOffReceiver, mScreenOffFilter); + } catch (ReceiverCallNotAllowedException e) { + /* Exception is thrown if the context is a ReceiverRestrictedContext object. As + * ReceiverRestrictedContext is not public, the context type cannot be checked before + * calling registerReceiver. The most likely scenario in which the exception would be + * thrown would be when a BroadcastReceiver creates a dialog to show the user. */ + mScreenOffReceiver = null; // clear receiver since it was not used. + } } @Override protected void onDetachedFromWindow() { - getContext().unregisterReceiver(mScreenOffReceiver); + if (mScreenOffReceiver != null) { + getContext().unregisterReceiver(mScreenOffReceiver); + mScreenOffReceiver = null; + } super.onDetachedFromWindow(); } diff --git a/core/jni/android_hardware_Radio.cpp b/core/jni/android_hardware_Radio.cpp index b6b1ac75f0e9..fcb72c2a869d 100644 --- a/core/jni/android_hardware_Radio.cpp +++ b/core/jni/android_hardware_Radio.cpp @@ -325,11 +325,12 @@ static jint convertProgramInfoFromNative(JNIEnv *env, ALOGV("%s channel %d tuned %d", __FUNCTION__, nProgramInfo->channel, nProgramInfo->tuned); + int flags = 0; // TODO(b/32621193): pass from the HAL *jProgramInfo = env->NewObject(gRadioProgramInfoClass, gRadioProgramInfoCstor, nProgramInfo->channel, nProgramInfo->sub_channel, nProgramInfo->tuned, nProgramInfo->stereo, nProgramInfo->digital, nProgramInfo->signal_strength, - jMetadata); + jMetadata, flags); env->DeleteLocalRef(jMetadata); return (jint)RADIO_STATUS_OK; @@ -932,7 +933,7 @@ int register_android_hardware_Radio(JNIEnv *env) jclass programInfoClass = FindClassOrDie(env, kRadioProgramInfoClassPathName); gRadioProgramInfoClass = MakeGlobalRefOrDie(env, programInfoClass); gRadioProgramInfoCstor = GetMethodIDOrDie(env, programInfoClass, "<init>", - "(IIZZZILandroid/hardware/radio/RadioMetadata;)V"); + "(IIZZZILandroid/hardware/radio/RadioMetadata;I)V"); jclass metadataClass = FindClassOrDie(env, kRadioMetadataClassPathName); gRadioMetadataClass = MakeGlobalRefOrDie(env, metadataClass); diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index 713287e4cd7a..8a7d1cf9c12f 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -135,6 +135,7 @@ int android_view_Surface_mapPublicFormatToHalFormat(PublicFormat f) { case PublicFormat::DEPTH16: return HAL_PIXEL_FORMAT_Y16; case PublicFormat::RAW_SENSOR: + case PublicFormat::RAW_DEPTH: return HAL_PIXEL_FORMAT_RAW16; default: // Most formats map 1:1 @@ -149,6 +150,7 @@ android_dataspace android_view_Surface_mapPublicFormatToHalDataspace( return HAL_DATASPACE_V0_JFIF; case PublicFormat::DEPTH_POINT_CLOUD: case PublicFormat::DEPTH16: + case PublicFormat::RAW_DEPTH: return HAL_DATASPACE_DEPTH; case PublicFormat::RAW_SENSOR: case PublicFormat::RAW_PRIVATE: @@ -182,8 +184,12 @@ PublicFormat android_view_Surface_mapHalFormatDataspaceToPublicFormat( // Enums overlap in both name and value return static_cast<PublicFormat>(format); case HAL_PIXEL_FORMAT_RAW16: - // Name differs, though value is the same - return PublicFormat::RAW_SENSOR; + switch (dataSpace) { + case HAL_DATASPACE_DEPTH: + return PublicFormat::RAW_DEPTH; + default: + return PublicFormat::RAW_SENSOR; + } case HAL_PIXEL_FORMAT_RAW_OPAQUE: // Name differs, though value is the same return PublicFormat::RAW_PRIVATE; diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 6fbf49bfee8c..066ce68e7e57 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -167,7 +167,7 @@ static jobject nativeScreenshotToBuffer(JNIEnv* env, jclass clazz, buffer->getHeight(), buffer->getPixelFormat(), buffer->getUsage(), - (void*)buffer.get()); + (jlong)buffer.get()); } static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, diff --git a/core/jni/com_android_internal_os_FuseAppLoop.cpp b/core/jni/com_android_internal_os_FuseAppLoop.cpp index dd003eb364c5..e125150e8329 100644 --- a/core/jni/com_android_internal_os_FuseAppLoop.cpp +++ b/core/jni/com_android_internal_os_FuseAppLoop.cpp @@ -20,140 +20,214 @@ #include <stdlib.h> #include <sys/stat.h> +#include <map> +#include <memory> + #include <android_runtime/Log.h> #include <android-base/logging.h> #include <android-base/unique_fd.h> #include <jni.h> #include <libappfuse/FuseAppLoop.h> #include <nativehelper/ScopedLocalRef.h> +#include <nativehelper/ScopedPrimitiveArray.h> #include "core_jni_helpers.h" namespace android { - namespace { - constexpr const char* CLASS_NAME = "com/android/internal/os/FuseAppLoop"; jclass gFuseAppLoopClass; -jmethodID gOnGetSizeMethod; +jmethodID gOnCommandMethod; jmethodID gOnOpenMethod; -jmethodID gOnFsyncMethod; -jmethodID gOnReleaseMethod; -jmethodID gOnReadMethod; -jmethodID gOnWriteMethod; class Callback : public fuse::FuseAppLoopCallback { private: - static constexpr size_t kBufferSize = std::max(fuse::kFuseMaxWrite, fuse::kFuseMaxRead); - static_assert(kBufferSize <= INT32_MAX, "kBufferSize should be fit in int32_t."); - + typedef ScopedLocalRef<jbyteArray> LocalBytes; JNIEnv* const mEnv; jobject const mSelf; - ScopedLocalRef<jbyteArray> mJniBuffer; - - template <typename T> - T checkException(T result) const { - if (mEnv->ExceptionCheck()) { - LOGE_EX(mEnv, nullptr); - mEnv->ExceptionClear(); - return -EIO; - } - return result; - } + std::map<uint64_t, std::unique_ptr<LocalBytes>> mBuffers; public: Callback(JNIEnv* env, jobject self) : - mEnv(env), - mSelf(self), - mJniBuffer(env, nullptr) {} + mEnv(env), mSelf(self) {} - bool Init() { - mJniBuffer.reset(mEnv->NewByteArray(kBufferSize)); - return mJniBuffer.get(); + void OnLookup(uint64_t unique, uint64_t inode) override { + mEnv->CallVoidMethod(mSelf, gOnCommandMethod, FUSE_LOOKUP, unique, inode, 0, 0, nullptr); + CHECK(!mEnv->ExceptionCheck()); } - bool IsActive() override { - return true; + void OnGetAttr(uint64_t unique, uint64_t inode) override { + mEnv->CallVoidMethod(mSelf, gOnCommandMethod, FUSE_GETATTR, unique, inode, 0, 0, nullptr); + CHECK(!mEnv->ExceptionCheck()); } - int64_t OnGetSize(uint64_t inode) override { - return checkException(mEnv->CallLongMethod(mSelf, gOnGetSizeMethod, inode)); - } + void OnOpen(uint64_t unique, uint64_t inode) override { + const jbyteArray buffer = static_cast<jbyteArray>(mEnv->CallObjectMethod( + mSelf, gOnOpenMethod, unique, inode)); + CHECK(!mEnv->ExceptionCheck()); + if (buffer == nullptr) { + return; + } - int32_t OnOpen(uint64_t inode) override { - return checkException(mEnv->CallIntMethod(mSelf, gOnOpenMethod, inode)); + mBuffers.insert(std::make_pair(inode, std::unique_ptr<LocalBytes>( + new LocalBytes(mEnv, buffer)))); } - int32_t OnFsync(uint64_t inode) override { - return checkException(mEnv->CallIntMethod(mSelf, gOnFsyncMethod, inode)); + void OnFsync(uint64_t unique, uint64_t inode) override { + mEnv->CallVoidMethod(mSelf, gOnCommandMethod, FUSE_FSYNC, unique, inode, 0, 0, nullptr); + CHECK(!mEnv->ExceptionCheck()); } - int32_t OnRelease(uint64_t inode) override { - return checkException(mEnv->CallIntMethod(mSelf, gOnReleaseMethod, inode)); + void OnRelease(uint64_t unique, uint64_t inode) override { + mBuffers.erase(inode); + mEnv->CallVoidMethod(mSelf, gOnCommandMethod, FUSE_RELEASE, unique, inode, 0, 0, nullptr); + CHECK(!mEnv->ExceptionCheck()); } - int32_t OnRead(uint64_t inode, uint64_t offset, uint32_t size, void* buffer) override { - CHECK_LE(size, static_cast<uint32_t>(kBufferSize)); - const int32_t result = checkException(mEnv->CallIntMethod( - mSelf, gOnReadMethod, inode, offset, size, mJniBuffer.get())); - if (result <= 0) { - return result; - } - if (result > static_cast<int32_t>(size)) { - LOG(ERROR) << "Returned size is too large."; - return -EIO; - } + void OnRead(uint64_t unique, uint64_t inode, uint64_t offset, uint32_t size) override { + CHECK_LE(size, static_cast<uint32_t>(fuse::kFuseMaxRead)); - mEnv->GetByteArrayRegion(mJniBuffer.get(), 0, result, static_cast<jbyte*>(buffer)); - CHECK(!mEnv->ExceptionCheck()); + auto it = mBuffers.find(inode); + CHECK(it != mBuffers.end()); - return checkException(result); + mEnv->CallVoidMethod( + mSelf, gOnCommandMethod, FUSE_READ, unique, inode, offset, size, + it->second->get()); + CHECK(!mEnv->ExceptionCheck()); } - int32_t OnWrite(uint64_t inode, uint64_t offset, uint32_t size, const void* buffer) override { - CHECK_LE(size, static_cast<uint32_t>(kBufferSize)); + void OnWrite(uint64_t unique, uint64_t inode, uint64_t offset, uint32_t size, + const void* buffer) override { + CHECK_LE(size, static_cast<uint32_t>(fuse::kFuseMaxWrite)); + + auto it = mBuffers.find(inode); + CHECK(it != mBuffers.end()); + + jbyteArray const javaBuffer = it->second->get(); - mEnv->SetByteArrayRegion(mJniBuffer.get(), 0, size, static_cast<const jbyte*>(buffer)); + mEnv->SetByteArrayRegion(javaBuffer, 0, size, static_cast<const jbyte*>(buffer)); CHECK(!mEnv->ExceptionCheck()); - return checkException(mEnv->CallIntMethod( - mSelf, gOnWriteMethod, inode, offset, size, mJniBuffer.get())); + mEnv->CallVoidMethod( + mSelf, gOnCommandMethod, FUSE_WRITE, unique, inode, offset, size, javaBuffer); + CHECK(!mEnv->ExceptionCheck()); } }; -jboolean com_android_internal_os_FuseAppLoop_start_loop(JNIEnv* env, jobject self, jint jfd) { - base::unique_fd fd(jfd); +jlong com_android_internal_os_FuseAppLoop_new(JNIEnv* env, jobject self, jint jfd) { + return reinterpret_cast<jlong>(new fuse::FuseAppLoop(base::unique_fd(jfd))); +} + +void com_android_internal_os_FuseAppLoop_delete(JNIEnv* env, jobject self, jlong ptr) { + delete reinterpret_cast<fuse::FuseAppLoop*>(ptr); +} + +void com_android_internal_os_FuseAppLoop_start(JNIEnv* env, jobject self, jlong ptr) { Callback callback(env, self); + reinterpret_cast<fuse::FuseAppLoop*>(ptr)->Start(&callback); +} - if (!callback.Init()) { - LOG(ERROR) << "Failed to init callback"; - return JNI_FALSE; +void com_android_internal_os_FuseAppLoop_replySimple( + JNIEnv* env, jobject self, jlong ptr, jlong unique, jint result) { + if (!reinterpret_cast<fuse::FuseAppLoop*>(ptr)->ReplySimple(unique, result)) { + reinterpret_cast<fuse::FuseAppLoop*>(ptr)->Break(); } +} - return fuse::StartFuseAppLoop(fd.release(), &callback); +void com_android_internal_os_FuseAppLoop_replyOpen( + JNIEnv* env, jobject self, jlong ptr, jlong unique, jlong fh) { + if (!reinterpret_cast<fuse::FuseAppLoop*>(ptr)->ReplyOpen(unique, fh)) { + reinterpret_cast<fuse::FuseAppLoop*>(ptr)->Break(); + } +} + +void com_android_internal_os_FuseAppLoop_replyLookup( + JNIEnv* env, jobject self, jlong ptr, jlong unique, jlong inode, jint size) { + if (!reinterpret_cast<fuse::FuseAppLoop*>(ptr)->ReplyLookup(unique, inode, size)) { + reinterpret_cast<fuse::FuseAppLoop*>(ptr)->Break(); + } +} + +void com_android_internal_os_FuseAppLoop_replyGetAttr( + JNIEnv* env, jobject self, jlong ptr, jlong unique, jlong inode, jint size) { + if (!reinterpret_cast<fuse::FuseAppLoop*>(ptr)->ReplyGetAttr( + unique, inode, size, S_IFREG | 0777)) { + reinterpret_cast<fuse::FuseAppLoop*>(ptr)->Break(); + } +} + +void com_android_internal_os_FuseAppLoop_replyWrite( + JNIEnv* env, jobject self, jlong ptr, jlong unique, jint size) { + if (!reinterpret_cast<fuse::FuseAppLoop*>(ptr)->ReplyWrite(unique, size)) { + reinterpret_cast<fuse::FuseAppLoop*>(ptr)->Break(); + } +} + +void com_android_internal_os_FuseAppLoop_replyRead( + JNIEnv* env, jobject self, jlong ptr, jlong unique, jint size, jbyteArray data) { + ScopedByteArrayRO array(env, data); + CHECK(size >= 0); + CHECK(static_cast<size_t>(size) < array.size()); + if (!reinterpret_cast<fuse::FuseAppLoop*>(ptr)->ReplyRead(unique, size, array.get())) { + reinterpret_cast<fuse::FuseAppLoop*>(ptr)->Break(); + } } const JNINativeMethod methods[] = { { - "native_start_loop", - "(I)Z", - (void *) com_android_internal_os_FuseAppLoop_start_loop - } + "native_new", + "(I)J", + reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_new) + }, + { + "native_delete", + "(J)V", + reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_delete) + }, + { + "native_start", + "(J)V", + reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_start) + }, + { + "native_replySimple", + "(JJI)V", + reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_replySimple) + }, + { + "native_replyOpen", + "(JJJ)V", + reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_replyOpen) + }, + { + "native_replyLookup", + "(JJJJ)V", + reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_replyLookup) + }, + { + "native_replyGetAttr", + "(JJJJ)V", + reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_replyGetAttr) + }, + { + "native_replyRead", + "(JJI[B)V", + reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_replyRead) + }, + { + "native_replyWrite", + "(JJI)V", + reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_replyWrite) + }, }; - } // namespace int register_com_android_internal_os_FuseAppLoop(JNIEnv* env) { gFuseAppLoopClass = MakeGlobalRefOrDie(env, FindClassOrDie(env, CLASS_NAME)); - gOnGetSizeMethod = GetMethodIDOrDie(env, gFuseAppLoopClass, "onGetSize", "(J)J"); - gOnOpenMethod = GetMethodIDOrDie(env, gFuseAppLoopClass, "onOpen", "(J)I"); - gOnFsyncMethod = GetMethodIDOrDie(env, gFuseAppLoopClass, "onFsync", "(J)I"); - gOnReleaseMethod = GetMethodIDOrDie(env, gFuseAppLoopClass, "onRelease", "(J)I"); - gOnReadMethod = GetMethodIDOrDie(env, gFuseAppLoopClass, "onRead", "(JJI[B)I"); - gOnWriteMethod = GetMethodIDOrDie(env, gFuseAppLoopClass, "onWrite", "(JJI[B)I"); + gOnCommandMethod = GetMethodIDOrDie(env, gFuseAppLoopClass, "onCommand", "(IJJJI[B)V"); + gOnOpenMethod = GetMethodIDOrDie(env, gFuseAppLoopClass, "onOpen", "(JJ)[B"); RegisterMethodsOrDie(env, CLASS_NAME, methods, NELEM(methods)); return 0; } - } // namespace android diff --git a/core/jni/include/android_runtime/android_view_Surface.h b/core/jni/include/android_runtime/android_view_Surface.h index 3f1bdff81aef..d27c5a354677 100644 --- a/core/jni/include/android_runtime/android_view_Surface.h +++ b/core/jni/include/android_runtime/android_view_Surface.h @@ -53,6 +53,7 @@ enum class PublicFormat { RGBA_1010102 = 0x2b, JPEG = 0x100, DEPTH_POINT_CLOUD = 0x101, + RAW_DEPTH = 0x1002, // @hide YV12 = 0x32315659, Y8 = 0x20203859, // @hide Y16 = 0x20363159, // @hide diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 8721f3414e4b..3dc8890c2de2 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -313,6 +313,10 @@ <protected-broadcast android:name="android.net.wifi.STATE_CHANGE" /> <protected-broadcast android:name="android.net.wifi.LINK_CONFIGURATION_CHANGED" /> <protected-broadcast android:name="android.net.wifi.CONFIGURED_NETWORKS_CHANGE" /> + <protected-broadcast android:name="android.net.wifi.action.PASSPOINT_DEAUTH_IMMINENT" /> + <protected-broadcast android:name="android.net.wifi.action.PASSPOINT_ICON" /> + <protected-broadcast android:name="android.net.wifi.action.PASSPOINT_OSU_PROVIDERS_LIST" /> + <protected-broadcast android:name="android.net.wifi.action.PASSPOINT_SUBSCRIPTION_REMEDIATION" /> <protected-broadcast android:name="android.net.wifi.supplicant.CONNECTION_CHANGE" /> <protected-broadcast android:name="android.net.wifi.supplicant.STATE_CHANGE" /> <protected-broadcast android:name="android.net.wifi.p2p.STATE_CHANGED" /> @@ -440,6 +444,7 @@ <protected-broadcast android:name="android.telecom.action.PHONE_ACCOUNT_UNREGISTERED" /> <protected-broadcast android:name="android.telecom.action.SHOW_MISSED_CALLS_NOTIFICATION" /> <protected-broadcast android:name="android.telephony.action.CARRIER_CONFIG_CHANGED" /> + <protected-broadcast android:name="android.telephony.action.SHOW_VOICEMAIL_NOTIFICATION" /> <protected-broadcast android:name="com.android.bluetooth.btservice.action.ALARM_WAKEUP" /> <protected-broadcast android:name="com.android.server.action.NETWORK_STATS_POLL" /> @@ -1346,7 +1351,7 @@ <permission android:name="android.permission.CONNECTIVITY_INTERNAL" android:protectionLevel="signature|privileged" /> - <!-- Allows an internal user to use restricted Networks. + <!-- @SystemApi Allows an internal user to use restricted Networks. @hide --> <permission android:name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS" android:protectionLevel="signature|privileged" /> @@ -2312,6 +2317,10 @@ <permission android:name="android.permission.MODIFY_ACCESSIBILITY_DATA" android:protectionLevel="signature" /> + <!-- @hide Allows an application to change the accessibility volume. --> + <permission android:name="android.permission.CHANGE_ACCESSIBILITY_VOLUME" + android:protectionLevel="signature" /> + <!-- @hide Allows an application to collect frame statistics --> <permission android:name="android.permission.FRAME_STATS" android:protectionLevel="signature" /> @@ -3120,6 +3129,15 @@ <permission android:name="android.permission.BIND_CHOOSER_TARGET_SERVICE" android:protectionLevel="signature" /> + <!-- @SystemApi Must be required by services that extend + {@link android.service.resolver.ResolverRankerService}, to ensure that only the system can + bind to them. + <p>Protection level: signature + @hide + --> + <permission android:name="android.permission.BIND_RESOLVER_RANKER_SERVICE" + android:protectionLevel="signature" /> + <!-- Must be required by a {@link android.service.notification.ConditionProviderService}, to ensure that only the system can bind to it. @@ -3625,6 +3643,14 @@ android:permission="android.permission.BIND_JOB_SERVICE" > </service> + <service android:name="com.android.internal.app.LRResolverRankerService" + android:permission="android.permission.BIND_RESOLVER_RANKER_SERVICE" + android:exported="false" + android:priority="-1" > + <intent-filter> + <action android:name="android.service.resolver.ResolverRankerService" /> + </intent-filter> + </service> </application> </manifest> diff --git a/core/res/res/layout/screen_action_bar.xml b/core/res/res/layout/screen_action_bar.xml index edcbb2b6b498..4c1d6cb53539 100644 --- a/core/res/res/layout/screen_action_bar.xml +++ b/core/res/res/layout/screen_action_bar.xml @@ -35,6 +35,7 @@ This is an optimized layout for a screen with the Action Bar enabled. android:layout_alignParentTop="true" style="?attr/actionBarStyle" android:transitionName="android:action_bar" + android:touchscreenBlocksFocus="true" android:keyboardNavigationCluster="true" android:gravity="top"> <com.android.internal.widget.ActionBarView @@ -54,6 +55,7 @@ This is an optimized layout for a screen with the Action Bar enabled. android:layout_height="wrap_content" style="?attr/actionBarSplitStyle" android:visibility="gone" + android:touchscreenBlocksFocus="true" android:keyboardNavigationCluster="true" android:gravity="center"/> </com.android.internal.widget.ActionBarOverlayLayout> diff --git a/core/res/res/layout/screen_toolbar.xml b/core/res/res/layout/screen_toolbar.xml index 0bec8c40c1a8..ded252798441 100644 --- a/core/res/res/layout/screen_toolbar.xml +++ b/core/res/res/layout/screen_toolbar.xml @@ -35,6 +35,7 @@ This is an optimized layout for a screen with a toolbar enabled. android:layout_alignParentTop="true" style="?attr/actionBarStyle" android:transitionName="android:action_bar" + android:touchscreenBlocksFocus="true" android:keyboardNavigationCluster="true" android:gravity="top"> <Toolbar diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 995f2c3b8356..a3b27052bf67 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -7226,6 +7226,10 @@ <!-- Whether to use single line for the preference title text. By default, preference title will be constrained to one line, so the default value of this attribute is true. --> <attr name="singleLineTitle" format="boolean" /> + <!-- Whether the space for the preference icon view will be reserved. By default, preference + icon view visibility will be set to GONE when there is no icon provided, so the default + value of this attribute is false. --> + <attr name="iconSpaceReserved" format="boolean" /> </declare-styleable> <!-- Base attributes available to CheckBoxPreference. --> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 68e766e46279..194c119f076c 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1880,8 +1880,16 @@ Takes effect only if the scrollbar drawables have no intrinsic size. --> <dimen name="config_scrollbarSize">4dp</dimen> - <!-- Distance that should be scrolled in response to a {@link MotionEvent#ACTION_SCROLL event} - with an axis value of 1. --> + <!-- Distance that should be scrolled, per axis value, in response to a horizontal + {@link MotionEvent#ACTION_SCROLL} event. --> + <dimen name="config_horizontalScrollFactor">64dp</dimen> + + <!-- Distance that should be scrolled, per axis value, in response to a vertical + {@link MotionEvent#ACTION_SCROLL} event. --> + <dimen name="config_verticalScrollFactor">64dp</dimen> + + <!-- Obsolete. Distance that should be scrolled, per axis value, in response to a + {@link MotionEvent#ACTION_SCROLL} event. --> <dimen name="config_scrollFactor">64dp</dimen> <!-- Maximum number of grid columns permitted in the ResolverActivity @@ -2580,12 +2588,14 @@ <integer name="config_defaultPictureInPictureGravity">0x55</integer> <!-- The minimum aspect ratio (width/height) that is supported for picture-in-picture. Any - ratio smaller than this is considered too tall and thin to be usable. --> - <item name="config_pictureInPictureMinAspectRatio" format="float" type="dimen">0.5</item> + ratio smaller than this is considered too tall and thin to be usable. Currently, this + is the inverse of the max landscape aspect ratio (1:2.39), but this is an extremely + skinny aspect ratio that is not expected to be widely used. --> + <item name="config_pictureInPictureMinAspectRatio" format="float" type="dimen">0.41841004184</item> <!-- The minimum aspect ratio (width/height) that is supported for picture-in-picture. Any - ratio larger than this is considered to wide and short to be usable. --> - <item name="config_pictureInPictureMaxAspectRatio" format="float" type="dimen">2.35</item> + ratio larger than this is considered to wide and short to be usable. Currently 2.39:1. --> + <item name="config_pictureInPictureMaxAspectRatio" format="float" type="dimen">2.39</item> <!-- The snap mode to use for picture-in-picture. These values correspond to constants defined in PipSnapAlgorithm and should not be changed independently. @@ -2799,4 +2809,9 @@ <!-- Colon separated list of package names that should be granted Notification Listener access --> <string name="config_defaultListenerAccessPackages" translatable="false"></string> + + <!-- Maximum size, specified in pixels, to restrain the display space width to. Height and + density will be scaled accordingly to maintain aspect ratio. A value of 0 indicates no + constraint will be enforced. --> + <integer name="config_maxUiWidth">0</integer> </resources> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 876d44da416b..6e20208cc2d6 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2813,6 +2813,7 @@ <public name="iconTint" /> <public name="iconTintMode" /> <public name="maxAspectRatio"/> + <public name="iconSpaceReserved"/> </public-group> <public-group type="style" first-id="0x010302e0"> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 868e256496bb..4afa8dcdfb4a 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -189,22 +189,23 @@ <!-- Displayed to tell the user that they cannot change the caller ID setting. --> <string name="CLIRPermanent">You can\'t change the caller ID setting.</string> - <!-- Displayed to tell the user that data service is blocked by access control. --> - <string name="RestrictedOnData">Data service is blocked.</string> - <!-- Displayed to tell the user that emergency service is blocked by access control. --> - <string name="RestrictedOnEmergency">Emergency service is blocked.</string> - <!-- Displayed to tell the user that normal service is blocked by access control. --> - <string name="RestrictedOnNormal">Voice service is blocked.</string> - <!-- Displayed to tell the user that all emergency and normal voice services are blocked by access control. --> - <string name="RestrictedOnAllVoice">All voice services are blocked.</string> - <!-- Displayed to tell the user that sms service is blocked by access control. --> - <string name="RestrictedOnSms">SMS service is blocked.</string> - <!-- Displayed to tell the user that voice/data service is blocked by access control. --> - <string name="RestrictedOnVoiceData">Voice/data services are blocked.</string> - <!-- Displayed to tell the user that voice and sms service are blocked by access control. --> - <string name="RestrictedOnVoiceSms">Voice/SMS services are blocked.</string> - <!-- Displayed to tell the user that all service is blocked by access control. --> - <string name="RestrictedOnAll">All voice/data/SMS services are blocked.</string> + <!-- Notification title to tell the user that data service is blocked by access control. --> + <string name="RestrictedOnDataTitle">No data service</string> + <!-- Notification title to tell the user that emergency service is blocked by access control. --> + <string name="RestrictedOnEmergencyTitle">No emergency service</string> + <!-- Notification title to tell the user that normal service is blocked by access control. --> + <string name="RestrictedOnNormalTitle">No voice service</string> + <!-- Notification title to tell the user that all emergency and normal voice services are blocked by access control. --> + <string name="RestrictedOnAllVoiceTitle">No voice/emergency service</string> + + <!-- Notification content to tell the user that data service is blocked by access control. --> + <string name="RestrictedOnDataContent">Your carrier has temporarily suspended data service at this location</string> + <!-- Notification content to tell the user that emergency service is blocked by access control. --> + <string name="RestrictedOnEmergencyContent">Your carrier has temporarily suspended emergency calls at this location</string> + <!-- Notification content to tell the user that normal service is blocked by access control. --> + <string name="RestrictedOnNormalContent">Your carrier has temporarily suspended voice calls at this location</string> + <!-- Notification content to tell the user that all emergency and normal voice services are blocked by access control. --> + <string name="RestrictedOnAllVoiceContent">Your carrier has temporarily suspended voice and emergency calls at this location</string> <!-- Displayed to tell the user that they should switch their network preference. --> <string name="NetworkPreferenceSwitchTitle">Can\u2019t reach network</string> diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index 25873d2f8fd7..7dac18dbda8d 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -1249,6 +1249,7 @@ please see styles_device_defaults.xml. <item name="collapseContentDescription">@string/toolbar_collapse_description</item> <item name="contentInsetStart">16dp</item> <item name="contentInsetStartWithNavigation">@dimen/action_bar_content_inset_with_nav</item> + <item name="touchscreenBlocksFocus">true</item> <item name="keyboardNavigationCluster">true</item> </style> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index b23c96c9b05f..24be0b04a047 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -434,6 +434,8 @@ <java-symbol type="dimen" name="config_viewMinFlingVelocity" /> <java-symbol type="dimen" name="config_viewMaxFlingVelocity" /> <java-symbol type="dimen" name="config_scrollbarSize" /> + <java-symbol type="dimen" name="config_horizontalScrollFactor" /> + <java-symbol type="dimen" name="config_verticalScrollFactor" /> <java-symbol type="dimen" name="config_scrollFactor" /> <java-symbol type="dimen" name="default_app_widget_padding_bottom" /> <java-symbol type="dimen" name="default_app_widget_padding_left" /> @@ -507,12 +509,16 @@ <java-symbol type="string" name="Noon" /> <java-symbol type="string" name="PinMmi" /> <java-symbol type="string" name="PwdMmi" /> - <java-symbol type="string" name="RestrictedOnAllVoice" /> - <java-symbol type="string" name="RestrictedOnData" /> - <java-symbol type="string" name="RestrictedOnEmergency" /> - <java-symbol type="string" name="RestrictedOnNormal" /> <java-symbol type="string" name="NetworkPreferenceSwitchSummary" /> <java-symbol type="string" name="NetworkPreferenceSwitchTitle" /> + <java-symbol type="string" name="RestrictedOnAllVoiceTitle" /> + <java-symbol type="string" name="RestrictedOnDataTitle" /> + <java-symbol type="string" name="RestrictedOnEmergencyTitle" /> + <java-symbol type="string" name="RestrictedOnNormalTitle" /> + <java-symbol type="string" name="RestrictedOnAllVoiceContent" /> + <java-symbol type="string" name="RestrictedOnDataContent" /> + <java-symbol type="string" name="RestrictedOnEmergencyContent" /> + <java-symbol type="string" name="RestrictedOnNormalContent" /> <java-symbol type="string" name="SetupCallDefault" /> <java-symbol type="string" name="accept" /> <java-symbol type="string" name="activity_chooser_view_see_all" /> @@ -2919,6 +2925,9 @@ <!-- Colon separated list of package names that should be granted Notification Listener access --> <java-symbol type="string" name="config_defaultListenerAccessPackages" /> + <!-- maximum width of the display --> + <java-symbol type="integer" name="config_maxUiWidth" /> + <!-- system notification channels --> <java-symbol type="string" name="notification_channel_virtual_keyboard" /> <java-symbol type="string" name="notification_channel_physical_keyboard" /> diff --git a/core/tests/coretests/README b/core/tests/coretests/README index 4a6984320e61..aced4417ba02 100644 --- a/core/tests/coretests/README +++ b/core/tests/coretests/README @@ -45,6 +45,10 @@ To run tests in debug mode: -e debug true +To uninstall the package: + + adb shell pm uninstall -k com.android.frameworks.coretests + For more arguments, see the guide to command=line testing: https://developer.android.com/studio/test/command-line.html diff --git a/core/tests/coretests/src/android/content/ContentTests.java b/core/tests/coretests/src/android/content/ContentTests.java index a1299e3a0e8d..567b79a674c1 100644 --- a/core/tests/coretests/src/android/content/ContentTests.java +++ b/core/tests/coretests/src/android/content/ContentTests.java @@ -23,6 +23,7 @@ public class ContentTests { TestSuite suite = new TestSuite(ContentTests.class.getName()); suite.addTestSuite(AssetTest.class); + suite.addTestSuite(ContentValuesTest.class); return suite; } } diff --git a/core/tests/coretests/src/android/content/ContentValuesTest.java b/core/tests/coretests/src/android/content/ContentValuesTest.java new file mode 100644 index 000000000000..7b39939b2d0c --- /dev/null +++ b/core/tests/coretests/src/android/content/ContentValuesTest.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2017 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 android.content; + +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.SmallTest; + + +/* + runtest -c android.content.ContentValuesTest frameworks-core + + or + + make -j256 FrameworksCoreTests && \ + adb shell pm uninstall -k com.android.frameworks.coretests && \ + adb install out/target/product/bullhead/testcases/FrameworksCoreTests/FrameworksCoreTests.apk && \ + adb shell am instrument -w -e package android.content \ + com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner +*/ +public class ContentValuesTest extends AndroidTestCase { + + @SmallTest + public void testIsEmpty() throws Exception { + ContentValues cv = new ContentValues(); + assertTrue(cv.isEmpty()); + assertEquals(0, cv.size()); + + cv.put("key", "value"); + assertFalse(cv.isEmpty()); + assertEquals(1, cv.size()); + } +} diff --git a/core/tests/coretests/src/android/database/PageViewCursorTest.java b/core/tests/coretests/src/android/database/PageViewCursorTest.java index 62b54105cf9a..fba6aaf3f406 100644 --- a/core/tests/coretests/src/android/database/PageViewCursorTest.java +++ b/core/tests/coretests/src/android/database/PageViewCursorTest.java @@ -13,20 +13,28 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package android.database; +import static com.android.internal.util.ArrayUtils.contains; +import static com.android.internal.util.Preconditions.checkArgument; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import android.annotation.Nullable; import android.content.ContentResolver; +import android.os.Build; import android.os.Bundle; import android.support.test.runner.AndroidJUnit4; +import android.util.Log; +import android.util.MathUtils; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import java.util.Arrays; import java.util.Random; @RunWith(AndroidJUnit4.class) @@ -37,32 +45,32 @@ public class PageViewCursorTest { private static final String NAME_COLUMN = "name"; private static final String NUM_COLUMN = "num"; - private static final String[] COLUMNS = new String[]{ - NAME_COLUMN, - NUM_COLUMN + private static final String[] COLUMNS = new String[] { + NAME_COLUMN, + NUM_COLUMN }; private static final String[] NAMES = new String[] { - "000", - "111", - "222", - "333", - "444", - "555", - "666", - "777", - "888", - "999", - "aaa", - "bbb", - "ccc", - "ddd", - "eee", - "fff", - "ggg", - "hhh", - "iii", - "jjj" + "000", + "111", + "222", + "333", + "444", + "555", + "666", + "777", + "888", + "999", + "aaa", + "bbb", + "ccc", + "ddd", + "eee", + "fff", + "ggg", + "hhh", + "iii", + "jjj" }; private MatrixCursor mDelegate; @@ -79,7 +87,7 @@ public class PageViewCursorTest { row.add(NUM_COLUMN, rand.nextInt()); } - mCursor = new PageViewCursor(mDelegate, 10, 5); + mCursor = new PageViewCursor(mDelegate, createArgs(10, 5)); } @Test @@ -94,7 +102,7 @@ public class PageViewCursorTest { @Test public void testPage_OffsetExceedsCursorCount_EffectivelyEmptyCursor() { - mCursor = new PageViewCursor(mDelegate, ITEM_COUNT * 2, 5); + mCursor = new PageViewCursor(mDelegate, createArgs(ITEM_COUNT * 2, 5)); assertEquals(0, mCursor.getCount()); } @@ -155,13 +163,13 @@ public class PageViewCursorTest { @Test public void testCount_ZeroForEmptyCursor() { - mCursor = new PageViewCursor(mDelegate, 0, 0); + mCursor = new PageViewCursor(mDelegate, createArgs(0, 0)); assertEquals(0, mCursor.getCount()); } @Test public void testIsBeforeFirst_TrueForEmptyCursor() { - mCursor = new PageViewCursor(mDelegate, 0, 0); + mCursor = new PageViewCursor(mDelegate, createArgs(0, 0)); assertTrue(mCursor.isBeforeFirst()); } @@ -175,7 +183,7 @@ public class PageViewCursorTest { @Test public void testIsAfterLast_TrueForEmptyCursor() { - mCursor = new PageViewCursor(mDelegate, 0, 0); + mCursor = new PageViewCursor(mDelegate, createArgs(0, 0)); assertTrue(mCursor.isAfterLast()); } @@ -247,71 +255,131 @@ public class PageViewCursorTest { } @Test - public void testOffset_LimitOutOfBounds() { - mCursor = new PageViewCursor(mDelegate, 5, 100); + public void testLimitOutOfBounds() { + mCursor = new PageViewCursor(mDelegate, createArgs(5, 100)); assertEquals(15, mCursor.getCount()); } @Test - public void testAutoPagedExtra() { - mCursor = new PageViewCursor(mDelegate, 5, 100); + public void testOffsetOutOfBounds_EmptyResult() { + mCursor = new PageViewCursor(mDelegate, createArgs(100000, 100)); + assertEquals(0, mCursor.getCount()); + } + + @Test + public void testAddsExtras() { + mCursor = new PageViewCursor(mDelegate, createArgs(5, 100)); assertTrue(mCursor.getExtras().getBoolean(PageViewCursor.EXTRA_AUTO_PAGED)); + String[] honoredArgs = mCursor.getExtras() + .getStringArray(ContentResolver.EXTRA_HONORED_ARGS); + assertTrue(contains(honoredArgs, ContentResolver.QUERY_ARG_OFFSET)); + assertTrue(contains(honoredArgs, ContentResolver.QUERY_ARG_LIMIT)); + } + + @Test + public void testAddsExtras_OnlyOffset() { + Bundle args = new Bundle(); + args.putInt(ContentResolver.QUERY_ARG_OFFSET, 5); + mCursor = new PageViewCursor(mDelegate, args); + String[] honoredArgs = mCursor.getExtras() + .getStringArray(ContentResolver.EXTRA_HONORED_ARGS); + assertTrue(contains(honoredArgs, ContentResolver.QUERY_ARG_OFFSET)); + assertFalse(contains(honoredArgs, ContentResolver.QUERY_ARG_LIMIT)); + } + + @Test + public void testAddsExtras_OnlyLimit() { + Bundle args = new Bundle(); + args.putInt(ContentResolver.QUERY_ARG_LIMIT, 5); + mCursor = new PageViewCursor(mDelegate, args); + String[] honoredArgs = mCursor.getExtras() + .getStringArray(ContentResolver.EXTRA_HONORED_ARGS); + assertFalse(contains(honoredArgs, ContentResolver.QUERY_ARG_OFFSET)); + assertTrue(contains(honoredArgs, ContentResolver.QUERY_ARG_LIMIT)); } @Test public void testGetWindow() { - mCursor = new PageViewCursor(mDelegate, 5, 5); + mCursor = new PageViewCursor(mDelegate, createArgs(5, 5)); CursorWindow window = mCursor.getWindow(); assertEquals(5, window.getNumRows()); } @Test - public void testWrap() { - Bundle queryArgs = new Bundle(); - queryArgs.putInt(ContentResolver.QUERY_ARG_OFFSET, 5); - queryArgs.putInt(ContentResolver.QUERY_ARG_LIMIT, 5); - Cursor wrapped = PageViewCursor.wrap(mDelegate, queryArgs); + public void testWraps() { + Bundle args = createArgs(5, 5); + Cursor wrapped = PageViewCursor.wrap(mDelegate, args); assertTrue(wrapped instanceof PageViewCursor); assertEquals(5, wrapped.getCount()); } @Test - public void testWrap_NoOpWithoutPagingArgs() { + public void testWraps_NullExtras() { + Bundle args = createArgs(5, 5); + mDelegate.setExtras(null); + Cursor wrapped = PageViewCursor.wrap(mDelegate, args); + assertTrue(wrapped instanceof PageViewCursor); + assertEquals(5, wrapped.getCount()); + } + + @Test + public void testWraps_WithJustOffset() { + Bundle args = new Bundle(); + args.putInt(ContentResolver.QUERY_ARG_OFFSET, 5); + Cursor wrapped = PageViewCursor.wrap(mDelegate, args); + assertTrue(wrapped instanceof PageViewCursor); + assertEquals(15, wrapped.getCount()); + } + + @Test + public void testWraps_WithJustLimit() { + Bundle args = new Bundle(); + args.putInt(ContentResolver.QUERY_ARG_LIMIT, 5); + Cursor wrapped = PageViewCursor.wrap(mDelegate, args); + assertTrue(wrapped instanceof PageViewCursor); + assertEquals(5, wrapped.getCount()); + } + + @Test + public void testNoWrap_WithoutPagingArgs() { Cursor wrapped = PageViewCursor.wrap(mDelegate, Bundle.EMPTY); assertTrue(mDelegate == wrapped); } @Test - public void testWrap_NoOpCursorsWithExistingPaging_ByTotalSize() { + public void testNoWrap_CursorsHasExistingPaging_ByTotalSize() { Bundle extras = new Bundle(); extras.putInt(ContentResolver.EXTRA_TOTAL_SIZE, 5); mDelegate.setExtras(extras); - Bundle queryArgs = new Bundle(); - queryArgs.putInt(ContentResolver.QUERY_ARG_OFFSET, 5); - queryArgs.putInt(ContentResolver.QUERY_ARG_LIMIT, 5); - Cursor wrapped = PageViewCursor.wrap(mDelegate, queryArgs); + Bundle args = createArgs(5, 5); + Cursor wrapped = PageViewCursor.wrap(mDelegate, args); assertTrue(mDelegate == wrapped); } @Test - public void testWrap_NoOpCursorsWithExistingPaging_ByHonoredArgs() { + public void testNoWrap_CursorsHasExistingPaging_ByHonoredArgs() { Bundle extras = new Bundle(); extras.putStringArray( ContentResolver.EXTRA_HONORED_ARGS, new String[] { - ContentResolver.QUERY_ARG_OFFSET, - ContentResolver.QUERY_ARG_LIMIT + ContentResolver.QUERY_ARG_OFFSET, + ContentResolver.QUERY_ARG_LIMIT }); mDelegate.setExtras(extras); - Bundle queryArgs = new Bundle(); - queryArgs.putInt(ContentResolver.QUERY_ARG_OFFSET, 5); - queryArgs.putInt(ContentResolver.QUERY_ARG_LIMIT, 5); - Cursor wrapped = PageViewCursor.wrap(mDelegate, queryArgs); + Bundle args = createArgs(5, 5); + Cursor wrapped = PageViewCursor.wrap(mDelegate, args); assertTrue(mDelegate == wrapped); } + private static Bundle createArgs(int offset, int limit) { + Bundle args = new Bundle(); + args.putInt(ContentResolver.QUERY_ARG_OFFSET, offset); + args.putInt(ContentResolver.QUERY_ARG_LIMIT, limit); + return args; + } + private void assertStringAt(int row, int column, String expected) { mCursor.moveToPosition(row); assertEquals(expected, mCursor.getString(column)); diff --git a/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java b/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java index ff98eb763f76..fbba6fffcd8e 100644 --- a/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java +++ b/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java @@ -264,7 +264,7 @@ public class StorageManagerIntegrationTest extends StorageManagerBaseTest { final MyThreadFactory factory = new MyThreadFactory(); int firstMountId; try (final ParcelFileDescriptor fd = mSm.openProxyFileDescriptor( - ParcelFileDescriptor.MODE_READ_ONLY, callback, factory)) { + ParcelFileDescriptor.MODE_READ_ONLY, callback, null, factory)) { assertNotSame(Thread.State.TERMINATED, factory.thread.getState()); firstMountId = mSm.getProxyFileDescriptorMountPointId(); assertNotSame(-1, firstMountId); @@ -276,7 +276,7 @@ public class StorageManagerIntegrationTest extends StorageManagerBaseTest { // StorageManager should mount another bridge on the next open request. try (final ParcelFileDescriptor fd = mSm.openProxyFileDescriptor( - ParcelFileDescriptor.MODE_WRITE_ONLY, callback, factory)) { + ParcelFileDescriptor.MODE_WRITE_ONLY, callback, null, factory)) { assertNotSame(Thread.State.TERMINATED, factory.thread.getState()); assertNotSame(firstMountId, mSm.getProxyFileDescriptorMountPointId()); } diff --git a/core/tests/coretests/src/android/provider/SettingsProviderTest.java b/core/tests/coretests/src/android/provider/SettingsProviderTest.java index 3fbf169460b2..108585dc0886 100644 --- a/core/tests/coretests/src/android/provider/SettingsProviderTest.java +++ b/core/tests/coretests/src/android/provider/SettingsProviderTest.java @@ -349,7 +349,6 @@ public class SettingsProviderTest extends AndroidTestCase { assertCanBeHandled(new Intent(Settings.ACTION_USER_DICTIONARY_SETTINGS)); assertCanBeHandled(new Intent(Settings.ACTION_WIFI_IP_SETTINGS)); assertCanBeHandled(new Intent(Settings.ACTION_WIFI_SETTINGS)); - assertCanBeHandled(new Intent(Settings.ACTION_WIFI_SAVED_NETWORK_SETTINGS)); assertCanBeHandled(new Intent(Settings.ACTION_WIRELESS_SETTINGS)); if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) { diff --git a/core/tests/utiltests/runtests.sh b/core/tests/utiltests/runtests.sh new file mode 100755 index 000000000000..853119f62334 --- /dev/null +++ b/core/tests/utiltests/runtests.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +if [ -z $ANDROID_BUILD_TOP ]; then + echo "You need to source and lunch before you can use this script" + exit 1 +fi + +echo "Running tests" + +set -e # fail early + +echo "+ mmma -j32 $ANDROID_BUILD_TOP/frameworks/base/core/tests/utiltests" +# NOTE Don't actually run the command above since this shell doesn't inherit functions from the +# caller. +make -j32 -C $ANDROID_BUILD_TOP -f build/core/main.mk MODULES-IN-frameworks-base-core-tests-utiltests + +set -x # print commands + +adb root +adb wait-for-device + +adb install -r -g "$OUT/data/app/FrameworksUtilTests/FrameworksUtilTests.apk" + +adb shell am instrument -w "$@" 'com.android.frameworks.utiltests/android.support.test.runner.AndroidJUnitRunner' diff --git a/core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java b/core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java index d29b5723065b..eb2a5165dc4f 100644 --- a/core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java @@ -80,6 +80,66 @@ public class StateMachineTest extends TestCase { } /** + * Tests {@link StateMachine#toString()}. + */ + class StateMachineToStringTest extends StateMachine { + StateMachineToStringTest(String name) { + super(name); + } + } + + class ExampleState extends State { + String mName; + + ExampleState(String name) { + mName = name; + } + + @Override + public String getName() { + return mName; + } + } + + @SmallTest + public void testToStringSucceedsEvenIfMachineHasNoStates() throws Exception { + StateMachine stateMachine = new StateMachineToStringTest("TestStateMachine"); + assertTrue(stateMachine.toString().contains("TestStateMachine")); + } + + @SmallTest + public void testToStringSucceedsEvenIfStateHasNoName() throws Exception { + StateMachine stateMachine = new StateMachineToStringTest("TestStateMachine"); + State exampleState = new ExampleState(null); + stateMachine.addState(exampleState); + stateMachine.setInitialState(exampleState); + stateMachine.start(); + assertTrue(stateMachine.toString().contains("TestStateMachine")); + assertTrue(stateMachine.toString().contains("(null)")); + } + + @SmallTest + public void testToStringIncludesMachineAndStateNames() throws Exception { + StateMachine stateMachine = new StateMachineToStringTest("TestStateMachine"); + State exampleState = new ExampleState("exampleState"); + stateMachine.addState(exampleState); + stateMachine.setInitialState(exampleState); + stateMachine.start(); + assertTrue(stateMachine.toString().contains("TestStateMachine")); + assertTrue(stateMachine.toString().contains("exampleState")); + } + + @SmallTest + public void testToStringDoesNotContainMultipleLines() throws Exception { + StateMachine stateMachine = new StateMachineToStringTest("TestStateMachine"); + State exampleState = new ExampleState("exampleState"); + stateMachine.addState(exampleState); + stateMachine.setInitialState(exampleState); + stateMachine.start(); + assertFalse(stateMachine.toString().contains("\n")); + } + + /** * Tests {@link StateMachine#quit()}. */ class StateMachineQuitTest extends StateMachine { diff --git a/data/etc/platform.xml b/data/etc/platform.xml index 344f3c83ba6c..5e3488c1ed42 100644 --- a/data/etc/platform.xml +++ b/data/etc/platform.xml @@ -181,6 +181,10 @@ <allow-in-power-save package="com.android.cellbroadcastreceiver" /> <allow-in-power-save package="com.android.shell" /> + <!-- Package in charge of provisioning that needs to freely run in the background --> + <!-- STOPSHIP: Revert this once it is fixed properly --> + <allow-in-power-save package="com.android.managedprovisioning" /> + <!-- These are the packages that are white-listed to be able to run as system user --> <system-user-whitelisted-app package="com.android.settings" /> diff --git a/graphics/java/android/graphics/Color.java b/graphics/java/android/graphics/Color.java index 33d19d4063f5..d69f67d138a1 100644 --- a/graphics/java/android/graphics/Color.java +++ b/graphics/java/android/graphics/Color.java @@ -22,6 +22,7 @@ import android.annotation.ColorLong; import android.annotation.HalfFloat; import android.annotation.IntRange; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.Size; import android.util.Half; @@ -288,7 +289,7 @@ import java.util.function.DoubleUnaryOperator; * and <code>(1.0, 0.0, 0.0, 0.5)</code>.</p> */ @AnyThread -public class Color { +public final class Color { @ColorInt public static final int BLACK = 0xFF000000; @ColorInt public static final int DKGRAY = 0xFF444444; @ColorInt public static final int GRAY = 0xFF888888; @@ -415,7 +416,7 @@ public class Color { * to this color space's color model, plus one extra component for * alpha. * - * @return An integer between 4 and 5 + * @return The integer 4 or 5 */ @IntRange(from = 4, to = 5) public int getComponentCount() { @@ -560,7 +561,37 @@ public class Color { @NonNull @Size(min = 4, max = 5) public float[] getComponents() { - return Arrays.copyOf(mComponents, mColorSpace.getComponentCount() + 1); + return Arrays.copyOf(mComponents, mComponents.length); + } + + /** + * Copies this color's components in the supplied array. The last element of the + * array is always the alpha component. + * + * @param components An array of floats whose size must be at least + * {@link #getComponentCount()}, can be null + * @return The array passed as a parameter if not null, or a new array of length + * {@link #getComponentCount()} + * + * @see #getComponent(int) + * + * @throws IllegalArgumentException If the specified array's length is less than + * {@link #getComponentCount()} + */ + @NonNull + @Size(min = 4) + public float[] getComponents(@Nullable @Size(min = 4) float[] components) { + if (components == null) { + return Arrays.copyOf(mComponents, mComponents.length); + } + + if (components.length < mComponents.length) { + throw new IllegalArgumentException("The specified array's length must be at " + + "least " + mComponents.length); + } + + System.arraycopy(mComponents, 0, components, 0, mComponents.length); + return components; } /** @@ -570,7 +601,7 @@ public class Color { * * <p>If the requested component index is {@link #getComponentCount()}, * this method returns the alpha component, always in the range - * \([0..1\).</p> + * \([0..1]\).</p> * * @see #getComponents() * diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java index b78df34f5c3e..ff9f11dae4dc 100644 --- a/graphics/java/android/graphics/FontListParser.java +++ b/graphics/java/android/graphics/FontListParser.java @@ -189,9 +189,8 @@ public class FontListParser { skip(parser); } } - String fullFilename = "/system/fonts/" + - FILENAME_WHITESPACE_PATTERN.matcher(filename).replaceAll(""); - return new FontConfig.Font(fullFilename, index, + String sanitizedName = FILENAME_WHITESPACE_PATTERN.matcher(filename).replaceAll(""); + return new FontConfig.Font(sanitizedName, index, axes.toArray(new FontConfig.Axis[axes.size()]), weight, isItalic); } diff --git a/graphics/java/android/graphics/ImageFormat.java b/graphics/java/android/graphics/ImageFormat.java index a226e85618e8..e3527e359d62 100644 --- a/graphics/java/android/graphics/ImageFormat.java +++ b/graphics/java/android/graphics/ImageFormat.java @@ -662,6 +662,15 @@ public class ImageFormat { public static final int DEPTH_POINT_CLOUD = 0x101; /** + * Unprocessed implementation-dependent raw + * depth measurements, opaque with 16 bit + * samples. + * + * @hide + */ + public static final int RAW_DEPTH = 0x1002; + + /** * Android private opaque image format. * <p> * The choices of the actual format and pixel data layout are entirely up to @@ -723,6 +732,7 @@ public class ImageFormat { return 24; case FLEX_RGBA_8888: return 32; + case RAW_DEPTH: case RAW_SENSOR: return 16; case RAW10: @@ -765,6 +775,7 @@ public class ImageFormat { case DEPTH16: case DEPTH_POINT_CLOUD: case PRIVATE: + case RAW_DEPTH: return true; } diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java index 228d9500180a..8c3a2e8068ca 100644 --- a/graphics/java/android/graphics/Typeface.java +++ b/graphics/java/android/graphics/Typeface.java @@ -1003,21 +1003,22 @@ public class Typeface { Map<String, ByteBuffer> bufferForPath) { FontFamily fontFamily = new FontFamily(family.getLanguage(), family.getVariant()); for (FontConfig.Font font : family.getFonts()) { - ByteBuffer fontBuffer = bufferForPath.get(font.getFontName()); + String fullPathName = "/system/fonts/" + font.getFontName(); + ByteBuffer fontBuffer = bufferForPath.get(fullPathName); if (fontBuffer == null) { - try (FileInputStream file = new FileInputStream(font.getFontName())) { + try (FileInputStream file = new FileInputStream(fullPathName)) { FileChannel fileChannel = file.getChannel(); long fontSize = fileChannel.size(); fontBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fontSize); - bufferForPath.put(font.getFontName(), fontBuffer); + bufferForPath.put(fullPathName, fontBuffer); } catch (IOException e) { - Log.e(TAG, "Error mapping font file " + font.getFontName()); + Log.e(TAG, "Error mapping font file " + fullPathName); continue; } } if (!fontFamily.addFontFromBuffer(fontBuffer, font.getTtcIndex(), font.getAxes(), font.getWeight(), font.isItalic() ? Builder.ITALIC : Builder.NORMAL)) { - Log.e(TAG, "Error creating font " + font.getFontName() + "#" + font.getTtcIndex()); + Log.e(TAG, "Error creating font " + fullPathName + "#" + font.getTtcIndex()); } } fontFamily.freeze(); diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp index 621d8c0e96f0..bd7b80469ddc 100644 --- a/libs/androidfw/LoadedArsc.cpp +++ b/libs/androidfw/LoadedArsc.cpp @@ -416,7 +416,9 @@ std::unique_ptr<LoadedPackage> LoadedPackage::Load(const Chunk& chunk) { ATRACE_CALL(); std::unique_ptr<LoadedPackage> loaded_package{new LoadedPackage()}; - const ResTable_package* header = chunk.header<ResTable_package>(); + constexpr size_t kMinPackageSize = + sizeof(ResTable_package) - sizeof(ResTable_package::typeIdOffset); + const ResTable_package* header = chunk.header<ResTable_package, kMinPackageSize>(); if (header == nullptr) { LOG(ERROR) << "Chunk RES_TABLE_PACKAGE_TYPE is too small."; return {}; diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk index ec8d63ecde98..fde0e4760d61 100644 --- a/libs/hwui/Android.mk +++ b/libs/hwui/Android.mk @@ -50,6 +50,7 @@ hwui_src_files := \ service/GraphicsStatsService.cpp \ thread/TaskManager.cpp \ utils/Blur.cpp \ + utils/Color.cpp \ utils/GLUtils.cpp \ utils/LinearAllocator.cpp \ utils/StringUtils.cpp \ diff --git a/libs/hwui/BakedOpRenderer.cpp b/libs/hwui/BakedOpRenderer.cpp index e8972aab9f8f..d154730058ee 100644 --- a/libs/hwui/BakedOpRenderer.cpp +++ b/libs/hwui/BakedOpRenderer.cpp @@ -363,6 +363,7 @@ void BakedOpRenderer::renderFunctor(const FunctorOp& op, const BakedOpState& sta state.computedState.transform.copyTo(&info.transform[0]); mRenderState.invokeFunctor(op.functor, DrawGlInfo::kModeDraw, &info); + if (!mRenderTarget.frameBufferId) mHasDrawn = true; } void BakedOpRenderer::dirtyRenderTarget(const Rect& uiDirty) { diff --git a/libs/hwui/GlLayer.h b/libs/hwui/GlLayer.h index 20aaf4a35ac1..c4f7fe2a56b8 100644 --- a/libs/hwui/GlLayer.h +++ b/libs/hwui/GlLayer.h @@ -44,7 +44,7 @@ public: } void setSize(uint32_t width, uint32_t height) override { - texture.updateSize(width, height, texture.internalFormat(), texture.format(), + texture.updateLayout(width, height, texture.internalFormat(), texture.format(), texture.target()); } diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp index 5cf52c69f0fd..3e7a246bb281 100644 --- a/libs/hwui/GlopBuilder.cpp +++ b/libs/hwui/GlopBuilder.cpp @@ -605,7 +605,11 @@ void GlopBuilder::build() { } else { mDescription.hasExternalTexture = true; } - mDescription.hasLinearTexture = mOutGlop->fill.texture.texture->isLinear(); + Texture* texture = mOutGlop->fill.texture.texture; + mDescription.hasLinearTexture = texture->isLinear(); + mDescription.hasColorSpaceConversion = texture->hasColorSpaceConversion(); + mDescription.transferFunction = texture->getTransferFunctionType(); + mDescription.hasTranslucentConversion = texture->blend; } mDescription.hasColors = mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::Color; diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp index 7be71eec4f76..8126d57a3a79 100644 --- a/libs/hwui/JankTracker.cpp +++ b/libs/hwui/JankTracker.cpp @@ -264,10 +264,15 @@ void JankTracker::addFrame(const FrameInfo& frame) { // the actual time spent blocked. nsecs_t forgiveAmount = std::min(expectedDequeueDuration, frame[FrameInfoIndex::DequeueBufferDuration]); + LOG_ALWAYS_FATAL_IF(forgiveAmount >= totalDuration, + "Impossible dequeue duration! dequeue duration reported %" PRId64 + ", total duration %" PRId64, forgiveAmount, totalDuration); totalDuration -= forgiveAmount; } } + LOG_ALWAYS_FATAL_IF(totalDuration <= 0, "Impossible totalDuration %" PRId64, totalDuration); uint32_t framebucket = frameCountIndexForFrameTime(totalDuration); + LOG_ALWAYS_FATAL_IF(framebucket < 0, "framebucket < 0 (%u)", framebucket); // Keep the fast path as fast as possible. if (CC_LIKELY(totalDuration < mFrameInterval)) { mData->frameCounts[framebucket]++; diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h index 5c8f8e93fa3d..2becfcb709c3 100644 --- a/libs/hwui/Program.h +++ b/libs/hwui/Program.h @@ -28,6 +28,7 @@ #include "FloatColor.h" #include "Matrix.h" #include "Properties.h" +#include "utils/Color.h" namespace android { namespace uirenderer { @@ -56,11 +57,11 @@ namespace uirenderer { #define PROGRAM_KEY_BITMAP_NPOT 0x80 #define PROGRAM_KEY_BITMAP_EXTERNAL 0x100 -#define PROGRAM_KEY_SWAP_SRC_DST 0x2000 - #define PROGRAM_KEY_BITMAP_WRAPS_MASK 0x600 #define PROGRAM_KEY_BITMAP_WRAPT_MASK 0x1800 +#define PROGRAM_KEY_SWAP_SRC_DST_SHIFT 13 + // Encode the xfermodes on 6 bits #define PROGRAM_MAX_XFERMODE 0x1f #define PROGRAM_XFERMODE_SHADER_SHIFT 26 @@ -89,6 +90,10 @@ namespace uirenderer { #define PROGRAM_HAS_GAMMA_CORRECTION 44 #define PROGRAM_HAS_LINEAR_TEXTURE 45 +#define PROGRAM_HAS_COLOR_SPACE_CONVERSION 46 +#define PROGRAM_TRANSFER_FUNCTION 47 // 2 bits for transfer function +#define PROGRAM_HAS_TRANSLUCENT_CONVERSION 49 + /////////////////////////////////////////////////////////////////////////////// // Types /////////////////////////////////////////////////////////////////////////////// @@ -105,13 +110,13 @@ typedef uint64_t programid; * A ProgramDescription must be used in conjunction with a ProgramCache. */ struct ProgramDescription { - enum class ColorFilterMode { + enum class ColorFilterMode : int8_t { None = 0, Matrix, Blend }; - enum Gradient { + enum Gradient : int8_t { kGradientLinear = 0, kGradientCircular, kGradientSweep @@ -168,6 +173,11 @@ struct ProgramDescription { // Set when sampling an image in linear space bool hasLinearTexture; + bool hasColorSpaceConversion; + TransferFunctionType transferFunction; + // Indicates whether the bitmap to convert between color spaces is translucent + bool hasTranslucentConversion; + /** * Resets this description. All fields are reset back to the default * values they hold after building a new instance. @@ -210,6 +220,10 @@ struct ProgramDescription { hasGammaCorrection = false; hasLinearTexture = false; + + hasColorSpaceConversion = false; + transferFunction = TransferFunctionType::None; + hasTranslucentConversion = false; } /** @@ -263,24 +277,27 @@ struct ProgramDescription { break; case ColorFilterMode::Blend: key |= PROGRAM_KEY_COLOR_BLEND; - key |= ((int)colorMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_COLOR_OP_SHIFT; + key |= ((int) colorMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_COLOR_OP_SHIFT; break; case ColorFilterMode::None: break; } - key |= ((int)framebufferMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT; - if (swapSrcDst) key |= PROGRAM_KEY_SWAP_SRC_DST; - if (modulate) key |= programid(0x1) << PROGRAM_MODULATE_SHIFT; - if (hasVertexAlpha) key |= programid(0x1) << PROGRAM_HAS_VERTEX_ALPHA_SHIFT; - if (useShadowAlphaInterp) key |= programid(0x1) << PROGRAM_USE_SHADOW_ALPHA_INTERP_SHIFT; - if (hasExternalTexture) key |= programid(0x1) << PROGRAM_HAS_EXTERNAL_TEXTURE_SHIFT; - if (hasTextureTransform) key |= programid(0x1) << PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT; - if (isSimpleGradient) key |= programid(0x1) << PROGRAM_IS_SIMPLE_GRADIENT; - if (hasColors) key |= programid(0x1) << PROGRAM_HAS_COLORS; - if (hasDebugHighlight) key |= programid(0x1) << PROGRAM_HAS_DEBUG_HIGHLIGHT; - if (hasRoundRectClip) key |= programid(0x1) << PROGRAM_HAS_ROUND_RECT_CLIP; - if (hasGammaCorrection) key |= programid(0x1) << PROGRAM_HAS_GAMMA_CORRECTION; - if (hasLinearTexture) key |= programid(0x1) << PROGRAM_HAS_LINEAR_TEXTURE; + key |= ((int) framebufferMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT; + key |= programid(swapSrcDst) << PROGRAM_KEY_SWAP_SRC_DST_SHIFT; + key |= programid(modulate) << PROGRAM_MODULATE_SHIFT; + key |= programid(hasVertexAlpha) << PROGRAM_HAS_VERTEX_ALPHA_SHIFT; + key |= programid(useShadowAlphaInterp) << PROGRAM_USE_SHADOW_ALPHA_INTERP_SHIFT; + key |= programid(hasExternalTexture) << PROGRAM_HAS_EXTERNAL_TEXTURE_SHIFT; + key |= programid(hasTextureTransform) << PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT; + key |= programid(isSimpleGradient) << PROGRAM_IS_SIMPLE_GRADIENT; + key |= programid(hasColors) << PROGRAM_HAS_COLORS; + key |= programid(hasDebugHighlight) << PROGRAM_HAS_DEBUG_HIGHLIGHT; + key |= programid(hasRoundRectClip) << PROGRAM_HAS_ROUND_RECT_CLIP; + key |= programid(hasGammaCorrection) << PROGRAM_HAS_GAMMA_CORRECTION; + key |= programid(hasLinearTexture) << PROGRAM_HAS_LINEAR_TEXTURE; + key |= programid(hasColorSpaceConversion) << PROGRAM_HAS_COLOR_SPACE_CONVERSION; + key |= programid(transferFunction) << PROGRAM_TRANSFER_FUNCTION; + key |= programid(hasTranslucentConversion) << PROGRAM_HAS_TRANSLUCENT_CONVERSION; return key; } diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp index 38c23e4babe8..1f78e09b5a58 100644 --- a/libs/hwui/ProgramCache.cpp +++ b/libs/hwui/ProgramCache.cpp @@ -161,17 +161,61 @@ const char* gFS_Uniforms_HasRoundRectClip = "uniform vec4 roundRectInnerRectLTRB;\n" "uniform float roundRectRadius;\n"; +const char* gFS_Uniforms_ColorSpaceConversion = + // TODO: Should we use a 3D LUT to combine the matrix and transfer functions? + // 32x32x32 fp16 LUTs (for scRGB output) are large and heavy to generate... + "uniform mat3 colorSpaceMatrix;\n"; + +const char* gFS_Uniforms_TransferFunction[4] = { + // In this order: g, a, b, c, d, e, f + // See ColorSpace::TransferParameters + // We'll use hardware sRGB conversion as much as possible + "", + "uniform float transferFunction[7];\n", + "uniform float transferFunction[5];\n", + "uniform float transferFunctionGamma;\n" +}; + const char* gFS_OETF[2] = { - "\nvec4 OETF(const vec4 linear) {\n" - " return linear;\n" - "}\n", - // We expect linear data to be scRGB so we mirror the gamma function - "\nvec4 OETF(const vec4 linear) {" - " return vec4(sign(linear.rgb) * OETF_sRGB(abs(linear.rgb)), linear.a);\n" - "}\n", + R"__SHADER__( + vec4 OETF(const vec4 linear) { + return linear; + } + )__SHADER__", + // We expect linear data to be scRGB so we mirror the gamma function + R"__SHADER__( + vec4 OETF(const vec4 linear) { + return vec4(sign(linear.rgb) * OETF_sRGB(abs(linear.rgb)), linear.a); + } + )__SHADER__" +}; + +const char* gFS_ColorConvert[3] = { + // Just OETF + R"__SHADER__( + vec4 colorConvert(const vec4 color) { + return OETF(color); + } + )__SHADER__", + // Full color conversion for opaque bitmaps + R"__SHADER__( + vec4 colorConvert(const vec4 color) { + return OETF(vec4(colorSpaceMatrix * EOTF_Parametric(color.rgb), color.a)); + } + )__SHADER__", + // Full color conversion for translucent bitmaps + // Note: 0.5/256=0.0019 + R"__SHADER__( + vec4 colorConvert(in vec4 color) { + color.rgb /= color.a + 0.0019; + color = OETF(vec4(colorSpaceMatrix * EOTF_Parametric(color.rgb), color.a)); + color.rgb *= color.a + 0.0019; + return color; + } + )__SHADER__", }; -const char* gFS_Transfer_Functions = R"__SHADER__( +const char* gFS_sRGB_TransferFunctions = R"__SHADER__( float OETF_sRGB(const float linear) { // IEC 61966-2-1:1999 return linear <= 0.0031308 ? linear * 12.92 : (pow(linear, 1.0 / 2.4) * 1.055) - 0.055; @@ -187,12 +231,56 @@ const char* gFS_Transfer_Functions = R"__SHADER__( } )__SHADER__"; +const char* gFS_TransferFunction[4] = { + // Conversion done by the texture unit (sRGB) + R"__SHADER__( + vec3 EOTF_Parametric(const vec3 x) { + return x; + } + )__SHADER__", + // Full transfer function + // TODO: We should probably use a 1D LUT (256x1 with texelFetch() since input is 8 bit) + // TODO: That would cause 3 dependent texture fetches. Is it worth it? + R"__SHADER__( + float EOTF_Parametric(float x) { + return x <= transferFunction[4] + ? transferFunction[3] * x + transferFunction[6] + : pow(transferFunction[1] * x + transferFunction[2], transferFunction[0]) + + transferFunction[5]; + } + + vec3 EOTF_Parametric(const vec3 x) { + return vec3(EOTF_Parametric(x.r), EOTF_Parametric(x.g), EOTF_Parametric(x.b)); + } + )__SHADER__", + // Limited transfer function, e = f = 0.0 + R"__SHADER__( + float EOTF_Parametric(float x) { + return x <= transferFunction[4] + ? transferFunction[3] * x + : pow(transferFunction[1] * x + transferFunction[2], transferFunction[0]); + } + + vec3 EOTF_Parametric(const vec3 x) { + return vec3(EOTF_Parametric(x.r), EOTF_Parametric(x.g), EOTF_Parametric(x.b)); + } + )__SHADER__", + // Gamma transfer function, e = f = 0.0 + R"__SHADER__( + vec3 EOTF_Parametric(const vec3 x) { + return vec3(pow(x.r, transferFunctionGamma), + pow(x.g, transferFunctionGamma), + pow(x.b, transferFunctionGamma)); + } + )__SHADER__" +}; + // Dithering must be done in the quantization space // When we are writing to an sRGB framebuffer, we must do the following: // EOTF(OETF(color) + dither) // The dithering pattern is generated with a triangle noise generator in the range [-1.0,1.0] // TODO: Handle linear fp16 render targets -const char* gFS_Gradient_Functions = R"__SHADER__( +const char* gFS_GradientFunctions = R"__SHADER__( float triangleNoise(const highp vec2 n) { highp vec2 p = fract(n * vec2(5.3987, 5.4421)); p += dot(p.yx, p.xy + vec2(21.5351, 14.3137)); @@ -200,7 +288,8 @@ const char* gFS_Gradient_Functions = R"__SHADER__( return fract(xy * 95.4307) + fract(xy * 75.04961) - 1.0; } )__SHADER__"; -const char* gFS_Gradient_Preamble[2] = { + +const char* gFS_GradientPreamble[2] = { // Linear framebuffer R"__SHADER__( vec4 dither(const vec4 color) { @@ -259,9 +348,9 @@ const char* gFS_Main_ApplyVertexAlphaShadowInterp = " fragColor *= texture2D(baseSampler, vec2(alpha, 0.5)).a;\n"; const char* gFS_Main_FetchTexture[2] = { // Don't modulate - " fragColor = OETF(texture2D(baseSampler, outTexCoords));\n", + " fragColor = colorConvert(texture2D(baseSampler, outTexCoords));\n", // Modulate - " fragColor = color * texture2D(baseSampler, outTexCoords);\n" + " fragColor = color * colorConvert(texture2D(baseSampler, outTexCoords));\n" }; const char* gFS_Main_FetchA8Texture[4] = { // Don't modulate @@ -290,9 +379,9 @@ const char* gFS_Main_FetchGradient[6] = { " vec4 gradientColor = gradientMix(startColor, endColor, clamp(index - floor(index), 0.0, 1.0));\n" }; const char* gFS_Main_FetchBitmap = - " vec4 bitmapColor = OETF(texture2D(bitmapSampler, outBitmapTexCoords));\n"; + " vec4 bitmapColor = colorConvert(texture2D(bitmapSampler, outBitmapTexCoords));\n"; const char* gFS_Main_FetchBitmapNpot = - " vec4 bitmapColor = OETF(texture2D(bitmapSampler, wrap(outBitmapTexCoords)));\n"; + " vec4 bitmapColor = colorConvert(texture2D(bitmapSampler, wrap(outBitmapTexCoords)));\n"; const char* gFS_Main_BlendShadersBG = " fragColor = blendShaders(gradientColor, bitmapColor)"; const char* gFS_Main_BlendShadersGB = @@ -627,6 +716,11 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti } shader.append(gFS_Uniforms_ColorOp[static_cast<int>(description.colorOp)]); + if (description.hasColorSpaceConversion) { + shader.append(gFS_Uniforms_ColorSpaceConversion); + } + shader.append(gFS_Uniforms_TransferFunction[static_cast<int>(description.transferFunction)]); + // Generate required functions if (description.hasGradient && description.hasBitmap) { generateBlend(shader, "blendShaders", description.shadersMode); @@ -640,16 +734,21 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti if (description.useShaderBasedWrap) { generateTextureWrap(shader, description.bitmapWrapS, description.bitmapWrapT); } - if (description.hasGradient || description.hasLinearTexture) { - shader.append(gFS_Transfer_Functions); + if (description.hasGradient || description.hasLinearTexture + || description.hasColorSpaceConversion) { + shader.append(gFS_sRGB_TransferFunctions); } if (description.hasBitmap || ((description.hasTexture || description.hasExternalTexture) && !description.hasAlpha8Texture)) { - shader.append(gFS_OETF[description.hasLinearTexture && !mHasLinearBlending]); + shader.append(gFS_TransferFunction[static_cast<int>(description.transferFunction)]); + shader.append(gFS_OETF[(description.hasLinearTexture || description.hasColorSpaceConversion) + && !mHasLinearBlending]); + shader.append(gFS_ColorConvert[description.hasColorSpaceConversion + ? 1 + description.hasTranslucentConversion : 0]); } if (description.hasGradient) { - shader.append(gFS_Gradient_Functions); - shader.append(gFS_Gradient_Preamble[mHasLinearBlending]); + shader.append(gFS_GradientFunctions); + shader.append(gFS_GradientPreamble[mHasLinearBlending]); } // Begin the shader diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp index 4f7f9d7f9b9a..8a504d4431c4 100644 --- a/libs/hwui/SkiaShader.cpp +++ b/libs/hwui/SkiaShader.cpp @@ -216,8 +216,13 @@ bool tryStoreBitmap(Caches& caches, const SkShader& shader, const Matrix4& model const float width = outData->bitmapTexture->width(); const float height = outData->bitmapTexture->height(); + Texture* texture = outData->bitmapTexture; + description->hasBitmap = true; - description->hasLinearTexture = outData->bitmapTexture->isLinear(); + description->hasLinearTexture = texture->isLinear(); + description->hasColorSpaceConversion = texture->hasColorSpaceConversion(); + description->transferFunction = texture->getTransferFunctionType(); + description->hasTranslucentConversion = texture->blend; description->isShaderBitmapExternal = hwuiBitmap->isHardware(); // gralloc doesn't support non-clamp modes if (hwuiBitmap->isHardware() || (!caches.extensions().hasNPot() diff --git a/libs/hwui/Texture.cpp b/libs/hwui/Texture.cpp index cfc2744e61b2..8b71086e1625 100644 --- a/libs/hwui/Texture.cpp +++ b/libs/hwui/Texture.cpp @@ -17,10 +17,13 @@ #include "Caches.h" #include "Texture.h" #include "utils/GLUtils.h" +#include "utils/MathUtils.h" #include "utils/TraceUtils.h" #include <utils/Log.h> +#include <math/mat4.h> + #include <SkCanvas.h> namespace android { @@ -48,12 +51,7 @@ static int bytesPerPixel(GLint glFormat) { } } -bool Texture::isLinear() const { - return mInternalFormat == GL_RGBA16F; -} - void Texture::setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture, bool force) { - if (force || wrapS != mWrapS || wrapT != mWrapT) { mWrapS = wrapS; mWrapT = wrapT; @@ -94,7 +92,7 @@ void Texture::deleteTexture() { } } -bool Texture::updateSize(uint32_t width, uint32_t height, GLint internalFormat, +bool Texture::updateLayout(uint32_t width, uint32_t height, GLint internalFormat, GLint format, GLenum target) { if (mWidth == width && mHeight == height @@ -122,7 +120,7 @@ void Texture::resetCachedParams() { void Texture::upload(GLint internalFormat, uint32_t width, uint32_t height, GLenum format, GLenum type, const void* pixels) { GL_CHECKPOINT(MODERATE); - bool needsAlloc = updateSize(width, height, internalFormat, format, GL_TEXTURE_2D); + bool needsAlloc = updateLayout(width, height, internalFormat, format, GL_TEXTURE_2D); if (!mId) { glGenTextures(1, &mId); needsAlloc = true; @@ -224,7 +222,6 @@ void Texture::colorTypeToGlFormatAndType(const Caches& caches, SkColorType color *outType = GL_UNSIGNED_BYTE; break; case kGray_8_SkColorType: - // TODO: Handle sRGB *outFormat = GL_LUMINANCE; *outInternalFormat = GL_LUMINANCE; *outType = GL_UNSIGNED_BYTE; @@ -252,15 +249,14 @@ SkBitmap Texture::uploadToN32(const SkBitmap& bitmap, bool hasLinearBlending, return rgbaBitmap; } -bool Texture::hasUnsupportedColorType(const SkImageInfo& info, bool hasLinearBlending, - SkColorSpace* sRGB) { - bool needSRGB = info.colorSpace() == sRGB; +bool Texture::hasUnsupportedColorType(const SkImageInfo& info, bool hasLinearBlending) { return info.colorType() == kARGB_4444_SkColorType || info.colorType() == kIndex_8_SkColorType - || (info.colorType() == kRGB_565_SkColorType && hasLinearBlending && needSRGB); + || (info.colorType() == kRGB_565_SkColorType + && hasLinearBlending + && info.colorSpace()->isSRGB()); } - void Texture::upload(Bitmap& bitmap) { if (!bitmap.readyToDraw()) { ALOGE("Cannot generate texture from bitmap"); @@ -284,23 +280,59 @@ void Texture::upload(Bitmap& bitmap) { setDefaultParams = true; } - sk_sp<SkColorSpace> sRGB = SkColorSpace::MakeSRGB(); - bool needSRGB = bitmap.info().colorSpace() == sRGB.get(); + bool hasLinearBlending = mCaches.extensions().hasLinearBlending(); + bool needSRGB = transferFunctionCloseToSRGB(bitmap.info().colorSpace()); GLint internalFormat, format, type; - colorTypeToGlFormatAndType(mCaches, bitmap.colorType(), needSRGB, &internalFormat, &format, &type); + colorTypeToGlFormatAndType(mCaches, bitmap.colorType(), + needSRGB && hasLinearBlending, &internalFormat, &format, &type); + + mConnector.reset(); + + // RGBA16F is always extended sRGB, alpha masks don't have color profiles + if (internalFormat != GL_RGBA16F && internalFormat != GL_ALPHA) { + SkColorSpace* colorSpace = bitmap.info().colorSpace(); + // If the bitmap is sRGB we don't need conversion + if (colorSpace != nullptr && !colorSpace->isSRGB()) { + SkMatrix44 xyzMatrix(SkMatrix44::kUninitialized_Constructor); + if (!colorSpace->toXYZD50(&xyzMatrix)) { + ALOGW("Incompatible color space!"); + } else { + SkColorSpaceTransferFn fn; + if (!colorSpace->isNumericalTransferFn(&fn)) { + ALOGW("Incompatible color space, no numerical transfer function!"); + } else { + float data[16]; + xyzMatrix.asColMajorf(data); + + ColorSpace::TransferParameters p = + {fn.fG, fn.fA, fn.fB, fn.fC, fn.fD, fn.fE, fn.fF}; + ColorSpace src("Unnamed", mat4f((const float*) &data[0]).upperLeft(), p); + mConnector.reset(new ColorSpaceConnector(src, ColorSpace::sRGB())); + + // A non-sRGB color space might have a transfer function close enough to sRGB + // that we can save shader instructions by using an sRGB sampler + // This is only possible if we have hardware support for sRGB textures + if (needSRGB && internalFormat == GL_RGBA + && mCaches.extensions().hasSRGB() && !bitmap.isHardware()) { + internalFormat = GL_SRGB8_ALPHA8; + } + } + } + } + } GLenum target = bitmap.isHardware() ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D; - needsAlloc |= updateSize(bitmap.width(), bitmap.height(), internalFormat, format, target); + needsAlloc |= updateLayout(bitmap.width(), bitmap.height(), internalFormat, format, target); blend = !bitmap.isOpaque(); mCaches.textureState().bindTexture(mTarget, mId); // TODO: Handle sRGB gray bitmaps - bool hasLinearBlending = mCaches.extensions().hasLinearBlending(); - if (CC_UNLIKELY(hasUnsupportedColorType(bitmap.info(), hasLinearBlending, sRGB.get()))) { + if (CC_UNLIKELY(hasUnsupportedColorType(bitmap.info(), hasLinearBlending))) { SkBitmap skBitmap; bitmap.getSkBitmap(&skBitmap); + sk_sp<SkColorSpace> sRGB = SkColorSpace::MakeSRGB(); SkBitmap rgbaBitmap = uploadToN32(skBitmap, hasLinearBlending, std::move(sRGB)); uploadToTexture(needsAlloc, internalFormat, format, type, rgbaBitmap.rowBytesAsPixels(), rgbaBitmap.bytesPerPixel(), rgbaBitmap.width(), @@ -333,9 +365,28 @@ void Texture::wrap(GLuint id, uint32_t width, uint32_t height, mFormat = format; mInternalFormat = internalFormat; mTarget = target; + mConnector.reset(); // We're wrapping an existing texture, so don't double count this memory notifySizeChanged(0); } +TransferFunctionType Texture::getTransferFunctionType() const { + if (mConnector.get() != nullptr && mInternalFormat != GL_SRGB8_ALPHA8) { + const ColorSpace::TransferParameters& p = mConnector->getSource().getTransferParameters(); + if (MathUtils::isZero(p.e) && MathUtils::isZero(p.f)) { + if (MathUtils::areEqual(p.a, 1.0f) && MathUtils::isZero(p.b) + && MathUtils::isZero(p.c) && MathUtils::isZero(p.d)) { + if (MathUtils::areEqual(p.g, 1.0f)) { + return TransferFunctionType::None; + } + return TransferFunctionType::Gamma; + } + return TransferFunctionType::Limited; + } + return TransferFunctionType::Full; + } + return TransferFunctionType::None; +} + }; // namespace uirenderer }; // namespace android diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h index e7fbf20cd898..052c01890317 100644 --- a/libs/hwui/Texture.h +++ b/libs/hwui/Texture.h @@ -19,6 +19,13 @@ #include "GpuMemoryTracker.h" #include "hwui/Bitmap.h" +#include "utils/Color.h" + +#include <memory> + +#include <math/mat3.h> + +#include <ui/ColorSpace.h> #include <GLES2/gl2.h> #include <EGL/egl.h> @@ -42,8 +49,7 @@ class Texture : public GpuMemoryTracker { public: static SkBitmap uploadToN32(const SkBitmap& bitmap, bool hasLinearBlending, sk_sp<SkColorSpace> sRGB); - static bool hasUnsupportedColorType(const SkImageInfo& info, - bool hasLinearBlending, SkColorSpace* sRGB); + static bool hasUnsupportedColorType(const SkImageInfo& info, bool hasLinearBlending); static void colorTypeToGlFormatAndType(const Caches& caches, SkColorType colorType, bool needSRGB, GLint* outInternalFormat, GLint* outFormat, GLint* outType); @@ -130,9 +136,26 @@ public: } /** + * Returns nullptr if this texture does not require color space conversion + * to sRGB, or a valid pointer to a ColorSpaceConnector if a conversion + * is required. + */ + constexpr const ColorSpaceConnector* getColorSpaceConnector() const { + return mConnector.get(); + } + + constexpr bool hasColorSpaceConversion() const { + return mConnector.get() != nullptr; + } + + TransferFunctionType getTransferFunctionType() const; + + /** * Returns true if this texture uses a linear encoding format. */ - bool isLinear() const; + constexpr bool isLinear() const { + return mInternalFormat == GL_RGBA16F; + } /** * Generation of the backing bitmap, @@ -171,8 +194,8 @@ private: // and external texture wrapper friend class GlLayer; - // Returns true if the size changed, false if it was the same - bool updateSize(uint32_t width, uint32_t height, GLint internalFormat, + // Returns true if the texture layout (size, format, etc.) changed, false if it was the same + bool updateLayout(uint32_t width, uint32_t height, GLint internalFormat, GLint format, GLenum target); void uploadHardwareBitmapToTexture(GraphicBuffer* buffer); void resetCachedParams(); @@ -196,6 +219,8 @@ private: GLenum mMagFilter = GL_LINEAR; Caches& mCaches; + + std::unique_ptr<ColorSpaceConnector> mConnector; }; // struct Texture class AutoTexture { diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp index 8823a9212958..f6b2912a6254 100644 --- a/libs/hwui/VectorDrawable.cpp +++ b/libs/hwui/VectorDrawable.cpp @@ -491,6 +491,36 @@ Bitmap& Tree::getBitmapUpdateIfDirty() { return *mCache.bitmap; } +void Tree::updateCache(sk_sp<SkSurface> surface) { + if (surface.get()) { + mCache.surface = surface; + } + if (surface.get() || mCache.dirty) { + SkSurface* vdSurface = mCache.surface.get(); + SkCanvas* canvas = vdSurface->getCanvas(); + float scaleX = vdSurface->width() / mProperties.getViewportWidth(); + float scaleY = vdSurface->height() / mProperties.getViewportHeight(); + SkAutoCanvasRestore acr(canvas, true); + canvas->clear(SK_ColorTRANSPARENT); + canvas->scale(scaleX, scaleY); + mRootNode->draw(canvas, false); + mCache.dirty = false; + canvas->flush(); + } +} + +void Tree::draw(SkCanvas* canvas) { + /* + * TODO address the following... + * + * 1) figure out how to set path's as volatile during animation + * 2) if mRoot->getPaint() != null either promote to layer (during + * animation) or cache in SkSurface (for static content) + */ + canvas->drawImageRect(mCache.surface->makeImageSnapshot().get(), + mutateProperties()->getBounds(), getPaint()); +} + void Tree::updateBitmapCache(Bitmap& bitmap, bool useStagingData) { SkBitmap outCache; bitmap.getSkBitmap(&outCache); diff --git a/libs/hwui/VectorDrawable.h b/libs/hwui/VectorDrawable.h index 729a4dd4ba76..22cfe29d2aa5 100644 --- a/libs/hwui/VectorDrawable.h +++ b/libs/hwui/VectorDrawable.h @@ -31,6 +31,7 @@ #include <SkPathMeasure.h> #include <SkRect.h> #include <SkShader.h> +#include <SkSurface.h> #include <cutils/compiler.h> #include <stddef.h> @@ -677,15 +678,37 @@ public: // This should only be called from animations on RT TreeProperties* mutateProperties() { return &mProperties; } + // called from RT only + const TreeProperties& properties() const { return mProperties; } + // This should always be called from RT. void markDirty() { mCache.dirty = true; } bool isDirty() const { return mCache.dirty; } bool getPropertyChangeWillBeConsumed() const { return mWillBeConsumed; } void setPropertyChangeWillBeConsumed(bool willBeConsumed) { mWillBeConsumed = willBeConsumed; } + // Returns true if VD cache surface is big enough. This should always be called from RT and it + // works with Skia pipelines only. + bool canReuseSurface() { + SkSurface* surface = mCache.surface.get(); + return surface && surface->width() >= mProperties.getScaledWidth() + && surface->height() >= mProperties.getScaledHeight(); + } + + // Draws VD cache into a canvas. This should always be called from RT and it works with Skia + // pipelines only. + void draw(SkCanvas* canvas); + + // Draws VD into a GPU backed surface. If canReuseSurface returns false, then "surface" must + // contain a new surface. This should always be called from RT and it works with Skia pipelines + // only. + void updateCache(sk_sp<SkSurface> surface); + private: struct Cache { - sk_sp<Bitmap> bitmap; + sk_sp<Bitmap> bitmap; //used by HWUI pipeline and software + //TODO: use surface instead of bitmap when drawing in software canvas + sk_sp<SkSurface> surface; //used only by Skia pipelines bool dirty = true; }; diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp index 72a9f4e34a2e..eed5b242c1d2 100644 --- a/libs/hwui/hwui/Bitmap.cpp +++ b/libs/hwui/hwui/Bitmap.cpp @@ -19,6 +19,7 @@ #include "renderthread/EglManager.h" #include "renderthread/RenderThread.h" #include "renderthread/RenderProxy.h" +#include "utils/Color.h" #include <sys/mman.h> @@ -223,8 +224,7 @@ sk_sp<Bitmap> Bitmap::allocateHardwareBitmap(uirenderer::renderthread::RenderThr return nullptr; } - sk_sp<SkColorSpace> sRGB = SkColorSpace::MakeSRGB(); - bool needSRGB = skBitmap.info().colorSpace() == sRGB.get(); + bool needSRGB = uirenderer::transferFunctionCloseToSRGB(skBitmap.info().colorSpace()); bool hasLinearBlending = caches.extensions().hasLinearBlending(); GLint format, type, internalFormat; uirenderer::Texture::colorTypeToGlFormatAndType(caches, skBitmap.colorType(), @@ -245,7 +245,8 @@ sk_sp<Bitmap> Bitmap::allocateHardwareBitmap(uirenderer::renderthread::RenderThr SkBitmap bitmap; if (CC_UNLIKELY(uirenderer::Texture::hasUnsupportedColorType(skBitmap.info(), - hasLinearBlending, sRGB.get()))) { + hasLinearBlending))) { + sk_sp<SkColorSpace> sRGB = SkColorSpace::MakeSRGB(); bitmap = uirenderer::Texture::uploadToN32(skBitmap, hasLinearBlending, std::move(sRGB)); } else { bitmap = skBitmap; diff --git a/libs/hwui/hwui_static_deps.mk b/libs/hwui/hwui_static_deps.mk index 8826cfcc3100..7f06421b02a0 100644 --- a/libs/hwui/hwui_static_deps.mk +++ b/libs/hwui/hwui_static_deps.mk @@ -27,7 +27,5 @@ LOCAL_SHARED_LIBRARIES += \ libft2 \ libminikin \ libandroidfw \ - libRScpp - -LOCAL_STATIC_LIBRARIES += \ + libRScpp \ libplatformprotos diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp index 496f7babd3cc..3ddc09fbeca1 100644 --- a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp +++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp @@ -19,6 +19,7 @@ #include "renderthread/CanvasContext.h" #include "VectorDrawable.h" #include "DumpOpsCanvas.h" +#include "SkiaPipeline.h" #include <SkImagePriv.h> @@ -92,6 +93,8 @@ bool SkiaDisplayList::prepareListAndChildren(TreeObserver& observer, TreeInfo& i // If any vector drawable in the display list needs update, damage the node. if (vectorDrawable->isDirty()) { isDirty = true; + static_cast<SkiaPipeline*>(info.canvasContext.getRenderPipeline()) + ->getVectorDrawables()->push_back(vectorDrawable); } vectorDrawable->setPropertyChangeWillBeConsumed(true); } diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.h b/libs/hwui/pipeline/skia/SkiaDisplayList.h index 6ee5922f9cd6..66375d13826c 100644 --- a/libs/hwui/pipeline/skia/SkiaDisplayList.h +++ b/libs/hwui/pipeline/skia/SkiaDisplayList.h @@ -60,7 +60,7 @@ public: * Use the linear allocator to create any SkDrawables needed by the display * list. This could be dangerous as these objects are ref-counted, so we * need to monitor that they don't extend beyond the lifetime of the class - * that creates them. + * that creates them. Allocator dtor invokes all SkDrawable dtors. */ template<class T, typename... Params> SkDrawable* allocateDrawable(Params&&... params) { diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp index 10c1865ac50c..75f1adc7755c 100644 --- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp @@ -25,6 +25,7 @@ #include <SkPictureRecorder.h> #include <SkPixelSerializer.h> #include <SkStream.h> +#include "VectorDrawable.h" #include <unistd.h> @@ -40,7 +41,9 @@ uint8_t SkiaPipeline::mSpotShadowAlpha = 0; Vector3 SkiaPipeline::mLightCenter = {FLT_MIN, FLT_MIN, FLT_MIN}; -SkiaPipeline::SkiaPipeline(RenderThread& thread) : mRenderThread(thread) { } +SkiaPipeline::SkiaPipeline(RenderThread& thread) : mRenderThread(thread) { + mVectorDrawables.reserve(30); +} TaskManager* SkiaPipeline::getTaskManager() { return &mTaskManager; @@ -74,6 +77,7 @@ void SkiaPipeline::renderLayers(const FrameBuilder::LightGeometry& lightGeometry const BakedOpRenderer::LightInfo& lightInfo) { updateLighting(lightGeometry, lightInfo); ATRACE_NAME("draw layers"); + renderVectorDrawableCache(); renderLayersImpl(*layerUpdateQueue, opaque); layerUpdateQueue->clear(); } @@ -176,10 +180,35 @@ public: } }; +void SkiaPipeline::renderVectorDrawableCache() { + //render VectorDrawables into offscreen buffers + for (auto vd : mVectorDrawables) { + sk_sp<SkSurface> surface; + if (!vd->canReuseSurface()) { +#ifndef ANDROID_ENABLE_LINEAR_BLENDING + sk_sp<SkColorSpace> colorSpace = nullptr; +#else + sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeSRGB(); +#endif + int scaledWidth = SkScalarCeilToInt(vd->properties().getScaledWidth()); + int scaledHeight = SkScalarCeilToInt(vd->properties().getScaledHeight()); + SkImageInfo info = SkImageInfo::MakeN32(scaledWidth, scaledHeight, + kPremul_SkAlphaType, colorSpace); + SkASSERT(mRenderThread.getGrContext() != nullptr); + surface = SkSurface::MakeRenderTarget(mRenderThread.getGrContext(), SkBudgeted::kYes, + info); + } + vd->updateCache(surface); + } + mVectorDrawables.clear(); +} + void SkiaPipeline::renderFrame(const LayerUpdateQueue& layers, const SkRect& clip, const std::vector<sp<RenderNode>>& nodes, bool opaque, const Rect &contentDrawBounds, sk_sp<SkSurface> surface) { + renderVectorDrawableCache(); + // draw all layers up front renderLayersImpl(layers, opaque); diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h index c58fedf834ff..6f5e719fc2c2 100644 --- a/libs/hwui/pipeline/skia/SkiaPipeline.h +++ b/libs/hwui/pipeline/skia/SkiaPipeline.h @@ -49,6 +49,8 @@ public: const std::vector< sp<RenderNode> >& nodes, bool opaque, const Rect &contentDrawBounds, sk_sp<SkSurface> surface); + std::vector<VectorDrawableRoot*>* getVectorDrawables() { return &mVectorDrawables; } + static void destroyLayer(RenderNode* node); static void prepareToDraw(const renderthread::RenderThread& thread, Bitmap* bitmap); @@ -119,8 +121,18 @@ private: const std::vector< sp<RenderNode> >& nodes, const Rect &contentDrawBounds, sk_sp<SkSurface>); + /** + * Render mVectorDrawables into offscreen buffers. + */ + void renderVectorDrawableCache(); + TaskManager mTaskManager; std::vector<sk_sp<SkImage>> mPinnedImages; + + /** + * populated by prepareTree with dirty VDs + */ + std::vector<VectorDrawableRoot*> mVectorDrawables; static float mLightRadius; static uint8_t mAmbientShadowAlpha; static uint8_t mSpotShadowAlpha; diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp index 559d268b71f7..b3173f2e1974 100644 --- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp +++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp @@ -62,6 +62,7 @@ void SkiaRecordingCanvas::drawRoundRect(uirenderer::CanvasPropertyPrimitive* lef uirenderer::CanvasPropertyPrimitive* top, uirenderer::CanvasPropertyPrimitive* right, uirenderer::CanvasPropertyPrimitive* bottom, uirenderer::CanvasPropertyPrimitive* rx, uirenderer::CanvasPropertyPrimitive* ry, uirenderer::CanvasPropertyPaint* paint) { + // Destructor of drawables created with allocateDrawable, will be invoked by ~LinearAllocator. drawDrawable(mDisplayList->allocateDrawable<AnimatedRoundRect>(left, top, right, bottom, rx, ry, paint)); } @@ -92,13 +93,14 @@ void SkiaRecordingCanvas::insertReorderBarrier(bool enableReorder) { void SkiaRecordingCanvas::drawLayer(uirenderer::DeferredLayerUpdater* layerUpdater) { if (layerUpdater != nullptr && layerUpdater->backingLayer() != nullptr) { uirenderer::Layer* layer = layerUpdater->backingLayer(); + // Create a ref-counted drawable, which is kept alive by sk_sp in SkLiteDL. sk_sp<SkDrawable> drawable(new LayerDrawable(layer)); drawDrawable(drawable.get()); } } void SkiaRecordingCanvas::drawRenderNode(uirenderer::RenderNode* renderNode) { - // record the child node + // Record the child node. Drawable dtor will be invoked when mChildNodes deque is cleared. mDisplayList->mChildNodes.emplace_back(renderNode, asSkCanvas(), true, mCurrentBarrier); auto& renderNodeDrawable = mDisplayList->mChildNodes.back(); drawDrawable(&renderNodeDrawable); @@ -113,6 +115,7 @@ void SkiaRecordingCanvas::drawRenderNode(uirenderer::RenderNode* renderNode) { void SkiaRecordingCanvas::callDrawGLFunction(Functor* functor, uirenderer::GlFunctorLifecycleListener* listener) { + // Drawable dtor will be invoked when mChildFunctors deque is cleared. mDisplayList->mChildFunctors.emplace_back(functor, listener, asSkCanvas()); drawDrawable(&mDisplayList->mChildFunctors.back()); } @@ -126,22 +129,7 @@ class VectorDrawable : public SkDrawable { return SkRect::MakeLargest(); } virtual void onDraw(SkCanvas* canvas) override { - Bitmap& hwuiBitmap = mRoot->getBitmapUpdateIfDirty(); - SkBitmap bitmap; - hwuiBitmap.getSkBitmap(&bitmap); - SkPaint* paint = mRoot->getPaint(); - canvas->drawBitmapRect(bitmap, mRoot->mutateProperties()->getBounds(), paint); - /* - * TODO we can draw this directly but need to address the following... - * - * 1) Add drawDirect(SkCanvas*) to VectorDrawableRoot - * 2) fix VectorDrawable.cpp's Path::draw to not make a temporary path - * so that we don't break caching - * 3) figure out how to set path's as volatile during animation - * 4) if mRoot->getPaint() != null either promote to layer (during - * animation) or cache in SkSurface (for static content) - * - */ + mRoot->draw(canvas); } private: diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp index 8bce990129de..c8833d2a7489 100644 --- a/libs/hwui/renderstate/RenderState.cpp +++ b/libs/hwui/renderstate/RenderState.cpp @@ -22,8 +22,11 @@ #include "renderthread/CanvasContext.h" #include "renderthread/EglManager.h" #include "utils/GLUtils.h" + #include <algorithm> +#include <ui/ColorSpace.h> + namespace android { namespace uirenderer { @@ -359,6 +362,40 @@ void RenderState::render(const Glop& glop, const Matrix4& orthoMatrix) { fill.skiaShaderData.bitmapData.bitmapTexture : nullptr; const AutoTexture autoCleanup(texture); + // If we have a shader and a base texture, the base texture is assumed to be an alpha mask + // which means the color space conversion applies to the shader's bitmap + Texture* colorSpaceTexture = texture != nullptr ? texture : fill.texture.texture; + if (colorSpaceTexture != nullptr) { + if (colorSpaceTexture->hasColorSpaceConversion()) { + const ColorSpaceConnector* connector = colorSpaceTexture->getColorSpaceConnector(); + glUniformMatrix3fv(fill.program->getUniform("colorSpaceMatrix"), 1, + GL_FALSE, connector->getTransform().asArray()); + } + + TransferFunctionType transferFunction = colorSpaceTexture->getTransferFunctionType(); + if (transferFunction != TransferFunctionType::None) { + const ColorSpaceConnector* connector = colorSpaceTexture->getColorSpaceConnector(); + const ColorSpace& source = connector->getSource(); + + switch (transferFunction) { + case TransferFunctionType::None: + break; + case TransferFunctionType::Full: + glUniform1fv(fill.program->getUniform("transferFunction"), 7, + reinterpret_cast<const float*>(&source.getTransferParameters().g)); + break; + case TransferFunctionType::Limited: + glUniform1fv(fill.program->getUniform("transferFunction"), 5, + reinterpret_cast<const float*>(&source.getTransferParameters().g)); + break; + case TransferFunctionType::Gamma: + glUniform1f(fill.program->getUniform("transferFunctionGamma"), + source.getTransferParameters().g); + break; + } + } + } + // ------------------------------------ // ---------- GL state setup ---------- // ------------------------------------ diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index 738c09141a7a..33eda96a2d77 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -194,6 +194,8 @@ public: void waitOnFences(); + IRenderPipeline* getRenderPipeline() { return mRenderPipeline.get(); } + private: CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode, IContextFactory* contextFactory, std::unique_ptr<IRenderPipeline> renderPipeline); diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp index e32fd63e1125..1450ec98dabf 100644 --- a/libs/hwui/renderthread/RenderThread.cpp +++ b/libs/hwui/renderthread/RenderThread.cpp @@ -98,6 +98,7 @@ void TaskQueue::queue(RenderTask* task) { } void TaskQueue::queueAtFront(RenderTask* task) { + LOG_ALWAYS_FATAL_IF(task->mNext || mHead == task, "Task is already in the queue!"); if (mTail) { task->mNext = mHead; mHead = task; diff --git a/libs/hwui/tests/unit/SkiaBehaviorTests.cpp b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp index 7ae58a68a76c..e15f5d95fc51 100644 --- a/libs/hwui/tests/unit/SkiaBehaviorTests.cpp +++ b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp @@ -17,6 +17,7 @@ #include "tests/common/TestUtils.h" #include <gtest/gtest.h> +#include <SkBlurDrawLooper.h> #include <SkColorMatrixFilter.h> #include <SkColorSpace.h> #include <SkImagePriv.h> @@ -95,3 +96,16 @@ TEST(SkiaBehavior, srgbColorSpaceIsSingleton) { sk_sp<SkColorSpace> sRGB2 = SkColorSpace::MakeSRGB(); ASSERT_EQ(sRGB1.get(), sRGB2.get()); } + +TEST(SkiaBehavior, blurDrawLooper) { + sk_sp<SkDrawLooper> looper = SkBlurDrawLooper::Make(SK_ColorRED, 5.0f, 3.0f, 4.0f); + + SkDrawLooper::BlurShadowRec blur; + bool success = looper->asABlurShadow(&blur); + ASSERT_TRUE(success); + + ASSERT_EQ(SK_ColorRED, blur.fColor); + ASSERT_EQ(5.0f, blur.fSigma); + ASSERT_EQ(3.0f, blur.fOffset.fX); + ASSERT_EQ(4.0f, blur.fOffset.fY); +} diff --git a/libs/hwui/utils/Color.cpp b/libs/hwui/utils/Color.cpp new file mode 100644 index 000000000000..7d234b06b8ca --- /dev/null +++ b/libs/hwui/utils/Color.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2017 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. + */ + +#include "Color.h" + +#include <cmath> + +namespace android { +namespace uirenderer { + +static inline bool almostEqual(float a, float b) { + return std::abs(a - b) < 1e-2f; +} + +bool transferFunctionCloseToSRGB(const SkColorSpace* colorSpace) { + if (colorSpace == nullptr) return true; + if (colorSpace->isSRGB()) return true; + + SkColorSpaceTransferFn transferFunction; + if (colorSpace->isNumericalTransferFn(&transferFunction)) { + // sRGB transfer function params: + const float sRGBParamA = 1 / 1.055f; + const float sRGBParamB = 0.055f / 1.055f; + const float sRGBParamC = 1 / 12.92f; + const float sRGBParamD = 0.04045f; + const float sRGBParamE = 0.0f; + const float sRGBParamF = 0.0f; + const float sRGBParamG = 2.4f; + + // This comparison will catch Display P3 + return + almostEqual(sRGBParamA, transferFunction.fA) + && almostEqual(sRGBParamB, transferFunction.fB) + && almostEqual(sRGBParamC, transferFunction.fC) + && almostEqual(sRGBParamD, transferFunction.fD) + && almostEqual(sRGBParamE, transferFunction.fE) + && almostEqual(sRGBParamF, transferFunction.fF) + && almostEqual(sRGBParamG, transferFunction.fG); + } + + return false; +} + +}; // namespace uirenderer +}; // namespace android diff --git a/libs/hwui/utils/Color.h b/libs/hwui/utils/Color.h index 4a27ca2f327a..9c096601c826 100644 --- a/libs/hwui/utils/Color.h +++ b/libs/hwui/utils/Color.h @@ -19,6 +19,7 @@ #include <math.h> #include <SkColor.h> +#include <SkColorSpace.h> namespace android { namespace uirenderer { @@ -82,6 +83,13 @@ namespace uirenderer { }; static constexpr int BrightColorsCount = sizeof(BrightColors) / sizeof(Color::Color); + enum class TransferFunctionType : int8_t { + None = 0, + Full, + Limited, + Gamma + }; + // Opto-electronic conversion function for the sRGB color space // Takes a linear sRGB value and converts it to a gamma-encoded sRGB value static constexpr float OECF_sRGB(float linear) { @@ -118,6 +126,11 @@ namespace uirenderer { return srgb; #endif } + + // Returns whether the specified color space's transfer function can be + // approximated with the native sRGB transfer function. This method + // returns true for sRGB, gamma 2.2 and Display P3 for instance + bool transferFunctionCloseToSRGB(const SkColorSpace* colorSpace); } /* namespace uirenderer */ } /* namespace android */ diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java index ce58a9c4b91e..77a82ec8cacd 100644 --- a/media/java/android/media/AudioAttributes.java +++ b/media/java/android/media/AudioAttributes.java @@ -912,6 +912,8 @@ public final class AudioAttributes implements Parcelable { return USAGE_UNKNOWN; } } + + // TODO remove, replaced by non-static API getVolumeControlStream() /** * Returns the stream type matching the given attributes for volume control. * Use this method to derive the stream type needed to configure the volume @@ -925,6 +927,7 @@ public final class AudioAttributes implements Parcelable { * the attributes, or {@link AudioManager#USE_DEFAULT_STREAM_TYPE} if there isn't a direct * match. Note that <code>USE_DEFAULT_STREAM_TYPE</code> is not a valid value * for {@link AudioManager#setStreamVolume(int, int, int)}. + * @deprecated use {@link #getVolumeControlStream()} */ public static int getVolumeControlStream(@NonNull AudioAttributes aa) { if (aa == null) { @@ -934,6 +937,24 @@ public final class AudioAttributes implements Parcelable { } /** + * Returns the stream type matching this {@code AudioAttributes} instance for volume control. + * Use this method to derive the stream type needed to configure the volume + * control slider in an {@link android.app.Activity} with + * {@link android.app.Activity#setVolumeControlStream(int)} for playback conducted with these + * attributes. + * <BR>Do not use this method to set the stream type on an audio player object + * (e.g. {@link AudioTrack}, {@link MediaPlayer}) as this is deprecated, + * use {@code AudioAttributes} instead. + * @return a valid stream type for {@code Activity} or stream volume control that matches + * the attributes, or {@link AudioManager#USE_DEFAULT_STREAM_TYPE} if there isn't a direct + * match. Note that {@code USE_DEFAULT_STREAM_TYPE} is not a valid value + * for {@link AudioManager#setStreamVolume(int, int, int)}. + */ + public int getVolumeControlStream() { + return toVolumeStreamType(true /*fromGetVolumeControlStream*/, this); + } + + /** * @hide * Only use to get which stream type should be used for volume control, NOT for audio playback * (all audio playback APIs are supposed to take AudioAttributes as input parameters) diff --git a/media/java/android/media/AudioManagerInternal.java b/media/java/android/media/AudioManagerInternal.java index b60dbd572b93..0a1de33b845b 100644 --- a/media/java/android/media/AudioManagerInternal.java +++ b/media/java/android/media/AudioManagerInternal.java @@ -15,6 +15,7 @@ */ package android.media; +import android.util.IntArray; import com.android.server.LocalServices; /** @@ -43,6 +44,8 @@ public abstract class AudioManagerInternal { public abstract void updateRingerModeAffectedStreamsInternal(); + public abstract void setAccessibilityServiceUids(IntArray uids); + public interface RingerModeDelegate { /** Called when external ringer mode is evaluated, returns the new internal ringer mode */ int onSetRingerModeExternal(int ringerModeOld, int ringerModeNew, String caller, diff --git a/media/java/android/media/ImageUtils.java b/media/java/android/media/ImageUtils.java index abf6b203daaf..2a0e04ebf051 100644 --- a/media/java/android/media/ImageUtils.java +++ b/media/java/android/media/ImageUtils.java @@ -62,6 +62,7 @@ class ImageUtils { case ImageFormat.RAW12: case ImageFormat.DEPTH16: case ImageFormat.DEPTH_POINT_CLOUD: + case ImageFormat.RAW_DEPTH: return 1; case ImageFormat.PRIVATE: return 0; @@ -103,6 +104,10 @@ class ImageUtils { throw new IllegalArgumentException( "Copy of RAW_OPAQUE format has not been implemented"); } + if (src.getFormat() == ImageFormat.RAW_DEPTH) { + throw new IllegalArgumentException( + "Copy of RAW_DEPTH format has not been implemented"); + } if (!(dst.getOwner() instanceof ImageWriter)) { throw new IllegalArgumentException("Destination image is not from ImageWriter. Only" + " the images from ImageWriter are writable"); @@ -206,6 +211,7 @@ class ImageUtils { case PixelFormat.RGB_565: case ImageFormat.YUY2: case ImageFormat.Y16: + case ImageFormat.RAW_DEPTH: case ImageFormat.RAW_SENSOR: case ImageFormat.RAW_PRIVATE: // round estimate, real size is unknown case ImageFormat.DEPTH16: @@ -253,6 +259,7 @@ class ImageUtils { case ImageFormat.RAW_SENSOR: case ImageFormat.RAW10: case ImageFormat.RAW12: + case ImageFormat.RAW_DEPTH: return new Size(image.getWidth(), image.getHeight()); case ImageFormat.PRIVATE: return new Size(0, 0); diff --git a/media/java/android/media/MediaCas.java b/media/java/android/media/MediaCas.java index 2e22132614d2..611fdd1d997b 100644 --- a/media/java/android/media/MediaCas.java +++ b/media/java/android/media/MediaCas.java @@ -18,6 +18,7 @@ package android.media; import android.annotation.NonNull; import android.annotation.Nullable; +import android.media.MediaCasException.*; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; @@ -28,6 +29,7 @@ import android.os.Parcelable; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.ServiceSpecificException; import android.util.Log; import android.util.Singleton; @@ -84,8 +86,6 @@ import android.util.Singleton; * sessionId of the descrambler can be retrieved by {@link MediaExtractor#getDrmInitData} * and used to initialize a MediaDescrambler object for MediaCodec. * <p> - * TODO: determine exception handling schemes. - * <p> * <h3>Listeners</h3> * <p>The app may register a listener to receive events from the CA system using * method {@link #setEventListener}. The exact format of the event is scheme-specific @@ -382,28 +382,22 @@ public final class MediaCas { mEventHandler = new EventHandler(looper); } - /* - * TODO: handle ServiceSpecificException from the IMediaCas - * All Drm-specific failures will be thrown by mICas as - * ServiceSpecificException exception with Drm error code. - * These need to be re-thrown as crypto exceptions. - */ - /** * Send the private data for the CA system. * * @param data byte array of the private data. * * @throws IllegalStateException if the MediaCas instance is not valid. + * @throws MediaCasException for CAS-specific errors. + * @throws MediaCasStateException for CAS-specific state exceptions. */ - /* - * TODO: need to re-throw DRM-specific exceptions - */ - public void setPrivateData(@NonNull byte[] data) { + public void setPrivateData(@NonNull byte[] data) throws MediaCasException { validateInternalStates(); try { mICas.setPrivateData(data); + } catch (ServiceSpecificException e) { + MediaCasException.throwExceptions(e); } catch (RemoteException e) { cleanupAndRethrowIllegalState(); } @@ -416,14 +410,17 @@ public final class MediaCas { * * @return session id of the newly opened session. * - * @throws IllegalStateException if the MediaCas instance is not valid, - * or IllegalArgumentException if a session for the program already exists. + * @throws IllegalStateException if the MediaCas instance is not valid. + * @throws MediaCasException for CAS-specific errors. + * @throws MediaCasStateException for CAS-specific state exceptions. */ - public byte[] openSession(int programNumber) { + public byte[] openSession(int programNumber) throws MediaCasException { validateInternalStates(); try { return mICas.openSession(programNumber); + } catch (ServiceSpecificException e) { + MediaCasException.throwExceptions(e); } catch (RemoteException e) { cleanupAndRethrowIllegalState(); } @@ -438,14 +435,18 @@ public final class MediaCas { * * @return session id of the newly opened session. * - * @throws IllegalStateException if the MediaCas instance is not valid, - * or IllegalArgumentException if a session for the stream already exists. + * @throws IllegalStateException if the MediaCas instance is not valid. + * @throws MediaCasException for CAS-specific errors. + * @throws MediaCasStateException for CAS-specific state exceptions. */ - public byte[] openSession(int programNumber, int elementaryPID) { + public byte[] openSession(int programNumber, int elementaryPID) + throws MediaCasException { validateInternalStates(); try { return mICas.openSessionForStream(programNumber, elementaryPID); + } catch (ServiceSpecificException e) { + MediaCasException.throwExceptions(e); } catch (RemoteException e) { cleanupAndRethrowIllegalState(); } @@ -457,14 +458,16 @@ public final class MediaCas { * * @param sessionId the session to be closed. * - * @throws IllegalStateException if the MediaCas instance is not valid, - * or IllegalArgumentException if the session is not valid. + * @throws IllegalStateException if the MediaCas instance is not valid. + * @throws MediaCasStateException for CAS-specific state exceptions. */ public void closeSession(@NonNull byte[] sessionId) { validateInternalStates(); try { mICas.closeSession(sessionId); + } catch (ServiceSpecificException e) { + MediaCasStateException.throwExceptions(e); } catch (RemoteException e) { cleanupAndRethrowIllegalState(); } @@ -476,17 +479,18 @@ public final class MediaCas { * @param sessionId the session for which the private data is intended. * @param data byte array of the private data. * - * @throws IllegalStateException if the MediaCas instance is not valid, - * or IllegalArgumentException if the session is not valid. - */ - /* - * TODO: need to re-throw DRM-specific exceptions + * @throws IllegalStateException if the MediaCas instance is not valid. + * @throws MediaCasException for CAS-specific errors. + * @throws MediaCasStateException for CAS-specific state exceptions. */ - public void setSessionPrivateData(@NonNull byte[] sessionId, @NonNull byte[] data) { + public void setSessionPrivateData(@NonNull byte[] sessionId, @NonNull byte[] data) + throws MediaCasException { validateInternalStates(); try { mICas.setSessionPrivateData(sessionId, data); + } catch (ServiceSpecificException e) { + MediaCasException.throwExceptions(e); } catch (RemoteException e) { cleanupAndRethrowIllegalState(); } @@ -500,19 +504,19 @@ public final class MediaCas { * @param offset position within data where the ECM data begins. * @param length length of the data (starting from offset). * - * @throws IllegalStateException if the MediaCas instance is not valid, - * or IllegalArgumentException if the session is not valid. - */ - /* - * TODO: need to re-throw DRM-specific exceptions + * @throws IllegalStateException if the MediaCas instance is not valid. + * @throws MediaCasException for CAS-specific errors. + * @throws MediaCasStateException for CAS-specific state exceptions. */ - public void processEcm( - @NonNull byte[] sessionId, @NonNull byte[] data, int offset, int length) { + public void processEcm(@NonNull byte[] sessionId, @NonNull byte[] data, + int offset, int length) throws MediaCasException { validateInternalStates(); try { mCasData.set(data, offset, length); mICas.processEcm(sessionId, mCasData); + } catch (ServiceSpecificException e) { + MediaCasException.throwExceptions(e); } catch (RemoteException e) { cleanupAndRethrowIllegalState(); } @@ -526,13 +530,12 @@ public final class MediaCas { * @param sessionId the session for which the ECM is intended. * @param data byte array of the ECM data. * - * @throws IllegalStateException if the MediaCas instance is not valid, - * or IllegalArgumentException if the session is not valid. - */ - /* - * TODO: need to re-throw DRM-specific exceptions + * @throws IllegalStateException if the MediaCas instance is not valid. + * @throws MediaCasException for CAS-specific errors. + * @throws MediaCasStateException for CAS-specific state exceptions. */ - public void processEcm(@NonNull byte[] sessionId, @NonNull byte[] data) { + public void processEcm(@NonNull byte[] sessionId, @NonNull byte[] data) + throws MediaCasException { processEcm(sessionId, data, 0, data.length); } @@ -544,16 +547,18 @@ public final class MediaCas { * @param length length of the data (starting from offset). * * @throws IllegalStateException if the MediaCas instance is not valid. + * @throws MediaCasException for CAS-specific errors. + * @throws MediaCasStateException for CAS-specific state exceptions. */ - /* - * TODO: need to re-throw DRM-specific exceptions - */ - public void processEmm(@NonNull byte[] data, int offset, int length) { + public void processEmm(@NonNull byte[] data, int offset, int length) + throws MediaCasException { validateInternalStates(); try { mCasData.set(data, offset, length); mICas.processEmm(mCasData); + } catch (ServiceSpecificException e) { + MediaCasException.throwExceptions(e); } catch (RemoteException e) { cleanupAndRethrowIllegalState(); } @@ -567,11 +572,10 @@ public final class MediaCas { * @param data byte array of the EMM data. * * @throws IllegalStateException if the MediaCas instance is not valid. + * @throws MediaCasException for CAS-specific errors. + * @throws MediaCasStateException for CAS-specific state exceptions. */ - /* - * TODO: need to re-throw DRM-specific exceptions - */ - public void processEmm(@NonNull byte[] data) { + public void processEmm(@NonNull byte[] data) throws MediaCasException { processEmm(data, 0, data.length); } @@ -584,12 +588,17 @@ public final class MediaCas { * @param data a byte array containing scheme-specific data for the event. * * @throws IllegalStateException if the MediaCas instance is not valid. + * @throws MediaCasException for CAS-specific errors. + * @throws MediaCasStateException for CAS-specific state exceptions. */ - public void sendEvent(int event, int arg, @Nullable byte[] data) { + public void sendEvent(int event, int arg, @Nullable byte[] data) + throws MediaCasException { validateInternalStates(); try { mICas.sendEvent(event, arg, data); + } catch (ServiceSpecificException e) { + MediaCasException.throwExceptions(e); } catch (RemoteException e) { cleanupAndRethrowIllegalState(); } @@ -603,12 +612,16 @@ public final class MediaCas { * specific. * * @throws IllegalStateException if the MediaCas instance is not valid. + * @throws MediaCasException for CAS-specific errors. + * @throws MediaCasStateException for CAS-specific state exceptions. */ - public void provision(@NonNull String provisionString) { + public void provision(@NonNull String provisionString) throws MediaCasException { validateInternalStates(); try { mICas.provision(provisionString); + } catch (ServiceSpecificException e) { + MediaCasException.throwExceptions(e); } catch (RemoteException e) { cleanupAndRethrowIllegalState(); } @@ -621,15 +634,17 @@ public final class MediaCas { * @param refreshData private data associated with the refreshment. * * @throws IllegalStateException if the MediaCas instance is not valid. + * @throws MediaCasException for CAS-specific errors. + * @throws MediaCasStateException for CAS-specific state exceptions. */ - /* - * TODO: define enums for refreshType - */ - public void refreshEntitlements(int refreshType, @Nullable byte[] refreshData) { + public void refreshEntitlements(int refreshType, @Nullable byte[] refreshData) + throws MediaCasException { validateInternalStates(); try { mICas.refreshEntitlements(refreshType, refreshData); + } catch (ServiceSpecificException e) { + MediaCasException.throwExceptions(e); } catch (RemoteException e) { cleanupAndRethrowIllegalState(); } diff --git a/media/java/android/media/MediaCasException.java b/media/java/android/media/MediaCasException.java index 1d5d3cdb2134..485f6eebf88e 100644 --- a/media/java/android/media/MediaCasException.java +++ b/media/java/android/media/MediaCasException.java @@ -16,11 +16,104 @@ package android.media; +import android.os.ServiceSpecificException; + /** * Base class for MediaCas exceptions */ public class MediaCasException extends Exception { + + /** @hide */ + public static final int DRM_ERROR_BASE = -2000; + /** @hide */ + public static final int ERROR_DRM_UNKNOWN = DRM_ERROR_BASE; + /** @hide */ + public static final int ERROR_DRM_NO_LICENSE = DRM_ERROR_BASE - 1; + /** @hide */ + public static final int ERROR_DRM_LICENSE_EXPIRED = DRM_ERROR_BASE - 2; + /** @hide */ + public static final int ERROR_DRM_SESSION_NOT_OPENED = DRM_ERROR_BASE - 3; + /** @hide */ + public static final int ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED = DRM_ERROR_BASE - 4; + /** @hide */ + public static final int ERROR_DRM_DECRYPT = DRM_ERROR_BASE - 5; + /** @hide */ + public static final int ERROR_DRM_CANNOT_HANDLE = DRM_ERROR_BASE - 6; + /** @hide */ + public static final int ERROR_DRM_TAMPER_DETECTED = DRM_ERROR_BASE - 7; + /** @hide */ + public static final int ERROR_DRM_NOT_PROVISIONED = DRM_ERROR_BASE - 8; + /** @hide */ + public static final int ERROR_DRM_DEVICE_REVOKED = DRM_ERROR_BASE - 9; + /** @hide */ + public static final int ERROR_DRM_RESOURCE_BUSY = DRM_ERROR_BASE - 10; + /** @hide */ + public static final int ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION = DRM_ERROR_BASE - 11; + /** @hide */ + public static final int ERROR_DRM_LAST_USED_ERRORCODE = DRM_ERROR_BASE - 11; + /** @hide */ + public static final int ERROR_DRM_VENDOR_MAX = DRM_ERROR_BASE - 500; + /** @hide */ + public static final int ERROR_DRM_VENDOR_MIN = DRM_ERROR_BASE - 999; + + /** @hide */ public MediaCasException(String detailMessage) { super(detailMessage); } + + static void throwExceptions(ServiceSpecificException e) throws MediaCasException { + if (e.errorCode == ERROR_DRM_NOT_PROVISIONED) { + throw new NotProvisionedException(e.getMessage()); + } else if (e.errorCode == ERROR_DRM_RESOURCE_BUSY) { + throw new ResourceBusyException(e.getMessage()); + } else if (e.errorCode == ERROR_DRM_DEVICE_REVOKED) { + throw new DeniedByServerException(e.getMessage()); + } else { + MediaCasStateException.throwExceptions(e); + } + } + + /** + * Exception thrown when an attempt is made to construct a MediaCas object + * using a CA_system_id that is not supported by the device + */ + public static final class UnsupportedCasException extends MediaCasException { + /** @hide */ + public UnsupportedCasException(String detailMessage) { + super(detailMessage); + } + } + + /** + * Exception thrown when an operation on a MediaCas object is attempted + * before it's provisioned successfully. + */ + public static final class NotProvisionedException extends MediaCasException { + /** @hide */ + public NotProvisionedException(String detailMessage) { + super(detailMessage); + } + } + + /** + * Exception thrown when the provisioning server or key server denies a + * license for a device. + */ + public static final class DeniedByServerException extends MediaCasException { + /** @hide */ + public DeniedByServerException(String detailMessage) { + super(detailMessage); + } + } + + /** + * Exception thrown when an operation on a MediaCas object is attempted + * and hardware resources are not available, due to being in use. + */ + public static final class ResourceBusyException extends MediaCasException { + /** @hide */ + public ResourceBusyException(String detailMessage) { + super(detailMessage); + } + } } diff --git a/media/java/android/media/MediaCasStateException.java b/media/java/android/media/MediaCasStateException.java new file mode 100644 index 000000000000..cf05c2975272 --- /dev/null +++ b/media/java/android/media/MediaCasStateException.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2017 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 android.media; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.ServiceSpecificException; + +import static android.media.MediaCasException.*; + +/** + * Base class for MediaCas runtime exceptions + */ +public class MediaCasStateException extends IllegalStateException { + private final int mErrorCode; + private final String mDiagnosticInfo; + + /** @hide */ + public MediaCasStateException(int err, @Nullable String msg, @Nullable String diagnosticInfo) { + super(msg); + mErrorCode = err; + mDiagnosticInfo = diagnosticInfo; + } + + static void throwExceptions(ServiceSpecificException e) { + String diagnosticInfo = ""; + switch (e.errorCode) { + case ERROR_DRM_UNKNOWN: + diagnosticInfo = "General CAS error"; + break; + case ERROR_DRM_NO_LICENSE: + diagnosticInfo = "No license"; + break; + case ERROR_DRM_LICENSE_EXPIRED: + diagnosticInfo = "License expired"; + break; + case ERROR_DRM_SESSION_NOT_OPENED: + diagnosticInfo = "Session not opened"; + break; + case ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED: + diagnosticInfo = "Not initialized"; + break; + case ERROR_DRM_DECRYPT: + diagnosticInfo = "Decrypt error"; + break; + case ERROR_DRM_CANNOT_HANDLE: + diagnosticInfo = "Unsupported scheme or data format"; + break; + case ERROR_DRM_TAMPER_DETECTED: + diagnosticInfo = "Tamper detected"; + break; + default: + diagnosticInfo = "Unknown CAS state exception"; + break; + } + throw new MediaCasStateException(e.errorCode, e.getMessage(), + String.format("%s (err=%d)", diagnosticInfo, e.errorCode)); + } + + /** + * Retrieve the associated error code + * + * @hide + */ + public int getErrorCode() { + return mErrorCode; + } + + /** + * Retrieve a developer-readable diagnostic information string + * associated with the exception. Do not show this to end-users, + * since this string will not be localized or generally comprehensible + * to end-users. + */ + @NonNull + public String getDiagnosticInfo() { + return mDiagnosticInfo; + } +} diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java index 13a22b49ff87..7ee0a7d6359c 100644 --- a/media/java/android/media/MediaCodec.java +++ b/media/java/android/media/MediaCodec.java @@ -1878,9 +1878,7 @@ final public class MediaCodec { * @param flags Specify {@link #CONFIGURE_FLAG_ENCODE} to configure the * component as an encoder. * @param descrambler Specify a descrambler object to facilitate secure - * descrambling of the media data. descrambler must not be - * null if this method is used. For non-secure codecs, use - * {@link #configure} and with null crypto parameter. + * descrambling of the media data, or null for non-secure codecs. * @throws IllegalArgumentException if the surface has been released (or is invalid), * or the format is unacceptable (e.g. missing a mandatory key), * or the flags are not set properly @@ -1891,8 +1889,9 @@ final public class MediaCodec { */ public void configure( @Nullable MediaFormat format, @Nullable Surface surface, - @ConfigureFlag int flags, @NonNull MediaDescrambler descrambler) { - configure(format, surface, null, descrambler.getBinder(), flags); + @ConfigureFlag int flags, @Nullable MediaDescrambler descrambler) { + configure(format, surface, null, + descrambler != null ? descrambler.getBinder() : null, flags); } private void configure( @@ -2441,6 +2440,8 @@ final public class MediaCodec { } }; + private final Pattern zeroPattern = new Pattern(0, 0); + /** * The pattern applicable to the protected data in each subsample. */ @@ -2463,7 +2464,7 @@ final public class MediaCodec { key = newKey; iv = newIV; mode = newMode; - pattern = new Pattern(0, 0); + pattern = zeroPattern; } /** diff --git a/media/java/android/media/MediaDescrambler.java b/media/java/android/media/MediaDescrambler.java index f5eede859eb1..2dd109721ca8 100644 --- a/media/java/android/media/MediaDescrambler.java +++ b/media/java/android/media/MediaDescrambler.java @@ -17,10 +17,12 @@ package android.media; import android.annotation.NonNull; +import android.media.MediaCasException.UnsupportedCasException; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; import android.os.RemoteException; +import android.os.ServiceSpecificException; import android.util.Log; import java.nio.ByteBuffer; @@ -54,13 +56,13 @@ public final class MediaDescrambler { /** * Class for parceling descrambling parameters over IDescrambler binder. */ + // This class currently is not used by Java binder. descramble() goes through + // jni to use shared memory. However, the parcelable is still required for AIDL. static class DescrambleInfo implements Parcelable { private DescrambleInfo() { - // TODO: implement } private DescrambleInfo(Parcel in) { - // TODO: disable } @Override @@ -70,7 +72,6 @@ public final class MediaDescrambler { @Override public void writeToParcel(Parcel dest, int flags) { - // TODO: implement } public static final Parcelable.Creator<DescrambleInfo> CREATOR @@ -112,13 +113,6 @@ public final class MediaDescrambler { return mIDescrambler.asBinder(); } - /* - * TODO: handle ServiceSpecificException from the mIDescrambler - * All Drm-specific failures will be thrown by mIDescrambler as - * ServiceSpecificException exception with Drm error code. - * These need to be re-thrown as crypto exceptions. - */ - /** * Query if the scrambling scheme requires the use of a secure decoder * to decode data of the given mime type. @@ -150,14 +144,16 @@ public final class MediaDescrambler { * @param sessionId the MediaCas sessionId to associate with this * MediaDescrambler instance. * - * @throws IllegalStateException if the descrambler instance is not valid, - * or IllegalArgumentException if the sessionId is not valid. + * @throws IllegalStateException if the descrambler instance is not valid. + * @throws MediaCasStateException for CAS-specific state exceptions. */ public final void setMediaCasSession(@NonNull byte[] sessionId) { validateInternalStates(); try { mIDescrambler.setMediaCasSession(sessionId); + } catch (ServiceSpecificException e) { + MediaCasStateException.throwExceptions(e); } catch (RemoteException e) { cleanupAndRethrowIllegalState(); } @@ -179,9 +175,7 @@ public final class MediaDescrambler { * values indicating errors. * * @throws IllegalStateException if the descrambler instance is not valid. - */ - /* - * TODO: throw DRM-specific exception if decrambling is failing. + * @throws MediaCasStateException for CAS-specific state exceptions. */ public final int descramble( @NonNull ByteBuffer srcBuf, int srcPos, ByteBuffer dstBuf, int dstPos, @@ -208,12 +202,17 @@ public final class MediaDescrambler { "Invalid CryptoInfo: key array is invalid!"); } - return native_descramble( - cryptoInfo.key[0], - cryptoInfo.numSubSamples, - cryptoInfo.numBytesOfClearData, - cryptoInfo.numBytesOfEncryptedData, - srcBuf, srcPos, dstBuf, dstPos); + try { + return native_descramble( + cryptoInfo.key[0], + cryptoInfo.numSubSamples, + cryptoInfo.numBytesOfClearData, + cryptoInfo.numBytesOfEncryptedData, + srcBuf, srcPos, dstBuf, dstPos); + } catch (ServiceSpecificException e) { + MediaCasStateException.throwExceptions(e); + } + return -1; } public final void release() { diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java index bee3f52c9b90..f10f4427d6f0 100644 --- a/media/java/android/media/session/MediaSession.java +++ b/media/java/android/media/session/MediaSession.java @@ -77,13 +77,19 @@ public final class MediaSession { /** * Set this flag on the session to indicate that it can handle media button * events. + * @deprecated This flag is no longer used. All media sessions are expected to handle media + * button events now. */ + @Deprecated public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1 << 0; /** * Set this flag on the session to indicate that it handles transport * control commands through its {@link Callback}. + * @deprecated This flag is no longer used. All media sessions are expected to handle transport + * controls now. */ + @Deprecated public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 1 << 1; /** diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java index 6808b57c2642..7bf69c06ab5e 100644 --- a/media/java/android/media/tv/TvContract.java +++ b/media/java/android/media/tv/TvContract.java @@ -1321,9 +1321,7 @@ public final class TvContract { * * <p>Type: INTEGER (boolean) * @see Channels#COLUMN_TRANSIENT - * @hide */ - @SystemApi public static final String COLUMN_TRANSIENT = "transient"; /** @@ -2164,10 +2162,9 @@ public final class TvContract { * specified, this value is set to 0 (not transient) by default. * * <p>Type: INTEGER (boolean) - * @see Programs#COLUMN_TRANSIENT - * @hide + * @see PreviewPrograms#COLUMN_TRANSIENT + * @see WatchNextPrograms#COLUMN_TRANSIENT */ - @SystemApi public static final String COLUMN_TRANSIENT = "transient"; /** diff --git a/media/java/android/media/tv/TvInputHardwareInfo.java b/media/java/android/media/tv/TvInputHardwareInfo.java index 957c5820838e..762f0c07e121 100644 --- a/media/java/android/media/tv/TvInputHardwareInfo.java +++ b/media/java/android/media/tv/TvInputHardwareInfo.java @@ -20,6 +20,7 @@ import static java.lang.annotation.RetentionPolicy.SOURCE; import android.annotation.IntDef; import android.annotation.SystemApi; +import android.hardware.tv.input.V1_0.Constants; import android.media.AudioManager; import android.os.Parcel; import android.os.Parcelable; @@ -37,16 +38,16 @@ public final class TvInputHardwareInfo implements Parcelable { static final String TAG = "TvInputHardwareInfo"; // Match hardware/libhardware/include/hardware/tv_input.h - public static final int TV_INPUT_TYPE_OTHER_HARDWARE = 1; - public static final int TV_INPUT_TYPE_TUNER = 2; - public static final int TV_INPUT_TYPE_COMPOSITE = 3; - public static final int TV_INPUT_TYPE_SVIDEO = 4; - public static final int TV_INPUT_TYPE_SCART = 5; - public static final int TV_INPUT_TYPE_COMPONENT = 6; - public static final int TV_INPUT_TYPE_VGA = 7; - public static final int TV_INPUT_TYPE_DVI = 8; - public static final int TV_INPUT_TYPE_HDMI = 9; - public static final int TV_INPUT_TYPE_DISPLAY_PORT = 10; + public static final int TV_INPUT_TYPE_OTHER_HARDWARE = Constants.TV_INPUT_TYPE_OTHER; + public static final int TV_INPUT_TYPE_TUNER = Constants.TV_INPUT_TYPE_TUNER; + public static final int TV_INPUT_TYPE_COMPOSITE = Constants.TV_INPUT_TYPE_COMPOSITE; + public static final int TV_INPUT_TYPE_SVIDEO = Constants.TV_INPUT_TYPE_SVIDEO; + public static final int TV_INPUT_TYPE_SCART = Constants.TV_INPUT_TYPE_SCART; + public static final int TV_INPUT_TYPE_COMPONENT = Constants.TV_INPUT_TYPE_COMPONENT; + public static final int TV_INPUT_TYPE_VGA = Constants.TV_INPUT_TYPE_VGA; + public static final int TV_INPUT_TYPE_DVI = Constants.TV_INPUT_TYPE_DVI; + public static final int TV_INPUT_TYPE_HDMI = Constants.TV_INPUT_TYPE_HDMI; + public static final int TV_INPUT_TYPE_DISPLAY_PORT = Constants.TV_INPUT_TYPE_DISPLAY_PORT; /** @hide */ @Retention(SOURCE) @@ -58,17 +59,20 @@ public final class TvInputHardwareInfo implements Parcelable { /** * The hardware is unsure about the connection status or does not support cable detection. */ - public static final int CABLE_CONNECTION_STATUS_UNKNOWN = 0; + public static final int CABLE_CONNECTION_STATUS_UNKNOWN = + Constants.CABLE_CONNECTION_STATUS_UNKNOWN; /** * Cable is connected to the hardware. */ - public static final int CABLE_CONNECTION_STATUS_CONNECTED = 1; + public static final int CABLE_CONNECTION_STATUS_CONNECTED = + Constants.CABLE_CONNECTION_STATUS_CONNECTED; /** * Cable is disconnected to the hardware. */ - public static final int CABLE_CONNECTION_STATUS_DISCONNECTED = 2; + public static final int CABLE_CONNECTION_STATUS_DISCONNECTED = + Constants.CABLE_CONNECTION_STATUS_DISCONNECTED; public static final Parcelable.Creator<TvInputHardwareInfo> CREATOR = new Parcelable.Creator<TvInputHardwareInfo>() { diff --git a/media/jni/android_media_MediaDescrambler.cpp b/media/jni/android_media_MediaDescrambler.cpp index 75856648f498..f031dbb273c6 100644 --- a/media/jni/android_media_MediaDescrambler.cpp +++ b/media/jni/android_media_MediaDescrambler.cpp @@ -129,7 +129,7 @@ void JDescrambler::ensureBufferCapacity(size_t neededSize) { mMem = mDealer->allocate(neededSize); } -ssize_t JDescrambler::descramble( +Status JDescrambler::descramble( jbyte key, size_t numSubSamples, ssize_t totalLength, @@ -137,7 +137,8 @@ ssize_t JDescrambler::descramble( const void *srcPtr, jint srcOffset, void *dstPtr, - jint dstOffset) { + jint dstOffset, + ssize_t *result) { // TODO: IDescrambler::descramble() is re-entrant, however because we // only have 1 shared mem buffer, we can only do 1 descramble at a time. // Concurrency might be improved by allowing on-demand allocation of up @@ -159,16 +160,16 @@ ssize_t JDescrambler::descramble( info.dstPtr = NULL; info.dstOffset = 0; - int32_t result; - binder::Status status = mDescrambler->descramble(info, &result); + int32_t descrambleResult; + Status status = mDescrambler->descramble(info, &descrambleResult); - if (!status.isOk() || result > totalLength) { - return -1; - } - if (result > 0) { - memcpy((void*)((uint8_t*)dstPtr + dstOffset), mMem->pointer(), result); + if (status.isOk()) { + *result = (descrambleResult <= totalLength) ? descrambleResult : -1; + if (*result > 0) { + memcpy((void*)((uint8_t*)dstPtr + dstOffset), mMem->pointer(), *result); + } } - return result; + return status; } } // namespace android @@ -251,11 +252,45 @@ static ssize_t getSubSampleInfo(JNIEnv *env, jint numSubSamples, numBytesOfClearData = NULL; } + if (totalSize < 0) { + delete[] subSamples; + return -1; + } + *outSubSamples = subSamples; return totalSize; } +static jthrowable createServiceSpecificException( + JNIEnv *env, int serviceSpecificError, const char *msg) { + if (env->ExceptionCheck()) { + ALOGW("Discarding pending exception"); + env->ExceptionDescribe(); + env->ExceptionClear(); + } + + ScopedLocalRef<jclass> clazz( + env, env->FindClass("android/os/ServiceSpecificException")); + CHECK(clazz.get() != NULL); + + const jmethodID ctor = env->GetMethodID(clazz.get(), "<init>", "(ILjava/lang/String;)V"); + CHECK(ctor != NULL); + + ScopedLocalRef<jstring> msgObj( + env, env->NewStringUTF(msg != NULL ? + msg : String8::format("Error %#x", serviceSpecificError))); + + return (jthrowable)env->NewObject( + clazz.get(), ctor, serviceSpecificError, msgObj.get()); +} + +static void throwServiceSpecificException( + JNIEnv *env, int serviceSpecificError, const char *msg) { + jthrowable exception = createServiceSpecificException(env, serviceSpecificError, msg); + env->Throw(exception); +} + static jint android_media_MediaDescrambler_native_descramble( JNIEnv *env, jobject thiz, jbyte key, jint numSubSamples, jintArray numBytesOfClearDataObj, jintArray numBytesOfEncryptedDataObj, @@ -290,11 +325,11 @@ static jint android_media_MediaDescrambler_native_descramble( env, dstBuf, dstOffset, totalLength, &dstPtr, &dstArray); } } - + Status status; if (err == OK) { - result = descrambler->descramble( + status = descrambler->descramble( key, numSubSamples, totalLength, subSamples, - srcPtr, srcOffset, dstPtr, dstOffset); + srcPtr, srcOffset, dstPtr, dstOffset, &result); } delete[] subSamples; @@ -304,6 +339,51 @@ static jint android_media_MediaDescrambler_native_descramble( if (dstArray != NULL) { env->ReleaseByteArrayElements(dstArray, (jbyte *)dstPtr, 0); } + + if (!status.isOk()) { + switch (status.exceptionCode()) { + case Status::EX_SECURITY: + jniThrowException(env, "java/lang/SecurityException", + status.exceptionMessage()); + break; + case Status::EX_BAD_PARCELABLE: + jniThrowException(env, "java/lang/BadParcelableException", + status.exceptionMessage()); + break; + case Status::EX_ILLEGAL_ARGUMENT: + jniThrowException(env, "java/lang/IllegalArgumentException", + status.exceptionMessage()); + break; + case Status::EX_NULL_POINTER: + jniThrowException(env, "java/lang/NullPointerException", + status.exceptionMessage()); + break; + case Status::EX_ILLEGAL_STATE: + jniThrowException(env, "java/lang/IllegalStateException", + status.exceptionMessage()); + break; + case Status::EX_NETWORK_MAIN_THREAD: + jniThrowException(env, "java/lang/NetworkOnMainThreadException", + status.exceptionMessage()); + break; + case Status::EX_UNSUPPORTED_OPERATION: + jniThrowException(env, "java/lang/UnsupportedOperationException", + status.exceptionMessage()); + break; + case Status::EX_SERVICE_SPECIFIC: + throwServiceSpecificException(env, status.serviceSpecificErrorCode(), + status.exceptionMessage()); + break; + default: + { + String8 msg; + msg.appendFormat("Unknown exception code: %d, msg: %s", + status.exceptionCode(), status.exceptionMessage().string()); + jniThrowException(env, "java/lang/RuntimeException", msg.string()); + break; + } + } + } return result; } diff --git a/media/jni/android_media_MediaDescrambler.h b/media/jni/android_media_MediaDescrambler.h index e944a90dba7a..aeef05e7968d 100644 --- a/media/jni/android_media_MediaDescrambler.h +++ b/media/jni/android_media_MediaDescrambler.h @@ -19,6 +19,7 @@ #include "jni.h" +#include <binder/Status.h> #include <media/cas/DescramblerAPI.h> #include <media/stagefright/foundation/ABase.h> #include <utils/Mutex.h> @@ -31,11 +32,12 @@ namespace media { class IDescrambler; }; using namespace media; +using binder::Status; struct JDescrambler : public RefBase { JDescrambler(JNIEnv *env, jobject descramberBinderObj); - ssize_t descramble( + Status descramble( jbyte key, size_t numSubSamples, ssize_t totalLength, @@ -43,7 +45,8 @@ struct JDescrambler : public RefBase { const void *srcPtr, jint srcOffset, void *dstPtr, - jint dstOffset); + jint dstOffset, + ssize_t *result); protected: virtual ~JDescrambler(); diff --git a/packages/CarrierDefaultApp/AndroidManifest.xml b/packages/CarrierDefaultApp/AndroidManifest.xml index 8df194c11800..e450283312c3 100644 --- a/packages/CarrierDefaultApp/AndroidManifest.xml +++ b/packages/CarrierDefaultApp/AndroidManifest.xml @@ -27,7 +27,9 @@ <uses-permission android:name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS" /> <uses-permission android:name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME" /> - <application android:label="@string/app_name" > + <application + android:label="@string/app_name" + android:directBootAware="true"> <receiver android:name="com.android.carrierdefaultapp.CarrierDefaultBroadcastReceiver"> <intent-filter> <action android:name="com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED" /> diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java index e49463f04ec6..227d8048292a 100644 --- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java +++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java @@ -58,6 +58,7 @@ import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.TextView; +import com.android.internal.util.ArrayUtils; import com.android.internal.util.CollectionUtils; import com.android.internal.util.Preconditions; @@ -109,6 +110,11 @@ public class DeviceDiscoveryService extends Service { private final ScanCallback mBLEScanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { + if (DEBUG) { + Log.i(LOG_TAG, + "BLE.onScanResult(callbackType = " + callbackType + ", result = " + result + + ")"); + } final DeviceFilterPair<ScanResult> deviceFilterPair = DeviceFilterPair.findMatch(result, mBLEFilters); if (deviceFilterPair == null) return; @@ -125,6 +131,10 @@ public class DeviceDiscoveryService extends Service { private BroadcastReceiver mBluetoothDeviceFoundBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { + if (DEBUG) { + Log.i(LOG_TAG, + "BL.onReceive(context = " + context + ", intent = " + intent + ")"); + } final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); final DeviceFilterPair<BluetoothDevice> deviceFilterPair = DeviceFilterPair.findMatch(device, mBluetoothFilters); @@ -180,15 +190,23 @@ public class DeviceDiscoveryService extends Service { } private void startDiscovery(AssociationRequest request) { - mRequest = request; + if (!request.equals(mRequest)) { + mRequest = request; + + mFilters = request.getDeviceFilters(); + mWifiFilters = CollectionUtils.filter(mFilters, WifiDeviceFilter.class); + mBluetoothFilters = CollectionUtils.filter(mFilters, BluetoothDeviceFilter.class); + mBLEFilters = CollectionUtils.filter(mFilters, BluetoothLEDeviceFilter.class); + mBLEScanFilters = CollectionUtils.map(mBLEFilters, BluetoothLEDeviceFilter::getScanFilter); + + reset(); + } else if (DEBUG) Log.i(LOG_TAG, "startDiscovery: duplicate request: " + request); - mFilters = request.getDeviceFilters(); - mWifiFilters = CollectionUtils.filter(mFilters, WifiDeviceFilter.class); - mBluetoothFilters = CollectionUtils.filter(mFilters, BluetoothDeviceFilter.class); - mBLEFilters = CollectionUtils.filter(mFilters, BluetoothLEDeviceFilter.class); - mBLEScanFilters = CollectionUtils.map(mBLEFilters, BluetoothLEDeviceFilter::getScanFilter); - reset(); + + if (!ArrayUtils.isEmpty(mDevicesFound)) { + onReadyToShowUI(); + } if (shouldScan(mBluetoothFilters)) { final IntentFilter intentFilter = new IntentFilter(); @@ -215,6 +233,7 @@ public class DeviceDiscoveryService extends Service { } private void reset() { + if (DEBUG) Log.i(LOG_TAG, "reset()"); mDevicesFound.clear(); mSelectedDevice = null; mDevicesAdapter.notifyDataSetChanged(); @@ -228,10 +247,18 @@ public class DeviceDiscoveryService extends Service { private void stopScan() { if (DEBUG) Log.i(LOG_TAG, "stopScan() called"); - mBluetoothAdapter.cancelDiscovery(); - mBLEScanner.stopScan(mBLEScanCallback); - unregisterReceiver(mBluetoothDeviceFoundBroadcastReceiver); - unregisterReceiver(mWifiDeviceFoundBroadcastReceiver); + + if (shouldScan(mBluetoothFilters)) { + mBluetoothAdapter.cancelDiscovery(); + unregisterReceiver(mBluetoothDeviceFoundBroadcastReceiver); + } + if (shouldScan(mBLEFilters)) { + mBLEScanner.stopScan(mBLEScanCallback); + } + if (shouldScan(mWifiFilters)) { + unregisterReceiver(mWifiDeviceFoundBroadcastReceiver); + } + stopSelf(); } @@ -355,8 +382,15 @@ public class DeviceDiscoveryService extends Service { public static <T extends Parcelable> DeviceFilterPair<T> findMatch( T dev, @Nullable List<? extends DeviceFilter<T>> filters) { if (isEmpty(filters)) return new DeviceFilterPair<>(dev, null); - final DeviceFilter<T> matchingFilter = CollectionUtils.find(filters, (f) -> f.matches(dev)); - return matchingFilter != null ? new DeviceFilterPair<>(dev, matchingFilter) : null; + final DeviceFilter<T> matchingFilter + = CollectionUtils.find(filters, f -> f.matches(dev)); + + DeviceFilterPair<T> result = matchingFilter != null + ? new DeviceFilterPair<>(dev, matchingFilter) + : null; + if (DEBUG) Log.i(LOG_TAG, "findMatch(dev = " + dev + ", filters = " + filters + + ") -> " + result); + return result; } public String getDisplayName() { diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java index 187e35ac842c..f11a9cde9520 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java +++ b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java @@ -113,12 +113,14 @@ public final class RemotePrintDocument { } // Notify we are done. mState = STATE_UPDATED; + mDocumentInfo.updated = true; notifyUpdateCompleted(); } } } else { // We always notify after a write. mState = STATE_UPDATED; + mDocumentInfo.updated = true; notifyUpdateCompleted(); } runPendingCommand(); @@ -229,6 +231,7 @@ public final class RemotePrintDocument { mDocumentInfo, oldAttributes, attributes, preview, mCommandResultCallback); scheduleCommand(command); + mDocumentInfo.updated = false; mState = STATE_UPDATING; // If no layout in progress and we don't have all pages - schedule a write. } else if ((!(mCurrentCommand instanceof LayoutCommand) @@ -249,6 +252,7 @@ public final class RemotePrintDocument { mDocumentInfo.fileProvider, mCommandResultCallback); scheduleCommand(command); + mDocumentInfo.updated = false; mState = STATE_UPDATING; } else { willUpdate = false; @@ -396,7 +400,7 @@ public final class RemotePrintDocument { private void notifyUpdateFailed(CharSequence error) { if (DEBUG) { - Log.i(LOG_TAG, "[CALLING] onUpdateCompleted()"); + Log.i(LOG_TAG, "[CALLING] notifyUpdateFailed()"); } mUpdateCallbacks.onUpdateFailed(error); } diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java index f6df9953bf0f..4cce166db645 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java +++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java @@ -491,8 +491,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat setState(STATE_UPDATE_FAILED); - updateOptionsUi(); - mPrintedDocument.kill(message); } @@ -502,7 +500,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat && canUpdateDocument() && updateDocument(true)) { ensurePreviewUiShown(); setState(STATE_CONFIGURING); - updateOptionsUi(); } } @@ -579,7 +576,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat updatePrintPreviewController(document.changed); setState(STATE_CONFIGURING); - updateOptionsUi(); } break; } } @@ -600,8 +596,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat } setState(STATE_UPDATE_FAILED); - - updateOptionsUi(); } @Override @@ -734,7 +728,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat updateOptionsUi(); } else { setState(STATE_CREATE_FILE_FAILED); - updateOptionsUi(); // Calling finish here does not invoke lifecycle callbacks but we // update the print job in onPause if finishing, hence post a message. mDestinationSpinner.post(new Runnable() { @@ -958,12 +951,14 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat Log.i(LOG_TAG, "[state]" + state); } mState = state; + updateOptionsUi(); } } else { if (DEBUG) { Log.i(LOG_TAG, "[state]" + state); } mState = state; + updateOptionsUi(); } } @@ -1230,6 +1225,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat final boolean willUpdate = mPrintedDocument.update(mPrintJob.getAttributes(), pages, preview); + updateOptionsUi(); if (willUpdate && !mPrintedDocument.hasLaidOutPages()) { // When the update is done we update the print preview. @@ -1254,7 +1250,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat private void cancelPrint() { setState(STATE_PRINT_CANCELED); - updateOptionsUi(); mPrintedDocument.cancel(true); doFinish(); } @@ -1274,7 +1269,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat private void confirmPrint() { setState(STATE_PRINT_CONFIRMED); - updateOptionsUi(); addCurrentPrinterToHistory(); setUserPrinted(); @@ -1629,6 +1623,8 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat // Always update the summary. updateSummary(); + mDestinationSpinner.setEnabled(!isFinalState(mState)); + if (mState == STATE_PRINT_CONFIRMED || mState == STATE_PRINT_COMPLETED || mState == STATE_PRINT_CANCELED @@ -1636,9 +1632,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat || mState == STATE_CREATE_FILE_FAILED || mState == STATE_PRINTER_UNAVAILABLE || mState == STATE_UPDATE_SLOW) { - if (mState != STATE_PRINTER_UNAVAILABLE) { - mDestinationSpinner.setEnabled(false); - } disableOptionsUi(isFinalState(mState)); return; } @@ -1927,7 +1920,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat mPrintButton.setImageResource(R.drawable.ic_menu_savetopdf); mPrintButton.setContentDescription(getString(R.string.savetopdf_button)); } - if (!mPrintedDocument.getDocumentInfo().laidout + if (!mPrintedDocument.getDocumentInfo().updated ||(mRangeOptionsSpinner.getSelectedItemPosition() == 1 && (TextUtils.isEmpty(mPageRangeEditText.getText()) || hasErrors())) || (mRangeOptionsSpinner.getSelectedItemPosition() == 0 @@ -2048,7 +2041,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat updateDocument(false); } ensurePreviewUiShown(); - updateOptionsUi(); } } @@ -2058,7 +2050,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat mPrintedDocument.cancel(false); ensureErrorUiShown(getString(R.string.print_error_printer_unavailable), PrintErrorFragment.ACTION_NONE); - updateOptionsUi(); } } @@ -3038,7 +3029,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat if (mState == STATE_UPDATE_SLOW) { setState(STATE_UPDATE_SLOW); ensureProgressUiShown(); - updateOptionsUi(); return; } else if (mPosted) { @@ -3080,7 +3070,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat mPreviousState = mState; setState(STATE_UPDATE_SLOW); ensureProgressUiShown(); - updateOptionsUi(); } } diff --git a/packages/SettingsLib/res/values-af/arrays.xml b/packages/SettingsLib/res/values-af/arrays.xml index d8df0d7413f3..6d6d2653ae3b 100644 --- a/packages/SettingsLib/res/values-af/arrays.xml +++ b/packages/SettingsLib/res/values-af/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Gebruik HDCP-kontrolering net vir DRM-inhoud"</item> <item msgid="45075631231212732">"Gebruik altyd HDCP-kontrolering"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (verstek)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Gebruik stelselkeuse (verstek)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Geoptimeer vir oudiogehalte (990 kbps/909 kbps)"</item> - <item msgid="2921767058740704969">"Gebalanseerde oudio- en verbindinggehalte (660 kbps/606 kbps)"</item> - <item msgid="8860982705384396512">"Geoptimeer vir verbindinggehalte (330 kbps/303 kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Geoptimeer vir oudiogehalte"</item> - <item msgid="4327143584633311908">"Gebalanseerde oudio- en verbindinggehalte"</item> - <item msgid="4681409244565426925">"Geoptimeer vir verbindinggehalte"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Af"</item> <item msgid="1593289376502312923">"64 K"</item> diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml index c4be395c7d05..671849f8beea 100644 --- a/packages/SettingsLib/res/values-af/strings.xml +++ b/packages/SettingsLib/res/values-af/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Sal nie outomaties koppel nie"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Geen internettoegang nie"</string> <string name="saved_network" msgid="4352716707126620811">"Gestoor deur <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Outomaties deur %1$s gekoppel"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Gekoppel via %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Beskikbaar via %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Baie snel"</item> <item msgid="9085102246155045744">"Vinnigste"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Kies profiel"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Persoonlik"</string> <string name="category_work" msgid="8699184680584175622">"Werk"</string> <string name="development_settings_title" msgid="215179176067683667">"Ontwikkelaaropsies"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Inligtingruiling"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Draadlose skermsertifisering"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktiveer Wi-Fi-woordryke aanmelding"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressiewe Wi‑Fi-na-mobiel-oorhandiging"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Laat altyd Wi-Fi-swerfskanderings toe"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiele data is altyd aktief"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Deaktiveer absolute volume"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP-weergawe"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Kies Bluetooth AVRCP-weergawe"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth-oudiokodek"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Kies Bluetooth-oudiokodek"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth-oudiovoorbeeldkoers"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Stroming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Wys opsies vir draadlose skermsertifisering"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Verhoog Wi-Fi-aantekeningvlak, wys per SSID RSSI in Wi‑Fi-kieser"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Wanneer dit geaktiveer is, sal Wi-Fi die dataverbinding aggressiewer na mobiel oordra wanneer die Wi-Fi-sein swak is"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Laat toe of verbied Wi-Fi-swerfskanderings op grond van die hoeveelheid dataverkeer wat op die koppelvlak teenwoordig is"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Loggerbuffer se groottes"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Kies loggergroottes per logbuffer"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Geneutraliseer deur <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Ongeveer <xliff:g id="TIME">%1$s</xliff:g> oor"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> oor"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – omtrent <xliff:g id="TIME">%2$s</xliff:g> oor"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> oor"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot vol gelaai"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot vol gelaai met AC"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot vol gelaai met USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot vol gelaai met draadloos"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Onbekend"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Laai"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Laai nie"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Vol"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Beheer deur administrateur"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Geaktiveer deur administrateur"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Gedeaktiveer deur administrateur"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Instellingstuisblad"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-am/arrays.xml b/packages/SettingsLib/res/values-am/arrays.xml index f613311e3df6..73dadec2d1aa 100644 --- a/packages/SettingsLib/res/values-am/arrays.xml +++ b/packages/SettingsLib/res/values-am/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"ለDRM ይዘት ብቻ HDCP ምልከታን ተጠቀም"</item> <item msgid="45075631231212732">"ሁልጊዜ የHDCP ምልከታ ተጠቀም"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (ነባሪ)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"የስርዓቱን ምርጫ (ነባሪ) ተጠቀም"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"ሞኖ"</item> <item msgid="8883739882299884241">"ስቲሪዮ"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"ለኦዲዮ ጥራት ተብቷል (990 ኪቢ/ሴ / 909 ኪቢ/ሴ)"</item> - <item msgid="2921767058740704969">"ለኦዲዮ ጥራት አትባ (660 ኪቢ/ሴ / 606 ኪቢ/ሴ)"</item> - <item msgid="8860982705384396512">"ለግንኙነት ጥራት ተብቷል (330 ኪቢ/ሴ / 303 ኪቢ/ሴ)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"ለኦዲዮ ጥራት ተብቷል"</item> - <item msgid="4327143584633311908">"የተመጣጠነ የኦዲዮ እና ግንኙነት ጥራት"</item> - <item msgid="4681409244565426925">"ለግንኙነት ጥራት ተብቷል"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"ጠፍቷል"</item> <item msgid="1593289376502312923">"64 ኪባ"</item> diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml index 0a94e7c3b29a..fa7ea7d721c7 100644 --- a/packages/SettingsLib/res/values-am/strings.xml +++ b/packages/SettingsLib/res/values-am/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"በራስ-ሰር አይገናኝም"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"ምንም የበይነመረብ መዳረሻ ያለም"</string> <string name="saved_network" msgid="4352716707126620811">"የተቀመጠው በ<xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"በ%1$s በኩል በራስ-ሰር ተገናኝቷል"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"በ%1$s በኩል መገናኘት"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"በ%1$s በኩል የሚገኝ"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"በጣም ቀልጣፋ"</item> <item msgid="9085102246155045744">"እጅግ በጣም ቀልጣፋ"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"መገለጫ ይምረጡ"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"የግል"</string> <string name="category_work" msgid="8699184680584175622">"ስራ"</string> <string name="development_settings_title" msgid="215179176067683667">"የገንቢዎች አማራጮች"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"አስገዳጅ ከWi‑Fi ወደ ሞባይል ማቀበል"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ሁልጊዜ የWi‑Fi ማንቀሳቀስ ቅኝቶችን ይፍቀዱ"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"የተንቀሳቃሽ ስልክ ውሂብ ሁልጊዜ ገቢር ነው"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ፍጹማዊ ድምፅን አሰናክል"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"የብሉቱዝ AVRCP ስሪት"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"የብሉቱዝ AVRCP ስሪት ይምረጡ"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"የብሉቱዝ ኦዲዮ ኮዴክ"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"የብሉቱዝ ኦዲዮ ኮዴክ ይምረጡ"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"የብሉቱዝ ኦዲዮ ናሙና ፍጥነት"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ዥረት፦ <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</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> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ሲነቃ የWi‑Fi ምልክት ዝቅተኛ ሲሆን Wi‑Fi የውሂብ ግንኙነት ለሞባይል ማስረከብ ላይ ይበልጥ አስገዳጅ ይሆናል"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"በበይነገጹ ላይ ባለው የውሂብ ትራፊክ መጠን ላይ ተመስርተው የWi‑Fi ማንቀሳቀስ ቅኝቶችን ይፍቀዱ/ይከልክሉ"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"የምዝግብ ማስታወሻ ያዥ መጠኖች"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"በአንድ ምዝግብ ማስታወሻ ቋጥ የሚኖረው የምዝግብ ማስታወሻ ያዥ መጠኖች ይምረጡ"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"በ<xliff:g id="TITLE">%1$s</xliff:g> ተሽሯል"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"<xliff:g id="TIME">%1$s</xliff:g> ገደማ ቀርቷል"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ቀርቷል"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> አካባቢ ይቀራል"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - በAC ሙሉ ለሙሉ እስኪሞላ ድረስ <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - በዩኤስቢ በኩል ሙሉ ለሙሉ እስኪሞላ ድረስ <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - በገመድ አልባ ሙሉ ለሙሉ እስኪሞላ ድረስ <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ኃይል እየሞላ አይደለም"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"ሙሉነው"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"በአስተዳዳሪ ቁጥጥር የተደረገበት"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"በአስተዳዳሪ የነቃ"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"በአስተዳዳሪ የተሰናከለ"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"የቅንብሮች መነሻ"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-ar/arrays.xml b/packages/SettingsLib/res/values-ar/arrays.xml index 9e29fe6eef6b..8fceb11fd5fb 100644 --- a/packages/SettingsLib/res/values-ar/arrays.xml +++ b/packages/SettingsLib/res/values-ar/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"استخدام التحقق من HDCP لمحتوى DRM فقط"</item> <item msgid="45075631231212732">"استخدام التحقق من HDCP دومًا"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (الافتراضي)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"استخدام اختيار النظام (افتراضي)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"أحادي"</item> <item msgid="8883739882299884241">"استريو"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"تحسين جودة الصوت (٩٩٠ كيلوبت في الثانية / ٩٠٩ كيلوبت في الثانية)"</item> - <item msgid="2921767058740704969">"جودة متوازنة للصوت والاتصال (660 كيلوبت في الثانية/606 كيلوبت في الثانية)"</item> - <item msgid="8860982705384396512">"تحسين جودة الاتصال (٣٣٠ كيلوبت في الثانية / ٣٠٣ كيلوبت في الثانية)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"تحسين جودة الصوت"</item> - <item msgid="4327143584633311908">"جودة متوازنة للصوت والاتصال"</item> - <item msgid="4681409244565426925">"تحسين جودة الاتصال"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"إيقاف"</item> <item msgid="1593289376502312923">"٦٤ كيلوبايت"</item> diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml index 875f526a143f..82a6a8a19708 100644 --- a/packages/SettingsLib/res/values-ar/strings.xml +++ b/packages/SettingsLib/res/values-ar/strings.xml @@ -26,15 +26,14 @@ <string name="wifi_disabled_generic" msgid="4259794910584943386">"معطلة"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"أخفقت تهيئة عنوان IP"</string> <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"الجهاز غير متصل بسبب انخفاض جودة الشبكة"</string> - <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"أخفق اتصال WiFi"</string> + <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"تعذّر اتصال WiFi"</string> <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"حدثت مشكلة في المصادقة"</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="3880396223819116454">"لا يتوفر اتصال بالإنترنت"</string> <string name="saved_network" msgid="4352716707126620811">"تم الحفظ بواسطة <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"تم الاتصال تلقائيًا عبر %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"تم الاتصال عبر %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"متوفرة عبر %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"خاطف جدًا"</item> <item msgid="9085102246155045744">"الأسرع"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"اختيار ملف شخصي"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"شخصي"</string> <string name="category_work" msgid="8699184680584175622">"العمل"</string> <string name="development_settings_title" msgid="215179176067683667">"خيارات مطور البرامج"</string> @@ -170,16 +170,12 @@ <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 Verbose"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"تسليم Wi-Fi حاد إلى جوّال"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"السماح دائمًا بعمليات فحص Wi-Fi للتجوال"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"بيانات الجوّال نشطة دائمًا"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"تعطيل مستوى الصوت المطلق"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"إصدار Bluetooth AVRCP"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"اختيار إصدار Bluetooth AVRCP"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"ترميز صوت بلوتوث"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"اختيار برنامج الترميز لصوت البلوتوث"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"معدّل عيّنة صوت بلوتوث"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"البث: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</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> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"عند تمكينه، سيكون Wi-Fi أكثر حدة في تسليم اتصال البيانات إلى الجوّال، وذلك عندما تكون إشارة WiFi منخفضة"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"السماح/عدم السماح بعمليات فحص Wi-Fi للتجوال بناءً على حجم حركة البيانات في الواجهة"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"أحجام ذاكرة التخزين المؤقت للتسجيل"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"حدد أحجامًا أكبر لكل ذاكرة تخزين مؤقت للتسجيل"</string> @@ -286,7 +281,7 @@ <string name="local_backup_password_summary_change" msgid="5376206246809190364">"انقر لتغيير كلمة مرور النسخ الاحتياطية الكاملة لسطح المكتب أو إزالتها."</string> <string name="local_backup_password_toast_success" msgid="582016086228434290">"تم تعيين كلمة مرور احتياطية جديدة"</string> <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"كلمة المرور الجديدة وتأكيدها لا يتطابقان"</string> - <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"أخفق تعيين كلمة مرور احتياطية"</string> + <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"تعذّر تعيين كلمة مرور احتياطية"</string> <string-array name="color_mode_names"> <item msgid="2425514299220523812">"نابض بالحياة (افتراضي)"</item> <item msgid="8446070607501413455">"طبيعي"</item> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"تم الاستبدال بـ <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"يتبقى <xliff:g id="TIME">%1$s</xliff:g> تقريبًا"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"يتبقى <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - يتبقى <xliff:g id="TIME">%2$s</xliff:g> تقريبًا"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - يتبقى <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> حتى يكتمل الشحن عبر التيار المتردد"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> حتى يكتمل الشحن عبر USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> حتى يكتمل الشحن اللاسلكي"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"لا يتم الشحن"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"ممتلئة"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"إعدادات يتحكم فيها المشرف"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"تم التمكين بواسطة المشرف"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"تم التعطيل بواسطة المشرف"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"الشاشة الرئيسية للإعدادات"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"٠٪"</item> diff --git a/packages/SettingsLib/res/values-az/arrays.xml b/packages/SettingsLib/res/values-az/arrays.xml index 2313161df8d1..a4e0e173b2a2 100644 --- a/packages/SettingsLib/res/values-az/arrays.xml +++ b/packages/SettingsLib/res/values-az/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Yalnız DRM məzmun oxumaq üçün HDCP istifadə edin"</item> <item msgid="45075631231212732">"Həmişə HDCP yoxlama istifadə edin"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (Defolt)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Sistem Seçimini istifadə edin (Defolt)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Audio Keyfiyyəti üçün optimallaşdırıldı (990kbps/909kbps)"</item> - <item msgid="2921767058740704969">"Balanslı Audio və Bağlantı Keyfiyyəti (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"Bağlantı Keyfiyyəti üçün optimallaşdırıldı (330kbps/303kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Audio Keyfiyyəti üçün optimallaşdırıldı"</item> - <item msgid="4327143584633311908">"Balanslı Audio və Bağlantı Keyfiyyəti"</item> - <item msgid="4681409244565426925">"Bağlantı Keyfiyyəti üçün optimallaşdırıldı"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Deaktiv"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml index 138ff6feff5c..01f524a0e8c4 100644 --- a/packages/SettingsLib/res/values-az/strings.xml +++ b/packages/SettingsLib/res/values-az/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Avtomatik qoşulmayacaq"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"İnternet girişi yoxdur"</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> tərəfindən saxlandı"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s üzərindən avtomatik qoşuldu"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s vasitəsilə qoşuludur"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s vasitəsilə əlçatandır"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Çox tez"</item> <item msgid="9085102246155045744">"Ən sürətli"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Profil Seçin"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Şəxsi"</string> <string name="category_work" msgid="8699184680584175622">"İş"</string> <string name="development_settings_title" msgid="215179176067683667">"Developer seçimləri"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Şəbəkələşmə"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Simsiz displey sertifikatlaşması"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi Çoxsözlü Girişə icazə verin"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Möbül ötürücüyə aqressiv Wi‑Fi"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi axtarışlarına həmişə icazə verin"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobil data həmişə aktiv"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Mütləq səs həcmi deaktiv edin"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP Versiya"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Bluetooth AVRCP Versiyasını seçin"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth Audio Kodek"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Bluetooth Audio Kodeki Seçin"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth Audio Nümunə Göstəricisi"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Canlı yayım: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Simsiz displey sertifikatlaşması üçün seçimləri göstərir"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi giriş səviyyəsini qaldırın, Wi‑Fi seçəndə hər SSID RSSI üzrə göstərin"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Aktiv edildikdə, Wi-Fi siqnalı zəif olan zaman, data bağlantısını mobilə ötürərəkən Wi-Fi daha aqressiv olacaq"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Wi‑Fi Axtarışlarına data trafikinə əsasən İcazə verin/Qadağan edin"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Logger bufer ölçüləri"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Hər jurnal buferinı Logger ölçüsü seçin"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> tərəfindən qəbul edilmir"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Təxminən <xliff:g id="TIME">%1$s</xliff:g> qalıb"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> qalıb"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - təxminən <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tam enerji yığana kimi"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC\'də tam enerji yığana kimi"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB ilə tam enerji yığana kimi"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> Wi-Fi\'dan tam enerji yığana kimi"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Naməlum"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Enerji doldurma"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Enerji doldurulmur"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Tam"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Admin tərəfindən nəzarət olunur"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Administrator tərəfindən aktiv edildi"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Administrator tərəfindən deaktiv edildi"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Ayarların əsas səhifəsi"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml index 7d098761c545..56709ec1b218 100644 --- a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml +++ b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Koristi HDCP proveru samo za DRM sadržaj"</item> <item msgid="45075631231212732">"Uvek koristi HDCP proveru"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (podrazumevano)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Koristi izbor sistema (podrazumevano)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Optimizovano za kvalitet zvuka (990 kb/s/909 kb/s)"</item> - <item msgid="2921767058740704969">"Ujednačen kvalitet zvuka i veze (660 kb/s/606 kb/s)"</item> - <item msgid="8860982705384396512">"Optimizovano za kvalitet veze (330 kb/s/303 kb/s)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Optimizovano za kvalitet zvuka"</item> - <item msgid="4327143584633311908">"Ujednačen kvalitet zvuka i veze"</item> - <item msgid="4681409244565426925">"Optimizovano za kvalitet veze"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Isključeno"</item> <item msgid="1593289376502312923">"64 kB"</item> diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml index 24b2a13854c3..ba3d592f8703 100644 --- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml +++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Automatsko povezivanje nije uspelo"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Nema pristupa internetu"</string> <string name="saved_network" msgid="4352716707126620811">"Sačuvao/la je <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatski povezano preko %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Veza je uspostavljena preko pristupne tačke %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Dostupna je preko pristupne tačke %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Veoma ubrzano"</item> <item msgid="9085102246155045744">"Najbrže"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Izaberite profil"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Lično"</string> <string name="category_work" msgid="8699184680584175622">"Posao"</string> <string name="development_settings_title" msgid="215179176067683667">"Opcije za programera"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Umrežavanje"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Sertifikacija bežičnog ekrana"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Omogući detaljniju evidenciju za Wi‑Fi"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agresivan prelaz sa Wi‑Fi mreže na mobilnu"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Uvek dozvoli skeniranje Wi‑Fi-ja u romingu"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilni podaci su uvek aktivni"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Onemogući glavno podešavanje jačine zvuka"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Verzija Bluetooth AVRCP-a"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Izaberite verziju Bluetooth AVRCP-a"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth audio kodek"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Izaberite Bluetooth audio kodek"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Brzina uzorkovanja za Bluetooth audio"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Strimovanje: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Prikaz opcija za sertifikaciju bežičnog ekrana"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povećava nivo evidentiranja za Wi‑Fi. Prikaz po SSID RSSI-u u biraču Wi‑Fi mreže"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Kad se omogući, Wi‑Fi će biti agresivniji pri prebacivanju mreže za prenos podataka na mobilnu ako je Wi‑Fi signal slab"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Dozvoli/zabrani skeniranje Wi-Fi-ja u romingu na osnovu prisutnog protoka podataka na interfejsu"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Veličine bafera podataka u programu za evidentiranje"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Izaberite veličine po baferu evidencije"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Zamenjuje ga <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Još otprilike <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Preostalo vreme: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – ostalo je oko <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"Preostalo je <xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do potpunog punjenja"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do potpunog punjenja preko utičnice"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do potpunog punjenja preko USB-a"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do potpunog punjenja na bežičnoj mreži"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Nepoznato"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Punjenje"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ne puni se"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Puno"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontroliše administrator"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Omogućio je administrator"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Onemogućio je administrator"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Početna za Podešavanja"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-be/arrays.xml b/packages/SettingsLib/res/values-be/arrays.xml index 6c883e3e0c54..76e1f95da93f 100644 --- a/packages/SettingsLib/res/values-be/arrays.xml +++ b/packages/SettingsLib/res/values-be/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Выкарыстанне праверкі HDCP только для змесціва, абароненага DRM"</item> <item msgid="45075631231212732">"Заўсёды выкарыстоўваць праверку HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (стандартная)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Выбар сістэмы (стандартны)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Мона"</item> <item msgid="8883739882299884241">"Стэрэа"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Аптымізавана якасць гуку (990 кбіт/c / 909 кбіт/c)"</item> - <item msgid="2921767058740704969">"Збалансаваная якасць аўдыя і падключэння (660кбіт/c / 606 кбіт/c)"</item> - <item msgid="8860982705384396512">"Аптымізавана якасць падключэння (330 кбіт/c / 303 кбіт/c)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Аптымізавана якасць гуку"</item> - <item msgid="4327143584633311908">"Збалансаваная якасць аўдыя і падключэння"</item> - <item msgid="4681409244565426925">"Аптымізавана якасць падключэння"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Выкл."</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml index 36ebaa309636..7071e52a7e86 100644 --- a/packages/SettingsLib/res/values-be/strings.xml +++ b/packages/SettingsLib/res/values-be/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Не будзе аўтаматычна падключацца"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Няма доступу да інтэрнэту"</string> <string name="saved_network" msgid="4352716707126620811">"Хто захаваў: <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Аўтаматычна падключана праз %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Падлучана праз %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Даступна праз %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Вельмі шпарка"</item> <item msgid="9085102246155045744">"Максімальна хутка"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Выбраць профіль"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Асабісты"</string> <string name="category_work" msgid="8699184680584175622">"Рабочы"</string> <string name="development_settings_title" msgid="215179176067683667">"Параметры распрацоўшчыка"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Інтэнсіўны пераход з Wi‑Fi на маб. сетку"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Заўсёды дазваляць роўмінгавае сканіраванне Wi‑Fi"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Мабільная перадача даных заўсёды актыўная"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Адключыць абсалютны гук"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Версія Bluetooth AVRCP"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Выбраць версію Bluetooth AVRCP"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Кодэк Bluetooth Audio"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Выбраць аўдыякодэк Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Частата дыскрэтызацыі Bluetooth Audio"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Перадача плынню: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Паказаць опцыі сертыфікацыі бесправаднога дысплея"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Падвыс. узровень дэтал-цыі журнала Wi‑Fi у залежн. ад SSID RSSI у Wi‑Fi Picker"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Калі гэта функцыя ўключана, Wi-Fi будзе больш інтэнсіўна імкнуцца перайсці на падключ. маб. перад. даных пры слабым сігнале Wi‑Fi"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Дазволіць/забараніць роўмінгавае сканіраванне Wi‑Fi ў залежнасці ад аб\'ёму трафіку даных у інтэрфейсе"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Памеры буфера для сродку вядзення журнала"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Выберыце памеры сродку вядзення журнала для буфераў журнала"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Перавызначаны <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Засталося прыблізна <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Засталося <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – засталося каля <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – засталося <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> да поўнай зарадкі ад сеткі пер. току"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> да поўнай зарадкі па USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> да поўнай бесправадной зарадкі"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не зараджаецца"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Поўная"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Кантралюецца адміністратарам"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Уключана адміністратарам"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Адключана адміністратарам"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Галоўная старонка налад"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0 %"</item> diff --git a/packages/SettingsLib/res/values-bg/arrays.xml b/packages/SettingsLib/res/values-bg/arrays.xml index 98d216e4dd8c..48407958ebdd 100644 --- a/packages/SettingsLib/res/values-bg/arrays.xml +++ b/packages/SettingsLib/res/values-bg/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Да се използва проверка с HDCP само за DRM съдържание"</item> <item msgid="45075631231212732">"Винаги да се използва проверка с HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (по подразбиране)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Използване на сист. избор (стандартно)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Моно"</item> <item msgid="8883739882299884241">"Стерео"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Оптимизирано за качество на звука (990 или 909 кб/сек)"</item> - <item msgid="2921767058740704969">"Балансирано качество на звука и връзката (660 или 606 кб/сек)"</item> - <item msgid="8860982705384396512">"Оптимизирано за качество на връзката (330 или 303 кб/сек)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Оптимизирано за качество на звука"</item> - <item msgid="4327143584633311908">"Балансирано качество на звука и връзката"</item> - <item msgid="4681409244565426925">"Оптимизирано за качество на връзката"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Изключено"</item> <item msgid="1593289376502312923">"64 КБ"</item> diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml index 9e1ffbb706c9..69b84a84ec29 100644 --- a/packages/SettingsLib/res/values-bg/strings.xml +++ b/packages/SettingsLib/res/values-bg/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Няма да се свърже автоматично"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Няма достъп до интернет"</string> <string name="saved_network" msgid="4352716707126620811">"Запазено от <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Автоматично е установена връзка чрез %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Установена е връзка през „%1$s“"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Мрежата е достъпна през „%1$s“"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Свръхбърза"</item> <item msgid="9085102246155045744">"Най-бърза"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Избиране на потр. профил"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Лични"</string> <string name="category_work" msgid="8699184680584175622">"Служебни"</string> <string name="development_settings_title" msgid="215179176067683667">"Опции на програмиста"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi-Fi към моб. мрежи: Агресивно предав."</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Сканирането за роуминг на Wi-Fi да е разрешено винаги"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Винаги активни мобилни данни"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Деактивиране на пълната сила на звука"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Версия на AVRCP за Bluetooth"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Избиране на версия на AVRCP за Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Аудиокодек за Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Изберете аудиокодек за Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Честота на дискретизация за звука през Bluetooth"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Поточно предаване: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Показване на опциите за сертифициране на безжичния дисплей"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"По-подробно регистр. на Wi‑Fi – данни за RSSI на SSID в инстр. за избор на Wi‑Fi"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"При активиране предаването на връзката за данни от Wi-Fi към мобилната мрежа ще е по-агресивно, когато сигналът за Wi-Fi е слаб"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Разрешаване/забраняване на сканирането за роуминг на Wi-Fi въз основа на посочения в интерфейса обем на трафика на данни"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Размери на регистрац. буфери"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Размер на един рег. буфер: Избор"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Заменено от „<xliff:g id="TITLE">%1$s</xliff:g>“"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Прибл. оставащо време: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Оставащо време: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – около <xliff:g id="TIME">%2$s</xliff:g> оставащо време"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – оставащо време: <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до пълно зареждане при променлив ток"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до пълно зареждане през USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до пълно безжично зареждане"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не се зарежда"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Пълна"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Контролира се от администратор"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Активирано от администратора"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Деактивирано от администратора"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Начален екран на Настройки"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-bn/arrays.xml b/packages/SettingsLib/res/values-bn/arrays.xml index 7a868219ccc8..cd40a63da602 100644 --- a/packages/SettingsLib/res/values-bn/arrays.xml +++ b/packages/SettingsLib/res/values-bn/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"শুধুমাত্র DRM সামগ্রীর জন্য HDCP চেক করা ব্যবহার করুন"</item> <item msgid="45075631231212732">"সর্বদা HDCP পরীক্ষণ ব্যবহার করুন"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (ডিফল্ট)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"সিস্টেমের নির্বাচন ব্যবহার করুন (ডিফল্ট)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"মোনো"</item> <item msgid="8883739882299884241">"স্টিরিও"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"অডিও গুণমানের জন্য অপ্টিমাইজ করা হয়েছে (৯৯০kbps/৯০৯kbps)"</item> - <item msgid="2921767058740704969">"সন্তুলিত গুণমানের অডিও এবং সংযোগ (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"সংযোগের গুণমানের জন্য অপটিমাইজ করা হয়েছে (৩৩০kbps/৩০৩kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"অডিও গুণমানের জন্য অপ্টিমাইজ করা হয়েছে"</item> - <item msgid="4327143584633311908">"সন্তুলিত গুণমানের অডিও এবং সংযোগ"</item> - <item msgid="4681409244565426925">"সংযোগের গুণমানের জন্য অপটিমাইজ করা হয়েছে"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"বন্ধ আছে"</item> <item msgid="1593289376502312923">"৬৪K"</item> diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml index 54cde462a343..443326c6fcc8 100644 --- a/packages/SettingsLib/res/values-bn/strings.xml +++ b/packages/SettingsLib/res/values-bn/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"স্বয়ংক্রিয়ভাবে সংযোগ করবে না"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"কোনো ইন্টারনেট অ্যাক্সেস নেই"</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> দ্বারা সংরক্ষিত"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"স্বয়ংক্রিয়ভাবে %1$s এর মাধ্যমে সংযুক্ত হয়েছে"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s মাধ্যমে সংযুক্ত হয়েছে"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s এর মাধ্যমে উপলব্ধ"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"খুব দ্রুত"</item> <item msgid="9085102246155045744">"দ্রুততম"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"প্রোফাইল বেছে নিন"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"ব্যক্তিগত"</string> <string name="category_work" msgid="8699184680584175622">"কর্মক্ষেত্র"</string> <string name="development_settings_title" msgid="215179176067683667">"বিকাশকারী বিকল্পগুলি"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"নেটওয়ার্কিং"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"ওয়্যারলেস ডিসপ্লে সার্টিফিকেশন"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"ওয়াই-ফাই ভারবোস লগিং সক্ষম করুন"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ওয়াই-ফাই থেকে মোবাইলে তৎপর হস্তান্তর"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"সর্বদা Wifi রোম স্ক্যানকে অনুমতি দিন"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"মোবাইল ডেটা সব সময় সক্রিয় থাক"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"চূড়ান্ত ভলিউম অক্ষম করুন"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ব্লুটুথ AVRCP সংস্করণ"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"ব্লুটুথ AVRCP সংস্করণ বেছে নিন"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"ব্লুটুথ অডিও কোডেক"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"ব্লুটুথ অডিও কোডেক বেছে নিন"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"ব্লুটুথ অডিওর নমুনা হার"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"স্ট্রিমিং: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ওয়্যারলেস প্রদর্শন সার্টিফিকেশন জন্য বিকল্পগুলি দেখান"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ওয়াই-ফাই লগিং স্তর বাড়ান, ওয়াই-ফাই চয়নকারীতে SSID RSSI অনুযায়ী দেখান"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"সক্ষম করা থাকলে, ওয়াই ফাই সিগন্যালের মান খারাপ হলে ডেটা সংযোগ মোবাইলের কাছে হস্তান্তর করার জন্য ওয়াই ফাই আরো বেশি তৎপর হবে।"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"ইন্টারফেসে উপস্থিত ডেটা ট্রাফিকের পরিমাণের উপরে ভিত্তি করে ওয়াই-ফাই রোম স্ক্যানকে অনুমোদিত/অননুমোদিত করুন"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"লগার বাফারের আকারগুলি"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"লগ বাফার প্রতি অপেক্ষাকৃত বড় আকারগুলির নির্বাচন করুন"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> এর দ্বারা ওভাররাইড করা হয়েছে"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"প্রায় <xliff:g id="TIME">%1$s</xliff:g> বাকী আছে"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> বাকী আছে"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - প্রায় <xliff:g id="TIME">%2$s</xliff:g> বাকি আছে"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - AC তে সম্পূর্ণ চার্জ হতে <xliff:g id="TIME">%2$s</xliff:g> লাগবে"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB এর মাধ্যমে সম্পূর্ণ চার্জ হতে <xliff:g id="TIME">%2$s</xliff:g> লাগবে"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - ওয়্যারলেস এর মাধ্যমে সম্পূর্ণ চার্জ হতে <xliff:g id="TIME">%2$s</xliff:g> সময় লাগবে"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"চার্জ হচ্ছে না"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"পূর্ণ"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"প্রশাসকের দ্বারা নিয়ন্ত্রিত"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"প্রশাসক সক্ষম করেছেন"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"প্রশাসক অক্ষম করেছেন"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"সেটিংস হোম"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"০%"</item> diff --git a/packages/SettingsLib/res/values-bs/arrays.xml b/packages/SettingsLib/res/values-bs/arrays.xml index 58b3a47d0030..4cbf09d308e8 100644 --- a/packages/SettingsLib/res/values-bs/arrays.xml +++ b/packages/SettingsLib/res/values-bs/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Koristi HDCP provjeru samo za DRM sadržaj"</item> <item msgid="45075631231212732">"Uvijek koristi HDCP provjeru"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (Zadano)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Koristi odabir sistema (Zadano)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Optimizirano za kvalitet zvuka (990 kbps/909 kbps)"</item> - <item msgid="2921767058740704969">"Uravnotežen kvalitet zvuka i veze (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"Optimizirano za kvalitet veze (330 kbps/303 kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Optimizirano za kvalitet zvuka"</item> - <item msgid="4327143584633311908">"Uravnotežen kvalitet zvuka i veze"</item> - <item msgid="4681409244565426925">"Optimizirano za kvalitet veze"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Isključeno"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml index ce40282174fd..79b701ebfe10 100644 --- a/packages/SettingsLib/res/values-bs/strings.xml +++ b/packages/SettingsLib/res/values-bs/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Neće se automatski povezati"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Nema pristupa internetu"</string> <string name="saved_network" msgid="4352716707126620811">"Sačuvao <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatski povezano koristeći %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Povezani preko %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Dostupan preko %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Veoma ubrzano"</item> <item msgid="9085102246155045744">"Najbrže"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Odaberite profil"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Lično"</string> <string name="category_work" msgid="8699184680584175622">"Posao"</string> <string name="development_settings_title" msgid="215179176067683667">"Opcije za programere"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Umrežavanje"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Certifikacija bežičnog prikaza"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Omogućiti Wi-Fi Verbose zapisivanje"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agresivni prijenos s Wi-Fi mreže na mob."</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Uvijek dopustiti Wi-Fi lutajuće skeniranje"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilna mreža za prijenos podataka je uvijek aktivna"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Onemogućite apsolutnu jačinu zvuka"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP verzija"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Odaberite Bluetooth AVRCP verziju"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth Audio kodek"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Odaberite Bluetooth Audio kodek"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Brzina uzorkovanja za Bluetooth audio"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Prijenos: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Pokaži opcije za certifikaciju Bežičnog prikaza"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povećajte nivo Wi-Fi zapisivanja, pokazati po SSID RSSI Wi-Fi Picker"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Kada je omogućeno, Wi-Fi veza će u slučaju slabog signala agresivnije predavati vezu za prijenos podataka na mobilnu vezu"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Dozvoli/Zabrani Wi-Fi lutajuće skeniranje na osnovu količine podatkovnog prometa prisutnog na sučelju"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Veličine bafera za zapisnik"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Izaberite veličine za Logger prema međumemoriji evidencije"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Zamjenjuje <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Još otprilike <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Imate još <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - imate još <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - imate još <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> do potpune napunjenosti"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> do potpune napunjenosti na adapteru"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> do potpune napunjenosti putem USB-a"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> do potpune napunjenosti bežično"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Nepoznato"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Puni se"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ne puni se"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Puna"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Pod kontrolom administratora"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Omogućio administrator"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Onemogućio je administrator"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Postavke početne stranice"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-ca/arrays.xml b/packages/SettingsLib/res/values-ca/arrays.xml index 3aa72c540e7e..0d79a81a1151 100644 --- a/packages/SettingsLib/res/values-ca/arrays.xml +++ b/packages/SettingsLib/res/values-ca/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Utilitza la comprovació HDCP només per a contingut DRM"</item> <item msgid="45075631231212732">"Utilitza sempre la comprovació HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (predeterminada)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Utilitza selecció del sistema (predeterminada)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Estèreo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Optimitzat per a la qualitat de l\'àudio (990 kbps / 909 kbps)"</item> - <item msgid="2921767058740704969">"Qualitat equilibrada de l\'àudio i la connexió (660 kbps/606 kbps)"</item> - <item msgid="8860982705384396512">"Optimitzat per a la qualitat de la connexió (330 kbps / 303 kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Optimitzat per a la qualitat de l\'àudio"</item> - <item msgid="4327143584633311908">"Qualitat equilibrada de l\'àudio i la connexió"</item> - <item msgid="4681409244565426925">"Optimitzat per a la qualitat de la connexió"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"No"</item> <item msgid="1593289376502312923">"64 K"</item> diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml index e2ba5dd682fe..1645c197f54d 100644 --- a/packages/SettingsLib/res/values-ca/strings.xml +++ b/packages/SettingsLib/res/values-ca/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"No es connectarà automàticament"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"No hi ha accés a Internet"</string> <string name="saved_network" msgid="4352716707126620811">"Desat per <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Connectada automàticament a través de: %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Connectada mitjançant %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Disponible mitjançant %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Molt veloç"</item> <item msgid="9085102246155045744">"Màxima"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Triar un perfil"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Personal"</string> <string name="category_work" msgid="8699184680584175622">"Feina"</string> <string name="development_settings_title" msgid="215179176067683667">"Opcions per a desenvolupadors"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Transferència agressiva de Wi-Fi a mòbil"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permet sempre cerca de Wi-Fi en ininerància"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Dades mòbils sempre actives"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desactiva el volum absolut"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versió AVRCP de Bluetooth"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Selecciona la versió AVRCP de Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Còdec d\'àudio per Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Selecciona el còdec d\'àudio per Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Velocitat de mostra d’àudio per Bluetooth"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"S\'està reproduint en temps real: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostra les opcions de certificació de pantalla sense fil"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Augmenta nivell de registre Wi‑Fi i mostra\'l per SSID RSSI al Selector de Wi‑Fi"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Quan s\'activa, la Wi-Fi és més agressiva en transferir la connexió de dades al mòbil quan el senyal de la Wi-Fi sigui dèbil"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Permet/No permetis cerques de xarxes Wi-Fi en itinerància basades en la quantitat de dades presents a la interfície"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Mides memòria intermèdia Logger"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Mida Logger per memòria intermèdia"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"S\'ha substituït per <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Temps restant aproximat: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Temps restant: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> aproximadament per esgotar la bateria"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g>; temps restant: <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega amb CA"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega per USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega sense fil"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Desconegut"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"S\'està carregant"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"No s\'està carregant"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Plena"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlat per l\'administrador"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Opció activada per l\'administrador"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Opció desactivada per l\'administrador"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Pàgina d\'inici de configuració"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-cs/arrays.xml b/packages/SettingsLib/res/values-cs/arrays.xml index e79e02c0b020..6ee90b4c6ff6 100644 --- a/packages/SettingsLib/res/values-cs/arrays.xml +++ b/packages/SettingsLib/res/values-cs/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Použít kontrolu HDCP pouze pro obsah DRM"</item> <item msgid="45075631231212732">"Vždy používat kontrolu HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (výchozí)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Použít systémový výběr (výchozí)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Optimalizováno pro kvalitu zvuku (990 kb/s / 909 kb/s)"</item> - <item msgid="2921767058740704969">"Vyvážená kvalita zvuku a připojení (660 kb/s / 606 kb/s)"</item> - <item msgid="8860982705384396512">"Optimalizováno pro kvalitu připojení (330 kb/s / 303 kb/s)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Optimalizováno pro kvalitu zvuku"</item> - <item msgid="4327143584633311908">"Vyvážená kvalita zvuku a připojení"</item> - <item msgid="4681409244565426925">"Optimalizováno pro kvalitu připojení"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Vypnuto"</item> <item msgid="1593289376502312923">"64 kB"</item> diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml index f79bd20fe170..709030ae76fa 100644 --- a/packages/SettingsLib/res/values-cs/strings.xml +++ b/packages/SettingsLib/res/values-cs/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Připojení nebude automaticky navázáno"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Nebyl zjištěn žádný přístup k internetu"</string> <string name="saved_network" msgid="4352716707126620811">"Uloženo uživatelem <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automaticky připojeno přes poskytovatele %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Připojeno prostřednictvím %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Dostupné prostřednictvím %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Ultra rychlá"</item> <item msgid="9085102246155045744">"Nejrychlejší"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Vyberte profil"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Osobní"</string> <string name="category_work" msgid="8699184680584175622">"Pracovní"</string> <string name="development_settings_title" msgid="215179176067683667">"Pro vývojáře"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Sítě"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Certifikace bezdrát. displeje"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Podrobné protokolování Wi‑Fi"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agresivní předání z Wi-Fi na mobilní síť"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vždy povolit Wi-Fi roaming"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilní data jsou vždy aktivní"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Zakázat absolutní hlasitost"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Verze profilu Bluetooth AVRCP"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Vyberte verzi profilu Bluetooth AVRCP"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth Audio – kodek"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Vyberte zvukový kodek Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth Audio – vzorkovací frekvence"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streamování: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Zobrazit možnosti certifikace bezdrátového displeje"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Zvýšit úroveň protokolování Wi‑Fi zobrazenou v SSID a RSSI při výběru sítě Wi‑Fi."</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Pokud je tato možnost zapnuta, bude síť Wi-Fi při předávání datového připojení mobilní síti při slabém signálu Wi-Fi agresivnější."</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Povolí nebo zakáže Wi-Fi roaming na základě množství datového provozu na rozhraní."</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Vyrovnávací paměť protokol. nástroje"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Velikost vyrovnávací paměti protokol. nástroje"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Přepsáno nastavením <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Zbývající čas: <xliff:g id="TIME">%1$s</xliff:g> (přibližně)"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Zbývající čas: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – zbývá přibližně <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – zbývá <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – plně se nabije za <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – pomocí adaptéru se plně nabije za <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – přes USB se plně nabije za <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – bezdrátově se plně nabije za <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Neznámé"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Nabíjí se"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nenabíjí se"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Nabitá"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Spravováno administrátorem"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Povoleno administrátorem"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Zakázáno administrátorem"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Domovská stránka Nastavení"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0 %"</item> diff --git a/packages/SettingsLib/res/values-da/arrays.xml b/packages/SettingsLib/res/values-da/arrays.xml index 299f9cd2c385..4e40a35d6311 100644 --- a/packages/SettingsLib/res/values-da/arrays.xml +++ b/packages/SettingsLib/res/values-da/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Brug kun HDCP-kontrol ved DRM-indhold"</item> <item msgid="45075631231212732">"Brug altid HDCP-kontrol"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (standard)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Brug systemvalg (standard)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Optimeret til lydkvalitet (990 kbps/909 kbps)"</item> - <item msgid="2921767058740704969">"Afbalancer lyd- og forbindelseskvalitet (660 kbps/606 kbps)"</item> - <item msgid="8860982705384396512">"Optimeret til forbindelseskvalitet (330 kbps/303 kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Optimeret til lydkvalitet"</item> - <item msgid="4327143584633311908">"Afbalancer lyd- og forbindelseskvalitet"</item> - <item msgid="4681409244565426925">"Optimeret til forbindelseskvalitet"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Fra"</item> <item msgid="1593289376502312923">"64 kB"</item> diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml index fda5fa2ea467..203ac00c0222 100644 --- a/packages/SettingsLib/res/values-da/strings.xml +++ b/packages/SettingsLib/res/values-da/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Der oprettes ikke automatisk forbindelse"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Ingen internetadgang"</string> <string name="saved_network" msgid="4352716707126620811">"Gemt af <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatisk tilsluttet via %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Tilsluttet via %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Tilgængelig via %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Ekstra lynhurtig"</item> <item msgid="9085102246155045744">"Hurtigst"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Vælg profil"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Personlig"</string> <string name="category_work" msgid="8699184680584175622">"Arbejde"</string> <string name="development_settings_title" msgid="215179176067683667">"Indstillinger for udviklere"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Netværk"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Certificering af trådløs skærm"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktivér detaljeret Wi-Fi-logføring"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Tvungen skift fra Wi-Fi til mobildata"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Tillad altid scanning af Wi-Fi-roaming"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobildata er altid aktiveret"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Deaktiver absolut lydstyrke"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"AVRCP-version for Bluetooth"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Vælg AVRCP-version for Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth-lydcodec"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Vælg codec for Bluetooth-lyd"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Eksempelfrekvens for Bluetooth-lyd"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streamer: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Vis valgmuligheder for certificering af trådløs skærm"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Øg mængden af Wi‑Fi-logføring. Vis opdelt efter SSID RSSI i Wi‑Fi-vælgeren"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Når dette er aktiveret, gennemtvinges en overdragelse af dataforbindelsen fra Wi-Fi til mobilnetværk, når Wi-Fi-signalet er svagt"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Tillad/forbyd scanning i forbindelse med Wi-Fi-roaming afhængigt af mængden af datatrafik i grænsefladen"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Størrelser for Logger-buffer"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Vælg Logger-størrelser pr. logbuffer"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Tilsidesat af <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Ca. <xliff:g id="TIME">%1$s</xliff:g> tilbage"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> tilbage"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – ca. <xliff:g id="TIME">%2$s</xliff:g> tilbage"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tilbage"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til det er fuldt opladet"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til det er fuldt opladet (via stikkontakt)"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til det er fuldt opladet (via USB)"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til fuldt opladet (via trådløs)"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Ukendt"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Oplader"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Oplader ikke"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Fuld"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrolleret af administratoren"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Aktiveret af administratoren"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Deaktiveret af administratoren"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Startside for Indstillinger"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0 %"</item> diff --git a/packages/SettingsLib/res/values-de/arrays.xml b/packages/SettingsLib/res/values-de/arrays.xml index 7e199b4a62f5..28dabb3305aa 100644 --- a/packages/SettingsLib/res/values-de/arrays.xml +++ b/packages/SettingsLib/res/values-de/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"HDCP-Prüfung nur für DRM-Inhalte verwenden"</item> <item msgid="45075631231212732">"HDCP-Prüfung immer verwenden"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (Standard)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Systemauswahl verwenden (Standard)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Für Audioqualität optimiert (990 kbit/s/909 kbit/s)"</item> - <item msgid="2921767058740704969">"Ausgeglichene Audio- und Verbindungsqualität (660 kbit/s/606 kbit/s)"</item> - <item msgid="8860982705384396512">"Für Verbindungsqualität optimiert (330 kbit/s/303 kbit/s)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Für Audioqualität optimiert"</item> - <item msgid="4327143584633311908">"Ausgeglichene Audio- und Verbindungsqualität"</item> - <item msgid="4681409244565426925">"Für Verbindungsqualität optimiert"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Aus"</item> <item msgid="1593289376502312923">"64.000"</item> diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml index b43f6a081cf3..a07d4e910a5f 100644 --- a/packages/SettingsLib/res/values-de/strings.xml +++ b/packages/SettingsLib/res/values-de/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Kein automatischer Verbindungsaufbau"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Kein Internetzugriff"</string> <string name="saved_network" msgid="4352716707126620811">"Gespeichert von <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatisch über %1$s verbunden"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Über %1$s verbunden"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Verfügbar über %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Sehr schnell"</item> <item msgid="9085102246155045744">"Am schnellsten"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Profil auswählen"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Nutzer"</string> <string name="category_work" msgid="8699184680584175622">"Geschäftlich"</string> <string name="development_settings_title" msgid="215179176067683667">"Entwickleroptionen"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Netzwerke"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Kabellose Übertragung"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Ausführliche WLAN-Protokolle aktivieren"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressives Handover von WLAN an Mobilfunk"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"WLAN-Roamingsuchen immer zulassen"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile Datennutzung immer aktiviert"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Maximallautstärke deaktivieren"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP-Version"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Bluetooth AVRCP-Version auswählen"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth-Audio-Codec"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Bluetooth-Audio-Codec auswählen"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth-Audio-Abtastrate"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</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">"Level für WLAN-Protokollierung erhöhen, in WiFi Picker pro SSID-RSSI anzeigen"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Wenn diese Option aktiviert ist, ist das WLAN bei schwachem Signal bei der Übergabe der Datenverbindung an den Mobilfunk aggressiver"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"WLAN-Roamingsuchen je nach Umfang des Datentraffics an der Schnittstelle zulassen bzw. nicht zulassen"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Logger-Puffergrößen"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Größe pro Protokollpuffer wählen"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Außer Kraft gesetzt von \"<xliff:g id="TITLE">%1$s</xliff:g>\""</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Noch ca. <xliff:g id="TIME">%1$s</xliff:g> verbleibend"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Noch <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – ungefähr noch <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – noch <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> bis vollständig geladen"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> bis vollständig am Stromnetz geladen"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> bis vollständig über USB geladen"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> bis drahtlos vollständig geladen"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Unbekannt"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Wird aufgeladen"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Wird nicht geladen"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Voll"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Durch den Administrator verwaltet"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Vom Administrator aktiviert"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Vom Administrator deaktiviert"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Startseite \"Einstellungen\""</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0 %"</item> diff --git a/packages/SettingsLib/res/values-el/arrays.xml b/packages/SettingsLib/res/values-el/arrays.xml index fdbece744d25..6987b9ae3b96 100644 --- a/packages/SettingsLib/res/values-el/arrays.xml +++ b/packages/SettingsLib/res/values-el/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Χρήση ελέγχου HDCP μόνο για περιεχόμενο DRM"</item> <item msgid="45075631231212732">"Να χρησιμοποιείται πάντα έλεγχος HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (Προεπιλογή)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Χρήση επιλογής συστήματος (Προεπιλογή)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Μονοφωνικό"</item> <item msgid="8883739882299884241">"Στερεοφωνικό"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Βελτιστοποιημένο για ποιότητα ήχου (990kbps/909kbps)"</item> - <item msgid="2921767058740704969">"Ισορροπημένος ήχος και ποιότητα σύνδεσης (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"Βελτιστοποιημένο για ποιότητα σύνδεσης (330kbps/303kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Βελτιστοποιημένο για ποιότητα ήχου"</item> - <item msgid="4327143584633311908">"Ισορροπημένος ήχος και ποιότητα σύνδεσης"</item> - <item msgid="4681409244565426925">"Βελτιστοποιημένο για ποιότητα σύνδεσης"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Ανενεργό"</item> <item msgid="1593289376502312923">"64 K"</item> diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml index a614a3026704..0632c7b24992 100644 --- a/packages/SettingsLib/res/values-el/strings.xml +++ b/packages/SettingsLib/res/values-el/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Δεν θα συνδεθεί αυτόματα"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Δεν υπάρχει πρόσβαση στο διαδίκτυο"</string> <string name="saved_network" msgid="4352716707126620811">"Αποθηκεύτηκε από <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Συνδέθηκε αυτόματα μέσω %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Συνδέθηκε μέσω %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Διαθέσιμο μέσω %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Εξαιρετικά ταχεία"</item> <item msgid="9085102246155045744">"Ταχύτατη"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Επιλογή προφίλ"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Προσωπικό"</string> <string name="category_work" msgid="8699184680584175622">"Εργασία"</string> <string name="development_settings_title" msgid="215179176067683667">"Επιλογές για προγραμματιστές"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Επιθ.μεταβ. Wi-Fi σε δίκτυο κιν.τηλ."</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Να επιτρέπεται πάντα η σάρωση Wi-Fi κατά την περιαγωγή"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Πάντα ενεργά δεδομένα κινητής τηλεφωνίας"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Απενεργοποίηση απόλυτης έντασης"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Έκδοση AVRCP Bluetooth"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Επιλογή έκδοσης AVRCP Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Κωδικοποιητής ήχου Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Επιλογή κωδικοποιητή ήχου Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Ρυθμός δειγματοληψίας ήχου Bluetooth"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Ροή: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</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> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Όταν είναι ενεργό, το Wi-Fi θα μεταβιβάζει πιο επιθετικά τη σύνδ.δεδομένων σε δίκτυο κινητής τηλ., όταν το σήμα Wi-Fi είναι χαμηλό"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Να επιτρέπεται/να μην επιτρέπεται η σάρωση Wi-Fi κατά την περιαγωγή, βάσει της ποσότητας επισκεψιμότητας δεδομένων στη διεπαφή"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Μέγεθος προσωρινής μνήμης για τη λειτουργία καταγραφής"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Μέγεθος αρχείων κατ/φής ανά προ/νή μνήμη αρχείου κατ/φής"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Αντικαταστάθηκε από <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Απομένουν περίπου <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Απομένει/ουν <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - απομένουν περίπου <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - απομένει/ουν <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για πλήρη φόρτιση με AC"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για πλήρη φόρτιση μέσω USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για πλήρη φόρτιση ασύρματα"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Δεν φορτίζει"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Πλήρης"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Ελέγχονται από το διαχειριστή"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Ενεργοποιήθηκε από το διαχειριστή"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Απενεργοποιήθηκε από το διαχειριστή"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Αρχική σελίδα ρυθμίσεων"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-en-rAU/arrays.xml b/packages/SettingsLib/res/values-en-rAU/arrays.xml index 9e125e7b7b0e..1bc7b8c2b515 100644 --- a/packages/SettingsLib/res/values-en-rAU/arrays.xml +++ b/packages/SettingsLib/res/values-en-rAU/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Use HDCP checking for DRM content only"</item> <item msgid="45075631231212732">"Always use HDCP checking"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Use System Selection (Default)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Optimised for Audio Quality (990kbps/909kbps)"</item> - <item msgid="2921767058740704969">"Balanced Audio And Connection Quality (660 kbps/606 kbps)"</item> - <item msgid="8860982705384396512">"Optimised for Connection Quality (330kbps/303kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Optimised for Audio Quality"</item> - <item msgid="4327143584633311908">"Balanced Audio and Connection Quality"</item> - <item msgid="4681409244565426925">"Optimised for Connection Quality"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Off"</item> <item msgid="1593289376502312923">"64 K"</item> diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml index ad6eae9f63be..04c51eaba53d 100644 --- a/packages/SettingsLib/res/values-en-rAU/strings.xml +++ b/packages/SettingsLib/res/values-en-rAU/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Won\'t automatically connect"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"No Internet access"</string> <string name="saved_network" msgid="4352716707126620811">"Saved by <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatically connected via %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Connected via %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Very rapid"</item> <item msgid="9085102246155045744">"Fastest"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Choose Profile"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Personal"</string> <string name="category_work" msgid="8699184680584175622">"Work"</string> <string name="development_settings_title" msgid="215179176067683667">"Developer options"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Wireless display certification"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Enable Wi‑Fi verbose logging"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressive Wi‑Fi to mobile handover"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Always allow Wi‑Fi Roam Scans"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Disable absolute volume"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP Version"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Select Bluetooth AVRCP Version"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth Audio Codec"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Select Bluetooth Audio Codec"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth Audio Sample Rate"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"When enabled, Wi‑Fi will be more aggressive in handing over the data connection to mobile, when Wi‑Fi signal is low"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Allow/Disallow Wi‑Fi Roam Scans based on the amount of data traffic present at the interface"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Logger buffer sizes"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Select Logger sizes per log buffer"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Approx. <xliff:g id="TIME">%1$s</xliff:g> left"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> left"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – about <xliff:g id="TIME">%2$s</xliff:g> left"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> left"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged on AC"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged over USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged from wireless"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Unknown"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Not charging"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Enabled by administrator"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Disabled by administrator"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Settings Home"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-en-rGB/arrays.xml b/packages/SettingsLib/res/values-en-rGB/arrays.xml index 9e125e7b7b0e..1bc7b8c2b515 100644 --- a/packages/SettingsLib/res/values-en-rGB/arrays.xml +++ b/packages/SettingsLib/res/values-en-rGB/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Use HDCP checking for DRM content only"</item> <item msgid="45075631231212732">"Always use HDCP checking"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Use System Selection (Default)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Optimised for Audio Quality (990kbps/909kbps)"</item> - <item msgid="2921767058740704969">"Balanced Audio And Connection Quality (660 kbps/606 kbps)"</item> - <item msgid="8860982705384396512">"Optimised for Connection Quality (330kbps/303kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Optimised for Audio Quality"</item> - <item msgid="4327143584633311908">"Balanced Audio and Connection Quality"</item> - <item msgid="4681409244565426925">"Optimised for Connection Quality"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Off"</item> <item msgid="1593289376502312923">"64 K"</item> diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml index ad6eae9f63be..04c51eaba53d 100644 --- a/packages/SettingsLib/res/values-en-rGB/strings.xml +++ b/packages/SettingsLib/res/values-en-rGB/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Won\'t automatically connect"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"No Internet access"</string> <string name="saved_network" msgid="4352716707126620811">"Saved by <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatically connected via %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Connected via %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Very rapid"</item> <item msgid="9085102246155045744">"Fastest"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Choose Profile"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Personal"</string> <string name="category_work" msgid="8699184680584175622">"Work"</string> <string name="development_settings_title" msgid="215179176067683667">"Developer options"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Wireless display certification"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Enable Wi‑Fi verbose logging"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressive Wi‑Fi to mobile handover"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Always allow Wi‑Fi Roam Scans"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Disable absolute volume"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP Version"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Select Bluetooth AVRCP Version"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth Audio Codec"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Select Bluetooth Audio Codec"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth Audio Sample Rate"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"When enabled, Wi‑Fi will be more aggressive in handing over the data connection to mobile, when Wi‑Fi signal is low"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Allow/Disallow Wi‑Fi Roam Scans based on the amount of data traffic present at the interface"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Logger buffer sizes"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Select Logger sizes per log buffer"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Approx. <xliff:g id="TIME">%1$s</xliff:g> left"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> left"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – about <xliff:g id="TIME">%2$s</xliff:g> left"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> left"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged on AC"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged over USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged from wireless"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Unknown"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Not charging"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Enabled by administrator"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Disabled by administrator"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Settings Home"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-en-rIN/arrays.xml b/packages/SettingsLib/res/values-en-rIN/arrays.xml index 9e125e7b7b0e..1bc7b8c2b515 100644 --- a/packages/SettingsLib/res/values-en-rIN/arrays.xml +++ b/packages/SettingsLib/res/values-en-rIN/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Use HDCP checking for DRM content only"</item> <item msgid="45075631231212732">"Always use HDCP checking"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Use System Selection (Default)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Optimised for Audio Quality (990kbps/909kbps)"</item> - <item msgid="2921767058740704969">"Balanced Audio And Connection Quality (660 kbps/606 kbps)"</item> - <item msgid="8860982705384396512">"Optimised for Connection Quality (330kbps/303kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Optimised for Audio Quality"</item> - <item msgid="4327143584633311908">"Balanced Audio and Connection Quality"</item> - <item msgid="4681409244565426925">"Optimised for Connection Quality"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Off"</item> <item msgid="1593289376502312923">"64 K"</item> diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml index ad6eae9f63be..04c51eaba53d 100644 --- a/packages/SettingsLib/res/values-en-rIN/strings.xml +++ b/packages/SettingsLib/res/values-en-rIN/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Won\'t automatically connect"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"No Internet access"</string> <string name="saved_network" msgid="4352716707126620811">"Saved by <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatically connected via %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Connected via %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Very rapid"</item> <item msgid="9085102246155045744">"Fastest"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Choose Profile"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Personal"</string> <string name="category_work" msgid="8699184680584175622">"Work"</string> <string name="development_settings_title" msgid="215179176067683667">"Developer options"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Wireless display certification"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Enable Wi‑Fi verbose logging"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressive Wi‑Fi to mobile handover"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Always allow Wi‑Fi Roam Scans"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Disable absolute volume"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP Version"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Select Bluetooth AVRCP Version"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth Audio Codec"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Select Bluetooth Audio Codec"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth Audio Sample Rate"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"When enabled, Wi‑Fi will be more aggressive in handing over the data connection to mobile, when Wi‑Fi signal is low"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Allow/Disallow Wi‑Fi Roam Scans based on the amount of data traffic present at the interface"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Logger buffer sizes"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Select Logger sizes per log buffer"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Approx. <xliff:g id="TIME">%1$s</xliff:g> left"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> left"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – about <xliff:g id="TIME">%2$s</xliff:g> left"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> left"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged on AC"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged over USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged from wireless"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Unknown"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Not charging"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Enabled by administrator"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Disabled by administrator"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Settings Home"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-es-rUS/arrays.xml b/packages/SettingsLib/res/values-es-rUS/arrays.xml index b97675456da3..ed30bace293b 100644 --- a/packages/SettingsLib/res/values-es-rUS/arrays.xml +++ b/packages/SettingsLib/res/values-es-rUS/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Usar comprobación HDCP para contenido DRM solamente"</item> <item msgid="45075631231212732">"Siempre utilizar comprobación HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (predeterminado)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Usar selección del sistema (predeterminado)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Estéreo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Optimizado para la calidad de audio (990 kbps/909 kbps)"</item> - <item msgid="2921767058740704969">"Calidad de audio y conexión equilibrada (660 kbps/606 kbps)"</item> - <item msgid="8860982705384396512">"Optimizado para la calidad de conexión (330 kbps/303 kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Optimizado para la calidad de audio"</item> - <item msgid="4327143584633311908">"Calidad de audio y conexión equilibrada"</item> - <item msgid="4681409244565426925">"Optimizado para calidad de conexión"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Desactivado"</item> <item msgid="1593289376502312923">"64 K"</item> diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index 4ce3bc22a28f..e0c911b3f5b8 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"No se conectará automáticamente"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"No se detectó acceso a Internet"</string> <string name="saved_network" msgid="4352716707126620811">"Guardadas por <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Conexión automática mediante %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Conexión a través de %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Disponible a través de %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Muy rápida"</item> <item msgid="9085102246155045744">"A velocidad máxima"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Elegir perfil"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Personal"</string> <string name="category_work" msgid="8699184680584175622">"Trabajo"</string> <string name="development_settings_title" msgid="215179176067683667">"Opciones del programador"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Certificación de pantalla inalámbrica"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Habilitar registro detallado de Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Priorizar cambio de red Wi-Fi a móvil"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permitir siempre búsquedas de Wi-Fi"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Datos móviles siempre activados"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Inhabilitar volumen absoluto"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versión de AVRCP del Bluetooth"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Selecciona la versión de AVRCP del Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Códec del audio Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Seleccionar códec del audio Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Frecuencia de muestreo del audio Bluetooth"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Transmitiendo: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opciones de certificación de pantalla inalámbrica"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar nivel de registro Wi-Fi; mostrar por SSID RSSI en el selector de Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Si habilitas esta opción, se priorizará el cambio de Wi-Fi a datos móviles cuando la señal de Wi-Fi sea débil"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Permitir/no permitir las búsquedas de Wi-Fi basadas la cantidad de tráfico de datos presente en la interfaz"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Tamaños de búfer de Logger"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Selecciona el tamaño del Logger por búfer"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Reemplazado por <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Falta <xliff:g id="TIME">%1$s</xliff:g> aproximadamente"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Tiempo restante: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> (tiempo restante: <xliff:g id="TIME">%2$s</xliff:g>)"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - Tiempo restante: <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g> hasta completar la carga)"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g> hasta completar la carga por CA)"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g> hasta completar la carga por USB)"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g> hasta completar la carga inalámbrica)"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Desconocido"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"No se realiza la carga"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Cargado"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlada por el administrador"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Habilitada por el administrador"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Inhabilitada por el administrador"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Pantalla de configuración"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-es/arrays.xml b/packages/SettingsLib/res/values-es/arrays.xml index 1bc0098bbc21..7c1528f56abb 100644 --- a/packages/SettingsLib/res/values-es/arrays.xml +++ b/packages/SettingsLib/res/values-es/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Utilizar comprobación de HDCP solo para contenido DRM"</item> <item msgid="45075631231212732">"Utilizar siempre comprobación de HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (Predeterminada)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Usar preferencia del sistema (predeter.)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Estéreo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Optimizado para la calidad del audio (990 kbps/909 kbps)"</item> - <item msgid="2921767058740704969">"Equilibrar la calidad del audio y de la conexión (660/606&nbsp;kbps)"</item> - <item msgid="8860982705384396512">"Optimizado para la calidad de la conexión (330 kbps/303 kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Se ha optimizado para la calidad del audio"</item> - <item msgid="4327143584633311908">"Equilibrar la calidad del audio y la de la conexión"</item> - <item msgid="4681409244565426925">"Se ha optimizado para la calidad de la conexión"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"No"</item> <item msgid="1593289376502312923">"64 K"</item> diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml index d9347a361f58..3506f62d481e 100644 --- a/packages/SettingsLib/res/values-es/strings.xml +++ b/packages/SettingsLib/res/values-es/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"No se establecerá conexión automáticamente"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"No se ha detectado acceso a Internet"</string> <string name="saved_network" msgid="4352716707126620811">"Guardadas por <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Conectada automáticamente a través de %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado a través de %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Disponible a través de %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Hiperrrápida"</item> <item msgid="9085102246155045744">"La más rápida"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Seleccionar perfil"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Personal"</string> <string name="category_work" msgid="8699184680584175622">"Trabajo"</string> <string name="development_settings_title" msgid="215179176067683667">"Opciones de desarrollo"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Certificación de pantalla inalámbrica"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Habilitar registro Wi-Fi detallado"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Transferencia total de Wi-Fi a móvil"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permitir siempre búsquedas de Wi-Fi"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Datos móviles siempre activos"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Inhabilitar volumen absoluto"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versión AVRCP del Bluetooth"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Selecciona la versión AVRCP del Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Códec de audio por Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Selecciona el códec de audio por Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Porcentaje de muestreo de audio por Bluetooth"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opciones para la certificación de la pantalla inalámbrica"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar el nivel de logging de Wi-Fi, mostrar por SSID RSSI en el selector Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Si está habilitada, la conexión Wi-Fi será más agresiva al transferir la conexión de datos al móvil (si la señal Wi-Fi es baja)"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Permitir/No permitir búsquedas de Wi-Fi basadas en la cantidad de tráfico de datos presente en la interfaz"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Tamaños de búfer de registrador"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Elige el tamaño del Logger por búfer"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Anulado por <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Tiempo restante (aproximado): <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Tiempo restante: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - tiempo aproximado restante: <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - Tiempo restante: <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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 la carga"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar la carga con CA"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar la carga con USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar la carga inalámbrica"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Desconocido"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"No se está cargando"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Completa"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlada por el administrador"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Habilitado por el administrador"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Inhabilitado por el administrador"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Página principal de ajustes"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-et/arrays.xml b/packages/SettingsLib/res/values-et/arrays.xml index db58188f37ee..f7a70003a24d 100644 --- a/packages/SettingsLib/res/values-et/arrays.xml +++ b/packages/SettingsLib/res/values-et/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Kasuta HDCP-kontrolli ainult DRM-sisu korral"</item> <item msgid="45075631231212732">"Kasuta alati HDCP-kontrollimist"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (vaikeseade)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Süsteemi valiku kasutamine (vaikeseade)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Helikvaliteedi jaoks optimeeritud (990/909 kbit/s)"</item> - <item msgid="2921767058740704969">"Tasakaalustatud heli- ja ühenduskvaliteet (660/606 kbit/s)"</item> - <item msgid="8860982705384396512">"Ühenduskvaliteedi jaoks optimeeritud (330/303 kbit/s)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Helikvaliteedi jaoks optimeeritud"</item> - <item msgid="4327143584633311908">"Tasakaalustatud heli- ja ühenduskvaliteet"</item> - <item msgid="4681409244565426925">"Ühenduskvaliteedi jaoks optimeeritud"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Väljas"</item> <item msgid="1593289376502312923">"64 000"</item> diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml index d643d9078f95..044389209e38 100644 --- a/packages/SettingsLib/res/values-et/strings.xml +++ b/packages/SettingsLib/res/values-et/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Automaatselt ei ühendata"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Interneti-ühendus puudub"</string> <string name="saved_network" msgid="4352716707126620811">"Salvestas: <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Ühendus loodi automaatselt teenusega %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Ühendatud üksuse %1$s kaudu"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Saadaval üksuse %1$s kaudu"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Väga tormakas"</item> <item msgid="9085102246155045744">"Kõige kiirem"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Profiili valimine"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Isiklik"</string> <string name="category_work" msgid="8699184680584175622">"Töö"</string> <string name="development_settings_title" msgid="215179176067683667">"Arendaja valikud"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Võrgustik"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Juhtmeta ekraaniühenduse sertifitseerimine"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Luba WiFi paljusõnaline logimine"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agress. üleminek WiFi-lt mobiilsidele"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Luba alati WiFi-rändluse skannimine"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiilne andmeside on alati aktiivne"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Keela absoluutne helitugevus"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetoothi AVRCP versioon"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Valige Bluetoothi AVRCP versioon"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetoothi heli kodek"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Valige Bluetoothi helikodek"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetoothi heli diskreetimissagedus"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Voogesitus: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Juhtmeta ekraaniühenduse sertifitseerimisvalikute kuvamine"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Suurenda WiFi logimistaset, kuva WiFi valijas SSID RSSI järgi"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Kui seade on lubatud, asendatakse nõrga signaaliga WiFi-ühendus agressiivsemalt mobiilse andmesideühendusega"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Luba/keela WiFi-rändluse skannimine liidese andmeliikluse põhjal"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Logija puhvri suurused"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Vali logija suur. logipuhvri kohta"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Alistas <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Umbes <xliff:g id="TIME">%1$s</xliff:g> on jäänud"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> on jäänud"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – umbes <xliff:g id="TIME">%2$s</xliff:g> on jäänud"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> on jäänud"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täislaadimiseni"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täislaadimiseni vahelduvvooluvõrgus"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täislaadimiseni USB kaudu"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täislaadim. juhtmeta ühenduse kaudu"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Tundmatu"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Laadimine"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ei lae"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Täis"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Juhib administraator"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Administraator on lubanud"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Administraator on keelanud"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Seadete avaleht"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-eu/arrays.xml b/packages/SettingsLib/res/values-eu/arrays.xml index 601bdea1cf0d..4214ea1ef81e 100644 --- a/packages/SettingsLib/res/values-eu/arrays.xml +++ b/packages/SettingsLib/res/values-eu/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Erabili HDCP egiaztapena DRM edukirako soilik"</item> <item msgid="45075631231212732">"Erabili beti HDCP egiaztapena"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (lehenetsia)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Erabili sistema-hautapena (lehenetsia)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Monoa"</item> <item msgid="8883739882299884241">"Estereoa"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Audioaren kalitatea areagotzeko optimizatua (990 Kb/s / 909 Kb/s)"</item> - <item msgid="2921767058740704969">"Audioaren eta konexioaren kalitate orekatua (660 Kb/s / 606 Kb/s)"</item> - <item msgid="8860982705384396512">"Konexioaren kalitatea areagotzeko optimizatua (330 Kb/s / 303 Kb/s)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Audioaren kalitatea areagotzeko optimizatua"</item> - <item msgid="4327143584633311908">"Orekatu audioaren eta konexioaren kalitateak"</item> - <item msgid="4681409244565426925">"Konexioaren kalitatea areagotzeko optimizatua"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Desaktibatuta"</item> <item msgid="1593289376502312923">"64 K"</item> diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml index 6556a485e3d5..9293ef4497e0 100644 --- a/packages/SettingsLib/res/values-eu/strings.xml +++ b/packages/SettingsLib/res/values-eu/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Ez da konektatuko automatikoki"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Ezin da konektatu Internetera"</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> aplikazioak gorde du"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s bidez automatikoki konektatuta"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s bidez konektatuta"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s bidez erabilgarri"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Oso bizkorra"</item> <item msgid="9085102246155045744">"Bizkorrena"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Aukeratu profila"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Pertsonalak"</string> <string name="category_work" msgid="8699184680584175622">"Lanekoak"</string> <string name="development_settings_title" msgid="215179176067683667">"Garatzaileen aukerak"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Sareak"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Hari gabeko bistaratze-egiaztatzea"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Gaitu Wi-Fi sareetan saioa hasteko modu xehatua"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Behartu Wi-Fi konexiotik datuenera aldatzera"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Onartu beti ibiltaritzan Wi-Fi sareak bilatzea"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Datu-konexioa beti aktibo"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desgaitu bolumen absolutua"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP bertsioa"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Hautatu Bluetooth AVRCP bertsioa"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth bidezko audioaren kodeka"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Hautatu Bluetooth audioaren kodeka"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth bidezko audioaren lagin-abiadura"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Igortzean: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Erakutsi hari gabeko bistaratze-egiaztapenaren aukerak"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Erakutsi datu gehiago Wi-Fi sareetan saioa hasterakoan. Erakutsi sarearen identifikatzailea eta seinalearen indarra Wi‑Fi sareen hautagailuan."</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Aukera hori gaituz gero, gailua nahitaez aldatuko da datu-konexiora Wi-Fi seinalea ahultzen dela nabaritutakoan"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Onartu edo debekatu ibiltaritzan Wi-Fi sareak bilatzea, interfazeko datu-trafikoaren arabera"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Erregistroen buffer-tamainak"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Hautatu erregistroen buffer-tamainak"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> hobespena gainjarri zaio"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"<xliff:g id="TIME">%1$s</xliff:g> inguru guztiz kargatu arte"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> guztiz kargatu arte"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> inguru gelditzen dira"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> guztiz kargatu arte"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> guztiz kargatu arte"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> korronte bidez guztiz kargatu arte"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB bidez guztiz kargatu arte"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> haririk gabe guztiz kargatu arte"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Ezezaguna"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Kargatzea"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ez da kargatzen ari"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Beteta"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Administratzaileak kontrolatzen du"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Administratzaileak gaitu du"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Administratzaileak desgaitu du"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Ezarpenen hasierako pantaila"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"% 0"</item> diff --git a/packages/SettingsLib/res/values-fa/arrays.xml b/packages/SettingsLib/res/values-fa/arrays.xml index 3dd6a3a54893..05bd6ca43cf2 100644 --- a/packages/SettingsLib/res/values-fa/arrays.xml +++ b/packages/SettingsLib/res/values-fa/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"استفاده از بررسی HDCP فقط برای محتوای DRM"</item> <item msgid="45075631231212732">"همیشه از بررسی HDCP استفاده شود"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP نسخه ۱.۴ (پیشفرض)"</item> + <item msgid="2089555299377409443">"AVRCP نسخه ۱.۵"</item> + <item msgid="2895327394279434278">"AVRCP نسخه ۱.۶"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp نسخه ۱۴"</item> + <item msgid="1913619118958233129">"avrcp نسخه ۱۵"</item> + <item msgid="7142710449249088270">"avrcp نسخه ۱۶"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"استفاده از انتخاب سیستم (پیشفرض)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"مونو"</item> <item msgid="8883739882299884241">"استریو"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"بهینهشده برای کیفیت صوت (۹۹۰ کیلوبیت در ثانیه/۹۰۹ کیلوبیت در ثانیه)"</item> - <item msgid="2921767058740704969">"کیفیت متعادل صوت و اتصال (۶۶۰ کیلوبیت در ثانیه/۶۰۶ کیلوبیت در ثانیه)"</item> - <item msgid="8860982705384396512">"بهینهشده برای کیفیت اتصال (۳۳۰ کیلوبیت در ثانیه/۳۰۳ کیلوبیت در ثانیه)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"بهینهشده برای کیفیت صوت"</item> - <item msgid="4327143584633311908">"کیفیت متعادل صوت و اتصال"</item> - <item msgid="4681409244565426925">"بهینهشده برای کیفیت اتصال"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"خاموش"</item> <item msgid="1593289376502312923">"۶۴ هزار"</item> diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index df66a1a43cb2..0cc42df5e95c 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"اتصال بهصورت خودکار انجام نمیشود"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"دسترسی به اینترنت وجود ندارد"</string> <string name="saved_network" msgid="4352716707126620811">"ذخیرهشده توسط <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"اتصال خودکار ازطریق %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"متصل از طریق %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"در دسترس از طریق %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"خیلی تند"</item> <item msgid="9085102246155045744">"سریعترین"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"انتخاب نمایه"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"شخصی"</string> <string name="category_work" msgid="8699184680584175622">"محل کار"</string> <string name="development_settings_title" msgid="215179176067683667">"گزینههای برنامهنویسان"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi‑Fi قوی برای واگذاری به دستگاه همراه"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"اسکنهای رومینگ Wi‑Fi همیشه مجاز است"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"داده تلفن همراه همیشه فعال باشد"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"غیرفعال کردن میزان صدای مطلق"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"نسخه AVRCP بلوتوث"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"انتخاب نسخه AVRCP بلوتوث"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"کدک بلوتوث صوتی"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"انتخاب کدک صوتی بلوتوث"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"سرعت نمونه بلوتوث صوتی"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"پخش جریانی: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</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> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"زمانیکه فعال است، درشرایطی که سیگنال Wi-Fi ضعیف باشد، Wi‑Fi برای واگذاری اتصال داده به دستگاه همراه قویتر عمل خواهد کرد."</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"مجاز/غیرمجاز کردن اسکنهای رومینگ Wi‑Fi براساس مقدار ترافیک داده موجود در واسط"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"اندازههای حافظه موقت ثبتکننده"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"انتخاب اندازه ثبتکننده در حافظه موقت ثبت"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"توسط <xliff:g id="TITLE">%1$s</xliff:g> لغو شد"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"تقریباً <xliff:g id="TIME">%1$s</xliff:g> باقی مانده است"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> باقی مانده"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - تقریباً <xliff:g id="TIME">%2$s</xliff:g> باقی مانده است"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> مانده تا شارژ کامل ازطریق برق متناوب"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> مانده تا شارژ کامل ازطریق USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> مانده تا شارژ کامل بهصورت بیسیم"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"شارژ نمیشود"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"پر"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"توسط سرپرست سیستم کنترل میشود"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"سرپرست آن را فعال کرده است"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"سرپرست آن را غیرفعال کرده است"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"صفحه اصلی تنظیمات"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"٪۰"</item> diff --git a/packages/SettingsLib/res/values-fi/arrays.xml b/packages/SettingsLib/res/values-fi/arrays.xml index dee7555a36e9..be638ba0a8e7 100644 --- a/packages/SettingsLib/res/values-fi/arrays.xml +++ b/packages/SettingsLib/res/values-fi/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Käytä HDCP-tarkistusta vain DRM-suojatulle sisällölle"</item> <item msgid="45075631231212732">"Käytä aina HDCP-tarkistusta"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (oletus)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Käytä järjestelmän valintaa (oletus)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Optimoi äänenlaatu (990 kb/s / 909 kb/s)"</item> - <item msgid="2921767058740704969">"Tasapainoinen yhteyden ja äänenlaadun optimointi (660 kb/s / 606 kb/s)"</item> - <item msgid="8860982705384396512">"Optimoi yhteyden laatu (330 kb/s / 303 kb/s)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Optimoi äänenlaatu"</item> - <item msgid="4327143584633311908">"Tasapainoinen yhteyden ja äänenlaadun optimointi"</item> - <item msgid="4681409244565426925">"Optimoi yhteyden laatu"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Ei käytössä"</item> <item msgid="1593289376502312923">"64 kt"</item> diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml index ff88d1c97b45..3b008bfe5780 100644 --- a/packages/SettingsLib/res/values-fi/strings.xml +++ b/packages/SettingsLib/res/values-fi/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Yhteyttä ei muodosteta automaattisesti"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Ei internetyhteyttä"</string> <string name="saved_network" msgid="4352716707126620811">"Tallentaja: <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automaattinen yhteys muodostettu palvelun %1$s kautta"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Yhdistetty seuraavan kautta: %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Käytettävissä seuraavan kautta: %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Erittäin nopea"</item> <item msgid="9085102246155045744">"Nopein"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Valitse profiili"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Henkilökohtainen"</string> <string name="category_work" msgid="8699184680584175622">"Työ"</string> <string name="development_settings_title" msgid="215179176067683667">"Kehittäjäasetukset"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Yhteysominaisuudet"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Langattoman näytön sertifiointi"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Käytä Wi-Fin laajennettua lokikirjausta"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Vaihda herkästi Wi-Fi mobiiliyhteyteen"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Salli Wi-Fi-verkkovierailuskannaus aina"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiilidata aina käytössä"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Poista yleinen äänenvoimakkuuden säätö käytöstä"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetoothin AVRCP-versio"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Valitse Bluetoothin AVRCP-versio"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth-äänen koodekki"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Valitse Bluetooth-äänen koodekki"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth-ääninäytteen siirtonopeus"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Striimaus: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Näytä langattoman näytön sertifiointiin liittyvät asetukset"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Lisää Wi‑Fin lokikirjaustasoa, näytä SSID RSSI -kohtaisesti Wi‑Fi-valitsimessa."</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Kun asetus on käytössä, datayhteys siirtyy helpommin Wi-Fistä matkapuhelinverkkoon, jos Wi-Fi-signaali on heikko."</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Salli/estä Wi-Fi-verkkovierailuskannaus liittymässä esiintyvän dataliikenteen perusteella."</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Lokipuskurien koot"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Valitse puskurikohtaiset lokikoot"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Tämän ohittaa <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Noin <xliff:g id="TIME">%1$s</xliff:g> jäljellä"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> jäljellä"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – noin <xliff:g id="TIME">%2$s</xliff:g> jäljellä"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> jäljellä"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täyteen lataukseen"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täyteen lataukseen (laturi)"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täyteen lataukseen (USB-lataus)"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täyteen lataukseen (langaton lataus)"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Tuntematon"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Ladataan"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ei laturissa"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Täynnä"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Järjestelmänvalvoja hallinnoi tätä asetusta."</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Järjestelmänvalvojan käyttöön ottama"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Järjestelmänvalvojan käytöstä poistama"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Asetusten etusivu"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0 %"</item> diff --git a/packages/SettingsLib/res/values-fr-rCA/arrays.xml b/packages/SettingsLib/res/values-fr-rCA/arrays.xml index f704ea44753d..8a9fbddfced0 100644 --- a/packages/SettingsLib/res/values-fr-rCA/arrays.xml +++ b/packages/SettingsLib/res/values-fr-rCA/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Utiliser la vérification HDCP uniquement pour le contenu GDN"</item> <item msgid="45075631231212732">"Toujours utiliser la vérification HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (par défaut)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Utiliser sélect. du système (par défaut)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stéréo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Optimisé pour la qualité audio (990 kbps/909 kbps)"</item> - <item msgid="2921767058740704969">"Qualité audio et de la connexion équilibrée (660 kbps/606 kbps)"</item> - <item msgid="8860982705384396512">"Optimisé pour la qualité de connexion (330 kbps/303 kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Optimisé pour la qualité audio"</item> - <item msgid="4327143584633311908">"Qualité audio et de la connexion équilibrée"</item> - <item msgid="4681409244565426925">"Optimisé pour la qualité de connexion"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Désactivé"</item> <item msgid="1593289376502312923">"64 ko"</item> diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml index ae57852e522b..e9d882ee81b5 100644 --- a/packages/SettingsLib/res/values-fr-rCA/strings.xml +++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Reconnexion automatique impossible"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Aucun accès à Internet"</string> <string name="saved_network" msgid="4352716707126620811">"Enregistrés par <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatiquement connecté par %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Connecté par %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Accessible par %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Très rapide"</item> <item msgid="9085102246155045744">"La plus rapide"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Sélectionnez un profil"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Personnel"</string> <string name="category_work" msgid="8699184680584175622">"Travail"</string> <string name="development_settings_title" msgid="215179176067683667">"Options pour les développeurs"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Réseautage"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Certification de l\'affichage sans fil"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Autoriser enreg. données Wi-Fi détaillées"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Passage forcé du Wi-Fi aux données cell."</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Toujours autoriser la détection de réseaux Wi-Fi en itinérance"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Données cellulaires toujours actives"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Désactiver le volume absolu"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Version du profil Bluetooth AVRCP"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Sélectionner la version du profil Bluetooth AVRCP"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Codec audio Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Sélectionner le codec audio Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Taux d\'échantillonnage pour l\'audio Bluetooth"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Diffusion : <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Afficher les options pour la certification d\'affichage sans fil"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Détailler davantage les données Wi-Fi, afficher par SSID RSSI dans sélect. Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Si cette option est activée, le passage du Wi-Fi aux données cellulaires est forcé lorsque le signal Wi-Fi est faible"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Autoriser ou non la détection de réseaux Wi-Fi en itinérance en fonction de l\'importance du transfert de données dans l\'interface"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Tailles des mémoires tampons d\'enregistreur"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Tailles enreg. par tampon journal"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Remplacé par <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Il reste environ <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Temps restant : <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> : il reste environ <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – Temps restant : <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> : <xliff:g id="TIME">%2$s</xliff:g> jusqu\'à la charge complète"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> : <xliff:g id="TIME">%2$s</xliff:g> avant charge complète sur courant"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> : <xliff:g id="TIME">%2$s</xliff:g> jusqu\'à charge complète par USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> : <xliff:g id="TIME">%2$s</xliff:g> jusqu\'à charge complète sans fil"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Inconnu"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Batterie en charge"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"N\'est pas en charge"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Pleine"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Contrôlé par l\'administrateur"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Activé par l\'administrateur"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Désactivé par l\'administrateur"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Accueil des paramètres"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0 %"</item> diff --git a/packages/SettingsLib/res/values-fr/arrays.xml b/packages/SettingsLib/res/values-fr/arrays.xml index 22b11eab9f41..8b6fb0430b53 100644 --- a/packages/SettingsLib/res/values-fr/arrays.xml +++ b/packages/SettingsLib/res/values-fr/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Utiliser la vérification HDCP uniquement pour le contenu DRM"</item> <item msgid="45075631231212732">"Toujours utiliser la vérification HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (par défaut)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Utiliser sélection système (par défaut)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stéréo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Optimisée pour la qualité audio (990/909 kbit/s)"</item> - <item msgid="2921767058740704969">"Qualité audio et de la connexion équilibrée (660/606 kbit/s)"</item> - <item msgid="8860982705384396512">"Optimisée pour la qualité de la connexion (330/303 kbit/s)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Optimisée pour la qualité audio"</item> - <item msgid="4327143584633311908">"Qualité audio et de la connexion équilibrée"</item> - <item msgid="4681409244565426925">"Optimisée pour la qualité de la connexion"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Désactivé"</item> <item msgid="1593289376502312923">"64 Ko"</item> diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml index ede81d3c6526..b9f814fc0cc7 100644 --- a/packages/SettingsLib/res/values-fr/strings.xml +++ b/packages/SettingsLib/res/values-fr/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Reconnexion automatique impossible"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Aucun accès à Internet"</string> <string name="saved_network" msgid="4352716707126620811">"Enregistré par <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Connecté automatiquement via %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Connecté via %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Disponible via %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Très rapide"</item> <item msgid="9085102246155045744">"La plus rapide"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Sélectionner un profil"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Personnel"</string> <string name="category_work" msgid="8699184680584175622">"Professionnel"</string> <string name="development_settings_title" msgid="215179176067683667">"Options pour les développeurs"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Mise en réseau"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Certification affichage sans fil"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Autoriser enreg. infos Wi-Fi détaillées"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Passage forcé Wi-Fi vers données mobiles"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Toujours autoriser la détection de réseaux Wi-Fi en itinérance"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Données mobiles toujours actives"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Désactiver le volume absolu"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Version Bluetooth AVRCP"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Sélectionner la version Bluetooth AVRCP"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Codec audio Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Sélectionner le codec audio Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Taux d\'échantillonnage audio Bluetooth"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Diffusion : <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Afficher les options de la certification de l\'affichage sans fil"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Détailler plus infos Wi-Fi, afficher par RSSI de SSID dans outil sélection Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Si cette option est activée, le passage du Wi-Fi aux données mobiles est forcé en cas de signal Wi-Fi faible."</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Autoriser ou non la détection de réseaux Wi-Fi en itinérance en fonction de l\'importance du trafic de données dans l\'interface"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Tailles mémoires tampons enregistr."</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Tailles enreg. par tampon journal"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Remplacé par <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Il reste environ <xliff:g id="TIME">%1$s</xliff:g>."</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Temps restant : <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - encore environ <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – Temps restant : <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> avant une charge complète"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> avant charge complète sur secteur"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> avant charge complète sur USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> avant charge complète sans fil"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Inconnu"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Batterie en charge"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Débranchée"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"pleine"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Contrôlé par l\'administrateur"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Activé par l\'administrateur"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Désactivé par l\'administrateur"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Paramètres"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0 %"</item> diff --git a/packages/SettingsLib/res/values-gl/arrays.xml b/packages/SettingsLib/res/values-gl/arrays.xml index 19fd7fe5e292..2e55bf465deb 100644 --- a/packages/SettingsLib/res/values-gl/arrays.xml +++ b/packages/SettingsLib/res/values-gl/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Utiliza a comprobación HDCP só para contido DRM"</item> <item msgid="45075631231212732">"Utilizar sempre a comprobación HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (predeterminado)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Usar selección sistema (predeterminado)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Estéreo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Optimizado para a calidade do audio (990 kb/s ou 909 kb/s)"</item> - <item msgid="2921767058740704969">"Calidade equilibrada do audio e da conexión (660 kb/s ou 606 kb/s)"</item> - <item msgid="8860982705384396512">"Optimizado para a calidade da conexión (330 kb/s ou 303 kb/s)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Optimizado para a calidade do audio"</item> - <item msgid="4327143584633311908">"Calidade equilibrada do audio e da conexión"</item> - <item msgid="4681409244565426925">"Optimizado para a calidade da conexión"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Desactivado"</item> <item msgid="1593289376502312923">"64 K"</item> diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml index e6d48c2f97e5..8d5254c2f5ce 100644 --- a/packages/SettingsLib/res/values-gl/strings.xml +++ b/packages/SettingsLib/res/values-gl/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Non se conectará automaticamente"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Non hai acceso a Internet"</string> <string name="saved_network" msgid="4352716707126620811">"Redes gardadas por <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Conectada automaticamente a través de %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado a través de %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Dispoñible a través de %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Moi rápido"</item> <item msgid="9085102246155045744">"O máis rápido"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Seleccionar perfil"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Persoal"</string> <string name="category_work" msgid="8699184680584175622">"Traballo"</string> <string name="development_settings_title" msgid="215179176067683667">"Opcións de programador"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Certificado de visualización sen fíos"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Activar rexistro detallado da wifi"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Entrega agresiva de wifi a móbil"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permitir sempre buscas de itinerancia da wifi"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Datos móbiles sempre activados"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desactivar volume absoluto"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versión AVRCP de Bluetooth"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Selecciona a versión AVRCP de Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Códec de audio por Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Seleccionar códec de audio por Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Taxa de mostraxe de audio por Bluetooth"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Reprodución en tempo real: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostra opcións para o certificado de visualización sen fíos"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar o nivel de rexistro da wifi, mostrar por SSID RSSI no selector de wifi"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Cando estea activada esta función, a wifi será máis agresiva ao entregar a conexión de datos ao móbil, se o sinal wifi é feble"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Permitir/Non permitir buscas de itinerancia da wifi baseadas na cantidade de tráfico de datos presente na interface"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Tamaños de búfer de rexistrador"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Seleccionar tamaños por búfer"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Anulado por <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Duración aproximada de <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Tempo restante: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> (tempo restante aproximado: <xliff:g id="TIME">%2$s</xliff:g>)"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> (tempo restante: <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ata que cargue por completo"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g>)"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ata que cargue por completo por CA"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g>)"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ata que cargue por completo por USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g>)"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ata que cargue por completo sen fíos"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Descoñecido"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Non está cargando"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Completa"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Opción controlada polo administrador"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Activado polo administrador"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Desactivado polo administrador"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Inicio da configuración"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0 %"</item> diff --git a/packages/SettingsLib/res/values-gu/arrays.xml b/packages/SettingsLib/res/values-gu/arrays.xml index 55c4092691a4..ca821cade285 100644 --- a/packages/SettingsLib/res/values-gu/arrays.xml +++ b/packages/SettingsLib/res/values-gu/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"ફક્ત DRM સામગ્રી માટે HDCP તપાસનો ઉપયોગ કરો"</item> <item msgid="45075631231212732">"હંમેશા HDCP તપાસનો ઉપયોગ કરો"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (ડિફૉલ્ટ)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"સિસ્ટમ પસંદગીનો ઉપયોગ કરો (ડિફૉલ્ટ)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"મૉનો"</item> <item msgid="8883739882299884241">"સ્ટીરિઓ"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"ઑડિઓની ગુણવત્તા (990 kbps/909 kbps) માટે ઓપ્ટિમાઇઝ કર્યું"</item> - <item msgid="2921767058740704969">"સંતુલિત ઑડિઓ અને કનેક્શનની ગુણવત્તા (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"કનેક્શનની ગુણવત્તા (330 kbps/303 kbps) માટે ઓપ્ટિમાઇઝ કર્યું"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"ઑડિઓની ગુણવત્તા માટે ઓપ્ટિમાઇઝ કર્યું"</item> - <item msgid="4327143584633311908">"સંતુલિત ઑડિઓ અને કનેક્શનની ગુણવત્તા"</item> - <item msgid="4681409244565426925">"કનેક્શનની ગુણવત્તા માટે ઓપ્ટિમાઇઝ કર્યું"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"બંધ"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml index bf66980b4286..60c1fbb41d79 100644 --- a/packages/SettingsLib/res/values-gu/strings.xml +++ b/packages/SettingsLib/res/values-gu/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"આપમેળે કનેક્ટ કરશે નહીં"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"કોઈ ઇન્ટરનેટ ઍક્સેસ નથી"</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> દ્વારા સચવાયું"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s દ્વારા સ્વત: કનેક્ટ થયેલ"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s દ્વારા કનેક્ટ થયેલ"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s દ્વારા ઉપલબ્ધ"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"ખૂબ જ તીવ્ર"</item> <item msgid="9085102246155045744">"સૌથી ઝડપી"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"પ્રોફાઇલ પસંદ કરો"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"વ્યક્તિગત"</string> <string name="category_work" msgid="8699184680584175622">"કાર્યાલય"</string> <string name="development_settings_title" msgid="215179176067683667">"વિકાસકર્તાનાં વિકલ્પો"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"સશક્ત Wi‑Fiથી મોબાઇલ પર હૅન્ડઓવર"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"હંમેશા Wi‑Fi રોમ સ્કૅન્સને મંજૂરી આપો"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"મોબાઇલ ડેટા હંમેશાં સક્રિય"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ચોક્કસ વૉલ્યૂમને અક્ષમ કરો"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP સંસ્કરણ"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Bluetooth AVRCP સંસ્કરણ પસંદ કરો"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth ઑડિઓ કોડેક"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Bluetooth ઑડિઓ LDAC કોડેક પસંદ કરો"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth ઑડિઓ નમૂના દર"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"સ્ટ્રીમિંગ: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</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> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"જ્યારે સક્ષમ કરેલ હોય, ત્યારે Wi‑Fi સિગ્નલ નબળું હોવા પર, Wi-Fi વધુ ઝડપથી ડેટા કનેક્શનને મોબાઇલ પર મોકલશે"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"ઇન્ટરફેસ પર હાજર ડેટા ટ્રાફિકના પ્રમાણનાં આધારે Wi‑Fi રોમ સ્કૅન્સને મંજૂરી આપો/નામંજૂર કરો"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"લોગર બફર કદ"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"લૉગ દીઠ લૉગર કદ બફર પસંદ કરો"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> દ્વારા ઓવરરાઇડ થયું"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"અંદાજે. <xliff:g id="TIME">%1$s</xliff:g> બાકી"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> બાકી"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - લગભગ <xliff:g id="TIME">%2$s</xliff:g> બાકી"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - AC પર સંપૂર્ણપણે ચાર્જ થવા માટે <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB પર સંપૂર્ણપણે ચાર્જ થવા માટે <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - વાયરલેસ પરથી સંપૂર્ણપણે ચાર્જ થવા માટે <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ચાર્જ થઈ રહ્યું નથી"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"પૂર્ણ"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"વ્યવસ્થાપક દ્વારા નિયંત્રિત"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"વ્યવસ્થાપક દ્વારા સક્ષમ કરેલ"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"વ્યવસ્થાપક દ્વારા અક્ષમ કરેલ"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"સેટિંગ્સ હોમ"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-hi/arrays.xml b/packages/SettingsLib/res/values-hi/arrays.xml index 60d10120a482..d1878a7cf5f6 100644 --- a/packages/SettingsLib/res/values-hi/arrays.xml +++ b/packages/SettingsLib/res/values-hi/arrays.xml @@ -116,16 +116,8 @@ <item msgid="8900559293912978337">"मोनो"</item> <item msgid="8883739882299884241">"स्टीरियो"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"ऑडियो की गुणवत्ता के लिए अनुकूलित किया गया (990kbps/909kbps)"</item> - <item msgid="2921767058740704969">"संतुलित ऑडियो और कनेक्शन गुणवत्ता (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"कनेक्शन की गुणवत्ता के लिए अनुकूलित किया गया (330kbps/303kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"ऑडियो की गुणवत्ता के लिए अनुकूलित किया गया"</item> - <item msgid="4327143584633311908">"संतुलित ऑडियो और कनेक्शन गुणवत्ता"</item> - <item msgid="4681409244565426925">"कनेक्शन की गुणवत्ता के लिए अनुकूलित किया गया"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"बंद"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml index f1f2d3a5a97c..8d4935f9fca8 100644 --- a/packages/SettingsLib/res/values-hi/strings.xml +++ b/packages/SettingsLib/res/values-hi/strings.xml @@ -34,7 +34,7 @@ <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> के द्वारा सहेजा गया"</string> <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s के द्वारा उपलब्ध"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s के द्वारा उपलब्ध"</string> @@ -141,7 +141,8 @@ <item msgid="5194774745031751806">"अत्यधिक तीव्र"</item> <item msgid="9085102246155045744">"सबसे तेज़"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"प्रोफ़ाइल चुनें"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"व्यक्तिगत"</string> <string name="category_work" msgid="8699184680584175622">"कार्यालय"</string> <string name="development_settings_title" msgid="215179176067683667">"डेवलपर विकल्प"</string> @@ -353,8 +354,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"चार्ज नहीं हो रही है"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"पूरी"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"व्यवस्थापक द्वारा नियंत्रित"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"व्यवस्थापक द्वारा सक्षम किया गया"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"व्यवस्थापक द्वारा अक्षम किया गया"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"सेटिंग होम"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-hr/arrays.xml b/packages/SettingsLib/res/values-hr/arrays.xml index b092a8ff896e..641b9fb204ac 100644 --- a/packages/SettingsLib/res/values-hr/arrays.xml +++ b/packages/SettingsLib/res/values-hr/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Upotrebljavaj HDCP provjeru samo za DRM sadržaj"</item> <item msgid="45075631231212732">"Uvijek upotrebljavaj HDCP provjeru"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (zadano)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Upotreba odabira sustava (zadano)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Optimizirano za kvalitetu audioreprodukcije (990 kbps/909 kbps)"</item> - <item msgid="2921767058740704969">"Uravnotežena kvaliteta audioreprodukcije i veze (660 kbps/606 kbps)"</item> - <item msgid="8860982705384396512">"Optimizirano za kvalitetu veze (330 kbps/303 kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Optimizirano za kvalitetu audioreprodukcije"</item> - <item msgid="4327143584633311908">"Uravnotežena kvaliteta audioreprodukcije i veze"</item> - <item msgid="4681409244565426925">"Optimizirano za kvalitetu veze"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Isključeno"</item> <item msgid="1593289376502312923">"64 KB"</item> diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml index 291e37a63e61..18242e3e76c0 100644 --- a/packages/SettingsLib/res/values-hr/strings.xml +++ b/packages/SettingsLib/res/values-hr/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Neće se povezati automatski"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Nema pristupa internetu"</string> <string name="saved_network" msgid="4352716707126620811">"Spremljeno: <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatski povezan putem %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Povezano putem %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Dostupno putem %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Vrlo ubrzano"</item> <item msgid="9085102246155045744">"Najbrže"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Odabir profila"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Osobno"</string> <string name="category_work" msgid="8699184680584175622">"Posao"</string> <string name="development_settings_title" msgid="215179176067683667">"Opcije za razvojne programere"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Umrežavanje"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Certifikacija bežičnog prikaza"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Omogući opširnu prijavu na Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aktivni prijelaz s Wi‑Fi na mob. mrežu"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Uvijek dopusti slobodno traženje Wi-Fi mreže"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilni podaci uvijek aktivni"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Onemogući apsolutnu glasnoću"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Verzija AVRCP-a za Bluetooth"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Odaberite verziju AVRCP-a za Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Kodek za Bluetooth Audio"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Odaberi kodek za Bluetooth Audio"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Brzina uzorka za Bluetooth Audio"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Strujanje: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Prikaži opcije za certifikaciju bežičnog prikaza"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povećana razina prijave na Wi‑Fi, prikaz po SSID RSSI-ju u Biraču Wi‑Fi-ja"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Ako je omogućeno, Wi-Fi će aktivno prebacivati podatkovnu vezu mobilnoj mreži kada je Wi-Fi signal slab."</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Dopustite ili blokirajte slobodno traženje Wi-Fi mreža na temelju količine podatkovnog prometa na sučelju."</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Veličine međuspremnika zapisnika"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Odaberite veličinu međuspremnika zapisnika"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Premošćeno postavkom <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Još približno <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Još <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – preostalo je približno <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – još <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do potpune napunjenosti"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napunjenosti putem utičnice"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napunjenosti putem USB-a"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napunjenosti bežičnim putem"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Nepoznato"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Punjenje"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ne puni se"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Puna"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrolira administrator"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Omogućio administrator"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Onemogućio administrator"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Početni zaslon postavki"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-hu/arrays.xml b/packages/SettingsLib/res/values-hu/arrays.xml index 160e9ebadfd8..e647f8650f3f 100644 --- a/packages/SettingsLib/res/values-hu/arrays.xml +++ b/packages/SettingsLib/res/values-hu/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Csak DRM-tartalomhoz használjon HDCP ellenőrzést"</item> <item msgid="45075631231212732">"Mindig használjon HDCP ellenőrzést"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (alapértelmezett)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Rendszerérték (alapértelmezett)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Monó"</item> <item msgid="8883739882299884241">"Sztereó"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Optimális hangminőség (990 kbps/909 kbps)"</item> - <item msgid="2921767058740704969">"Kiegyensúlyozott hang- és kapcsolatminőség (660 kbps/606 kbps)"</item> - <item msgid="8860982705384396512">"Optimális kapcsolatminőség (330 kbps/303 kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Optimális hangminőség"</item> - <item msgid="4327143584633311908">"Kiegyensúlyozott hang- és kapcsolatminőség"</item> - <item msgid="4681409244565426925">"Optimális kapcsolatminőség"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Ki"</item> <item msgid="1593289376502312923">"64 KB"</item> diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml index 33e80348190d..f4b7dd0d0c06 100644 --- a/packages/SettingsLib/res/values-hu/strings.xml +++ b/packages/SettingsLib/res/values-hu/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Nem csatlakozik automatikusan"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Nincs internet-hozzáférés"</string> <string name="saved_network" msgid="4352716707126620811">"Mentette: <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatikusan csatlakozott a következőn keresztül: %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Csatlakozva a következőn keresztül: %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Elérhető a következőn keresztül: %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Rendkívül gyors"</item> <item msgid="9085102246155045744">"Leggyorsabb"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Profil kiválasztása"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Személyes"</string> <string name="category_work" msgid="8699184680584175622">"Munkahelyi"</string> <string name="development_settings_title" msgid="215179176067683667">"Fejlesztői beállítások"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Hálózatok"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Vezeték nélküli kijelző tanúsítványa"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Részletes Wi-Fi-naplózás engedélyezése"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agresszív Wi‑Fi–mobilhálózat átadás"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi-roaming ellenőrzésének engedélyezése mindig"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"A mobilhálózati kapcsolat mindig aktív"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Abszolút hangerő funkció letiltása"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"A Bluetooth AVRCP-verziója"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"A Bluetooth AVRCP-verziójának kiválasztása"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth hang – Kodek"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Bluetooth hangkodek kiválasztása"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth hang – mintavételezési gyakoriság"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streamelés: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Vezeték nélküli kijelző tanúsítványával kapcsolatos lehetőségek megjelenítése"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi-naplózási szint növelése, RSSI/SSID megjelenítése a Wi‑Fi-választóban"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Ha engedélyezi, a Wi-Fi agresszívebben fogja átadni az adatkapcsolatot a mobilhálózatnak gyenge Wi-Fi-jel esetén"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"A Wi-Fi-roaming ellenőrzésének engedélyezése vagy letiltása az interfészen jelen lévő adatforgalom mennyiségétől függően"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Naplózási puffer mérete"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Naplózási pufferméret kiválasztása"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Felülírva erre: <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Kb. <xliff:g id="TIME">%1$s</xliff:g> van hátra"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> van hátra"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - körülbelül <xliff:g id="TIME">%2$s</xliff:g> van hátra"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> van hátra"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> a teljes feltöltésig"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> a hálózati áramról való feltöltésig"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> a teljes feltöltésig USB-n"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> a vezeték nélküli teljes feltöltésig"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Ismeretlen"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Töltés"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nem töltődik"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Feltöltve"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Rendszergazda által irányítva"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Engedélyezve a rendszergazda által"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Letiltva a rendszergazda által"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Beállítások kezdőlapja"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-hy/arrays.xml b/packages/SettingsLib/res/values-hy/arrays.xml index 868735e9d843..0138d2ef177c 100644 --- a/packages/SettingsLib/res/values-hy/arrays.xml +++ b/packages/SettingsLib/res/values-hy/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Օգտագործել HDCP-ը` միայն DRM-ի բովանդակությունը ստուգելու համար"</item> <item msgid="45075631231212732">"Միշտ օգտագործել HDCP ստուգումը"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (կանխադրված)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Օգտագործել համակարգի կարգավորումը (կանխադրված)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Մոնո"</item> <item msgid="8883739882299884241">"Ստերեո"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Օպտիմալացված ձայնի որակի համար (990 կբ/վ / 909 կբ/վ)"</item> - <item msgid="2921767058740704969">"Ձայնի և կապի հավասարակշռված որակ (660 կբ/վ / 606 կբ/վ)"</item> - <item msgid="8860982705384396512">"Օպտիմալացված կապի որակի համար (330 կբ/վ / 303 կբ/վ)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Օպտիմալացված ձայնի որակի համար"</item> - <item msgid="4327143584633311908">"Ձայնի և կապի հավասարակշռված որակ"</item> - <item msgid="4681409244565426925">"Օպտիմալացված կապի որակի համար"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Անջատված է"</item> <item msgid="1593289376502312923">"64ԿԲ"</item> diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml index b06f8ddfe4f6..64ee1fce50dc 100644 --- a/packages/SettingsLib/res/values-hy/strings.xml +++ b/packages/SettingsLib/res/values-hy/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Չի միանա ավտոմատ"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Ինտերնետ կապ չկա"</string> <string name="saved_network" msgid="4352716707126620811">"Պահել է հետևյալ օգտատերը՝ <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Ավտոմատ կերպով կապակցվել է %1$s-ի միջոցով"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Կապակցված է %1$s-ի միջոցով"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Հասանելի է %1$s-ի միջոցով"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Չափազանց արագ"</item> <item msgid="9085102246155045744">"Ամենաարագ"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Ընտրել պրոֆիլ"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Անձնական"</string> <string name="category_work" msgid="8699184680584175622">"Աշխատանքային"</string> <string name="development_settings_title" msgid="215179176067683667">"Ծրագրավորողի ընտրանքներ"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi-Fi-ից կտրուկ անցում բջջային ինտերնետի"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Միշտ թույլատրել Wi‑Fi ռոումինգի որոնումը"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Բջջային ինտերնետը միշտ ակտիվ է"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Անջատել ձայնի բացարձակ ուժգնությունը"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP տարբերակը"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Ընտրել Bluetooth AVRCP տարբերակը"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth աուդիո կոդեկ"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Ընտրեք Bluetooth աուդիո կոդեկը"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth աուդիոյի Ընդհատավորման հաճախականությունը"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Հեռարձակում՝ <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Ցույց տալ անլար էկրանի հավաստագրման ընտրանքները"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Բարձրացնել մակարդակը, Wi‑Fi ընտրիչում ամեն մի SSID-ի համար ցույց տալ RSSI"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Եթե այս գործառույթը միացված է, Wi-Fi-ի թույլ ազդանշանի դեպքում Wi‑Fi ինտերնետից բջջային ինտերնետի անցումը ավելի կտրուկ կկատարվի"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Թույլատրել/արգելել Wi‑Fi ռոումինգի որոնումը՝ կախված միջերեսում տվյալների երթևեկի ծավալից"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Տեղեկամատյանի պահնակի չափերը"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Ընտրեք տեղեկամատյանի չափը մեկ պահնակի համար"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Գերազանցված է <xliff:g id="TITLE">%1$s</xliff:g>-ից"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Մնացել է մոտ <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Մնացել է <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – մնացել է մոտ <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - մնացել է <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> մինչև հոսանքից լրիվ լիցքավորումը"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> մինչև USB-ով լրիվ լիցքավորումը"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> մինչև լրիվ լիցքավորումը անլար եղանակով"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Չի լիցքավորվում"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Լիցքավորված"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Վերահսկվում է ադմինիստրատորի կողմից"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Միացված է ադմինիստրատորի կողմից"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Կասեցված է ադմինիստրատորի կողմից"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Կարգավորումների գլխավոր էջ"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-in/arrays.xml b/packages/SettingsLib/res/values-in/arrays.xml index b2f3891477da..5289d265e442 100644 --- a/packages/SettingsLib/res/values-in/arrays.xml +++ b/packages/SettingsLib/res/values-in/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Gunakan pemeriksaan HDCP untuk konten DRM saja"</item> <item msgid="45075631231212732">"Selalu gunakan pemeriksaan HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Gunakan Pilihan Sistem (Default)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Dioptimalkan untuk Kualitas Audio (990kbps/909kbps)"</item> - <item msgid="2921767058740704969">"Kualitas Audio dan Sambungan Seimbang (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"Dioptimalkan untuk Kualitas Sambungan for Connection Quality (330kbps/303kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Dioptimalkan untuk Kualitas Audio"</item> - <item msgid="4327143584633311908">"Kualitas Audio dan Sambungan Seimbang"</item> - <item msgid="4681409244565426925">"Dioptimalkan untuk Kualitas Sambungan"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Nonaktif"</item> <item msgid="1593289376502312923">"64 K"</item> diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml index 5d8ecb210b0e..fe2840f2d29a 100644 --- a/packages/SettingsLib/res/values-in/strings.xml +++ b/packages/SettingsLib/res/values-in/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Tidak akan tersambung otomatis"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Tidak ada akses internet"</string> <string name="saved_network" msgid="4352716707126620811">"Disimpan oleh <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Tersambung otomatis melalui %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Terhubung melalui %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Tersedia melalui %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Sangat cepat sekali"</item> <item msgid="9085102246155045744">"Tercepat"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Pilih Profil"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Pribadi"</string> <string name="category_work" msgid="8699184680584175622">"Kantor"</string> <string name="development_settings_title" msgid="215179176067683667">"Opsi developer"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Jaringan"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Sertifikasi layar nirkabel"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktifkan Pencatatan Log Panjang Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Pengalihan Wi-Fi Agresif ke seluler"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Selalu izinkan Pemindaian Roaming Wi-Fi"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Data seluler selalu aktif"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Nonaktifkan volume absolut"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versi AVRCP Bluetooth"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Pilih Versi AVRCP Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Codec Audio Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Pilih Codec Audio Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Frekuensi Sampel Audio Bluetooth"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Tampilkan opsi untuk sertifikasi layar nirkabel"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Tingkatkan level pencatatan log Wi-Fi, tampilkan per SSID RSSI di Pemilih Wi‑Fi"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Jika diaktifkan, Wi-Fi akan menjadi lebih agresif dalam mengalihkan sambungan data ke seluler saat sinyal Wi-Fi lemah"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Izinkan/Larang Pemindaian Roaming Wi-Fi berdasarkan jumlah lalu lintas data yang ada di antarmuka"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Ukuran penyangga pencatat log"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Ukuran Pencatat Log per penyangga log"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Digantikan oleh <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Kira-kira tersisa <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> tersisa"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - kira-kira <xliff:g id="TIME">%2$s</xliff:g> lagi"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tersisa"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lagi terisi penuh"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lagi terisi penuh pada AC"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lagi terisi penuh melalui USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lagi terisi penuh dari nirkabel"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Tidak diketahui"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Mengisi daya"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Tidak mengisi daya"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Penuh"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Dikontrol oleh admin"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Diaktifkan oleh administrator"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Dinonaktifkan oleh administrator"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Layar Utama Setelan"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-is/arrays.xml b/packages/SettingsLib/res/values-is/arrays.xml index b9213f41c61f..0a1e19e1bb2b 100644 --- a/packages/SettingsLib/res/values-is/arrays.xml +++ b/packages/SettingsLib/res/values-is/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Nota HDCP-athugun aðeins fyrir höfundarréttarvarið efni"</item> <item msgid="45075631231212732">"Nota alltaf HDCP-eftirlit"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (sjálfgefið)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Nota val kerfisins (sjálfgefið)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Einóma"</item> <item msgid="8883739882299884241">"Víðóma"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Fínstillt fyrir hljóðgæði (990kbps/909kbps)"</item> - <item msgid="2921767058740704969">"Jafnvægi á milli gæða hljóðs og tengingar (660 kbps / 606 kbps)"</item> - <item msgid="8860982705384396512">"Fínstillt fyrir gæði tengingar (330kbps/303kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Fínstillt fyrir hljóðgæði"</item> - <item msgid="4327143584633311908">"Jafnvægi á milli gæða hljóðs og tengingar"</item> - <item msgid="4681409244565426925">"Fínstillt fyrir gæði tengingar"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Slökkt"</item> <item msgid="1593289376502312923">"64 k"</item> diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml index d8a95581b013..5ef8087875fa 100644 --- a/packages/SettingsLib/res/values-is/strings.xml +++ b/packages/SettingsLib/res/values-is/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Mun ekki tengjast sjálfkrafa"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Enginn netaðgangur"</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> vistaði"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Sjálfkrafa tengt um %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Tengt í gegnum %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Í boði í gegnum %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Næsthraðast"</item> <item msgid="9085102246155045744">"Hraðast"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Veldu snið"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Persónulegt"</string> <string name="category_work" msgid="8699184680584175622">"Vinna"</string> <string name="development_settings_title" msgid="215179176067683667">"Forritunarkostir"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Netkerfi"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Vottun þráðlausra skjáa"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Kveikja á ítarlegri skráningu Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Hröð skipti úr Wi‑Fi í farsímagögn"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Leyfa alltaf reikileit með Wi-Fi"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Alltaf kveikt á farsímagögnum"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Slökkva á samstillingu hljóðstyrks"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP-útgáfa"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Velja Bluetooth AVRCP-útgáfu"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth hljóðkóðari"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Velja Bluetooth-hljóðkóðara"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth hljóðtökutíðni"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streymi: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Sýna valkosti fyrir vottun þráðlausra skjáa"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Auka skráningarstig Wi-Fi, sýna RSSI fyrir hvert SSID í Wi-Fi vali"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Þegar þetta er virkt mun Wi-Fi skipta hraðar yfir í farsímagagnatengingu þegar Wi-Fi-tenging er léleg"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Leyfa/banna reikileit með Wi-Fi á grunni þess hversu mikil gagnaumferð er fyrir hendi í viðmótinu"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Annálsritastærðir biðminna"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Veldu annálsritastærðir á biðminni"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Hnekkt af <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Um það bil <xliff:g id="TIME">%1$s</xliff:g> eftir"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> eftir"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – um <xliff:g id="TIME">%2$s</xliff:g> eftir"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> eftir"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> þar til fullri hleðslu er náð"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> þar til fullhlaðið með hleðslutæki"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> þar til fullhlaðið með USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> þar til fullhlaðið þráðlaust"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Óþekkt"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Í hleðslu"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ekki í hleðslu"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Fullhlaðin"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Stjórnað af kerfisstjóra"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Virkjað af stjórnanda"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Stjórnandi gerði óvirkt"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Stillingar"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-it/arrays.xml b/packages/SettingsLib/res/values-it/arrays.xml index 0c46df4dbb57..da6b885d691f 100644 --- a/packages/SettingsLib/res/values-it/arrays.xml +++ b/packages/SettingsLib/res/values-it/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Usa la verifica HDCP solo per contenuti DRM"</item> <item msgid="45075631231212732">"Usa sempre la verifica HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (predefinita)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Usa selezione di sistema (predefinita)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Ottimizzato per qualità audio (990 kbps/909 kbps)"</item> - <item msgid="2921767058740704969">"Audio bilanciato e qualità di connessione (660 kbps/606 kbps)"</item> - <item msgid="8860982705384396512">"Ottimizzato per qualità di connessione (330 kbps/303 kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Ottimizzato per qualità audio"</item> - <item msgid="4327143584633311908">"Audio bilanciato e qualità di connessione"</item> - <item msgid="4681409244565426925">"Ottimizzato per qualità di connessione"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Off"</item> <item msgid="1593289376502312923">"64 kB"</item> diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml index 9858d3c5a9db..711971ef725a 100644 --- a/packages/SettingsLib/res/values-it/strings.xml +++ b/packages/SettingsLib/res/values-it/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Non verrà eseguita la connessione automatica"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Nessun accesso a Internet"</string> <string name="saved_network" msgid="4352716707126620811">"Salvata da <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Collegato automaticamente tramite %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Collegato tramite %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Disponibile tramite %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Molto rapida"</item> <item msgid="9085102246155045744">"Massima velocità"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Scegli profilo"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Personali"</string> <string name="category_work" msgid="8699184680584175622">"Lavoro"</string> <string name="development_settings_title" msgid="215179176067683667">"Opzioni sviluppatore"</string> @@ -170,16 +170,12 @@ <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 registrazione dettagliata Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi‑Fi aggressivo per passaggio a cellulare"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Consenti sempre scansioni roaming Wi-Fi"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Dati mobili sempre attivi"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Disattiva volume assoluto"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versione Bluetooth AVRCP"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Seleziona versione Bluetooth AVRCP"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Codec audio Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Seleziona il codec audio Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Frequenza di campionamento audio Bluetooth"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostra opzioni per la certificazione display wireless"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumenta il livello di registrazione Wi-Fi, mostrando il SSID RSSI nel selettore Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Con questa impostazione attivata, il Wi-Fi è più aggressivo nel passare la connessione dati al cellulare, con segnale Wi-Fi basso"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Consenti/vieta scansioni roaming Wi-Fi basate sulla quantità di traffico dati presente a livello di interfaccia"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Dimensioni buffer Logger"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Seleziona dimensioni Logger per buffer log"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Valore sostituito da <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Circa <xliff:g id="TIME">%1$s</xliff:g> rimanenti"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Tempo rimanente: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ancora circa <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - Tempo rimanente: <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla carica completa"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla carica completa tramite CA"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla carica completa tramite USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla carica completa con wireless"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Sconosciuta"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"In carica"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Non in carica"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Carica"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Gestita dall\'amministratore"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Attivata dall\'amministratore"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Disattivata dall\'amministratore"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Home page Impostazioni"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-iw/arrays.xml b/packages/SettingsLib/res/values-iw/arrays.xml index c918740a174f..f106a34fdb73 100644 --- a/packages/SettingsLib/res/values-iw/arrays.xml +++ b/packages/SettingsLib/res/values-iw/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"השתמש בבדיקת HDCP עבור תוכן DRM בלבד"</item> <item msgid="45075631231212732">"תמיד השתמש בבדיקת HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (ברירת המחדל)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"שימוש בבחירת המערכת (ברירת המחדל)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"מונו"</item> <item msgid="8883739882299884241">"סטריאו"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"אופטימיזציה להשגת איכות אודיו מרבית (990kbps/909kbps)"</item> - <item msgid="2921767058740704969">"איזון בין איכות החיבור לאיכות אודיו (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"אופטימיזציה להשגת איכות חיבור מרבית (330kbps/303kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"אופטימיזציה להשגת איכות אודיו מרבית"</item> - <item msgid="4327143584633311908">"אזן בין איכות החיבור לאיכות אודיו"</item> - <item msgid="4681409244565426925">"אופטימיזציה להשגת איכות חיבור מרבית"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"כבוי"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml index 4bea8a5bda7e..fedc9b6e1781 100644 --- a/packages/SettingsLib/res/values-iw/strings.xml +++ b/packages/SettingsLib/res/values-iw/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"לא יתבצע חיבור באופן אוטומטי"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"אין גישה לאינטרנט"</string> <string name="saved_network" msgid="4352716707126620811">"נשמר על ידי <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"מחובר אוטומטית דרך %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"מחובר דרך %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"זמינה דרך %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"יותר מהיר ממהיר במיוחד"</item> <item msgid="9085102246155045744">"הכי מהיר"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"בחר פרופיל"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"אישי"</string> <string name="category_work" msgid="8699184680584175622">"עבודה"</string> <string name="development_settings_title" msgid="215179176067683667">"אפשרויות מפתח"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"תקשורת רשתות"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"אישור של תצוגת WiFi"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"הפעל רישום מפורט של Wi‑Fi ביומן"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"העברה אגרסיבית מ-Wi‑Fi לרשת סלולרית"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"התר תמיד סריקות נדידה של Wi‑Fi"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"חבילת הגלישה פעילה תמיד"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"השבת עוצמת קול מוחלטת"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth גרסה AVRCP"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"בחר Bluetooth גרסה AVRCP"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Codec אודיו ל-Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"בחירת Codec אודיו ל-Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"קצב דגימה של אודיו ל-Bluetooth"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"סטרימינג: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"הצג אפשרויות עבור אישור של תצוגת WiFi"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"העלה את רמת הרישום של Wi‑Fi ביומן, הצג לכל SSID RSSI ב-Wi‑Fi Picker"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"כשאפשרות זו מופעלת, Wi-Fi יתנהג בצורה אגרסיבית יותר בעת העברת חיבור הנתונים לרשת הסלולרית כשאות ה-Wi-Fi חלש."</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"התר/מנע סריקות נדידה של Wi-Fi בהתבסס על נפח תנועת הנתונים הקיימת בממשק"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"גדלי מאגר של יוצר יומן"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"בחר גדלים של יוצר יומן לכל מאגר יומן"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"נעקף על ידי <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"נשארו <xliff:g id="TIME">%1$s</xliff:g> בערך"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"נותרו <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - הזמן הנותר: בערך <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - נותרו <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> עד לטעינה מלאה בזרם חילופין"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> עד לטעינה מלאה באמצעות USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> עד לטעינה מלאה בחיבור אלחוטי"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"לא טוען"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"מלא"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"נמצא בשליטת מנהל מערכת"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"הופעל על ידי מנהל המערכת"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"הושבת על ידי מנהל המערכת"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"דף הבית של ההגדרות"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-ja/arrays.xml b/packages/SettingsLib/res/values-ja/arrays.xml index 2b6004fe2d3c..18945ec8f6df 100644 --- a/packages/SettingsLib/res/values-ja/arrays.xml +++ b/packages/SettingsLib/res/values-ja/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"DRMコンテンツにのみHDCPチェックを使用する"</item> <item msgid="45075631231212732">"HDCPチェックを常に使用する"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4(デフォルト)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"システムの選択(デフォルト)を使用"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"モノラル"</item> <item msgid="8883739882299884241">"ステレオ"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"音質重視で最適化(990 kbps / 909 kbps)"</item> - <item msgid="2921767058740704969">"音質と接続の品質のバランスを確保(660 kbps / 606 kbps)"</item> - <item msgid="8860982705384396512">"接続の品質重視で最適化(330 kbps / 303 kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"音質重視で最適化"</item> - <item msgid="4327143584633311908">"音質と接続の品質のバランスを確保"</item> - <item msgid="4681409244565426925">"接続の品質重視で最適化"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"OFF"</item> <item msgid="1593289376502312923">"64 K"</item> diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml index 267af1ae5efd..55c140c273c0 100644 --- a/packages/SettingsLib/res/values-ja/strings.xml +++ b/packages/SettingsLib/res/values-ja/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"自動的に接続されません"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"インターネットに接続していません"</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g>で保存"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s 経由で自動的に接続しています"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s経由で接続"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s経由で使用可能"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"非常に高速"</item> <item msgid="9085102246155045744">"最高速"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"プロファイルの選択"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"個人用"</string> <string name="category_work" msgid="8699184680584175622">"仕事用"</string> <string name="development_settings_title" msgid="215179176067683667">"開発者向けオプション"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi-Fi を強制的にモバイル接続に切り替える"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fiローミングスキャンを常に許可する"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"モバイルデータを常に ON にする"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"絶対音量を無効にする"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP バージョン"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Bluetooth AVRCP バージョンを選択する"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth オーディオ コーデック"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Bluetooth オーディオ コーデックを選択"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth オーディオ サンプルレート"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ストリーミング: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</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> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ON にすると、Wi-Fi の電波強度が弱い場合は強制的にモバイルデータ接続に切り替わるようになります"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"インターフェースのデータトラフィック量に基づいたWi-Fiローミングスキャンを許可するかしないかを設定できます"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"ログバッファのサイズ"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"各ログバッファのログサイズを選択"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g>によって上書き済み"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"あと約 <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g>(残り時間)"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - 残り約 <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - フル充電まで <xliff:g id="TIME">%2$s</xliff:g>(AC)"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - フル充電まで <xliff:g id="TIME">%2$s</xliff:g>(USB)"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - フル充電まで <xliff:g id="TIME">%2$s</xliff:g>(ワイヤレス)"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -355,8 +345,10 @@ <!-- no translation found for battery_info_status_full (2824614753861462808) --> <skip /> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"管理者により管理されています"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"管理者によって有効にされています"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"管理者によって無効にされています"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"設定のホーム"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-ka/arrays.xml b/packages/SettingsLib/res/values-ka/arrays.xml index 2dd47d9a06a8..9c326a732145 100644 --- a/packages/SettingsLib/res/values-ka/arrays.xml +++ b/packages/SettingsLib/res/values-ka/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"HDCP შემოწმების გამოყენება მხოლოდ DRM კონტენტის შემთხვევაში"</item> <item msgid="45075631231212732">"ყოველთვის გამოიყენე HDCP შემოწმება"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (ნაგულისხმევი)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"სისტემის არჩეულის გამოყენება (ნაგულისხმევი)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"მონო"</item> <item msgid="8883739882299884241">"სტერეო"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"აუდიოს ხარისხისთვის ოპტიმიზებული (990/909 კბიტი/წმ)"</item> - <item msgid="2921767058740704969">"აუდიოსა და კავშირის დაბალანსებული ხარისხი (660/606 კბიტი/წმ)"</item> - <item msgid="8860982705384396512">"კავშირის ხარისხისთვის ოპტიმიზებული (330/303 კბიტი/წმ)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"აუდიოს ხარისხისთვის ოპტიმიზებული"</item> - <item msgid="4327143584633311908">"აუდიოსა და კავშირის დაბალანსებული ხარისხი"</item> - <item msgid="4681409244565426925">"კავშირის ხარისხისთვის ოპტიმიზებული"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"გამორთული"</item> <item msgid="1593289376502312923">"64 კბაიტი"</item> diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml index ef8c6ba28dd2..abda1ddc024b 100644 --- a/packages/SettingsLib/res/values-ka/strings.xml +++ b/packages/SettingsLib/res/values-ka/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"ავტომატურად დაკავშირება ვერ მოხერხდება"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"ინტერნეტთან კავშირი არ არის"</string> <string name="saved_network" msgid="4352716707126620811">"შენახული <xliff:g id="NAME">%1$s</xliff:g>-ის მიერ"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"ავტომატურად დაკავშირდა %1$s-ის მეშვეობით"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s-ით დაკავშირებული"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"ხელმისაწვდომია %1$s-ით"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"ძალიან ჩქარი"</item> <item msgid="9085102246155045744">"უსწრაფესი"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"პროფილის არჩევა"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"პირადი"</string> <string name="category_work" msgid="8699184680584175622">"სამსახური"</string> <string name="development_settings_title" msgid="215179176067683667">"პარამეტრები დეველოპერებისთვის"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi‑Fi-ს მობ. ინტერნეტზე აგრესიული გადართვა"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi Roam სკანირების მუდამ დაშვება"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"მობილური ინტერნეტის ყოველთვის გააქტიურება"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ხმის აბსოლუტური სიძლიერის გათიშვა"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth-ის AVRCP-ის ვერსია"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"აირჩიეთ Bluetooth-ის AVRCP-ის ვერსია"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth აუდიოს კოდეკი"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"აირჩიეთ Bluetooth აუდიოს კოდეკი"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth აუდიოს დისკრეტიზაციის სიხშირე"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"სტრიმინგი: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</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> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ჩართვის შემთხვევაში, Wi‑Fi უფრო აქტიურად შეეცდება მობილურ ინტერნეტზე გადართვას, როცა Wi‑Fi სიგნალი სუსტია"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Wifi Roam სკანირების დაშვება/აკრძალვა, ინტერფეისზე არსებული მონაცემთა ტრაფიკზე დაფუძნებით"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"ჟურნალიზაციის ბუფერის ზომები"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"აირჩიეთ ჟურნ. ზომა / ჟურნ. ბუფერზე"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"უკუგებულია <xliff:g id="TITLE">%1$s</xliff:g>-ის მიერ"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"დარჩენილია დაახლოებით <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"დარჩენილია <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> — დარჩა დაახლოებით <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> — დარჩენილია <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> — ელკვებით სრულ დატენვამდე დარჩა <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> — USB-ით სრულ დატენვამდე დარჩა <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> — სრულ უსადენო დატენვამდე დარჩა <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"არ იტენება"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"ბატარეა დატენილია"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"იმართება ადმინისტრატორის მიერ"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"ჩართულია ადმინისტრატორის მიერ"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"გათიშულია ადმინისტრატორის მიერ"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"პარამეტრების გვერდი"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-kk/arrays.xml b/packages/SettingsLib/res/values-kk/arrays.xml index 3f8bda2a5915..d4e23536f703 100644 --- a/packages/SettingsLib/res/values-kk/arrays.xml +++ b/packages/SettingsLib/res/values-kk/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"HDCP (кең жолақты сандық мазмұн қорғау) тексеруді DRM (авторлық құқықты техникалық қорғау) мазмұны үшін ғана қолданыңыз"</item> <item msgid="45075631231212732">"Әрқашан HDCP (жоғары кең жолақты сандық мазмұн қорғаушы) тексерулерін қолданыңыз"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (әдепкі)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Жүйені таңдау (әдепкі)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Моно"</item> <item msgid="8883739882299884241">"Стерео"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Аудиомазмұн сапасы бойынша оңтайландырылды (990 кбит/сек не 909 кбит/сек)"</item> - <item msgid="2921767058740704969">"Теңгерілген аудиомазмұн мен байланыс сапасы (660 кб/сек не 606 кб/сек)"</item> - <item msgid="8860982705384396512">"Байланыс сапасы бойынша оңтайландырылды (330 кбит/сек не 303 кбит/сек)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Аудиомазмұн сапасы үшін оңтайландырылды"</item> - <item msgid="4327143584633311908">"Теңгерілген аудиомазмұн мен байланыс сапасы"</item> - <item msgid="4681409244565426925">"Байланыс сапасы бойынша оңтайландырылды"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Өшірулі"</item> <item msgid="1593289376502312923">"64 КБ"</item> diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml index b43e82dfaaff..cacc9c60be75 100644 --- a/packages/SettingsLib/res/values-kk/strings.xml +++ b/packages/SettingsLib/res/values-kk/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Автоматты қосылмайды"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Интернетпен байланыс жоқ"</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> сақтаған"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s арқылы автоматты қосылды"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s арқылы қосылған"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s арқылы қолжетімді"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Өте тез"</item> <item msgid="9085102246155045744">"Ең тез"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Профильді таңдау"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Жеке"</string> <string name="category_work" msgid="8699184680584175622">"Жұмыс"</string> <string name="development_settings_title" msgid="215179176067683667">"Әзірлеуші опциялары"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi-Fi желісінен мобильдік желіге ауысу"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi роумингін іздеулерге әрқашан рұқсат ету"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобильдік деректер әрқашан қосулы"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Абсолютті дыбыс деңгейін өшіру"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP нұсқасы"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Bluetooth AVRCP нұсқасын таңдау"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth аудимазмұн кодегі"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Bluetooth аудиокодегін таңдау"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth аудиомазмұны бойынша үлгі жиілігі"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Трансляция: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</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> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Wi‑Fi сигналы әлсіз болғанда, деректер байланысы мәжбүрлі түрде мобильдік желіге ауысады"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Интерфейсте бар деректер трафигінің мөлшерінің негізінде Wi-Fi роумингін іздеулерге рұқсат ету/тыйым салу"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Журналға тіркеуші буферінің өлшемдері"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Әр журнал буфері үшін журналға тіркеуші өлшемдерін таңдау"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> үстінен басқан"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Шамамен <xliff:g id="TIME">%1$s</xliff:g> қалды"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> қалды"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – шамамен <xliff:g id="TIME">%2$s</xliff:g> қалды"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – желі арқылы толық зарядталғанға дейін <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – USB арқылы толық зарядталғанға дейін <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – сымсыз толық зарядталғанға дейін <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Зарядталып тұрған жоқ"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Толық"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Әкімші басқарады"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Әкімші қосқан"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Әкімші өшірген"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Параметрлер негізгі беті"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-km/arrays.xml b/packages/SettingsLib/res/values-km/arrays.xml index 2ba33f4d99c1..5e6656b3a3bf 100644 --- a/packages/SettingsLib/res/values-km/arrays.xml +++ b/packages/SettingsLib/res/values-km/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"ប្រើការពិនិត្យ HDCP សម្រាប់តែមាតិកា DRM ប៉ុណ្ណោះ"</item> <item msgid="45075631231212732">"ប្រើការពិនិត្យ HDCP ជានិច្ច"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (លំនាំដើម)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"ប្រើការជ្រើសរើសប្រព័ន្ធ (លំនាំដើម)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"ម៉ូណូ"</item> <item msgid="8883739882299884241">"ស្តេរ៉េអូ"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"បានបង្កើនប្រសិទ្ធភាពសម្រាប់គុណភាពសំឡេង (990kbps/909kbps)"</item> - <item msgid="2921767058740704969">"សំឡេងដែលមានតុល្យភាព និងគុណភាពនៃការតភ្ជាប់ (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"បានបង្កើនប្រសិទ្ធភាពសម្រាប់គុណភាពនៃការតភ្ជាប់ (330kbps/303kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"បានបង្កើនប្រសិទ្ធភាពសម្រាប់គុណភាពសំឡេង"</item> - <item msgid="4327143584633311908">"សំឡេងដែលមានតុល្យភាព និងគុណភាពនៃការតភ្ជាប់"</item> - <item msgid="4681409244565426925">"បានបង្កើនប្រសិទ្ធភាពសម្រាប់គុណភាពនៃការតភ្ជាប់"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"បិទ"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml index f59587813903..daa4c93c76b1 100644 --- a/packages/SettingsLib/res/values-km/strings.xml +++ b/packages/SettingsLib/res/values-km/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"នឹងមិនភ្ជាប់ដោយស្វ័យប្រវត្តិទេ"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"មិនមានអ៊ីនធឺណិតទេ"</string> <string name="saved_network" msgid="4352716707126620811">"បានរក្សាទុកដោយ <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"បានភ្ជាប់ដោយស្វ័យប្រវត្តិតាមរយៈ %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"បានភ្ជាប់តាមរយៈ %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"មានតាមរយៈ %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"រហ័សខ្លាំង"</item> <item msgid="9085102246155045744">"លឿនបំផុត"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"ជ្រើសប្រវត្តិរូប"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"ផ្ទាល់ខ្លួន"</string> <string name="category_work" msgid="8699184680584175622">"កន្លែងធ្វើការ"</string> <string name="development_settings_title" msgid="215179176067683667">"ជម្រើសអ្នកអភិវឌ្ឍ"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"ការភ្ជាប់បណ្ដាញ"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"បង្ហាញការកំណត់រចនាសម្ព័ន្ធឥតខ្សែ"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"បើកកំណត់ហេតុរៀបរាប់វ៉ាយហ្វាយ"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ប្តូរទៅប្រើបណ្តាញចល័តពេល Wi‑Fi មានរលកសញ្ញាខ្លាំងពេក"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"តែងតែអនុញ្ញាតការវិភាគរ៉ូមវ៉ាយហ្វាយ"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"ទិន្នន័យទូរសព្ទចល័តដំណើរការជានិច្ច"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"បិទកម្រិតសំឡេងលឺខ្លាំង"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"កំណែប្ល៊ូធូស AVRCP"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"ជ្រើសរើសកំណែប្ល៊ូធូស AVRCP"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"កូឌិកសំឡេងប៊្លូធូស"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"ជ្រើសរើសកូឌិកសំឡេងប៊្លូធូស"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"អត្រាគំរូសំឡេងប៊្លូធូស"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"កំពុងចាក់៖ <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"បង្ហាញជម្រើសសម្រាប់វិញ្ញាបនបត្របង្ហាញឥតខ្សែ"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"បង្កើនកម្រិតកំណត់ហេតុវ៉ាយហ្វាយបង្ហាញក្នុង SSID RSSI ក្នុងកម្មវិធីជ្រើសវ៉ាយហ្វាយ"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"នៅពេលដែលបើក នោះ Wi‑Fi នឹងធ្វើការប្រគល់ការតភ្ជាប់ទិន្នន័យយ៉ាងគំហុកទៅបណ្តាញទូរសព្ទចល័ត នៅពេលរលកសញ្ញា Wi‑Fi ចុះខ្សោយ។"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"អនុញ្ញាត/មិនអនុញ្ញាតការវិភាគរ៉ូមវ៉ាយហ្វាយផ្អែកលើចំនួនការបង្ហាញចរាចរណ៍ទិន្នន័យនៅចំណុចប្រទាក់"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"ទំហំ buffer របស់ Logger"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"ជ្រើសទំហំ Logger per log buffer"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"បដិសេធដោយ <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"នៅសល់ប្រហែល <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"នៅសល់ <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - សល់ប្រហែល <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - នៅសល់ <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> រហូតដល់សាកពេញដោយប្រើឆ្នាំងសាក"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> រហូតដល់សាកពេញដោយប្រើ USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> រហូតដល់សាកពេញដោយឥតប្រើខ្សែ"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"មិនបញ្ចូលថ្ម"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"ពេញ"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"គ្រប់គ្រងដោយអ្នកគ្រប់គ្រង"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"បានបើកដំណើរការដោយអ្នកគ្រប់គ្រង"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"បានបិទដំណើរការដោយអ្នកគ្រប់គ្រង"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"ទំព័រដើមនៃការកំណត់"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-kn/arrays.xml b/packages/SettingsLib/res/values-kn/arrays.xml index c94dc235940b..2936bf084298 100644 --- a/packages/SettingsLib/res/values-kn/arrays.xml +++ b/packages/SettingsLib/res/values-kn/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"DRM ವಿಷಯಗಳಿಗೆ ಮಾತ್ರ HDCP ಪರೀಕ್ಷಿಸುವಿಕೆಯನ್ನು ಬಳಸು"</item> <item msgid="45075631231212732">"HDCP ಪರಿಶೀಲನೆಯನ್ನು ಯಾವಾಗಲೂ ಬಳಸು"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (ಡಿಫಾಲ್ಟ್)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"ಸಿಸ್ಟಂ ಆಯ್ಕೆಯನ್ನು ಬಳಸಿ (ಡಿಫಾಲ್ಟ್)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"ಮೊನೊ"</item> <item msgid="8883739882299884241">"ಸ್ಟೀರಿಯೊ"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"ಆಡಿಯೋ ಗುಣಮಟ್ಟಕ್ಕಾಗಿ (990kbps/909kbps) ಆಪ್ಟಿಮೈಸ್ ಮಾಡಲಾಗಿದೆ"</item> - <item msgid="2921767058740704969">"ಸಂತುಲಿತ ಆಡಿಯೊ ಮತ್ತು ಸಂಪರ್ಕದ ಗುಣಮಟ್ಟ (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"ಸಂಪರ್ಕದ ಗುಣಮಟ್ಟಕ್ಕಾಗಿ (330kbps/303kbps) ಆಪ್ಟಿಮೈಸ್ ಮಾಡಲಾಗಿದೆ"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"ಆಡಿಯೊ ಗುಣಮಟ್ಟಕ್ಕಾಗಿ ಆಪ್ಟಿಮೈಸ್ ಮಾಡಲಾಗಿದೆ"</item> - <item msgid="4327143584633311908">"ಸಂತುಲಿತ ಆಡಿಯೊ ಮತ್ತು ಸಂಪರ್ಕದ ಗುಣಮಟ್ಟ"</item> - <item msgid="4681409244565426925">"ಸಂಪರ್ಕ ಗುಣಮಟ್ಟಕ್ಕಾಗಿ ಆಪ್ಟಿಮೈಸ್ ಮಾಡಲಾಗಿದೆ"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"ಆಫ್"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml index 776c658c3b81..34d426c295ff 100644 --- a/packages/SettingsLib/res/values-kn/strings.xml +++ b/packages/SettingsLib/res/values-kn/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"ಯಾವುದೇ ಇಂಟರ್ನೆಟ್ ಪ್ರವೇಶವಿಲ್ಲ"</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> ರಿಂದ ಉಳಿಸಲಾಗಿದೆ"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s ಮೂಲಕ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸಂಪರ್ಕಿಸಲಾಗಿದೆ"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s ಮೂಲಕ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s ಮೂಲಕ ಲಭ್ಯವಿದೆ"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"ಅತ್ಯಂತ ತ್ವರಿತ"</item> <item msgid="9085102246155045744">"ಅತಿ ಕ್ಷಿಪ್ರ"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"ಪ್ರೊಫೈಲ್ ಆಯ್ಕೆಮಾಡಿ"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"ವೈಯಕ್ತಿಕ"</string> <string name="category_work" msgid="8699184680584175622">"ಕೆಲಸದ ಸ್ಥಳ"</string> <string name="development_settings_title" msgid="215179176067683667">"ಡೆವಲಪರ್ ಆಯ್ಕೆಗಳು"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ವೈ-ಫೈನಿಂದ ಮೊಬೈಲ್ಗೆ ಆಕ್ರಮಣಕಾರಿ ಹಸ್ತಾಂತರ"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ವೈ-ಫೈ ರೋಮ್ ಸ್ಕ್ಯಾನ್ಗಳನ್ನು ಯಾವಾಗಲೂ ಅನುಮತಿಸಿ"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"ಮೊಬೈಲ್ ಡೇಟಾ ಯಾವಾಗಲೂ ಸಕ್ರಿಯ"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ಸಂಪೂರ್ಣ ವಾಲ್ಯೂಮ್ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ಬ್ಲೂಟೂತ್ AVRCP ಆವೃತ್ತಿ"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"ಬ್ಲೂಟೂತ್ AVRCP ಆವೃತ್ತಿಯನ್ನು ಆಯ್ಕೆ ಮಾಡಿ"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"ಬ್ಲೂಟೂತ್ ಆಡಿಯೋ ಕೋಡೆಕ್"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"ಬ್ಲೂಟೂತ್ ಆಡಿಯೊ ಕೋಡೆಕ್ ಆಯ್ಕೆ ಮಾಡಿ"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"ಬ್ಲೂಟೂತ್ ಆಡಿಯೋ ಮಾದರಿ ದರ"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ಸ್ಟ್ರೀಮಿಂಗ್: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</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> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ಇದು ಸಕ್ರಿಯಗೊಂಡರೆ, ವೈ-ಫೈ ಸಿಗ್ನಲ್ ದುರ್ಬಲವಾಗಿದ್ದಾಗ, ಮೊಬೈಲ್ಗೆ ಡೇಟಾ ಸಂಪರ್ಕವನ್ನು ಹಸ್ತಾಂತರಿಸುವಲ್ಲಿ ವೈ-ಫೈ ಹೆಚ್ಚು ಆಕ್ರಮಣಕಾರಿಯಾಗಿರುತ್ತದೆ"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"ಇಂಟರ್ಫೇಸ್ನಲ್ಲಿ ಲಭ್ಯವಿರುವ ಡೇಟಾ ಟ್ರಾಫಿಕ್ ಆಧಾರದ ಮೇಲೆ Wi‑Fi ರೋಮ್ ಸ್ಕ್ಯಾನ್ಗಳನ್ನು ಅನುಮತಿಸಿ/ನಿರಾಕರಿಸಿ"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"ಲಾಗರ್ ಬಫರ್ ಗಾತ್ರಗಳು"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"ಪ್ರತಿ ಲಾಗ್ ಬಫರ್ಗೆ ಲಾಗರ್ ಗಾತ್ರಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ಮೂಲಕ ಅತಿಕ್ರಮಿಸುತ್ತದೆ"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"ಸುಮಾರು <xliff:g id="TIME">%1$s</xliff:g> ಉಳಿದಿದೆ"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ಉಳಿದಿದೆ"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ಸುಮಾರು <xliff:g id="TIME">%2$s</xliff:g> ಬಾಕಿಯಿದೆ"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - AC ಮೂಲಕ ಸಂಪೂರ್ಣ ಚಾರ್ಜ್ ಆಗಲು <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB ಮೂಲಕ ಸಂಪೂರ್ಣ ಚಾರ್ಜ್ ಆಗಲು <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - ವಯರ್ಲೆಸ್ ಮೂಲಕ ಸಂಪೂರ್ಣ ಚಾರ್ಜ್ ಆಗಲು <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ಚಾರ್ಜ್ ಆಗುತ್ತಿಲ್ಲ"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"ಭರ್ತಿ"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"ನಿರ್ವಾಹಕರ ಮೂಲಕ ನಿಯಂತ್ರಿಸಲಾಗಿದೆ"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"ನಿರ್ವಾಹಕರಿಂದ ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"ನಿರ್ವಾಹಕರಿಂದ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"ಸೆಟ್ಟಿಂಗ್ಗಳ ಮುಖಪುಟ"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-ko/arrays.xml b/packages/SettingsLib/res/values-ko/arrays.xml index 8248fdb4d01b..62c018323a73 100644 --- a/packages/SettingsLib/res/values-ko/arrays.xml +++ b/packages/SettingsLib/res/values-ko/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"DRM 콘텐츠에 대해서만 HDCP 확인 사용"</item> <item msgid="45075631231212732">"항상 HDCP 확인 사용"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4(기본)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"시스템 설정 사용(기본)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"모노"</item> <item msgid="8883739882299884241">"스테레오"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"오디오 품질(990kbps/909kbps)에 최적화됨"</item> - <item msgid="2921767058740704969">"오디오 및 연결 품질의 균형 유지(660Kbps/606Kbps)"</item> - <item msgid="8860982705384396512">"연결 품질(330kbps/303kbps)에 최적화됨"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"오디오 품질에 최적화됨"</item> - <item msgid="4327143584633311908">"오디오 및 연결 품질의 균형 유지"</item> - <item msgid="4681409244565426925">"연결 품질에 최적화됨"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"사용 안함"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml index 735bb2210129..326d1d887a5d 100644 --- a/packages/SettingsLib/res/values-ko/strings.xml +++ b/packages/SettingsLib/res/values-ko/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"자동으로 연결되지 않습니다."</string> <string name="wifi_no_internet" msgid="3880396223819116454">"인터넷에 연결되어 있지 않습니다."</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g>(으)로 저장됨"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s을(를) 통해 자동으로 연결됨"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s을(를) 통해 연결됨"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s을(를) 통해 사용 가능"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"매우 빠르게"</item> <item msgid="9085102246155045744">"가장 빠르게"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"프로필 선택"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"개인"</string> <string name="category_work" msgid="8699184680584175622">"직장"</string> <string name="development_settings_title" msgid="215179176067683667">"개발자 옵션"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"적극적인 Wi-Fi-모바일 핸드오버"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi 로밍 스캔 항상 허용"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"항상 모바일 데이터 활성화"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"절대 볼륨 사용 안함"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"블루투스 AVRCP 버전"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"블루투스 AVRCP 버전 선택"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"블루투스 오디오 코덱"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"블루투스 오디오 코덱 선택"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"블루투스 오디오 샘플링 비율"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"스트리밍: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</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> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"사용 설정하면 Wi-Fi 신호가 약할 때 데이터 연결을 Wi-Fi에서 모바일 네트워크로 더욱 적극적으로 핸드오버합니다."</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"인터페이스에 표시되는 데이터 트래픽의 양을 기반으로 Wi-Fi 로밍 스캔을 허용하거나 허용하지 않습니다."</string> <string name="select_logd_size_title" msgid="7433137108348553508">"로거 버퍼 크기"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"로그 버퍼당 로거 크기 선택"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> 우선 적용됨"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"약 <xliff:g id="TIME">%1$s</xliff:g> 남음"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> 남음"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - 약 <xliff:g id="TIME">%2$s</xliff:g> 남음"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - 충전 완료까지 <xliff:g id="TIME">%2$s</xliff:g> 남음(AC 전원)"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - 충전 완료까지 <xliff:g id="TIME">%2$s</xliff:g> 남음(USB)"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - 충전 완료까지 <xliff:g id="TIME">%2$s</xliff:g> 남음(무선)"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"충전 안함"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"충전 완료"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"관리자가 제어"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"관리자가 사용 설정함"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"관리자가 사용 중지함"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"설정 홈"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-ky/arrays.xml b/packages/SettingsLib/res/values-ky/arrays.xml index 9cb2b172b54c..1d1480e34374 100644 --- a/packages/SettingsLib/res/values-ky/arrays.xml +++ b/packages/SettingsLib/res/values-ky/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"HDCP текшерүү DRM мазмунуна гана колдонулсун"</item> <item msgid="45075631231212732">"Ар дайым HDCP текшерүү колдонулсун"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (Демейки)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Тутум тандаганды колдонуу (демейки)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Моно"</item> <item msgid="8883739882299884241">"Стерео"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Аудионун сапатын оптималдаштыруу (990кб/сек./909кб/сек.)"</item> - <item msgid="2921767058740704969">"Теңделген аудио жана туташуу сапаты (660кб/сек./606кб/сек.)"</item> - <item msgid="8860982705384396512">"Туташуунун сапатын оптималдаштыруу (330кб/сек./303кб/сек.)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Аудионун сапатын оптималдаштыруу"</item> - <item msgid="4327143584633311908">"Теңделген аудио жана туташуу сапаты"</item> - <item msgid="4681409244565426925">"Туташуунун сапатын оптималдаштыруу"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Өчүк"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml index d5716ba8c6cf..b5a8cf327bc3 100644 --- a/packages/SettingsLib/res/values-ky/strings.xml +++ b/packages/SettingsLib/res/values-ky/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Автоматтык түрдө туташпайт"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Интернетке туташпай турат"</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> тарабынан сакталды"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s аркылуу автоматтык түрдө туташты"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s аркылуу жеткиликтүү"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s аркылуу жеткиликтүү"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Өтө тез"</item> <item msgid="9085102246155045744">"Эң ылдам"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Профиль тандоо"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Жеке"</string> <string name="category_work" msgid="8699184680584175622">"Жумуш"</string> <string name="development_settings_title" msgid="215179176067683667">"Иштеп чыгуучунун параметрлери"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi‑Fi начар болсо, мобилдик Инт-ке өтсүн"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi-Fi Роуминг Скандоо мүмкүнчүлүгүнө ар дайым уруксат берилсин"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобилдик дайындар ар дайым иштетилсин"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Үндүн абсолюттук деңгээли өчүрүлсүн"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP версиясы"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Bluetooth AVRCP версиясын тандоо"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth аудио кодек"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Bluetooth аудио кодегин тандаңыз"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth аудио үлгүсүнүн ылдамдыгы"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Трансляция: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</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> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Иштетилсе, Wi-Fi байланышы үзүл-кесил болуп жатканда, Wi-Fi тармагы туташууну мобилдик Интернетке өжөрлүк менен өткөрүп берет"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Интерфейстеги дайындар трафигинин көлөмүнө жараша Wi-Fi Роуминг скандоо мүмкүнчүлүгүн иштетүү/өчүрүү"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Каттагыч буферлеринин өлчөмдөрү"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Каттоо буфери үчүн Каттагычтын көлөмүн тандаңыз"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> менен алмаштырылган"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Болжол менен <xliff:g id="TIME">%1$s</xliff:g> калды"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> калды"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – болжол менен <xliff:g id="TIME">%2$s</xliff:g> калды"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – кубаттагычтан <xliff:g id="TIME">%2$s</xliff:g> кийин толук кубатталат"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – USB аркылуу <xliff:g id="TIME">%2$s</xliff:g> кийин толук кубатталат"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – зымсыз <xliff:g id="TIME">%2$s</xliff:g> кийин толук кубатталат"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Кубатталган жок"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Толук"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Администратор тарабынан көзөмөлдөнөт"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Администратор иштетип койгон"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Администратор өчүрүп койгон"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Жөндөөлөрдүн башкы бети"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-lo/arrays.xml b/packages/SettingsLib/res/values-lo/arrays.xml index 48bef580cd69..119779c4e615 100644 --- a/packages/SettingsLib/res/values-lo/arrays.xml +++ b/packages/SettingsLib/res/values-lo/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"ໃຊ້ການກວດສອບ HDCP ສຳລັບເນື້ອຫາ DRM ເທົ່ານັ້ນ"</item> <item msgid="45075631231212732">"ໃຊ້ການກວດສອບ HDCP ສະເໝີ"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Use System Selection (Default)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"ໂທນດຽວ"</item> <item msgid="8883739882299884241">"ສະເຕຣິໂອ"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"ປັບແຕ່ງສຳລັບຄຸນນະພາບສຽງ (990kbps/909kbps)"</item> - <item msgid="2921767058740704969">"Balanced Audio And Connection Quality (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"ປັບແຕ່ງສຳລັບຄຸນນະພາບການເຊື່ອມຕໍ່ (330kbps/303kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"ປັບແຕ່ງສຳລັບຄຸນນະພາບສຽງ"</item> - <item msgid="4327143584633311908">"Balanced Audio And Connection Quality"</item> - <item msgid="4681409244565426925">"ປັບແຕ່ງສຳລັບຄຸນນະພາບການເຊື່ອມຕໍ່"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"ປິດ"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml index 3dee662c4fc1..1972dc70a741 100644 --- a/packages/SettingsLib/res/values-lo/strings.xml +++ b/packages/SettingsLib/res/values-lo/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"ຈະບໍ່ເຊື່ອມຕໍ່ອັດຕະໂນມັດ"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"ບໍ່ມີການເຊື່ອມຕໍ່ອິນເຕີເນັດ"</string> <string name="saved_network" msgid="4352716707126620811">"ບັນທຶກໂດຍ <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatically connected via %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"ເຊື່ອມຕໍ່ຜ່ານ %1$s ແລ້ວ"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"ມີໃຫ້ຜ່ານ %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"ໄວສຸດໆ"</item> <item msgid="9085102246155045744">"ໄວທີ່ສຸດ"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"ເລືອກໂປຣໄຟລ໌"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"ສ່ວນໂຕ"</string> <string name="category_work" msgid="8699184680584175622">"ບ່ອນເຮັດວຽກ"</string> <string name="development_settings_title" msgid="215179176067683667">"ໂຕເລືອກນັກພັດທະນາ"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"ການສ້າງເຄືອຂ່າຍ"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"ສະແດງການຮັບຮອງຂອງລະບົບໄຮ້ສາຍ"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"ເປີດນຳໃຊ້ການເກັບປະຫວັດ Verbose Wi‑Fi"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressive Wi‑Fi to mobile handover"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ອະນຸຍາດການສະແກນການໂຣມ Wi‑Fi ສະເໝີ"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ປິດໃຊ້ລະດັບສຽງສົມບູນ"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP Version"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Select Bluetooth AVRCP Version"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth Audio Codec"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Select Bluetooth Audio Codec"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth Audio Sample Rate"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ສະແດງໂຕເລືອກສຳລັບການສະແດງການຮັບຮອງລະບົບໄຮ້ສາຍ"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ເພີ່ມລະດັບການເກັບປະຫວັດ Wi‑Fi, ສະແດງຕໍ່ SSID RSSI ໃນ Wi‑Fi Picker"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ເມື່ອເປີດນຳໃຊ້ແລ້ວ, ເຄືອຂ່າຍ Wi-Fi ຈະຖືກປ່ຽນໄປໃຊ້ເຄືອຂ່າຍໂທລະສັບແທນຫາກສັນຍານ Wi-Fi ອ່ອນ"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"ອະນຸຍາດ/ບໍ່ອະນຸຍາດການສະແກນການໂຣມ Wi-Fi ອີງຕາມຈຳນວນຂໍ້ມູນທີ່ເກີດຂຶ້ນໃນລະດັບສ່ວນຕິດຕໍ່"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"ຂະໜາດບັບເຟີໂຕລັອກ"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"ເລືອກຂະໜາດລັອກຕໍ່ບັບເຟີ"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"ຖືກແທນໂດຍ <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"ຍັງເຫຼືອປະມານ <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"ຍັງເຫຼືອ <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ຍັງເຫຼືອ <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - ຍັງເຫຼືອ <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until fully charged"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until fully charged on AC"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until fully charged over USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until fully charged from wireless"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ບໍ່ໄດ້ສາກໄຟ"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"ເຕັມ"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"ຄວບຄຸມໂດຍຜູ້ເບິ່ງແຍງ"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"ຖືກເປີດໃຊ້ໂດຍຜູ້ເບິ່ງແຍງລະບົບ"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"ຖືກປິດໄວ້ໂດຍຜູ້ເບິ່ງແຍງລະບົບ"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"ໜ້າທຳອິດຂອງການຕັ້ງຄ່າ"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-lt/arrays.xml b/packages/SettingsLib/res/values-lt/arrays.xml index 25891742ac04..2c4c3215fc3c 100644 --- a/packages/SettingsLib/res/values-lt/arrays.xml +++ b/packages/SettingsLib/res/values-lt/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Taikyti HDCP tikrinimą tik DRM turiniui"</item> <item msgid="45075631231212732">"Visada naudoti HDCP tikrinimą"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (numatytoji)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Naudoti sistemos pasirink. (numatytasis)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Monofoninis garsas"</item> <item msgid="8883739882299884241">"Stereofoninis garsas"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Optimizuota garso kokybė (990 Kb/s; 909 Kb/s)"</item> - <item msgid="2921767058740704969">"Subalansuotą garso ir ryšio kokybė (660 kbps / 606 kbps)"</item> - <item msgid="8860982705384396512">"Optimizuota ryšio kokybė (330 Kb/s; 303 Kb/s)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Optimizuota garso kokybė"</item> - <item msgid="4327143584633311908">"Subalansuota garso ir ryšio kokybė"</item> - <item msgid="4681409244565426925">"Optimizuota ryšio kokybė"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Išjungta"</item> <item msgid="1593289376502312923">"64 KB"</item> diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml index 9d98e09c32e6..39c8c5ed0042 100644 --- a/packages/SettingsLib/res/values-lt/strings.xml +++ b/packages/SettingsLib/res/values-lt/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Nebus automatiškai prisijungiama"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Nėra interneto ryšio"</string> <string name="saved_network" msgid="4352716707126620811">"Išsaugojo <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatiškai prisijungta naudojant „%1$s“"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Prisijungta naudojant „%1$s“"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Pasiekiama naudojant „%1$s“"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Labai spartus"</item> <item msgid="9085102246155045744">"Greičiausias"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Profilio pasirinkimas"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Asmeninės"</string> <string name="category_work" msgid="8699184680584175622">"Darbo"</string> <string name="development_settings_title" msgid="215179176067683667">"Kūrėjo parinktys"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Tinklai"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Belaidžio rodymo sertifikavimas"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Įgal. „Wi‑Fi“ daugiaž. įraš. į žurnalą"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agres. „Wi‑Fi“ perd. į mob. r. tinklą"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Visada leisti „Wi-Fi“ tarptiklinio ryšio nuskaitymą"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiliojo ryšio duomenys visada suaktyvinti"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Išjungti didžiausią garsą"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"„Bluetooth“ AVRCP versija"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Pasirinkite „Bluetooth“ AVRCP versiją"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"„Bluetooth“ garso kodekas"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Pasirinkite „Bluetooth“ garso kodeką"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"„Bluetooth“ garso pavyzdžio dažnis"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Srautinis perdavimas: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Rodyti belaidžio rodymo sertifikavimo parinktis"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Padidinti „Wi‑Fi“ įrašymo į žurnalą lygį, rodyti SSID RSSI „Wi-Fi“ rinkiklyje"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Jei ši parinktis įgalinta, „Wi‑Fi“ agresyviau perduos duomenų ryšiu į mobiliojo ryšio tinklą, kai „Wi‑Fi“ signalas silpnas"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Leisti / neleisti „Wi‑Fi“ tarptinklinio ryšio nuskaitymo, atsižvelgiant į sąsajos duomenų srauto kiekį"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Registruotuvo buferio dydžiai"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Pasir. registr. dydž. žurn. bufer."</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Nepaisyta naudojant nuostatą „<xliff:g id="TITLE">%1$s</xliff:g>“"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Liko maždaug <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Liko <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – liko maždaug <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – liko <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> iki visiško įkrovimo"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> iki visiško įkrovimo (kint. srovė)"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> iki visiško įkrovimo (per USB)"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> iki visiško įkrovimo (belaidis įkr.)"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Nežinomas"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Kraunasi..."</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nekraunama"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Visiškai įkrautas"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Valdo administratorius"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Įgalino administratorius"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Išjungė administratorius"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Pagrindinis Nustatymų ekranas"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0 %"</item> diff --git a/packages/SettingsLib/res/values-lv/arrays.xml b/packages/SettingsLib/res/values-lv/arrays.xml index 0ae31f526d9d..664b4cf94b9a 100644 --- a/packages/SettingsLib/res/values-lv/arrays.xml +++ b/packages/SettingsLib/res/values-lv/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Izmantot HDCP pārbaudi tikai DRM saturam"</item> <item msgid="45075631231212732">"Vienmēr izmantot HDCP pārbaudi"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (noklusējuma)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Sistēmas atlases izmantošana (nokl.)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Audio kvalitātes optimizēšana (990 Kb/s/909 Kb/s)"</item> - <item msgid="2921767058740704969">"Samērīga audio un savienojuma kvalitāte (660 Kb/s/606 Kb/s)"</item> - <item msgid="8860982705384396512">"Savienojuma kvalitātes optimizēšana (330 Kb/s/303 Kb/s)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Audio kvalitātes optimizēšana"</item> - <item msgid="4327143584633311908">"Samērīga audio un savienojuma kvalitāte"</item> - <item msgid="4681409244565426925">"Savienojuma kvalitātes optimizēšana"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Izslēgts"</item> <item msgid="1593289376502312923">"64 KB"</item> diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml index e09da0ea462c..df6b0809092e 100644 --- a/packages/SettingsLib/res/values-lv/strings.xml +++ b/packages/SettingsLib/res/values-lv/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Savienojums netiks izveidots automātiski"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Nav piekļuves internetam"</string> <string name="saved_network" msgid="4352716707126620811">"Saglabāja: <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automātiski savienots, izmantojot %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Savienots, izmantojot %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Pieejams, izmantojot %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Ļoti raiti"</item> <item msgid="9085102246155045744">"Visātrāk"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Profila izvēlēšanās"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Privāts"</string> <string name="category_work" msgid="8699184680584175622">"Darba"</string> <string name="development_settings_title" msgid="215179176067683667">"Izstrādātāju opcijas"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Tīklošana"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Bezvadu attēlošanas sertifikācija"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Iespējot Wi‑Fi detalizēto reģistrēšanu"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agresīva pāreja no Wi‑Fi uz mobilo tīklu"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vienmēr atļaut Wi‑Fi meklēšanu"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Vienmēr aktīvs mobilo datu savienojums"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Atspējot absolūto skaļumu"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP versija"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Atlasiet Bluetooth AVRCP versiju"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth audio kodeks"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Atlasīt Bluetooth audio kodeku"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth audio iztveršanas ātrums"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Straumēšana: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Rādīt bezvadu attēlošanas sertifikācijas iespējas"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Palieliniet Wi‑Fi reģistrēšanas līmeni; rādīt katram SSID RSSI Wi‑Fi atlasītājā."</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Ja opcija ir iespējota un Wi‑Fi signāls ir vājš, datu savienojuma pāreja no Wi-Fi uz mobilo tīklu tiks veikta agresīvāk."</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Atļaujiet/neatļaujiet Wi‑Fi meklēšanu, pamatojoties uz saskarnē saņemto datplūsmas apjomu."</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Reģistrētāja buferu lielumi"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Atlasīt reģistrētāja bufera liel."</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Jaunā preference: <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Atlikušais laiks: aptuveni <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Atlicis: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - vēl apmēram <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> — atlicis: <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>, kamēr pilnībā uzlādēts"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>, kamēr pilnībā uzlādēts kontaktligzdā"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>, kamēr pilnībā uzlādēts (USB)"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>, kamēr pilnībā uzlādēts (bezvadu)"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Nezināms"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Uzlāde"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nenotiek uzlāde"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Pilns"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrolē administrators"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Iespējojis administrators"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Atspējojis administrators"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Iestatījumu sākumekrāns"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-mk/arrays.xml b/packages/SettingsLib/res/values-mk/arrays.xml index 90a0d7242429..7a0c04783117 100644 --- a/packages/SettingsLib/res/values-mk/arrays.xml +++ b/packages/SettingsLib/res/values-mk/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Користи ХДЦП проверка само за ДРМ содржина"</item> <item msgid="45075631231212732">"Секогаш користи ХДЦП проверка"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (Стандардно)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Користи избор на системот (стандардно)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Моно"</item> <item msgid="8883739882299884241">"Стерео"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Оптимизирано за квалитет на аудиото (990 кб/с - 909 кб/с)"</item> - <item msgid="2921767058740704969">"Балансиран квалитет на звукот и врската (660 kb/s/606 kb/s)"</item> - <item msgid="8860982705384396512">"Оптимизирано за квалитет на врската (330 кб/с - 303 кб/с)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Оптимизирано за квалитет на аудиото"</item> - <item msgid="4327143584633311908">"Балансиран квалитет на звукот и врската"</item> - <item msgid="4681409244565426925">"Оптимизирано за квалитет на врската"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Исклучено"</item> <item msgid="1593289376502312923">"64.000"</item> diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml index 15c314b015a2..34e57184926c 100644 --- a/packages/SettingsLib/res/values-mk/strings.xml +++ b/packages/SettingsLib/res/values-mk/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Не може да се поврзе автоматски"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Нема пристап до Интернет"</string> <string name="saved_network" msgid="4352716707126620811">"Зачувано од <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Автоматски поврзано преку %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Поврзано преку %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Достапно преку %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Многу рапидно"</item> <item msgid="9085102246155045744">"Најбрзо"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Изберете профил"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Лични"</string> <string name="category_work" msgid="8699184680584175622">"Работа"</string> <string name="development_settings_title" msgid="215179176067683667">"Програмерски опции"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Агресивно предавање од Wi‑Fi на мобилен"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Секогаш дозволувај Wi‑Fi скенирање во роаминг"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобилниот интернет е секогаш активен"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Оневозможете апсолутна јачина на звук"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Верзија Bluetooth AVRCP"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Изберете верзија Bluetooth AVRCP"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Кодек за аудио преку Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Изберете кодек за аудио преку Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Стапка на семпл преку Bluetooth"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Емитување: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</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> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Кога е овозможено, Wi-Fi ќе биде поагресивна при предавање на интернет-врската на мобилната мрежа при слаб сигнал на Wi-Fi"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Дозволи/Забрани Wi‑Fi скенирање во роаминг според количината на постоечкиот податочен сообраќај на интерфејсот."</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Величини на меѓумеморија на забележувач"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Величина/меѓумеморија на дневник"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Прескокнато според <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Преостанаа прибл. <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"уште <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - уште околу <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - уште <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> дури се наполни целосно преку AC"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> дури се наполни целосно преку USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> дури се наполни целосно преку Wi-Fi"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не се полни"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Полна"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Контролирано од администраторот"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Овозможено од администраторот"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Оневозможено од администраторот"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Почетна страница за поставки"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-ml/arrays.xml b/packages/SettingsLib/res/values-ml/arrays.xml index 13d65e7bb37b..fe28f588965d 100644 --- a/packages/SettingsLib/res/values-ml/arrays.xml +++ b/packages/SettingsLib/res/values-ml/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"DRM ഉള്ളടക്കത്തിനുമാത്രമായി HDCP പരിശോധന ഉപയോഗിക്കുക"</item> <item msgid="45075631231212732">"എല്ലായ്പ്പോഴും HDCP പരിശോധന ഉപയോഗിക്കുക"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (ഡിഫോൾട്ട്)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"സിസ്റ്റം സെലക്ഷൻ ഉപയോഗിക്കൂ (ഡിഫോൾട്ട്)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"മോണോ"</item> <item msgid="8883739882299884241">"സ്റ്റീരിയോ"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"ശബ്ദനിലവാരമുയർത്താൻ ഒപ്റ്റിമൈസ് ചെയ്തു (990kbps/909kbps)"</item> - <item msgid="2921767058740704969">"സന്തുലിതമായ ഓഡിയോ/കണക്ഷൻ നിലവാരം (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"കണക്ഷൻ നിലവാരമുയർത്താൻ ഒപ്റ്റിമൈസ് ചെയ്തു (330kbps/303kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"ശബ്ദനിലവാരമുയർത്താൻ ഒപ്റ്റിമൈസ് ചെയ്തു"</item> - <item msgid="4327143584633311908">"സന്തുലിതമായ ഓഡിയോ/കണക്ഷൻ നിലവാരം"</item> - <item msgid="4681409244565426925">"കണക്ഷൻ നിലവാരമുയർത്താൻ ഒപ്റ്റിമൈസ് ചെയ്തു"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"ഓഫ്"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml index 6501fba88ed1..420502b49b5f 100644 --- a/packages/SettingsLib/res/values-ml/strings.xml +++ b/packages/SettingsLib/res/values-ml/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"സ്വയമേവ കണക്റ്റുചെയ്യില്ല"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"ഇന്റർനെറ്റ് ആക്സസ്സ് ഇല്ല"</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> സംരക്ഷിച്ചത്"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s വഴി സ്വയമേവ ബന്ധിപ്പിച്ചു"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s വഴി ബന്ധിപ്പിച്ചു"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s വഴി ലഭ്യം"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"വളരെ ശീഘ്രം"</item> <item msgid="9085102246155045744">"ഏറ്റവും വേഗത്തിൽ"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"പ്രൊഫൈൽ തിരഞ്ഞെടുക്കുക"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"വ്യക്തിഗതം"</string> <string name="category_work" msgid="8699184680584175622">"ഔദ്യോഗികം"</string> <string name="development_settings_title" msgid="215179176067683667">"ഡെവലപ്പർ ഓപ്ഷനുകൾ"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"നെറ്റ്വര്ക്കിംഗ്"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"വയർലെസ് ഡിസ്പ്ലേ സർട്ടിഫിക്കേഷൻ"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"വൈഫൈ വെർബോസ് ലോഗിംഗ് പ്രവർത്തനക്ഷമമാക്കുക"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"മൊബൈൽ ഹാൻഡ്ഓവറിലേക്ക് വൈഫൈ സക്രിയമാക്കുക"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"എപ്പോഴും വൈഫൈ റോം സ്കാൻ അനുവദിക്കൂ"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"മൊബൈൽ ഡാറ്റ എല്ലായ്പ്പോഴും സജീവം"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"അബ്സൊല്യൂട്ട് വോളിയം പ്രവർത്തനരഹിതമാക്കുക"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP പതിപ്പ്"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Bluetooth AVRCP പതിപ്പ് തിരഞ്ഞെടുക്കുക"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth ഓഡിയോ കോഡെക്"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Bluetooth ഓഡിയോ കോഡെക് തിരഞ്ഞെടുക്കുക"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth ഓഡിയോ സാമ്പിൾ നിരക്ക്"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"സ്ട്രീമിംഗ്: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"വയർലെസ് ഡിസ്പ്ലേ സർട്ടിഫിക്കേഷനായി ഓപ്ഷനുകൾ ദൃശ്യമാക്കുക"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"വൈഫൈ പിക്കറിൽ ഓരോ SSID RSSI പ്രകാരം കാണിക്കാൻ വൈഫൈ ലോഗിംഗ് നില വർദ്ധിപ്പിക്കുക"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"പ്രവർത്തനക്ഷമമായിരിക്കുമ്പോൾ, വൈഫൈ സിഗ്നൽ കുറവായിരിക്കുന്ന സമയത്ത് മൊബൈലിലേക്ക് ഡാറ്റ കണക്ഷൻ വഴി കൈമാറുന്നതിൽ വൈഫൈ കൂടുതൽ സക്രിയമായിരിക്കും"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"ഇന്റർഫേസിലെ ഡാറ്റ ട്രാഫിക്ക് സാന്നിദ്ധ്യത്തിന്റെ കണക്ക് അടിസ്ഥാനമാക്കി വൈഫൈ റോം സ്കാനുകൾ അനുവദിക്കുക/അനുവദിക്കാതിരിക്കുക"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"ലോഗർ ബഫർ വലുപ്പം"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"ഓരോ ലോഗ് ബഫറിനും വലുപ്പം തിരഞ്ഞെടുക്കൂ"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ഉപയോഗിച്ച് അസാധുവാക്കി"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"ഏകദേശം <xliff:g id="TIME">%1$s</xliff:g> ശേഷിക്കുന്നു"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ശേഷിക്കുന്നു"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ഏതാണ്ട് <xliff:g id="TIME">%2$s</xliff:g> ശേഷിക്കുന്നു"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - AC-യിൽ പൂർണ്ണമായും ചാർജ്ജാകുന്നതിന് <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB-യിൽ പൂർണ്ണമായും ചാർജ്ജാകുന്നതിന് <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - വയർലെസ് വഴി പൂർണ്ണമായും ചാർജ്ജാകുന്നതിന് <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ചാർജ്ജുചെയ്യുന്നില്ല"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"നിറഞ്ഞു"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"അഡ്മിൻ നിയന്ത്രിക്കുന്നത്"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"അഡ്മിനിസ്ട്രേറ്റർ പ്രവർത്തനക്ഷമമാക്കി"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"അഡ്മിനിസ്ട്രേറ്റർ പ്രവർത്തനരഹിതമാക്കി"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"ക്രമീകരണ ഹോം"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-mn/arrays.xml b/packages/SettingsLib/res/values-mn/arrays.xml index e252d2f6afe3..af033d228143 100644 --- a/packages/SettingsLib/res/values-mn/arrays.xml +++ b/packages/SettingsLib/res/values-mn/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"HDCP шалгахыг зөвхөн DRM контентэд ашиглах"</item> <item msgid="45075631231212732">"Байнга HDCP шалгахыг ашиглах"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (Өгөгдмөл)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Системийн сонголтыг ашиглах (Өгөгдмөл)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Моно"</item> <item msgid="8883739882299884241">"Стерео"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Аудио чанарт тааруулсан (990кб/цаг/909кб/цаг)"</item> - <item msgid="2921767058740704969">"Аудио, холболтын чанарыг тэнцүүлсэн (660кб/цаг/606кб/цаг)"</item> - <item msgid="8860982705384396512">"Холболтын чанарт тааруулсан (330кб/цаг/303кб/цаг)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Аудио чанарт тааруулсан"</item> - <item msgid="4327143584633311908">"Аудио, холболтын чанарыг тэнцүүлсэн"</item> - <item msgid="4681409244565426925">"Холболтын чанарт тааруулсан"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Идэвхгүй"</item> <item msgid="1593289376502312923">"64000"</item> diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml index ce6a637122ce..6740d2751954 100644 --- a/packages/SettingsLib/res/values-mn/strings.xml +++ b/packages/SettingsLib/res/values-mn/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Автоматаар холбогдохгүй"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Интернэт холболт алга"</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> хадгалсан"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s-р автоматаар холбогдсон"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s-р холбогдсон"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s-р боломжтой"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Маш түргэн"</item> <item msgid="9085102246155045744">"Хамгийн хурдан"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Профайлаа сонгоно уу"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Хувийн"</string> <string name="category_work" msgid="8699184680584175622">"Ажил"</string> <string name="development_settings_title" msgid="215179176067683667">"Хөгжүүлэгчийн тохиргоо"</string> @@ -170,16 +170,12 @@ <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 Verbose лог-г идэвхжүүлэх"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Идэвхтэй Wi‑Fi-с мобайл сүлжээнд"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi Роум сканыг байнга зөвшөөрөх"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобайл дата байнга идэвхтэй"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Үнэмлэхүй дууны түвшинг идэвхгүй болгох"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP хувилбар"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Bluetooth AVRCP хувилбарыг сонгох"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth аудио кодлогч"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Bluetooth аудио кодлогч сонгох"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth аудио жишээний үнэлгээ"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Дамжуулж байна: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</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> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Идэвхжүүлсэн үед Wi‑Fi холболт сул байх үед дата холболтыг мобайлд шилжүүлэхэд илүү идэвхтэй байх болно"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Интерфэйс дээрх дата трафикын хэмжээнээс хамааран Wi‑Fi Роум Скан-г зөвшөөрөх/үл зөвшөөрөх"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Логгерын буферын хэмжээ"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Лог буфер бүрт ногдох логгерын хэмжээг сонгоно уу"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Давхарласан <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Ойролцоогоор <xliff:g id="TIME">%1$s</xliff:g> үлдсэн"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> үлдсэн"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g>-с <xliff:g id="TIME">%2$s</xliff:g> үлдсэн"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"AC-р бүрэн цэнэглэх хүртэл <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"USB-р бүрэн цэнэглэх хүртэл <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"Wi-Fi-р бүрэн цэнэглэх хүртэл <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Цэнэглэхгүй байна"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Дүүрэн"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Админ удирдсан"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Админ идэвхтэй болгосон"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Админ идэвхгүй болгосон"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Тохиргооны нүүр хуудас"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-mr/arrays.xml b/packages/SettingsLib/res/values-mr/arrays.xml index 218833df29f5..17a1b11b4a1f 100644 --- a/packages/SettingsLib/res/values-mr/arrays.xml +++ b/packages/SettingsLib/res/values-mr/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"केवळ DRM सामग्रीसाठी HDCP तपासणी वापरा"</item> <item msgid="45075631231212732">"नेहमी HDCP तपासणी वापरा"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (डीफॉल्ट)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"प्रणाली निवड वापरा (डीफॉल्ट)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"मोनो"</item> <item msgid="8883739882299884241">"स्टिरिओ"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"ऑडिओ गुणवत्ता (990kbps/909kbps) साठी ऑप्टिमाइझ केली"</item> - <item msgid="2921767058740704969">"संतुलित ऑडिओ आणि कनेक्शन गुणवत्ता (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"कनेक्शन गुणवत्ता (330kbps/303kbps) साठी ऑप्टिमाइझ केली"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"ऑडिओ गुणवत्तेसाठी ऑप्टिमाइझ केले"</item> - <item msgid="4327143584633311908">"संतुलित ऑडिओ आणि कनेक्शन गुणवत्ता"</item> - <item msgid="4681409244565426925">"कनेक्शन गुणवत्तेसाठी ऑप्टिमाइझ केले"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"बंद"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml index a0879e1216b1..e1938cde5b73 100644 --- a/packages/SettingsLib/res/values-mr/strings.xml +++ b/packages/SettingsLib/res/values-mr/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"स्वयंचलितपणे कनेक्ट करणार नाही"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"इंटरनेट प्रवेश नाही"</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> द्वारे जतन केले"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s द्वारे स्वयंचलितपणे कनेक्ट केले"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s द्वारे कनेक्ट केले"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s द्वारे उपलब्ध"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"अतिशीघ्र"</item> <item msgid="9085102246155045744">"जलद"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"प्रोफाईल निवडा"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"वैयक्तिक"</string> <string name="category_work" msgid="8699184680584175622">"कार्य"</string> <string name="development_settings_title" msgid="215179176067683667">"विकासक पर्याय"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"नेटवर्किंग"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"वायरलेस प्रदर्शन प्रमाणीकरण"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"वाय-फाय शब्दपाल्हाळ लॉगिंग सक्षम करा"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"मोबाइलकडे सोपवण्यासाठी आक्रमक वाय-फाय"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"वाय-फाय रोम स्कॅनला नेहमी अनुमती द्या"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"मोबाइल डेटा नेहमी सक्रिय"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"संपूर्ण आवाज अक्षम करा"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ब्लूटुथ AVRCP आवृत्ती"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"ब्लूटुथ AVRCP आवृत्ती निवडा"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"ब्लूटूथ ऑडिओ कोडेक"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"ब्लूटुथ ऑडिओ कोडेक निवडा"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"ब्लूटूथ ऑडिओ नमुना दर"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"धारावाहिक: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"वायरलेस प्रदर्शन प्रमाणिकरणासाठी पर्याय दर्शवा"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"वाय-फाय लॉगिंग स्तर वाढवा, वाय-फाय निवडकामध्ये प्रति SSID RSSI दर्शवा"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"सक्षम केले असताना, वाय-फाय सिग्नल कमी असताना, मोबाइलकडे डेटा कनेक्शन सोपवण्यासाठी वाय-फाय अधिक आक्रमक असेल."</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"वाय-फाय रोम स्कॅनला इंटरफेसवर उपस्थित असलेल्या रहदारी डेटाच्या प्रमाणावर आधारित अनुमती द्या/अनुमती देऊ नका"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"लॉगर बफर आकार"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"प्रति लॉग बफर लॉगर आकार निवडा"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> द्वारे अधिलिखित"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"अंदाजे. <xliff:g id="TIME">%1$s</xliff:g> शिल्लक"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> शिल्लक"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - सुमारे <xliff:g id="TIME">%2$s</xliff:g> शिल्लक"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - AC वर पूर्णपणे चार्ज होण्यात <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB वर पूर्णपणे चार्ज होण्यात <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - वायरलेसवरून पूर्णपणे चार्ज होण्यात <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"चार्ज होत नाही"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"पूर्ण"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"प्रशासकाने नियंत्रित केलेले"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"प्रशासकाने सक्षम केलेले"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"प्रशासकाने अक्षम केलेले"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"सेटिंग्ज मुख्यपृष्ठ"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-ms/arrays.xml b/packages/SettingsLib/res/values-ms/arrays.xml index 6629591b1331..a9d15613b0ca 100644 --- a/packages/SettingsLib/res/values-ms/arrays.xml +++ b/packages/SettingsLib/res/values-ms/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Gunakan penyemakan HDCP untuk kandungan DRM sahaja"</item> <item msgid="45075631231212732">"Sentiasa gunakan penyemakan HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (Lalai)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Gunakan Pilihan Sistem (Lalai)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Dioptimumkan untuk Kualiti Audio (990kbps/909kbps)"</item> - <item msgid="2921767058740704969">"Audio Seimbang dan Kualiti Sambungan (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"Dioptimumkan untuk Kualiti Sambungan (330kbps/303kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Dioptimumkan untuk Kualiti Audio"</item> - <item msgid="4327143584633311908">"Audio Seimbang dan Kualiti Sambungan"</item> - <item msgid="4681409244565426925">"Dioptimumkan untuk Kualiti Sambungan"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Mati"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml index 3ba846e0e62e..2433d792cacc 100644 --- a/packages/SettingsLib/res/values-ms/strings.xml +++ b/packages/SettingsLib/res/values-ms/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Tidak akan menyambung secara automatik"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Tiada akses Internet"</string> <string name="saved_network" msgid="4352716707126620811">"Diselamatkan oleh <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Disambungkan secara automatik melalui %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Disambungkan melalui %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Tersedia melalui %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Sangat pantas"</item> <item msgid="9085102246155045744">"Paling laju"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Pilih Profil"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Peribadi"</string> <string name="category_work" msgid="8699184680584175622">"Tempat Kerja"</string> <string name="development_settings_title" msgid="215179176067683667">"Pilihan pembangun"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Perangkaian"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Pensijilan paparan wayarles"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Dayakan Pengelogan Berjela-jela Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Penyerahan Wi-Fi ke mudah alih agresif"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Sentiasa benarkan Imbasan Perayauan Wi-Fi"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Data mudah alih sentiasa aktif"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Lumpuhkan kelantangan mutlak"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versi AVRCP Bluetooth"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Pilih Versi AVRCP Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Codec Audio Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Pilih Codec Audio Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Kadar Sampel Audio Bluetooth"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Penstriman: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Tunjukkan pilihan untuk pensijilan paparan wayarles"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Tingkatkan tahap pengelogan Wi-Fi, tunjuk setiap SSID RSSI dalam Pemilih Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Apabila didayakan, Wi-Fi akan menjadi lebih agresif dalam menyerahkan sambungan data ke mudah alih, apabila isyarat Wi-Fi rendah"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Benarkan/Jangan benarkan Imbasan Perayauan Wi-Fi berdasarkan jumlah trafik data yang ada pada antara muka"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Saiz penimbal pengelog"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Pilih saiz Pengelog bagi setiap penimbal log"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Diatasi oleh <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Kira-kira <xliff:g id="TIME">%1$s</xliff:g> lagi"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> lagi"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - kira-kira <xliff:g id="TIME">%2$s</xliff:g> lagi"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lagi"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga dicas penuh"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga dicas penuh menggunakan AC"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga dicas penuh melalui USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga dicas penuh drp wayarles"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Tidak diketahui"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Mengecas"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Tidak mengecas"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Penuh"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Dikawal oleh pentadbir"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Didayakan oleh pentadbir"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Dilumpuhkan oleh pentadbir"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Laman Utama Tetapan"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-my/arrays.xml b/packages/SettingsLib/res/values-my/arrays.xml index 22ac5aa12de1..22e91ac9ceb3 100644 --- a/packages/SettingsLib/res/values-my/arrays.xml +++ b/packages/SettingsLib/res/values-my/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"DRMအကြောင်းအရာအတွက် HDCPစစ်ဆေးခြင်းကိုသုံးမည်"</item> <item msgid="45075631231212732">"HDCP checkingအားအမြဲသုံးပါ"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (မူလ)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"စနစ်ရွေးချယ်မှုကို အသုံးပြုပါ (မူရင်း)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"မိုနို"</item> <item msgid="8883739882299884241">"စတီရီယို"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"အသံအရည်အသွေးကို ပိုကောင်းအောင် ပြုလုပ်ထားသည် (၉၉၀kbps/၉၀၉kbps)"</item> - <item msgid="2921767058740704969">"အသံနှင့် ချိတ်ဆက်မှု အရည်အသွေးကို မျှတအောင် ချိန်ဆပေးသည် (၆၆၀kbps/၆၀၆kbps)"</item> - <item msgid="8860982705384396512">"ချိတ်ဆက်မှု အရည်အသွေးကို ပိုကောင်းအောင် ပြုလုပ်ထားသည် (၃၃၀kbps/၃၀၃kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"အသံအရည်အသွေးကို ပိုကောင်းအောင် ပြုလုပ်ထားသည်"</item> - <item msgid="4327143584633311908">"အသံနှင့် ချိတ်ဆက်မှု အရည်သွေးကို မျှတအောင် ချိန်ဆပေးသည်"</item> - <item msgid="4681409244565426925">"ချိတ်ဆက်မှု အရည်အသွေးကို ပိုကောင်းအောင် ပြုလုပ်ထားသည်"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"ပိတ်ပါ"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml index f53a28d84a8e..998801c2c9fc 100644 --- a/packages/SettingsLib/res/values-my/strings.xml +++ b/packages/SettingsLib/res/values-my/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"အလိုအလျောက်ချိတ်ဆက်မည်မဟုတ်ပါ"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"အင်တာနက် ချိတ်ဆက်မှု မရှိပါ"</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> မှသိမ်းဆည်းခဲ့သည်"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s မှတစ်ဆင့် အလိုအလျောက် ချိတ်ဆက်ထားပါသည်"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s မှတစ်ဆင့် ချိတ်ဆက်ထားသည်"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s မှတစ်ဆင့်ရနိုင်သည်"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"အရမ်းသွက်"</item> <item msgid="9085102246155045744">"အမြန်ဆုံး"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"ပရိုဖိုင်ရွေးရန်"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"ကိုယ်ရေး"</string> <string name="category_work" msgid="8699184680584175622">"အလုပ်အကိုင်"</string> <string name="development_settings_title" msgid="215179176067683667">"ဆော့ဝဲလ်ရေးသူ၏ ရွေးချယ်မှုများ"</string> @@ -170,16 +170,12 @@ <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 Verbose မှတ်တမ်းတင်ခြင်းအား ဖွင့်မည်"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi‑Fi မှ မိုဘိုင်းသို့ လွှဲပြောင်းရန်"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi ရွမ်းရှာဖွေမှုကို အမြဲတမ်း ခွင့်ပြုမည်"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"မိုဘိုင်းဒေတာကို အမြဲဖွင့်ထားရန်"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ပကတိ အသံနှုန်း သတ်မှတ်ချက် ပိတ်ရန်"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ဘလူးတုသ် AVRCP ဗားရှင်း"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"ဘလူးတုသ် AVRCP ဗားရှင်းကို ရွေးပါ"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"ဘလူးတုသ်အသံ ကိုးဒက်ခ်"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"ဘလူးတုသ်အသံကိုးဒက်ခ်ကို ရွေးပါ"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"ဘလူးတုသ်အသံနမူနာနှုန်း"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"တိုက်ရိုက်လွှင့်နေသည်− <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</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> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ဖွင့်ထားပါက Wi‑Fi လွှင့်အား နည်းချိန်တွင် Wi‑Fi မှ မိုဘိုင်းသို့ ဒေတာချိတ်ဆက်မှုကို လွှဲပြောင်းရာ၌ ပိုမိုထိရောက်ပါသည်"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"မျက်နှာပြင်တွင် ဖော်ပြသည့် အချက်လက် အသွားအလာ ပမာဏပေါ်တွင် အခြေခံ၍ WIFI ရွမ်းရှာဖွေမှုအား ဖွင့်/ပိတ်မည်"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"လော့ဂါး ဘာဖား ဆိုက်များ"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"လော့ ဘာဖားတွက် လော့ဂါးဆိုက် ရွေး"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> မှ ကျော်၍ လုပ်ထားသည်။"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"ခန့်မှန်းခြေ <xliff:g id="TIME">%1$s</xliff:g> ကျန်ပါသည်"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ကျန်သည်"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> − <xliff:g id="TIME">%2$s</xliff:g> ခန့်ကျန်သည်"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> − AC ဖြင့် အားအပြည့်သွင်းရန် <xliff:g id="TIME">%2$s</xliff:g> ကျန်သည်"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> − USB ဖြင့် အားအပြည့်သွင်းရန် <xliff:g id="TIME">%2$s</xliff:g> ကျန်သည်"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> − ဝါယာလက်စနစ်ဖြင့်အားပြည့်ရန် <xliff:g id="TIME">%2$s</xliff:g> ကျန်သည်"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"အားသွင်းမနေပါ"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"အပြည့်"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"စီမံခန့်ခွဲသူမှ ထိန်းချုပ်ပါသည်"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"စီမံခန့်ခွဲသူမှ ဖွင့်ထားသည်"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"စီမံခန့်ခွဲသူမှ ပိတ်ထားသည်"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"ဆက်တင် ပင်မစာမျက်နှာ"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"၀%"</item> diff --git a/packages/SettingsLib/res/values-nb/arrays.xml b/packages/SettingsLib/res/values-nb/arrays.xml index 605a8ded550f..ba555bc85411 100644 --- a/packages/SettingsLib/res/values-nb/arrays.xml +++ b/packages/SettingsLib/res/values-nb/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Bruk HDCP-kontroll kun for DRM-innhold"</item> <item msgid="45075631231212732">"Bruk alltid HDCP-kontroll"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (standard)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Bruk systemvalg (standard)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Optimalisert for lydkvalitet (990 kbps / 909 kbps)"</item> - <item msgid="2921767058740704969">"Balansert lyd- og tilkoblingskvalitet (660 kbps/606kbps)"</item> - <item msgid="8860982705384396512">"Optimalisert for tilkoblingskvalitet (330 kbps / 303 kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Optimalisert for lydkvalitet"</item> - <item msgid="4327143584633311908">"Balansert lyd- og tilkoblingskvalitet"</item> - <item msgid="4681409244565426925">"Optimalisert for tilkoblingskvalitet"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Av"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml index bcb30cda4635..1fdfe5d6d466 100644 --- a/packages/SettingsLib/res/values-nb/strings.xml +++ b/packages/SettingsLib/res/values-nb/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Kobler ikke til automatisk"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Ingen Internett-tilgang"</string> <string name="saved_network" msgid="4352716707126620811">"Lagret av <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatisk tilkoblet via %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Tilkoblet via %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Tilgjengelig via %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Veldig hurtig"</item> <item msgid="9085102246155045744">"Raskest"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Velg profil"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Personlig"</string> <string name="category_work" msgid="8699184680584175622">"Jobb"</string> <string name="development_settings_title" msgid="215179176067683667">"Utvikleralternativer"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Nettverk"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Trådløs skjermsertifisering"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktiver detaljert Wi-Fi-loggføring"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressiv overføring fra Wi-Fi til mobil"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Tillat alltid skanning for Wi-Fi-roaming"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobildata er alltid aktiv"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Slå av funksjonen for absolutt volum"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP-versjon"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Velg Bluetooth AVRCP-versjon"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Kodek for Bluetooth-lyd"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Velg kodek for Bluetooth-lyd"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Samplefrekvens for Bluetooth-lyd"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Strømming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Vis alternativer for sertifisering av trådløs skjerm"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Øk Wi-Fi-loggenivå – vis per SSID RSSI i Wi-Fi-velgeren"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Hvis dette slås på, overfører Wi-Fi-nettverket datatilkoblingen til mobil mer aggressivt når Wi-Fi-signalet er svakt"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Tillat / ikke tillat skanning for Wi-Fi-roaming basert på mengden datatrafikk til stede i grensesnittet"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Bufferstørrelser for logg"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Velg loggstørrelse per loggbuffer"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overstyres av <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Ca. <xliff:g id="TIME">%1$s</xliff:g> gjenstår"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> gjenstår"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – omtrent <xliff:g id="TIME">%2$s</xliff:g> gjenstår"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> gjenstår"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til det er fulladet"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til det er fulladet via strømuttak"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til det er fulladet via USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til full lading via trådløs lading"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Ukjent"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Lader"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Lader ikke"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Fullt"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrollert av administratoren"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Slått på av administratoren"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Avslått av administratoren"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Innstillinger for startsiden"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0 %"</item> diff --git a/packages/SettingsLib/res/values-ne/arrays.xml b/packages/SettingsLib/res/values-ne/arrays.xml index 7bf3b4f18f32..d3e0cd625a0c 100644 --- a/packages/SettingsLib/res/values-ne/arrays.xml +++ b/packages/SettingsLib/res/values-ne/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"DRM सामग्रीको लागि मात्र HDCP जाँचको प्रयोग गर्नुहोस्"</item> <item msgid="45075631231212732">"सधैँ HDCP जाँच प्रयोग गर्नुहोस्"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP १.४ (पूर्वनिर्धारित)"</item> + <item msgid="2089555299377409443">"AVRCP १.५"</item> + <item msgid="2895327394279434278">"AVRCP १.६"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"प्रणालीको चयन प्रयोग गर्नुहोस् (पूर्वनिर्धारित)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"मोनो"</item> <item msgid="8883739882299884241">"स्टेरियो"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"अडियोको गुणस्तर सुधार्न अनुकूलन गरिएको (990kbps/909kbps)"</item> - <item msgid="2921767058740704969">"सन्तुलित अडियो र जडान गुणस्तर (६६०kbps/६०६kbps)"</item> - <item msgid="8860982705384396512">"जडानको गुणस्तर सुधार्न अनुकूलन गरिएको (330kbps/303kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"अडियोको गुणस्तर सुधार्न अनुकूलन गरिएको"</item> - <item msgid="4327143584633311908">"सन्तुलित अडियो र जडान गुणस्तर"</item> - <item msgid="4681409244565426925">"जडानको गुणस्तर सुधार्न अनुकूलन गरिएको"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"निष्क्रिय गर्नुहोस्"</item> <item msgid="1593289376502312923">"६४के"</item> diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml index 7ccf28bd5ef2..e3dbd9d36593 100644 --- a/packages/SettingsLib/res/values-ne/strings.xml +++ b/packages/SettingsLib/res/values-ne/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"स्वतः जडान हुने छैन"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"इन्टरनेट माथिको पहुँच छैन"</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> द्वारा सुरक्षित गरियो"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s मार्फत् स्वतः जडान गरिएको"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s मार्फत जडित"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s मार्फत उपलब्ध"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"धेरै तीव्र"</item> <item msgid="9085102246155045744">"सबभन्दा छिटो"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"प्रोफाइल रोज्नुहोस्"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"व्यक्तिगत"</string> <string name="category_work" msgid="8699184680584175622">"काम"</string> <string name="development_settings_title" msgid="215179176067683667">"विकासकर्ताका विकल्पहरू"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"आक्रामक ढंगले Wi‑Fi बाट मोबाइलमा हस्तान्तरण"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi-Fi घुम्ने स्क्यान गर्न सधैँ अनुमति दिनुहोस्"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"मोबाइल डेटा सधैँ सक्रिय राख्नुहोस्"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"निरपेक्ष आवाज असक्षम गर्नुहोस्"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ब्लुटुथको AVRCP संस्करण"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"ब्लुटुथको AVRCP संस्करण चयन गर्नुहोस्"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"ब्लुटुथ अडियोको कोडेक"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"ब्लुटुथ अडियोको कोडेक चयन गर्नुहोस्"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"ब्लुटुथ अडियोको नमूना दर"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"स्ट्रिमिङ: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</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> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"सक्षम गरिएको अवस्थामा, Wi-Fi सिग्नल न्यून हुँदा, Wi-Fi ले बढी आक्रामक ढंगले मोबाइलमा डेटा जडान हस्तान्तरण गर्नेछ"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Wi-Fi घुम्ने स्क्यान इन्टरफेसमा रहेको डेटा यातायातको मात्रामा आधारित अनुमति दिनुहोस्/नदिनुहोस्"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"लगर बफर आकारहरू"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"लग बफर प्रति लगर आकार चयन गर्नुहोस्"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> द्वारा अधिरोहित"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"लगभग <xliff:g id="TIME">%1$s</xliff:g> बाँकी छ"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"बाँकी समय <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - करिब <xliff:g id="TIME">%2$s</xliff:g> बाँकी"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"बाँकी समय <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - AC मा पूर्णरूपमा चार्ज हुन <xliff:g id="TIME">%2$s</xliff:g> बाँकी"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB मार्फत पूर्णरूपमा चार्ज हुन <xliff:g id="TIME">%2$s</xliff:g> बाँकी"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - वायरलेसबाट पूर्णरूपमा चार्ज हुन <xliff:g id="TIME">%2$s</xliff:g> बाँकी"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"चार्ज हुँदै छैन"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"पूर्ण"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"प्रशासकद्वारा नियन्त्रित"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"प्रशासकद्वारा सक्षम गरिएको छ"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"प्रशासकद्वारा असक्षम गरिएको छ"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"सेटिङहरूको गृहपृष्ठ"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"०%"</item> diff --git a/packages/SettingsLib/res/values-nl/arrays.xml b/packages/SettingsLib/res/values-nl/arrays.xml index 7962e407e3a1..1147c89ffe9d 100644 --- a/packages/SettingsLib/res/values-nl/arrays.xml +++ b/packages/SettingsLib/res/values-nl/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"HDCP-controle alleen voor DRM-content gebruiken"</item> <item msgid="45075631231212732">"HDCP-controle altijd gebruiken"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (standaard)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Systeemselectie gebruiken (standaard)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Geoptimaliseerd voor audiokwaliteit (990 kbps/909 kbps)"</item> - <item msgid="2921767058740704969">"Gebalanceerde audio- en verbindingskwaliteit (660 kbps/606 kbps)"</item> - <item msgid="8860982705384396512">"Geoptimaliseerd voor verbindingskwaliteit (330 kbps/303 kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Geoptimaliseerd voor audiokwaliteit"</item> - <item msgid="4327143584633311908">"Gebalanceerde audio- en verbindingskwaliteit"</item> - <item msgid="4681409244565426925">"Geoptimaliseerd voor verbindingskwaliteit"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Uit"</item> <item msgid="1593289376502312923">"64 K"</item> diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml index a41072d5f6a2..0c315b9c6ca9 100644 --- a/packages/SettingsLib/res/values-nl/strings.xml +++ b/packages/SettingsLib/res/values-nl/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Er wordt niet automatisch verbinding gemaakt"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Geen internettoegang"</string> <string name="saved_network" msgid="4352716707126620811">"Opgeslagen door <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatisch verbonden via %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Verbonden via %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Beschikbaar via %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Snelst"</item> <item msgid="9085102246155045744">"Allerallersnelst"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Profiel kiezen"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Persoonlijk"</string> <string name="category_work" msgid="8699184680584175622">"Werk"</string> <string name="development_settings_title" msgid="215179176067683667">"Opties voor ontwikkelaars"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Netwerken"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Certificering van draadloze weergave"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Uitgebreide wifi-logregistratie insch."</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agressieve handover van wifi naar mobiel"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Altijd roamingscans voor wifi toestaan"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiele data altijd actief"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Absoluut volume uitschakelen"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth-AVRCP-versie"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Bluetooth-AVRCP-versie selecteren"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth-audiocodec"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Bluetooth-audiocodec selecteren"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bemonsteringsfrequentie (sample rate) van Bluetooth-audio"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Opties weergeven voor certificering van draadloze weergave"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Logniveau voor wifi verhogen, weergeven per SSID RSSI in wifi-kiezer"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Indien ingeschakeld, is wifi agressiever bij het overgeven van de gegevensverbinding aan mobiel wanneer het wifi-signaal zwak is"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Roamingscans voor wifi (niet) toestaan op basis van de hoeveelheid dataverkeer die aanwezig is bij de interface"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Logger-buffergrootten"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Kies Logger-grootten per logbuffer"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overschreven door <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Ca. <xliff:g id="TIME">%1$s</xliff:g> resterend"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> resterend"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ongeveer <xliff:g id="TIME">%2$s</xliff:g> resterend"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> resterend"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot volledig opgeladen"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot volledig opgeladen via netvoeding"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot volledig opgeladen via USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot volledig opgeladen via draadloos"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Onbekend"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Opladen"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Wordt niet opgeladen"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Volledig"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Ingesteld door beheerder"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Ingeschakeld door beheerder"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Uitgeschakeld door beheerder"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Homepage voor instellingen"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-pa/arrays.xml b/packages/SettingsLib/res/values-pa/arrays.xml index cb91b57ae71f..7454776c4d36 100644 --- a/packages/SettingsLib/res/values-pa/arrays.xml +++ b/packages/SettingsLib/res/values-pa/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"ਕੇਵਲ DRM ਸਮੱਗਰੀ ਲਈ HDCP ਜਾਂਚ"</item> <item msgid="45075631231212732">"ਹਮੇਸਾਂ HDCP ਜਾਂਚ ਵਰਤੋ"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (ਪੂਰਵ-ਨਿਰਧਾਰਤ)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"ਸਿਸਟਮ ਚੋਣ ਦੀ ਵਰਤੋਂ ਕਰੋ (ਪੂਰਵ-ਨਿਰਧਾਰਤ)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"ਮੋਨੋ"</item> <item msgid="8883739882299884241">"ਸਟੀਰੀਓ"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"ਔਡੀਓ ਗੁਣਵੱਤਾ ਲਈ ਸੁਯੋਗ ਬਣਾਇਆ ਗਿਆ (990kbps/909kbps)"</item> - <item msgid="2921767058740704969">"ਸੰਤੁਲਿਤ ਔਡੀਓ ਅਤੇ ਕਨੈਕਸ਼ਨ ਗੁਣਵੱਤਾ (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"ਕਨੈਕਸ਼ਨ ਗੁਣਵੱਤਾ ਲਈ ਸੁਯੋਗ ਬਣਾਇਆ ਗਿਆ (330kbps/303kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"ਔਡੀਓ ਗੁਣਵੱਤਾ ਲਈ ਸੁਯੋਗ ਬਣਾਇਆ ਗਿਆ"</item> - <item msgid="4327143584633311908">"ਸੰਤੁਲਿਤ ਔਡੀਓ ਅਤੇ ਕਨੈਕਸ਼ਨ ਗੁਣਵੱਤਾ"</item> - <item msgid="4681409244565426925">"ਕਨੈਕਸ਼ਨ ਗੁਣਵੱਤਾ ਲਈ ਸੁਯੋਗ ਬਣਾਇਆ ਗਿਆ"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"ਬੰਦ"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml index a179818e943d..d2876f297091 100644 --- a/packages/SettingsLib/res/values-pa/strings.xml +++ b/packages/SettingsLib/res/values-pa/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਜਾਵੇਗਾ"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"ਕੋਈ ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ ਨਹੀਂ"</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> ਵੱਲੋਂ ਸੁਰੱਖਿਅਤ ਕੀਤਾ"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s ਰਾਹੀਂ ਆਪਣੇ-ਆਪ ਕਨੈਕਟ ਹੋਇਆ"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s ਰਾਹੀਂ ਕਨੈਕਟ ਕੀਤਾ"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s ਰਾਹੀਂ ਉਪਲਬਧ"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"ਬਹੁਤ ਤੇਜ਼"</item> <item msgid="9085102246155045744">"ਸਭ ਤੋਂ ਵੱਧ ਤੇਜ਼"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"ਪ੍ਰੋਫਾਈਲ ਚੁਣੋ"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"ਨਿੱਜੀ"</string> <string name="category_work" msgid="8699184680584175622">"ਦਫ਼ਤਰ"</string> <string name="development_settings_title" msgid="215179176067683667">"ਵਿਕਾਸਕਾਰ ਚੋਣਾਂ"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ਆਕਰਮਣਸ਼ੀਲ Wi‑Fi ਤੋਂ ਮੋਬਾਈਲ ਹੈਂਡਓਵਰ"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ਹਮੇਸ਼ਾਂ Wi‑Fi Roam Scans ਦੀ ਆਗਿਆ ਦਿਓ"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"ਮੋਬਾਈਲ ਡੈਟਾ ਹਮੇਸ਼ਾਂ ਕਿਰਿਆਸ਼ੀਲ"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ਪੂਰਨ ਵੌਲਿਊਮ ਨੂੰ ਅਯੋਗ ਬਣਾਓ"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ਬਲੂਟੁੱਥ AVRCP ਰੂਪ"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"ਬਲੂਟੁੱਥ AVRCP ਰੂਪ ਚੁਣੋ"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"ਬਲੂਟੁੱਥ ਔਡੀਓ ਕੋਡੇਕ"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"ਬਲੂਟੁੱਥ ਔਡੀਓ ਕੋਡੇਕ ਚੁਣੋ"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"ਬਲੂਟੁੱਥ ਔਡੀਓ ਨਮੂਨਾ ਦਰ"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ਸਟ੍ਰੀਮਿੰਗ: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ਵਾਇਰਲੈਸ ਡਿਸਪਲੇ ਪ੍ਰਮਾਣੀਕਰਨ ਲਈ ਚੋਣਾਂ ਦਿਖਾਓ"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi ਲੌਗਿੰਗ ਪੱਧਰ ਵਧਾਓ, Wi‑Fi Picker ਵਿੱਚ ਪ੍ਰਤੀ SSID RSSI ਦਿਖਾਓ"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ਜਦੋਂ ਯੋਗ ਬਣਾਇਆ ਹੋਵੇ, ਤਾਂ Wi‑Fi ਸਿਗਨਲ ਘੱਟ ਹੋਣ \'ਤੇ Wi‑Fi ਡੈਟਾ ਕਨੈਕਸ਼ਨ ਮੋਬਾਈਲ ਨੂੰ ਹੈਂਡ ਓਵਰ ਕਰਨ ਵਿੱਚ ਵੱਧ ਆਕਰਮਣਸ਼ੀਲ ਹੋਵੇਗਾ।"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"ਇੰਟਰਫੇਸ ਤੇ ਮੌਜੂਦ ਡੈਟਾ ਟ੍ਰੈਫਿਕ ਦੀ ਮਾਤਰਾ ਦੇ ਆਧਾਰ ਤੇ Wi‑Fi ਰੋਮ ਸਕੈਨ ਦੀ ਆਗਿਆ ਦਿਓ/ਅਸਵੀਕਾਰ ਕਰੋ"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"ਲੌਗਰ ਬਫਰ ਆਕਾਰ"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"ਪ੍ਰਤੀ ਲੌਗ ਬਫਰ ਲੌਗਰ ਆਕਾਰ ਚੁਣੋ"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ਦੁਆਰਾ ਓਵਰਰਾਈਡ ਕੀਤਾ"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"ਲਗਭਗ <xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਲਗਭਗ <xliff:g id="TIME">%2$s</xliff:g> ਬਾਕੀ"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"AC \'ਤੇ ਪੂਰੀ ਤਰ੍ਹਾਂ ਚਾਰਜ ਹੋਣ ਤੱਕ <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"USB \'ਤੇ ਪੂਰੀ ਤਰ੍ਹਾਂ ਚਾਰਜ ਹੋਣ ਤੱਕ <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"ਵਾਇਰਲੈੱਸ ਤੋਂ ਪੂਰੀ ਤਰ੍ਹਾਂ ਚਾਰਜ ਹੋਣ ਤੱਕ <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ਚਾਰਜ ਨਹੀਂ ਹੋ ਰਿਹਾ"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"ਪੂਰੀ"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਕੰਟਰੋਲ ਕੀਤੀ ਗਈ"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਯੋਗ ਬਣਾਈ ਗਈ"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਅਯੋਗ ਬਣਾਈ ਗਈ"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"ਸੈਟਿੰਗਾਂ ਮੁੱਖ ਪੰਨਾ"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-pl/arrays.xml b/packages/SettingsLib/res/values-pl/arrays.xml index 6a79cfe5738a..ca0a60db0315 100644 --- a/packages/SettingsLib/res/values-pl/arrays.xml +++ b/packages/SettingsLib/res/values-pl/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Użyj sprawdzania HDCP tylko w przypadku treści chronionych DRM"</item> <item msgid="45075631231212732">"Zawsze używaj sprawdzania HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (domyślna)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Użyj wyboru systemu (domyślnie)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Optymalizacja pod kątem jakości dźwięku (990 kb/s lub 909 kb/s)"</item> - <item msgid="2921767058740704969">"Zrównoważona jakość dźwięku i połączenia (660 kb/s lub 606 kb/s)"</item> - <item msgid="8860982705384396512">"Optymalizacja pod kątem jakości połączenia (330 kb/s lub 303 kb/s)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Optymalizacja pod kątem jakości dźwięku"</item> - <item msgid="4327143584633311908">"Zrównoważona jakość dźwięku i połączenia"</item> - <item msgid="4681409244565426925">"Optymalizacja pod kątem jakości połączenia"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Wył."</item> <item msgid="1593289376502312923">"64 KB"</item> diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml index 28a92dfc7ab4..019061edc0df 100644 --- a/packages/SettingsLib/res/values-pl/strings.xml +++ b/packages/SettingsLib/res/values-pl/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Nie można połączyć automatycznie"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Brak dostępu do internetu"</string> <string name="saved_network" msgid="4352716707126620811">"Zapisane przez: <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatycznie połączono przez: %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Połączono przez %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Dostępne przez %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Bardzo szybko"</item> <item msgid="9085102246155045744">"Najszybciej"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Wybierz profil"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Osobiste"</string> <string name="category_work" msgid="8699184680584175622">"Praca"</string> <string name="development_settings_title" msgid="215179176067683667">"Opcje programistyczne"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Sieci"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Wyświetlacz bezprzewodowy"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Szczegółowy dziennik Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Przełączaj z Wi-Fi na sieć komórkową"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Zawsze szukaj Wi-Fi w roamingu"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilna transmisja danych zawsze aktywna"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Wyłącz głośność bezwzględną"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Wersja AVRCP Bluetooth"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Wybierz wersję AVRCP Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Kodek dźwięku Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Wybierz kodek dźwięku Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Dźwięk Bluetooth – współczynnik próbkowania"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Strumieniowe przesyłanie danych: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Pokaż opcje certyfikacji wyświetlacza bezprzewodowego"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Zwiększ poziom rejestrowania Wi‑Fi, pokazuj według RSSI SSID w selektorze Wi‑Fi"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Po włączeniu połączenie danych będzie bardziej agresywnie przełączać się z Wi-Fi na sieć komórkową przy słabym sygnale Wi-Fi"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Zezwalaj/nie zezwalaj na wyszukiwanie sieci Wi-Fi w roamingu w zależności od natężenia ruchu"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Rozmiary bufora Rejestratora"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Wybierz rozmiary Rejestratora/bufor dziennika"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Nadpisana przez <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Pozostało około <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Zostało <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – pozostało około <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – zostało <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania (ładowarka)"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania (USB)"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania (bezprzewod.)"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Nieznane"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Ładowanie"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nie podłączony"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Naładowana"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrolowane przez administratora"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Włączone przez administratora"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Wyłączone przez administratora"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Ekran główny ustawień"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-pt-rBR/arrays.xml b/packages/SettingsLib/res/values-pt-rBR/arrays.xml index 864eaaf4d768..7b17e6cc6d4b 100644 --- a/packages/SettingsLib/res/values-pt-rBR/arrays.xml +++ b/packages/SettingsLib/res/values-pt-rBR/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Usar a verificação HDCP somente para conteúdo DRM"</item> <item msgid="45075631231212732">"Sempre usar a verificação HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (padrão)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Usar seleção do sistema (padrão)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Estéreo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Otimizado para qualidade de áudio (990 kbps/909 kbps)"</item> - <item msgid="2921767058740704969">"Qualidade de áudio e de conexão balanceada (660 kbps/606 kbps)"</item> - <item msgid="8860982705384396512">"Otimizado para qualidade de conexão (330 kbps/303 kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Otimizado para qualidade de áudio"</item> - <item msgid="4327143584633311908">"Qualidade de áudio e de conexão balanceada"</item> - <item msgid="4681409244565426925">"Otimizado para qualidade de conexão"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Desativado"</item> <item msgid="1593289376502312923">"64 K"</item> diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml index 9b649c79cda5..1ca691f22706 100644 --- a/packages/SettingsLib/res/values-pt-rBR/strings.xml +++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Não se conectará automaticamente"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Sem acesso à Internet"</string> <string name="saved_network" msgid="4352716707126620811">"Salvas por <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Conectado automaticamente via %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado via %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Disponível via %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Muito rápida"</item> <item msgid="9085102246155045744">"Super-rápida"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Escolher perfil"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Pessoal"</string> <string name="category_work" msgid="8699184680584175622">"Trabalho"</string> <string name="development_settings_title" msgid="215179176067683667">"Opções do desenvolvedor"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Certificação de Display sem fio"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Ativar registro extenso de Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Mudança agressiva de Wi-Fi para móvel"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Sempre permitir verif. de roaming de Wi-Fi"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Dados móveis sempre ativos"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desativar volume absoluto"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versão do Bluetooth AVRCP"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Selecionar versão do Bluetooth AVRCP"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Codec de áudio Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Selecionar codec de áudio Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Taxa de amostra do áudio Bluetooth"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opções de certificação de Display sem fio"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar o nível de registro do Wi-Fi; mostrar conforme o RSSI de SSID na Seleção de Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Quando ativada, o Wi-Fi será mais agressivo em passar a conexão de dados para móvel, quando o sinal de Wi-Fi estiver fraco"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Permitir/proibir verificações de roaming de Wi-Fi com base no volume do tráfego de dados presente na interface"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Tamanhos de buffer de logger"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Sel. tam. de logger/buffer de log"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Aproximadamente <xliff:g id="TIME">%1$s</xliff:g> restante(s)"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> restante(s)"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - cerca de <xliff:g id="TIME">%2$s</xliff:g> restante(s)"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> restante(s)"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até a carga completa"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até a carga completa em CA"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até a carga completa por USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até a carga completa sem fio"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Desconhecido"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Carregando"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Não está carregando"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Cheio"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlada pelo admin"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Ativada pelo administrador"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Desativada pelo administrador"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Página inicial das configurações"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-pt-rPT/arrays.xml b/packages/SettingsLib/res/values-pt-rPT/arrays.xml index ff2fe91488b3..a5754804bf4a 100644 --- a/packages/SettingsLib/res/values-pt-rPT/arrays.xml +++ b/packages/SettingsLib/res/values-pt-rPT/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Utilizar a verificação HDCP para conteúdo DRM apenas"</item> <item msgid="45075631231212732">"Utilizar sempre a verificação HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (predefinição)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Utilizar seleção do sistema (predef.)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Estéreo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Otimizado para a qualidade do áudio (990 kbps/909 kbps)"</item> - <item msgid="2921767058740704969">"Qualidade de áudio e de ligação equilibrada (660 kbps/606 kbps)"</item> - <item msgid="8860982705384396512">"Otimizado para a qualidade da ligação (330 kbps/303 kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Otimizado para a qualidade do áudio"</item> - <item msgid="4327143584633311908">"Qualidade de áudio e de ligação equilibradas"</item> - <item msgid="4681409244565426925">"Otimizado para a qualidade da ligação"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Desativado"</item> <item msgid="1593289376502312923">"64 K"</item> diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml index 879788976213..bd148821d57a 100644 --- a/packages/SettingsLib/res/values-pt-rPT/strings.xml +++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Não é efetuada uma ligação automaticamente"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Sem acesso à Internet"</string> <string name="saved_network" msgid="4352716707126620811">"Guardada por <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Ligado automaticamente através de %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Ligado através de %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Disponível através de %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Muito acelerada"</item> <item msgid="9085102246155045744">"A mais rápida"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Escolher perfil"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Pessoal"</string> <string name="category_work" msgid="8699184680584175622">"Trabalho"</string> <string name="development_settings_title" msgid="215179176067683667">"Opções de programador"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Certificação de display sem fios"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Ativar o registo verboso de Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Transm. agressiva de Wi‑Fi p/ rede móvel"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permitir sempre a deteção de Wi-Fi em roaming"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Dados móveis sempre ativos"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desativar volume absoluto"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versão de Bluetooth AVRCP"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Selecionar versão de Bluetooth AVRCP"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Codec de áudio Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Selecionar codec de áudio Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Taxa de amostragem de áudio Bluetooth"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Transmissão em fluxo contínuo: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opções da certificação de display sem fios"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar o nível de reg. de Wi-Fi, mostrar por RSSI de SSID no Selec. de Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Se estiver ativado, o Wi-Fi será mais agressivo ao transmitir a lig. de dados para a rede móvel quando o sinal Wi-Fi estiver fraco"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Permitir/impedir a deteção de Wi-Fi em roaming com base na quantidade de tráfego de dados presente na interface"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Tamanhos da memória intermédia do registo"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Selec. tam. reg. p/ mem. int. reg."</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Resta(m) aproximadamente <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Resta(m) <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – falta(m) cerca de <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – resta(m) <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até ficar totalmente carregada"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até ficar totalmente carregada em CA"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até ficar totalmente carreg. via USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até ficar totalmente carreg. s/ fios"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Desconhecido"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"A carregar"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Não está a carregar"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Completo"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlado pelo administrador"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Ativado pelo administrador"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Desativado pelo administrador"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Página inicial de definições"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-pt/arrays.xml b/packages/SettingsLib/res/values-pt/arrays.xml index 864eaaf4d768..7b17e6cc6d4b 100644 --- a/packages/SettingsLib/res/values-pt/arrays.xml +++ b/packages/SettingsLib/res/values-pt/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Usar a verificação HDCP somente para conteúdo DRM"</item> <item msgid="45075631231212732">"Sempre usar a verificação HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (padrão)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Usar seleção do sistema (padrão)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Estéreo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Otimizado para qualidade de áudio (990 kbps/909 kbps)"</item> - <item msgid="2921767058740704969">"Qualidade de áudio e de conexão balanceada (660 kbps/606 kbps)"</item> - <item msgid="8860982705384396512">"Otimizado para qualidade de conexão (330 kbps/303 kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Otimizado para qualidade de áudio"</item> - <item msgid="4327143584633311908">"Qualidade de áudio e de conexão balanceada"</item> - <item msgid="4681409244565426925">"Otimizado para qualidade de conexão"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Desativado"</item> <item msgid="1593289376502312923">"64 K"</item> diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml index 9b649c79cda5..1ca691f22706 100644 --- a/packages/SettingsLib/res/values-pt/strings.xml +++ b/packages/SettingsLib/res/values-pt/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Não se conectará automaticamente"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Sem acesso à Internet"</string> <string name="saved_network" msgid="4352716707126620811">"Salvas por <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Conectado automaticamente via %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado via %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Disponível via %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Muito rápida"</item> <item msgid="9085102246155045744">"Super-rápida"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Escolher perfil"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Pessoal"</string> <string name="category_work" msgid="8699184680584175622">"Trabalho"</string> <string name="development_settings_title" msgid="215179176067683667">"Opções do desenvolvedor"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Certificação de Display sem fio"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Ativar registro extenso de Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Mudança agressiva de Wi-Fi para móvel"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Sempre permitir verif. de roaming de Wi-Fi"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Dados móveis sempre ativos"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desativar volume absoluto"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versão do Bluetooth AVRCP"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Selecionar versão do Bluetooth AVRCP"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Codec de áudio Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Selecionar codec de áudio Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Taxa de amostra do áudio Bluetooth"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opções de certificação de Display sem fio"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar o nível de registro do Wi-Fi; mostrar conforme o RSSI de SSID na Seleção de Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Quando ativada, o Wi-Fi será mais agressivo em passar a conexão de dados para móvel, quando o sinal de Wi-Fi estiver fraco"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Permitir/proibir verificações de roaming de Wi-Fi com base no volume do tráfego de dados presente na interface"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Tamanhos de buffer de logger"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Sel. tam. de logger/buffer de log"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Aproximadamente <xliff:g id="TIME">%1$s</xliff:g> restante(s)"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> restante(s)"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - cerca de <xliff:g id="TIME">%2$s</xliff:g> restante(s)"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> restante(s)"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até a carga completa"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até a carga completa em CA"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até a carga completa por USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até a carga completa sem fio"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Desconhecido"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Carregando"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Não está carregando"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Cheio"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlada pelo admin"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Ativada pelo administrador"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Desativada pelo administrador"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Página inicial das configurações"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-ro/arrays.xml b/packages/SettingsLib/res/values-ro/arrays.xml index 041c6e4ce75a..8ff8eb94420c 100644 --- a/packages/SettingsLib/res/values-ro/arrays.xml +++ b/packages/SettingsLib/res/values-ro/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Utilizează verificarea HDCP numai pentru conținut DRM"</item> <item msgid="45075631231212732">"Utilizează întotdeauna verificarea HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (prestabilit)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Folosiți selectarea sist. (prestabilit)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Optimizat pentru calitatea audio (990 kbps/909 kbps)"</item> - <item msgid="2921767058740704969">"Calitatea audio și a conexiunii echilibrată (660 kbps/606 kbps)"</item> - <item msgid="8860982705384396512">"Optimizat pentru calitatea conexiunii (330 kbps/303 kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Optimizat pentru calitatea audio"</item> - <item msgid="4327143584633311908">"Calitatea audio și a conexiunii echilibrată"</item> - <item msgid="4681409244565426925">"Optimizat pentru calitatea conexiunii"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Dezactivată"</item> <item msgid="1593289376502312923">"64 KB"</item> diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml index caa28ec0380d..507bfc1cd043 100644 --- a/packages/SettingsLib/res/values-ro/strings.xml +++ b/packages/SettingsLib/res/values-ro/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Nu se va conecta automat"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Nu există acces la internet"</string> <string name="saved_network" msgid="4352716707126620811">"Salvată de <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Conectată automat prin %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Conectată prin %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Disponibilă prin %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Foarte rapid"</item> <item msgid="9085102246155045744">"Cel mai repede"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Alegeți un profil"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Personal"</string> <string name="category_work" msgid="8699184680584175622">"Serviciu"</string> <string name="development_settings_title" msgid="215179176067683667">"Opțiuni pentru dezvoltatori"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Conectare la rețele"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Certificare Ecran wireless"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Înregistrare prin Wi-Fi de volume mari de date"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Predare agresivă de la Wi-Fi la mobilă"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Se permite întotdeauna scanarea traficului Wi-Fi"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Date mobile permanent active"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Dezactivați volumul absolut"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versiunea AVRCP pentru Bluetooth"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Selectați versiunea AVRCP pentru Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Codec audio Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Selectați codecul audio Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Rată de eșantionare audio Bluetooth"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Transmitere în flux: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Afișați opțiunile pentru certificarea Ecran wireless"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Măriți niv. de înr. prin Wi‑Fi, afișați în fcț. de SSID RSSI în Selectorul Wi‑Fi"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Când este activată, Wi-Fi va fi mai agresivă la predarea conexiunii de date către rețeaua mobilă când semnalul Wi-Fi este slab"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Permiteți/Nu permiteți scanarea traficului Wi-Fi în funcție de traficul de date din interfață"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Dimensiunile tamponului jurnalului"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Dimensiuni jurnal / tampon jurnal"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Valoare înlocuită de <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Timp rămas: aproximativ <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Timp rămas: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - mai rămân(e) <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – timp rămas: <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcare completă"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcare completă la c.a."</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcare completă prin USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcare completă wireless"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Necunoscut"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Încarcă"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nu încarcă"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Complet"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlată de administrator"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Activată de administrator"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Dezactivată de administrator"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Ecran principal Setări"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-ru/arrays.xml b/packages/SettingsLib/res/values-ru/arrays.xml index d366d9c4e12b..0a7f8ac7d8ae 100644 --- a/packages/SettingsLib/res/values-ru/arrays.xml +++ b/packages/SettingsLib/res/values-ru/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Использовать проверку HDCP только для DRM-контента"</item> <item msgid="45075631231212732">"Всегда использовать проверку HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (по умолчанию)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Выбор системы (по умолчанию)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Моно"</item> <item msgid="8883739882299884241">"Стерео"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Оптимизировать качество звука (990/909 Кбит/с)"</item> - <item msgid="2921767058740704969">"Баланс качества звука и скорости подключения (660/606 кбит/с)"</item> - <item msgid="8860982705384396512">"Оптимизировать скорость подключения (330/303 Кбит/с)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Оптимизировать качество звука"</item> - <item msgid="4327143584633311908">"Баланс качества звука и скорости подключения"</item> - <item msgid="4681409244565426925">"Оптимизировать скорость подключения"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Выкл."</item> <item msgid="1593289376502312923">"64 КБ"</item> diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml index 4f53edcb79bb..78cb659f6acc 100644 --- a/packages/SettingsLib/res/values-ru/strings.xml +++ b/packages/SettingsLib/res/values-ru/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Подключение не будет выполняться автоматически"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Отсутствует подключение к Интернету"</string> <string name="saved_network" msgid="4352716707126620811">"Кто сохранил: <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Автоматически подключено к %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Подключено к %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Доступно через %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Сильно ускоренная"</item> <item msgid="9085102246155045744">"Максимальная"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Выберите профиль"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Личные данные"</string> <string name="category_work" msgid="8699184680584175622">"Работа"</string> <string name="development_settings_title" msgid="215179176067683667">"Для разработчиков"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Переключаться на мобильную сеть"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Всегда включать поиск сетей Wi-Fi"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Не отключать мобильный Интернет"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Отключить абсолютный уровень громкости"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Версия Bluetooth AVRCP"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Выберите версию Bluetooth AVRCP"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Аудиокодек для передачи через Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Аудиокодек для Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Частота дискретизации при передаче через Bluetooth"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Потоковая передача: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Показывать параметры сертификации беспроводных мониторов"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"При выборе Wi‑Fi указывать в журнале RSSI для каждого SSID"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Принудительно переключаться на мобильную сеть, если сигнал Wi-Fi слабый"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Включать или отключать поиск сетей Wi-Fi во время передачи данных в зависимости от объема трафика"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Размер буфера журнала"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Выберите размер буфера журнала"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Новая настройка: <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Осталось примерно <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Осталось: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – осталось примерно <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g>, осталось: <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки от сети"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки через USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки (беспроводная)"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не заряжается"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Батарея заряжена"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Контролируется администратором"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Включено администратором"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Отключено администратором"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Настройки"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-si/arrays.xml b/packages/SettingsLib/res/values-si/arrays.xml index 124545e71b1e..89b9e80c4aee 100644 --- a/packages/SettingsLib/res/values-si/arrays.xml +++ b/packages/SettingsLib/res/values-si/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"DRM අන්තර්ගත සඳහා පමණක් HDCP පරික්ෂාව භාවිතා කරන්න"</item> <item msgid="45075631231212732">"සැමවිටම HDCP පිරික්සුම භාවිතා කරන්න"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (පෙරනිමි)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"පද්ධති තේරීම භාවිත කරන්න (පෙරනිමි)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"ඒකල"</item> <item msgid="8883739882299884241">"ස්ටීරියෝ"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"ශ්රව්ය ගුණත්වය සඳහා ප්රශස්ත කරන ලදී (990kbps/909kbps)"</item> - <item msgid="2921767058740704969">"සමබර ශ්රව්ය සහ සබැඳුම් ගුණත්වය (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"සබැඳුම් ගුණත්වය සඳහා ප්රශස්ත කරන ලදී (330kbps/303kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"ශ්රව්ය ගුණත්වය සඳහා ප්රශස්ත කරන ලදී"</item> - <item msgid="4327143584633311908">"සමබර ශ්රව්ය සහ සබැඳුම් ගුණත්වය"</item> - <item msgid="4681409244565426925">"සබැඳුම් ගුණත්වය සඳහා ප්රශස්ත කරන ලදී"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"ක්රියාවිරහිතය"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml index 647b0e3c638e..494bce8e7162 100644 --- a/packages/SettingsLib/res/values-si/strings.xml +++ b/packages/SettingsLib/res/values-si/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"ස්වයංක්රිය නැවත සම්බන්ධ නොවනු ඇත"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"අන්තර්ජාල ප්රවේශය නැත"</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> විසින් සුරකින ලදී"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s හරහා ස්වයංක්රියව සම්බන්ධ විය"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s හරහා සම්බන්ධ විය"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s හරහා ලබා ගැනීමට හැකිය"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"ඉතා ශීඝ්ර"</item> <item msgid="9085102246155045744">"ඉතාම වේගවත්"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"පැතිකඩ තෝරන්න"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"පෞද්ගලික"</string> <string name="category_work" msgid="8699184680584175622">"කාර්යාලය"</string> <string name="development_settings_title" msgid="215179176067683667">"වර්ධක විකල්ප"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ආක්රමණික Wi‑Fi සිට ජංගම බාර දීම"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi රෝම් පරිලෝකන වෙතට සැමවිට අවසර දෙන්න"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"ජංගම දත්ත සැමවිට ක්රියාකාරීය"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"නිරපේක්ෂ හඩ පරිමාව අබල කරන්න"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"බ්ලූටූත් AVRCP අනුවාදය"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"බ්ලූටූත් AVRCP අනුවාදය තෝරන්න"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"බ්ලූටූත් ශ්රව්ය Codec"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"බ්ලූටූත් ශ්රව්ය කොඩෙක් තෝරන්න"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"බ්ලූටූත් ශ්රව්ය නියැදි අනුපාතය"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ප්රවාහ කරමින්: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</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> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"සබල විට Wi‑Fi සිග්නලය අඩු විට Wi‑Fi දත්ත සම්බන්ධතාවය ජංගම වෙත භාර දීමට වඩා ආක්රමණික වේ"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"අතුරු මුහුණතෙහි ඇති දත්ත තදබදය අනුව Wi‑Fi රෝම් පරිලෝකන වෙත ඉඩ දෙන්න/නොදෙන්න"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"ලෝගයේ අන්තරාවක ප්රමාණය"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"ලොග අන්තරාවකට ලෝගයේ ප්රමාණය තෝරන්න"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> මගින් ඉක්මවන ලදී"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"දළ වශයෙන් <xliff:g id="TIME">%1$s</xliff:g>ක් ඉතිරිය"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"ඉතිරි <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>ක් පමණ ඇත"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - ඉතිරි <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC මත සම්පූර්ණයෙන් ආරෝපණය වන තෙක්"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB හරහා සම්පූර්ණයෙන් ආරෝපණය වන තෙක්"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> රැහැන් රහිතව සම්පූර්ණයෙන් ආරෝපණය වන තෙක්"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ආරෝපණය නොවෙමින්"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"පූර්ණ"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"පරිපාලක විසින් පාලනය කරන ලදී"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"පරිපාලක විසින් සබල කරන ලදී"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"පරිපාලක විසින් අබල කරන ලදී"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"සැකසීම් මුල් පිටුව"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-sk/arrays.xml b/packages/SettingsLib/res/values-sk/arrays.xml index c1e85b1bf853..a1c8c31ce818 100644 --- a/packages/SettingsLib/res/values-sk/arrays.xml +++ b/packages/SettingsLib/res/values-sk/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Použiť kontrolu HDCP len pre obsah DRM"</item> <item msgid="45075631231212732">"Vždy používať kontrolu HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (predvolené)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Použiť voľbu systému (predvolené)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Optimalizovaná kvalita zvuku (990kbps/909kbps)"</item> - <item msgid="2921767058740704969">"Vyrovnaná kvalita zvuku a pripojenia (660/606 kb/s)"</item> - <item msgid="8860982705384396512">"Optimalizovaná kvalita pripojenia (330kbps/303kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Optimalizovaná kvalita zvuku"</item> - <item msgid="4327143584633311908">"Vyrovnaná kvalita zvuku a pripojenia"</item> - <item msgid="4681409244565426925">"Optimalizovaná kvalita pripojenia"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Vypnuté"</item> <item msgid="1593289376502312923">"64 kB"</item> diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml index e3f427e25ec3..0334772557f5 100644 --- a/packages/SettingsLib/res/values-sk/strings.xml +++ b/packages/SettingsLib/res/values-sk/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Nedôjde k automatickému pripojeniu"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Žiadny prístup k internetu"</string> <string name="saved_network" msgid="4352716707126620811">"Uložil(a) <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automaticky pripojené prostredníctvom %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Pripojené prostredníctvom %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"K dispozícii prostredníctvom %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Veľmi rýchlo"</item> <item msgid="9085102246155045744">"Najrýchlejšie"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Výber profilu"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Osobné"</string> <string name="category_work" msgid="8699184680584175622">"Práca"</string> <string name="development_settings_title" msgid="215179176067683667">"Pre vývojárov"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Možnosti siete"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Certifikácia bezdrôtového zobrazenia"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Podrobné denníky Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agres. odovzdávať Wi-Fi na mobilnú sieť"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vždy povoliť funkciu Wi-Fi Roam Scans"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilné dáta ponechať vždy aktívne"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Zakázať absolútnu hlasitosť"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Verzia rozhrania Bluetooth AVRCP"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Zvoľte verziu rozhrania Bluetooth AVRCP"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth Audio – kodek"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Vybrať kodek Bluetooth Audio"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth Audio – vzorkovacia frekvencia"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streamovanie: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Zobraziť možnosti certifikácie bezdrôtového zobrazenia"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Zvýšiť úroveň denníkov Wi-Fi, zobrazovať podľa SSID RSSI pri výbere siete Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Keď túto možnosť zapnete, Wi-Fi bude agresívnejšie odovzdávať dátové pripojenie na mobilnú sieť vtedy, keď bude slabý signál Wi-Fi"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Povoliť alebo zakázať funkciu Wifi Roam Scans na základe objemu prenosu údajov v rozhraní"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Vyrovnávacia pamäť nástroja denníkov"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Veľkosť vyrovnávacej pamäte nástroja denníkov"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Prekonané predvoľbou <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Zostáva cca. <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Zostávajúci čas: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – približný zostávajúci čas: <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – zostávajúci čas: <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia zo zásuvky"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia z USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia z bezdrôt. zdroja"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Neznáme"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Nabíjanie"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nenabíja sa"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Nabitá"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Ovládané správcom"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Povolené správcom"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Zakázané správcom"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Domovská stránka nastavení"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0 %"</item> diff --git a/packages/SettingsLib/res/values-sl/arrays.xml b/packages/SettingsLib/res/values-sl/arrays.xml index 832c70003cec..4438fdc17093 100644 --- a/packages/SettingsLib/res/values-sl/arrays.xml +++ b/packages/SettingsLib/res/values-sl/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Preverjanje HDCP uporabi samo za vsebino DRM"</item> <item msgid="45075631231212732">"Vedno uporabi preverjanje HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (privzeto)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Uporabi sistemsko izbiro (privzeto)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Optimizirano za kakovost zvoka (990/909 kb/s)"</item> - <item msgid="2921767058740704969">"Uravnotežena kakovost zvoka in povezave (660/606 kb/s)"</item> - <item msgid="8860982705384396512">"Optimizirano za kakovost povezave (330/303 kb/s)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Optimizirano za kakovost zvoka"</item> - <item msgid="4327143584633311908">"Uravnotežena kakovost zvoka in povezave"</item> - <item msgid="4681409244565426925">"Optimizirano za kakovost povezave"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Izklopljeno"</item> <item msgid="1593289376502312923">"64 K"</item> diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml index 95cfba8d9b79..aa1f11d4be45 100644 --- a/packages/SettingsLib/res/values-sl/strings.xml +++ b/packages/SettingsLib/res/values-sl/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Samodejna vnovična vzpostavitev povezave se ne bo izvedla"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Ni dostopa do interneta"</string> <string name="saved_network" msgid="4352716707126620811">"Shranil(-a): <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Samodejno vzpostavljena povezava prek: %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Vzpostavljena povezava prek: %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Na voljo prek: %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Zelo naglo"</item> <item msgid="9085102246155045744">"Najhitreje"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Izbira profila"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Osebno"</string> <string name="category_work" msgid="8699184680584175622">"Služba"</string> <string name="development_settings_title" msgid="215179176067683667">"Možnosti za razvijalce"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Omrežja"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Potrdilo brezžičnega zaslona"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Omogoči podrob. zapis. dnevnika za Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Odločen prehod iz Wi-Fi-ja v mobil. omr."</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vedno omogoči iskanje omrežij Wi-Fi za gostovanje"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Prenos podatkov v mobilnem omrežju je vedno aktiven"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Onemogočanje absolutnega praga glasnosti"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Različica profila AVRCP za Bluetooth"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Izberite različico profila AVRCP za Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Zvočni kodek za Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Izberi zvočni kodek za Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Hitrost vzorčenja zvoka prek Bluetootha"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Pretočno predvajanje: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</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> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Če je ta možnost omogočena, Wi-Fi odločneje preda podatkovno povezavo mobilnemu omrežju, ko je signal Wi-Fi šibek."</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Omogoči/onemogoči iskanje omrežij Wi-Fi za gostovanje glede na količino podatkovnega prometa pri vmesniku"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Velikosti medpomn. zapisov. dnevnika"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Izberite velikost medpomnilnika dnevnika"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Preglasila nastavitev: <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Še približno <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Še <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – še približno <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – še <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti prek vtičnice"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti prek USB-ja"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti prek brezžič. poln."</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Neznano"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Polnjenje"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Se ne polni"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Poln"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Nadzira skrbnik"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Omogočil skrbnik"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Onemogočil skrbnik"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Začetna stran nastavitev"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0 %"</item> diff --git a/packages/SettingsLib/res/values-sq/arrays.xml b/packages/SettingsLib/res/values-sq/arrays.xml index 15cef4379b77..62bf99b60368 100644 --- a/packages/SettingsLib/res/values-sq/arrays.xml +++ b/packages/SettingsLib/res/values-sq/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Përdor kontrollin e HDCP-së vetëm për përmbajtjet DRM"</item> <item msgid="45075631231212732">"Përdor gjithmonë kontrollin e HDCP-së"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (I parazgjedhur)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Përdor përzgjedhjen e sistemit (e parazgjedhur)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Optimizuar për cilësi audioje (990 kbps/909 kbps)"</item> - <item msgid="2921767058740704969">"Cilësi e balancuar e audios dhe e lidhjes (660 kbps/606 kbps)"</item> - <item msgid="8860982705384396512">"Optimizuar për cilësi lidhjeje (330 kbps/303 kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Optimizuar për cilësi audioje"</item> - <item msgid="4327143584633311908">"Cilësi e balancuar e audios dhe e lidhjes"</item> - <item msgid="4681409244565426925">"Optimizuar për cilësi lidhjeje"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Joaktiv"</item> <item msgid="1593289376502312923">"64 mijë"</item> diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml index 3b1a5678bdde..7e6317962015 100644 --- a/packages/SettingsLib/res/values-sq/strings.xml +++ b/packages/SettingsLib/res/values-sq/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Nuk do të lidhet automatikisht"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Nuk ka qsaje në internet"</string> <string name="saved_network" msgid="4352716707126620811">"E ruajtur nga <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Lidhur automatikisht përmes %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"E lidhur përmes %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"E mundshme përmes %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Shumë e shpejtë"</item> <item msgid="9085102246155045744">"Më e shpejta"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Zgjidh profilin"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Personale"</string> <string name="category_work" msgid="8699184680584175622">"Punë"</string> <string name="development_settings_title" msgid="215179176067683667">"Opsionet e zhvilluesit"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Rrjetet"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Certifikimi i ekranit valor"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktivizo hyrjen Wi-Fi Verbose"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Dorëzimi agresiv i Wi‑Fi te rrjeti celular"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Lejo gjithmonë skanimet për Wi-Fi edhe kur je në lëvizje"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Të dhënat celulare gjithmonë aktive"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Çaktivizo volumin absolut"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versioni AVRCP i Bluetooth-it"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Zgjidh versionin AVRCP të Bluetooth-it"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Kodeku Bluetooth Audio"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Zgjidh kodekun e audios së Bluetooth-it"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Shpejtësia e shembullit të Bluetooth Audio"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Transmetimi: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Shfaq opsionet për certifikimin e ekranit valor"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Rrit nivelin regjistrues të Wi‑Fi duke shfaqur SSID RSSI-në te Zgjedhësi i Wi‑Fi"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Kur ky funksion aktivizohet, Wi‑Fi bëhet më agresiv në kalimin e lidhjes së të dhënave te rrjeti celular, në rastet kur sinjali Wi‑Fi është i dobët"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Lejo/Ndalo skanimet për Wi‑Fi në roaming, bazuar në sasinë e trafikut të të dhënave të pranishme në ndërfaqe"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Madhësitë e regjistruesit"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Përzgjidh madhësitë e regjistruesit"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Mbivendosur nga <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Afërsisht <xliff:g id="TIME">%1$s</xliff:g> të mbetura"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> të mbetura"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - rreth <xliff:g id="TIME">%2$s</xliff:g> të mbetura"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> të mbetura"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> derisa të mbushet plotësisht"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> derisa të mbushet plotësisht përmes rrymës së alternuar"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> derisa të mbushet plotësisht përmes USB-së"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> derisa të mbushet plotësisht me valë"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"I panjohur"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Po ngarkohet"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nuk po ngarkohet"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"E mbushur"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrolluar nga administratori"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Aktivizuar nga administratori"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Çaktivizuar nga administratori"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Kreu i cilësimeve"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-sr/arrays.xml b/packages/SettingsLib/res/values-sr/arrays.xml index b02cc1f5d3a3..147f3db166cc 100644 --- a/packages/SettingsLib/res/values-sr/arrays.xml +++ b/packages/SettingsLib/res/values-sr/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Користи HDCP проверу само за DRM садржај"</item> <item msgid="45075631231212732">"Увек користи HDCP проверу"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (подразумевано)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Користи избор система (подразумевано)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Моно"</item> <item msgid="8883739882299884241">"Стерео"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Оптимизовано за квалитет звука (990 kb/s/909 kb/s)"</item> - <item msgid="2921767058740704969">"Уједначен квалитет звука и везе (660 kb/s/606 kb/s)"</item> - <item msgid="8860982705384396512">"Оптимизовано за квалитет везе (330 kb/s/303 kb/s)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Оптимизовано за квалитет звука"</item> - <item msgid="4327143584633311908">"Уједначен квалитет звука и везе"</item> - <item msgid="4681409244565426925">"Оптимизовано за квалитет везе"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Искључено"</item> <item msgid="1593289376502312923">"64 kB"</item> diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml index 1f106b6ae3bc..8680b0861e39 100644 --- a/packages/SettingsLib/res/values-sr/strings.xml +++ b/packages/SettingsLib/res/values-sr/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Аутоматско повезивање није успело"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Нема приступа интернету"</string> <string name="saved_network" msgid="4352716707126620811">"Сачувао/ла је <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Аутоматски повезано преко %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Веза је успостављена преко приступне тачке %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Доступна је преко приступне тачке %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Веома убрзано"</item> <item msgid="9085102246155045744">"Најбрже"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Изаберите профил"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Лично"</string> <string name="category_work" msgid="8699184680584175622">"Посао"</string> <string name="development_settings_title" msgid="215179176067683667">"Опције за програмера"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Агресиван прелаз са Wi‑Fi мреже на мобилну"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Увек дозволи скенирање Wi‑Fi-ја у ромингу"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобилни подаци су увек активни"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Онемогући главно подешавање јачине звука"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Верзија Bluetooth AVRCP-а"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Изаберите верзију Bluetooth AVRCP-а"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth аудио кодек"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Изаберите Bluetooth аудио кодек"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Брзина узорковања за Bluetooth аудио"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Стримовање: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</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> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Кад се омогући, Wi‑Fi ће бити агресивнији при пребацивању мреже за пренос података на мобилну ако је Wi‑Fi сигнал слаб"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Дозволи/забрани скенирање Wi-Fi-ја у ромингу на основу присутног протока података на интерфејсу"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Величине бафера података у програму за евидентирање"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Изаберите величине по баферу евиденције"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Замењује га <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Још отприлике <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Преостало време: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – остало је око <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"Преостало је <xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до потпуног пуњења преко утичнице"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до потпуног пуњења преко USB-а"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до потпуног пуњења на бежичној мрежи"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не пуни се"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Пуно"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Контролише администратор"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Омогућио је администратор"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Онемогућио је администратор"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Почетна за Подешавања"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-sv/arrays.xml b/packages/SettingsLib/res/values-sv/arrays.xml index 34c58cb1f172..ea966170534d 100644 --- a/packages/SettingsLib/res/values-sv/arrays.xml +++ b/packages/SettingsLib/res/values-sv/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Använd bara HDCP-kontroll för DRM-innehåll"</item> <item msgid="45075631231212732">"Använd alltid HDCP-kontroll"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (standard)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Använd systemval (standardinställning)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Optimerad för ljudkvalitet (990 kbit/s eller 909 kbit/s)"</item> - <item msgid="2921767058740704969">"Balanserad ljud- och anslutningskvalitet (660 kbit/s/606 kbit/s)"</item> - <item msgid="8860982705384396512">"Optimerad för anslutningskvalitet (330 kbit/s eller 303 kbit/s)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Optimerad för ljudkvalitet"</item> - <item msgid="4327143584633311908">"Balanserad ljud- och anslutningskvalitet"</item> - <item msgid="4681409244565426925">"Optimerad för anslutningskvalitet"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Av"</item> <item msgid="1593289376502312923">"64 kB"</item> diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml index d873d070bfac..b545039d5be8 100644 --- a/packages/SettingsLib/res/values-sv/strings.xml +++ b/packages/SettingsLib/res/values-sv/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Det går inte att ansluta automatiskt"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Ingen internetåtkomst"</string> <string name="saved_network" msgid="4352716707126620811">"Sparades av <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatiskt ansluten via %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Anslutet via %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Tillgängligt via %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Turbosnabbt"</item> <item msgid="9085102246155045744">"Snabbast"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Välj profil"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Personligt"</string> <string name="category_work" msgid="8699184680584175622">"Arbetet"</string> <string name="development_settings_title" msgid="215179176067683667">"Utvecklaralternativ"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Nätverk"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Certifiering för Wi-Fi-skärmdelning"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktivera utförlig loggning för Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressiv överlämning fr. Wi-Fi t. mobil"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Tillåt alltid sökning efter Wi-Fi-roaming"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobildata alltid aktiverad"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Inaktivera Absolute volume"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"AVRCP-version för Bluetooth"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Välj AVRCP-version för Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Ljudkodek för Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Välj Ljudkodek för Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Samplingsfrekvens för Bluetooth-ljud"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Visa certifieringsalternativ för Wi-Fi-skärmdelning"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Öka loggningsnivån för Wi-Fi, visa per SSID RSSI i Wi‑Fi Picker"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"När funktionen har aktiverats kommer dataanslutningen lämnas över från Wi-Fi till mobilen på ett aggressivare sätt när Wi-Fi-signalen är svag"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Tillåt/tillåt inte sökning efter Wi-Fi-roaming utifrån mängden datatrafik i gränssnittet"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Buffertstorlekar för logg"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Välj loggstorlekar per loggbuffert"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Har åsidosatts av <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Ca <xliff:g id="TIME">%1$s</xliff:g> kvar"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> kvar"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – cirka <xliff:g id="TIME">%2$s</xliff:g> kvar"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> kvar"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tills det är fulladdat"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tills fulladdat via AC"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tills fulladdat via USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tills fulladdat m. trådlös laddning"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Okänd"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Laddar"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Laddar inte"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Fullt"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Strys av administratören"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Har aktiverats av administratören"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Har inaktiverats av administratören"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Startskärmen för inställningar"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0 %"</item> diff --git a/packages/SettingsLib/res/values-sw/arrays.xml b/packages/SettingsLib/res/values-sw/arrays.xml index 9bfc15ca6bff..7a2d277cfafe 100644 --- a/packages/SettingsLib/res/values-sw/arrays.xml +++ b/packages/SettingsLib/res/values-sw/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Tumia ukaguaji wa HDCP kwa maudhui ya DRM pekee"</item> <item msgid="45075631231212732">"Kila wakati tumia ukakuaji wa HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (Chaguo-msingi)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Tumia Uteuzi wa Mfumo (Chaguo-msingi)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Imeimarishwa kwa ajili ya Ubora wa Sauti (990kbps/909kbps)"</item> - <item msgid="2921767058740704969">"Ubora wa Muunganisho na Sauti Umesawazishwa (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"Imeimarishwa kwa ajili ya Ubora wa Muunganisho (330kbps/303kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Imeimarishwa kwa ajili ya Ubora wa Sauti"</item> - <item msgid="4327143584633311908">"Ubora wa Muunganisho na Sauti Umesawazishwa"</item> - <item msgid="4681409244565426925">"Imeimarishwa kwa ajili ya Ubora wa Muunganisho"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Imezimwa"</item> <item msgid="1593289376502312923">"K64"</item> diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml index 8a04c9d9f2c7..ce1c057895e9 100644 --- a/packages/SettingsLib/res/values-sw/strings.xml +++ b/packages/SettingsLib/res/values-sw/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Haiwezi kuunganisha kiotomatiki"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Hakuna muunganisho wa Intaneti"</string> <string name="saved_network" msgid="4352716707126620811">"Ilihifadhiwa na <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Imeunganishwa kiotomatiki kupitia %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Imeunganishwa kupitia %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Inapatikana kupitia %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Kasi sana"</item> <item msgid="9085102246155045744">"Kasi zaidi"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Chagua Wasifu"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Ya Kibinafsi"</string> <string name="category_work" msgid="8699184680584175622">"Kazini"</string> <string name="development_settings_title" msgid="215179176067683667">"Chaguo za wasanidi"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Mtandao"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Chaguo za cheti cha kuonyesha pasiwaya"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Washa Uwekaji kumbukumbu za WiFi kutumia Sauti"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Ukabidhi hima kutoka Wifi kwenda mtandao wa simu"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Ruhusu Uchanganuzi wa Matumizi ya Mitandao mingine"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Iendelee kutumia data ya simu"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Zima sauti kamili"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Toleo la Bluetooth AVRCP"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Chagua Toleo la Bluetooth AVRCP"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Kodeki ya Sauti ya Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Chagua Kodeki ya Sauti ya Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Kiwango cha Sampuli ya Sauti ya Bluetooth"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Kutiririsha: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Onyesha chaguo za cheti cha kuonyesha pasiwaya"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Ongeza hatua ya uwekaji kumbukumbu ya Wi-Fi, onyesha kwa kila SSID RSSI kwenye Kichukuzi cha Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Ikiwashwa, Wi-Fi itakabidhi kwa hima muunganisho wa data kwa mtandao wa simu, wakati mtandao wa Wi-Fi si thabiti"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Ruhusu au Zuia Uchanganuzi wa Matumizi ya Mitandao mingine ya Wifi kulingana na kiasi cha trafiki ya data kilicho kwenye kiolesura"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Ukubwa wa kiweka bafa ya kumbukumbu"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Chagua ukubwa wa kila Kumbukumbu"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Imetanguliwa na <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Zimesalia takribani <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Zimesalia <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - imesalia takribani <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"Imechaji <xliff:g id="LEVEL">%1$s</xliff:g> - Zimesalia <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hadi ijae chaji"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hadi ijae chaji ukitumia AC"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hadi ijae chaji ukitumia USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hadi ijae chaji bila kutumia waya"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Haijulikani"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Inachaji"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Haichaji"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Imejaa"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Imedhibitiwa na msimamizi"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Msimamizi amewasha mapendeleo ya mipangilio"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Msimamizi amezima mapendeleo ya mipangilio"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Ukurasa wa Kwanza wa Mipangilio"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-ta/arrays.xml b/packages/SettingsLib/res/values-ta/arrays.xml index c50ea1d500dd..1dfcc4d558fb 100644 --- a/packages/SettingsLib/res/values-ta/arrays.xml +++ b/packages/SettingsLib/res/values-ta/arrays.xml @@ -116,16 +116,8 @@ <item msgid="8900559293912978337">"மோனோ"</item> <item msgid="8883739882299884241">"ஸ்டீரியோ"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"ஆடியோ தரத்திற்காக மேம்படுத்தியது (990kbps/909kbps)"</item> - <item msgid="2921767058740704969">"சமன்படுத்தப்பட்ட ஆடியோ மற்றும் இணைப்புத் தரம் (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"இணைப்புத் தரத்திற்காக மேம்படுத்தியது (330kbps/303kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"ஆடியோ தரத்திற்காக மேம்படுத்தியது"</item> - <item msgid="4327143584633311908">"சமன்படுத்தப்பட்ட ஆடியோ மற்றும் இணைப்புத் தரம்"</item> - <item msgid="4681409244565426925">"இணைப்புத் தரத்திற்காக மேம்படுத்தியது"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"முடக்கு"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml index 262fa1141c05..5c0cd9f80a76 100644 --- a/packages/SettingsLib/res/values-ta/strings.xml +++ b/packages/SettingsLib/res/values-ta/strings.xml @@ -34,7 +34,7 @@ <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> சேமித்தது"</string> <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s வழியாக இணைக்கப்பட்டது"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s வழியாகக் கிடைக்கிறது"</string> @@ -141,7 +141,8 @@ <item msgid="5194774745031751806">"மிக அதிக வேகமாக"</item> <item msgid="9085102246155045744">"அதிகபட்ச வேகம்"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"சுயவிவரத்தைத் தேர்வுசெய்யவும்"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"தனிப்பட்டவை"</string> <string name="category_work" msgid="8699184680584175622">"பணியிடம்"</string> <string name="development_settings_title" msgid="215179176067683667">"டெவெலப்பர் விருப்பங்கள்"</string> @@ -353,8 +354,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"சார்ஜ் ஏறவில்லை"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"முழுமை"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"நிர்வாகி கட்டுப்படுத்துகிறார்"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"நிர்வாகி இயக்கியுள்ளார்"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"நிர்வாகி முடக்கியுள்ளார்"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"அமைப்புகள் முகப்பு"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-te/arrays.xml b/packages/SettingsLib/res/values-te/arrays.xml index 2cd556401ce7..87919d252b1c 100644 --- a/packages/SettingsLib/res/values-te/arrays.xml +++ b/packages/SettingsLib/res/values-te/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"DRM కంటెంట్కు మాత్రమే HDCP తనిఖీని ఉపయోగించండి"</item> <item msgid="45075631231212732">"ఎప్పటికీ HDCP తనిఖీని ఉపయోగించు"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (డిఫాల్ట్)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"మోనో"</item> <item msgid="8883739882299884241">"స్టీరియో"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"ఆడియో నాణ్యత (990kbps/909kbps) కోసం అనుకూలీకరించబడింది"</item> - <item msgid="2921767058740704969">"సమతుల్య ఆడియో మరియు కనెక్షన్ నాణ్యత (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"కనెక్షన్ నాణ్యత (330kbps/303kbps) కోసం అనుకూలీకరించబడింది"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"ఆడియో నాణ్యత కోసం అనుకూలీకరించబడింది"</item> - <item msgid="4327143584633311908">"సమతుల్య ఆడియో మరియు కనెక్షన్ నాణ్యత"</item> - <item msgid="4681409244565426925">"కనెక్షన్ నాణ్యత కోసం అనుకూలీకరించబడింది"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"ఆఫ్"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml index b18c23fa7c77..0bbf6ca7a9c3 100644 --- a/packages/SettingsLib/res/values-te/strings.xml +++ b/packages/SettingsLib/res/values-te/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"స్వయంచాలకంగా కనెక్ట్ కాదు"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"ఇంటర్నెట్ ప్రాప్యత లేదు"</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> ద్వారా సేవ్ చేయబడింది"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s ద్వారా స్వయంచాలకంగా కనెక్ట్ చేయబడింది"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s ద్వారా కనెక్ట్ చేయబడింది"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s ద్వారా అందుబాటులో ఉంది"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"అత్యంత వేగం"</item> <item msgid="9085102246155045744">"అత్యంత వేగవంతం"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"ప్రొఫైల్ను ఎంచుకోండి"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"వ్యక్తిగతం"</string> <string name="category_work" msgid="8699184680584175622">"కార్యాలయం"</string> <string name="development_settings_title" msgid="215179176067683667">"డెవలపర్ ఎంపికలు"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"మొబైల్కి మార్చేలా చురుకైన Wi‑Fi"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi సంచార స్కాన్లను ఎల్లప్పుడూ అనుమతించు"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"మొబైల్ డేటాని ఎల్లప్పుడూ సక్రియంగా ఉంచు"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"సంపూర్ణ వాల్యూమ్ను నిలిపివేయి"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"బ్లూటూత్ AVRCP సంస్కరణ"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"బ్లూటూత్ AVRCP సంస్కరణను ఎంచుకోండి"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"బ్లూటూత్ ఆడియో కోడెక్"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"బ్లూటూత్ ఆడియో కోడెక్ని ఎంచుకోండి"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"బ్లూటూత్ ఆడియో నమూనా రేట్"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ప్రసారం చేస్తోంది: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</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> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ప్రారంభించబడినప్పుడు, Wi‑Fi సిగ్నల్ బలహీనంగా ఉంటే డేటా కనెక్షన్ను మొబైల్కి మార్చేలా Wi‑Fi చురుగ్గా వ్యవహరిస్తుంది"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"ఇంటర్ఫేస్లో ఉండే డేటా ట్రాఫిక్ పరిమాణం ఆధారంగా Wi‑Fi సంచార స్కాన్లను అనుమతించు/నిరాకరించు"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"లాగర్ బఫర్ పరిమాణాలు"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"లాగ్ బఫర్కి లాగర్ పరిమా. ఎంచుకోండి"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ద్వారా భర్తీ చేయబడింది"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"సుమారు <xliff:g id="TIME">%1$s</xliff:g> మిగిలి ఉంది"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> మిగిలి ఉంది"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> పని చేస్తుంది"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>లో ACతో పూర్తిగా ఛార్జ్ అవుతుంది"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>లో USB ద్వారా పూర్తిగా ఛార్జ్ అవుతుంది"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>లో వైర్లెస్లో పూర్తిగా ఛార్జ్ అవుతుంది"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ఛార్జ్ కావడం లేదు"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"నిండింది"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"నిర్వాహకుని ద్వారా నియంత్రించబడింది"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"నిర్వాహకులు ప్రారంభించారు"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"నిర్వాహకులు నిలిపివేసారు"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"సెట్టింగ్ల హోమ్"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-th/arrays.xml b/packages/SettingsLib/res/values-th/arrays.xml index 26f231674113..fc3fd97011d0 100644 --- a/packages/SettingsLib/res/values-th/arrays.xml +++ b/packages/SettingsLib/res/values-th/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"ใช้การตรวจสอบ HDCP สำหรับเนื้อหา DRM เท่านั้น"</item> <item msgid="45075631231212732">"ใช้การตรวจสอบ HDCP เสมอ"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (ค่าเริ่มต้น)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"ใช้การเลือกระบบ (ค่าเริ่มต้น)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"โมโน"</item> <item msgid="8883739882299884241">"สเตอริโอ"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"เพิ่มประสิทธิภาพสำหรับคุณภาพเสียง (990 kbps/909 kbps)"</item> - <item msgid="2921767058740704969">"คุณภาพเสียงและการเชื่อมต่อที่สมดุล (660 kbps/606 kbps)"</item> - <item msgid="8860982705384396512">"เพิ่มประสิทธิภาพสำหรับคุณภาพการเชื่อมต่อ (330 kbps/303 kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"เพิ่มประสิทธิภาพสำหรับคุณภาพเสียง"</item> - <item msgid="4327143584633311908">"คุณภาพเสียงและการเชื่อมต่อที่สมดุล"</item> - <item msgid="4681409244565426925">"เพิ่มประสิทธิภาพสำหรับคุณภาพการเชื่อมต่อ"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"ปิด"</item> <item msgid="1593289376502312923">"64 K"</item> diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml index c8470e5f9f22..ea71092c5f85 100644 --- a/packages/SettingsLib/res/values-th/strings.xml +++ b/packages/SettingsLib/res/values-th/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"จะไม่เชื่อมต่อโดยอัตโนมัติ"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"ไม่สามารถเข้าถึงอินเทอร์เน็ต"</string> <string name="saved_network" msgid="4352716707126620811">"บันทึกโดย <xliff:g id="NAME">%1$s</xliff:g> แล้ว"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"เชื่อมต่ออัตโนมัติผ่าน %1$s แล้ว"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"เชื่อมต่อผ่าน %1$s แล้ว"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"พร้อมใช้งานผ่านทาง %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"เร็วมาก"</item> <item msgid="9085102246155045744">"เร็วที่สุด"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"เลือกโปรไฟล์"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"ส่วนตัว"</string> <string name="category_work" msgid="8699184680584175622">"ที่ทำงาน"</string> <string name="development_settings_title" msgid="215179176067683667">"สำหรับนักพัฒนาซอฟต์แวร์"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"สลับ Wi‑Fi เป็นมือถือเมื่อสัญญาณอ่อน"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ใช้การสแกน Wi-Fi ข้ามเครือข่ายเสมอ"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"เปิดใช้อินเทอร์เน็ตมือถือเสมอ"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ปิดใช้การควบคุมระดับเสียงของอุปกรณ์อื่น"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"เวอร์ชันของบลูทูธ AVRCP"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"เลือกเวอร์ชันของบลูทูธ AVRCP"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"ตัวแปลงรหัสเสียงบลูทูธ"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"เลือกตัวแปลงรหัสเสียงบลูทูธ"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"อัตราตัวอย่างเสียงบลูทูธ"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"สตรีมมิง: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</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> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"เมื่อเปิดใช้แล้ว Wi-Fi จะส่งผ่านการเชื่อมต่อข้อมูลไปยังเครือข่ายมือถือเมื่อสัญญาณ Wi-Fi อ่อน"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"อนุญาต/ไม่อนุญาตการสแกน Wi-Fi ข้ามเครือข่าย ตามปริมาณข้อมูลการเข้าชมที่ปรากฏในอินเทอร์เฟซ"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"ขนาดบัฟเฟอร์ของ Logger"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"เลือกขนาด Logger ต่อบัฟเฟอร์ไฟล์บันทึก"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"แทนที่โดย <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"เหลืออีกประมาณ <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"เหลืออีก <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - เหลือเวลาประมาณ <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - เหลืออีก <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะชาร์จเต็มผ่าน AC"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะชาร์จเต็มผ่าน USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะชาร์จเต็มผ่านระบบไร้สาย"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ไม่ได้ชาร์จ"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"เต็ม"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"ผู้ดูแลระบบเป็นผู้ควบคุม"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"เปิดใช้โดยผู้ดูแลระบบ"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"ปิดใช้โดยผู้ดูแลระบบ"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"หน้าแรกของการตั้งค่า"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-tl/arrays.xml b/packages/SettingsLib/res/values-tl/arrays.xml index eeec945be525..414fca94ed48 100644 --- a/packages/SettingsLib/res/values-tl/arrays.xml +++ b/packages/SettingsLib/res/values-tl/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Gamitin lang ang pagsusuring HDCP para sa nilalamang DRM"</item> <item msgid="45075631231212732">"Palaging gumamit ng pagsusuring HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Gamitin ang Pagpili ng System (Default)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Naka-optimize para sa Kalidad ng Audio (990kbps/909kbps)"</item> - <item msgid="2921767058740704969">"Balanse ang Kalidad ng Audio at Koneksyon (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"Naka-optimize para sa Kalidad ng Koneksyon (330kbps/303kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Naka-optimize para sa Kalidad ng Audio"</item> - <item msgid="4327143584633311908">"Balanse ang Kalidad ng Audio at Koneksyon"</item> - <item msgid="4681409244565426925">"Naka-optimize para sa Kalidad ng Koneksyon"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"I-off"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml index b5f558d8a801..48934e43b3c5 100644 --- a/packages/SettingsLib/res/values-tl/strings.xml +++ b/packages/SettingsLib/res/values-tl/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Hindi awtomatikong kokonekta"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Walang access sa Internet"</string> <string name="saved_network" msgid="4352716707126620811">"Na-save ni <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Awtomatikong nakakonekta sa pamamagitan ng %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Nakakonekta sa pamamagitan ng %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Available sa pamamagitan ng %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Napakatulin"</item> <item msgid="9085102246155045744">"Pinakamabilis"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Pumili ng Profile"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Personal"</string> <string name="category_work" msgid="8699184680584175622">"Trabaho"</string> <string name="development_settings_title" msgid="215179176067683667">"Mga opsyon ng developer"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Certification ng wireless display"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"I-enable ang Pagla-log sa Wi‑Fi Verbose"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agresibong paglipat ng Wi‑Fi sa mobile"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Palaging payagan ang Mga Pag-scan sa Roaming ng Wi‑Fi"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Palaging aktibo ang mobile data"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"I-disable ang absolute volume"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bersyon ng AVRCP ng Bluetooth"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Pumili ng Bersyon ng AVRCP ng Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth Audio Codec"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Piliin ang Audio Codec ng Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Sample na Rate ng Bluetooth Audio"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Ipakita ang mga opsyon para sa certification ng wireless display"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Pataasin ang antas ng Wi‑Fi logging, ipakita sa bawat SSID RSSI sa Wi‑Fi Picker"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Kapag na-enable, magiging mas agresibo ang Wi‑Fi sa paglipat sa koneksyon ng mobile data kapag mahina ang signal ng Wi‑Fi"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Payagan/Huwag payagan ang Mga Pag-scan sa Roaming ng Wi‑Fi batay sa dami ng trapiko ng data na mayroon sa interface"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Mga laki ng buffer ng Logger"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Pumili ng mga laki ng Logger bawat log buffer"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Na-override ng <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Humigit-kumulang <xliff:g id="TIME">%1$s</xliff:g> na lang ang natitira"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> pa"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - humigit-kumulang <xliff:g id="TIME">%2$s</xliff:g> pa ang natitira"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> pa"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hanggang sa makumpleto ang charge"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hanggang sa matapos mag-charge sa AC"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hanggang sa matapos mag-charge sa USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hanggang sa matapos mag-charge sa wireless"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Hindi Kilala"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Nagcha-charge"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Hindi nagkakarga"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Puno"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Pinapamahalaan ng admin"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Na-enable ng administrator"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Na-disable ng administrator"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Home ng Mga Setting"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-tr/arrays.xml b/packages/SettingsLib/res/values-tr/arrays.xml index 6519a11ea25a..aea0525e8c97 100644 --- a/packages/SettingsLib/res/values-tr/arrays.xml +++ b/packages/SettingsLib/res/values-tr/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"HDCP denetimini yalnızca DRM içeriği için kullan"</item> <item msgid="45075631231212732">"HDCP denetimini her zaman kullan"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (Varsayılan)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Sistem Seçimini Kullan (Varsayılan)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Ses Kalitesi (990 kb/sn. / 909 kb/sn.) için optimize edildi"</item> - <item msgid="2921767058740704969">"Dengeli Ses ve Bağlantı Kalitesi (660 kb/sn. / 606 kb/sn.)"</item> - <item msgid="8860982705384396512">"Bağlantı Kalitesi (330 kb/sn. / 303 kb/sn.) için optimize edildi"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Ses Kalitesi için optimize edildi"</item> - <item msgid="4327143584633311908">"Dengeli Ses ve Bağlantı Kalitesi"</item> - <item msgid="4681409244565426925">"Bağlantı Kalitesi için optimize edildi"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Kapalı"</item> <item msgid="1593289376502312923">"64 KB"</item> diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml index 6a35f949f814..77a3bb4e7ee2 100644 --- a/packages/SettingsLib/res/values-tr/strings.xml +++ b/packages/SettingsLib/res/values-tr/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Otomatik olarak bağlanma"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"İnternet erişimi yok"</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> tarafından kaydedildi"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s üzerinden otomatik olarak bağlı"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s üzerinden bağlı"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s üzerinden kullanılabilir"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Çok seri"</item> <item msgid="9085102246155045744">"En hızlı"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Profil Seçin"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Kişisel"</string> <string name="category_work" msgid="8699184680584175622">"İş"</string> <string name="development_settings_title" msgid="215179176067683667">"Geliştirici seçenekleri"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Ağ işlemleri"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Kablosuz ekran sertifikası"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Kablosuz Ayrıntılı Günlük Kaydını etkinleştir"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Kablosuzdan mobil ağa agresif geçiş"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Kablosuz Dolaşım Taramalarına daima izin ver"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobil veri her zaman etkin"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Mutlak sesi iptal et"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP Sürümü"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Bluetooth AVRCP Sürümünü seçin"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth Ses Codec\'i"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Bluetooth Ses Codec\'ini Seçin"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth Ses Örnek Hızı"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Akış: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Kablosuz ekran sertifikası seçeneklerini göster"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Kablosuz günlük kaydı seviyesini artır. Kablosuz Seçici\'de her bir SSID RSSI için göster."</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Etkinleştirildiğinde, kablosuz ağ sinyali zayıfken veri bağlantısının mobil ağa geçirilmesinde daha agresif olunur"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Arayüzde mevcut veri trafiği miktarına bağlı olarak Kablosuz Dolaşım Taramalarına İzin Verin/Vermeyin"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Günlük Kaydedici arabellek boyutları"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Gün. arabel. başına Gün. Kayd. boyutunu seç"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> tarafından geçersiz kılındı"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Yaklaşık <xliff:g id="TIME">%1$s</xliff:g> kaldı"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> kaldı"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - yaklaşık <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - Tam şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - Prize bağlı, tam şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB ile tam şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - Kablosuz ile tam şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Bilinmiyor"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Şarj oluyor"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Şarj etmiyor"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Dolu"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Yönetici tarafından denetleniyor"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Yönetici tarafından etkinleştirildi"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Yönetici tarafından devre dışı bırakıldı"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Ayarlar Ana Sayfası"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"%0"</item> diff --git a/packages/SettingsLib/res/values-uk/arrays.xml b/packages/SettingsLib/res/values-uk/arrays.xml index 961119e6379c..6bbae3d62664 100644 --- a/packages/SettingsLib/res/values-uk/arrays.xml +++ b/packages/SettingsLib/res/values-uk/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Використовувати перевірку HDCP лише для вмісту, захищеного DRM"</item> <item msgid="45075631231212732">"Завжди використовувати перевірку HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (за умовчанням)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Використовувати вибір системи (за умовчанням)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Моно"</item> <item msgid="8883739882299884241">"Стерео"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Оптимізовано для кращої якості аудіо (990/909 кбіт/с)"</item> - <item msgid="2921767058740704969">"Збалансована якість аудіо та з’єднання (660/606 кбіт/с)"</item> - <item msgid="8860982705384396512">"Оптимізовано для кращої якості з’єднання (330/303 кбіт/с)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Оптимізовано для кращої якості аудіо"</item> - <item msgid="4327143584633311908">"Збалансована якість аудіо та з’єднання"</item> - <item msgid="4681409244565426925">"Оптимізовано для кращої якості з’єднання"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Вимкнено"</item> <item msgid="1593289376502312923">"64 Кб"</item> diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml index 97b286d916ae..eda466be3d15 100644 --- a/packages/SettingsLib/res/values-uk/strings.xml +++ b/packages/SettingsLib/res/values-uk/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Не під’єднуватиметься автоматично"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Немає доступу до Інтернету"</string> <string name="saved_network" msgid="4352716707126620811">"Збережено додатком <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Автоматично під’єднано через %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Під’єднано через %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Доступ через %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Украй швидко"</item> <item msgid="9085102246155045744">"Найшвидше"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Вибрати профіль"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Особисте"</string> <string name="category_work" msgid="8699184680584175622">"Робота"</string> <string name="development_settings_title" msgid="215179176067683667">"Параметри розробника"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Перемикатися з Wi-Fi на мобільну мережу"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Завжди шукати мережі Wi-Fi"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Не вимикати мобільне передавання даних"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Вимкнути абсолютну гучність"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Версія Bluetooth AVRCP"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Виберіть версію Bluetooth AVRCP"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Кодек для аудіо Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Вибрати кодек для аудіо Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Частота вибірки для аудіо Bluetooth"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Трансляція: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Показати параметри сертифікації бездротового екрана"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Показувати в журналі RSSI для кожного SSID під час вибору Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Примусово перемикатися на мобільну мережу, коли сигнал Wi-Fi слабкий"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Дозволити чи заборонити Wi-Fi шукати роумінг на основі обсягу трафіку даних в інтерфейсі"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Розміри буфера журналу"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Виберіть розміри буфера журналу"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Замінено на <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Залишилося приблизно <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Залишилося <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – ще <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – залишилося <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного заряду від розетки"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного заряду через USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного заряду від бездротового пристрою"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не заряджається"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Акумулятор заряджено"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Керується адміністратором"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Увімкнено адміністратором"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Вимкнено адміністратором"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Головний екран налаштувань"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-ur/arrays.xml b/packages/SettingsLib/res/values-ur/arrays.xml index ad111cc229c1..432a6dc280cc 100644 --- a/packages/SettingsLib/res/values-ur/arrays.xml +++ b/packages/SettingsLib/res/values-ur/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"HDCP چیکنگ صرف DRM مواد کیلئے استعمال کریں"</item> <item msgid="45075631231212732">"ہمیشہ HDCP چیکنگ استعمال کریں"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (ڈیفالٹ)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"سسٹم انتخاب کا استعمال کریں (ڈیفالٹ)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"مونو"</item> <item msgid="8883739882299884241">"اسٹیریو"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"آڈیو کے معیار کیلئے بہتر بنایا گيا (990kbps/909kbps)"</item> - <item msgid="2921767058740704969">"متوازن آڈیو اور کنکشن کا معیار (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"کنکشن کے معیار کیلئے بہتر بنایا گيا (330kbps/303kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"آڈیو کے معیار کیلئے بہتر بنایا گيا"</item> - <item msgid="4327143584633311908">"متوازن آڈیو اور کنکشن کا معیار"</item> - <item msgid="4681409244565426925">"کنکشن کے معیار کیلئے بہتر بنایا گيا"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"آف"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml index 15ff61b62b85..7933ca4c65fb 100644 --- a/packages/SettingsLib/res/values-ur/strings.xml +++ b/packages/SettingsLib/res/values-ur/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"خودکار طور پر منسلک نہیں ہو گا"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"انٹرنیٹ تک کوئی رسائی نہیں"</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> کی جانب سے محفوظ کردہ"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s کے ذریعے از خود منسلک کردہ"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"منسلک بذریعہ %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"دستیاب بذریعہ %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"کافی تیز"</item> <item msgid="9085102246155045744">"تیز ترین"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"پروفائل منتخب کریں"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"ذاتی"</string> <string name="category_work" msgid="8699184680584175622">"دفتر"</string> <string name="development_settings_title" msgid="215179176067683667">"ڈویلپر کے اختیارات"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi‑Fi سے موبائل کو جارحانہ ہینڈ اوور"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ہمیشہ Wi‑Fi روم اسکینز کی اجازت دیں"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"موبائل ڈیٹا ہمیشہ فعال رکھیں"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"مطلق والیوم کو غیر فعال کریں"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"بلوٹوتھ AVRCP ورژن"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"بلوٹوتھ AVRCP ورژن منتخب کریں"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"بلوٹوتھ آڈیو کوڈیک"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"بلوٹوتھ آڈیو کوڈیک منتخب کریں"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"بلوٹوتھ آڈیو کے نمونے کی شرح"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"سلسلہ بندی: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</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> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"فعال کئے جانے پر، جب Wi‑Fi سگنل کمزور ہوگا، تو Wi‑Fi موبائل پر ڈیٹا کنکشن بھیجنے کیلئے مزید جارحانہ کارروائی کرے گا"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"انٹرفیس پر موجود ڈیٹا ٹریفک کی مقدار کی بنیاد پر Wi‑Fi روم اسکینز کی اجازت دیں/اجازت نہ دیں"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"لاگر بفر کے سائز"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"فی لاگ بفر لاگر کے سائز منتخب کریں"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> کے ذریعہ منسوخ کردیا گیا"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"تقریبا <xliff:g id="TIME">%1$s</xliff:g> باقی ہیں"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> باقی ہے"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - تقریباً <xliff:g id="TIME">%2$s</xliff:g> باقی ہے"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC پر پوری طرح چارج ہونے تک"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB پر پوری طرح چارج ہونے تک"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> وائر لیس سے پوری طرح چارج ہونے تک"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"چارج نہیں ہو رہا ہے"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"مکمل"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"کنٹرول کردہ بذریعہ منتظم"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"منتظم نے فعال کر دیا"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"منتظم نے غیر فعال کر دیا"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"ترتیبات ہوم"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-uz/arrays.xml b/packages/SettingsLib/res/values-uz/arrays.xml index 9d8c5b0600f0..1ee282312022 100644 --- a/packages/SettingsLib/res/values-uz/arrays.xml +++ b/packages/SettingsLib/res/values-uz/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"HDCP tekshiruvi faqat DRM kontent uchun ishlatilsin"</item> <item msgid="45075631231212732">"Har doim HDCP tekshiruvidan foydalanilsin"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (asosiy)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Tizim tanlovi (birlamchi)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Mono"</item> <item msgid="8883739882299884241">"Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Ovoz sifatini optimallashtirish (990/909 kbit/s)"</item> - <item msgid="2921767058740704969">"Audio sifati balansi va ulanish tezligi (660/606 kbit/s)"</item> - <item msgid="8860982705384396512">"Ulanish tezligini optimallashtirish (330/303 kbit/s)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Ovoz sifatini optimallashtirish"</item> - <item msgid="4327143584633311908">"Audio sifati balansi va ulanish tezligi"</item> - <item msgid="4681409244565426925">"Ulanish tezligini optimallashtirish"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"O‘chiq"</item> <item msgid="1593289376502312923">"64 KB"</item> diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml index 7a395ed738db..93adf3b11ab0 100644 --- a/packages/SettingsLib/res/values-uz/strings.xml +++ b/packages/SettingsLib/res/values-uz/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Avtomatik ravishda ulanilmaydi"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Internet aloqasi yo‘q"</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> tomonidan saqlangan"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s orqali avtomatik ulandi"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s orqali ulangan"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s orqali ishlaydi"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Juda tez"</item> <item msgid="9085102246155045744">"Eng tez"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Profil tanlash"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Shaxsiy"</string> <string name="category_work" msgid="8699184680584175622">"Ish"</string> <string name="development_settings_title" msgid="215179176067683667">"Dasturchi sozlamalari"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Tarmoqlar"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Simsiz monitor sertifikatlari"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Batafsil Wi-Fi jurnali"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Mobil internetga o‘tish"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi-Fi tarmoqlarini qidirishga doim ruxsat"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobil internet o‘chirilmasin"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Ovoz balangligining mutlaq darajasini o‘chirib qo‘yish"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP versiyasi"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Bluetooth AVRCP versiyasini tanlang"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth audio kodeki"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Bluetooth orqali uzatish uchun audiokodek"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth audio namunasi chastotasi"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Translatsiya: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Simsiz monitorlarni sertifikatlash parametrini ko‘rsatish"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi-Fi ulanishini tanlashda har bir SSID uchun jurnalda ko‘rsatilsin"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Agar ushbu funksiya yoqilsa, Wi-Fi signali past bo‘lganda internetga ulanish majburiy ravishda mobil internetga o‘tkaziladi"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Ma’lumotlarni uzatish vaqtida trafik hajmiga qarab Wi-Fi tarmoqlarni qidirish funksiyasini yoqish yoki o‘chirish"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Jurnal buferi hajmi"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Jurnal xotirasi hajmini tanlang"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> bilan almashtirildi"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Taxminan <xliff:g id="TIME">%1$s</xliff:g> qoldi"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> qoldi"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – taxminan <xliff:g id="TIME">%2$s</xliff:g> qoldi"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> qoldi"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – to‘liq quvvatlashga <xliff:g id="TIME">%2$s</xliff:g> ketadi"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – AC orqali to‘liq quvvatlashga <xliff:g id="TIME">%2$s</xliff:g> ketadi"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – USB orqali to‘liq quvvatlashga <xliff:g id="TIME">%2$s</xliff:g> ketadi"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – simsiz to‘liq quvvatlashga <xliff:g id="TIME">%2$s</xliff:g> ketadi"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Noma’lum"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Quvvat olmoqda"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Quvvatlanmayapti"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"To‘la"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Administrator tomonidan boshqariladi"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Administrator tomonidan yoqilgan"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Administrator tomonidan o‘chirilgan"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Sozlamalar"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-vi/arrays.xml b/packages/SettingsLib/res/values-vi/arrays.xml index 5e34660df1f4..3391f21347e8 100644 --- a/packages/SettingsLib/res/values-vi/arrays.xml +++ b/packages/SettingsLib/res/values-vi/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Chỉ sử dụng kiểm tra HDCP cho nội dung DRM"</item> <item msgid="45075631231212732">"Luôn sử dụng kiểm tra HDCP"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (Mặc định)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Sử dụng lựa chọn hệ thống (Mặc định)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Đơn âm"</item> <item msgid="8883739882299884241">"Âm thanh nổi"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Được tối ưu hóa cho chất lượng âm thanh (990kb/giây/909kb/giây)"</item> - <item msgid="2921767058740704969">"Chất lượng kết nối và âm thanh cân bằng (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"Được tối ưu hóa cho chất lượng kết nối (330kb/giây/303kb/giây)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Được tối ưu hóa cho chất lượng âm thanh"</item> - <item msgid="4327143584633311908">"Chất lượng kết nối và âm thanh cân bằng"</item> - <item msgid="4681409244565426925">"Được tối ưu hóa cho chất lượng kết nối"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Tắt"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml index 95a5281e9973..cedb8a9712cd 100644 --- a/packages/SettingsLib/res/values-vi/strings.xml +++ b/packages/SettingsLib/res/values-vi/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Sẽ không tự động kết nối"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Không có quyền truy cập Internet"</string> <string name="saved_network" msgid="4352716707126620811">"Được lưu bởi <xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Tự động được kết nối qua %1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Được kết nối qua %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Có sẵn qua %1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Rất nhanh"</item> <item msgid="9085102246155045744">"Nhanh nhất"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Chọn hồ sơ"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Cá nhân"</string> <string name="category_work" msgid="8699184680584175622">"Cơ quan"</string> <string name="development_settings_title" msgid="215179176067683667">"Tùy chọn nhà phát triển"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Mạng"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Chứng nhận hiển thị không dây"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Bật ghi nhật ký chi tiết Wi‑Fi"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Chuyển vùng Wi‑Fi tích cực sang mạng DĐ"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Luôn cho phép quét chuyển vùng Wi‑Fi"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Dữ liệu di động luôn hiện hoạt"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Vô hiệu hóa âm lượng tuyệt đối"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth phiên bản AVRCP"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Chọn Bluetooth phiên bản AVRCP"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Codec âm thanh Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Chọn Codec âm thanh Bluetooth"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Tốc độ lấy mẫu âm thanh Bluetooth"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Truyền trực tuyến: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Hiển thị tùy chọn chứng nhận hiển thị không dây"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Tăng mức ghi nhật ký Wi‑Fi, hiển thị mỗi SSID RSSI trong bộ chọn Wi‑Fi"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Khi được bật, Wi‑Fi sẽ tích cực hơn trong việc chuyển vùng kết nối dữ liệu sang mạng di động khi tín hiệu Wi‑Fi yếu"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Cho phép/Không cho phép quét chuyển vùng Wi‑Fi dựa trên lưu lượng truy cập dữ liệu có tại giao diện"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Kích cỡ tải trình ghi"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Chọn kích thước Trình ghi/lần tải nhật ký"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Bị ghi đè bởi <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Còn khoảng <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Còn lại <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - còn khoảng <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - còn lại <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> cho tới khi được sạc đầy"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> cho tới khi được sạc đầy trên AC"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> cho tới khi được sạc đầy qua USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> cho tới khi được sạc đầy từ không dây"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Không xác định"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Đang sạc"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Hiện không sạc"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Đầy"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Do quản trị viên kiểm soát"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Được bật bởi quản trị viên"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Bị tắt bởi quản trị viên"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Trang chủ cài đặt"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-zh-rCN/arrays.xml b/packages/SettingsLib/res/values-zh-rCN/arrays.xml index 5691c5ea56d6..7664328802db 100644 --- a/packages/SettingsLib/res/values-zh-rCN/arrays.xml +++ b/packages/SettingsLib/res/values-zh-rCN/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"仅使用 HDCP 检查 DRM 内容"</item> <item msgid="45075631231212732">"始终使用 HDCP 检查"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4(默认)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"使用系统选择(默认)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"单声道"</item> <item msgid="8883739882299884241">"立体声"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"偏重音频质量 (990kbps/909kbps)"</item> - <item msgid="2921767058740704969">"兼顾音频和连接质量 (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"偏重连接质量 (330kbps/303kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"偏重音频质量"</item> - <item msgid="4327143584633311908">"兼顾音频和连接质量"</item> - <item msgid="4681409244565426925">"偏重连接质量"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"关闭"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml index 369260b4af6f..d88d356e46b4 100644 --- a/packages/SettingsLib/res/values-zh-rCN/strings.xml +++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"无法自动连接"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"无法连接到互联网"</string> <string name="saved_network" msgid="4352716707126620811">"已通过<xliff:g id="NAME">%1$s</xliff:g>保存"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"已通过%1$s自动连接"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"已通过%1$s连接"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"可通过%1$s连接"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"极快"</item> <item msgid="9085102246155045744">"最快"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"选择个人资料"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"个人"</string> <string name="category_work" msgid="8699184680584175622">"工作"</string> <string name="development_settings_title" msgid="215179176067683667">"开发者选项"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"网络"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"无线显示认证"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"启用WLAN详细日志记录功能"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"主动从 WLAN 网络切换到移动数据网络"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"一律允许WLAN漫游扫描"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"始终开启移动数据网络"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"停用绝对音量功能"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"蓝牙 AVRCP 版本"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"选择蓝牙 AVRCP 版本"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"蓝牙音频编解码器"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"选择蓝牙音频编解码器"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"蓝牙音频采样率"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"正在流式传输:<xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"显示无线显示认证选项"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"提升WLAN日志记录级别(在WLAN选择器中显示每个SSID的RSSI)"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"开启此设置后,系统会在 WLAN 信号较弱时,主动将网络模式从 WLAN 网络切换到移动数据网络"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"根据接口中目前的数据流量允许/禁止WLAN漫游扫描"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"日志记录器缓冲区大小"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"选择每个日志缓冲区的日志记录器大小"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"已被“<xliff:g id="TITLE">%1$s</xliff:g>”覆盖"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"还剩大约 <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"还可用 <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - 大约还剩 <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还可用 <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需 <xliff:g id="TIME">%2$s</xliff:g>充满(交流电充电)"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需 <xliff:g id="TIME">%2$s</xliff:g>充满(USB 充电)"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需 <xliff:g id="TIME">%2$s</xliff:g>充满(无线充电)"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"未在充电"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"电量充足"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"由管理员控制"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"已被管理员启用"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"已被管理员禁用"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"设置主屏幕"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-zh-rHK/arrays.xml b/packages/SettingsLib/res/values-zh-rHK/arrays.xml index 92fb80ff3db6..a50a3d0fee9e 100644 --- a/packages/SettingsLib/res/values-zh-rHK/arrays.xml +++ b/packages/SettingsLib/res/values-zh-rHK/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"僅使用 HDCP 檢查 DRM 內容"</item> <item msgid="45075631231212732">"永遠使用 HDCP 檢查"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (預設)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"使用系統選擇 (預設)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"單聲道"</item> <item msgid="8883739882299884241">"立體聲"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"已優化音訊品質 (990kbps/909kbps)"</item> - <item msgid="2921767058740704969">"平衡音訊和連線品質 (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"已優化連線品質 (330kbps/303kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"已優化音訊品質"</item> - <item msgid="4327143584633311908">"平衡音訊和連線品質"</item> - <item msgid="4681409244565426925">"已優化連線品質"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"關閉"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml index 270543fbb985..558475e4ab6e 100644 --- a/packages/SettingsLib/res/values-zh-rHK/strings.xml +++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"不會自動連線"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"無法偵測互聯網連線"</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> 的儲存"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"已透過 %1$s 自動連線"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"已透過 %1$s 連線"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"可透過 %1$s 連線"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"極快"</item> <item msgid="9085102246155045744">"最快"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"選擇設定檔"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"個人"</string> <string name="category_work" msgid="8699184680584175622">"公司"</string> <string name="development_settings_title" msgid="215179176067683667">"開發人員選項"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"加強 Wi-Fi 至流動數據轉換"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"永遠允許 Wi-Fi 漫遊掃瞄"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"一律保持啟用流動數據"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"停用絕對音量功能"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"藍牙 AVRCP 版本"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"選擇藍牙 AVRCP 版本"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"藍牙音訊編解碼器"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"選擇藍牙音訊編解碼器"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"藍牙音訊取樣率"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"正在串流:<xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"顯示無線螢幕分享認證的選項"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"讓 Wi‑Fi 記錄功能升級,在 Wi‑Fi 選擇器中依每個 SSID RSSI 顯示 Wi‑Fi 詳細紀錄"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"啟用後,Wi-Fi 連線會在訊號不穩定的情況下更積極轉換成流動數據連線"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"根據介面中目前的數據流量允許/禁止 WiFi 漫遊掃瞄"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"記錄器緩衝區空間"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"選取每個記錄緩衝區的記錄器空間"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"已由「<xliff:g id="TITLE">%1$s</xliff:g>」覆寫"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"尚餘大約 <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"尚餘 <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - 剩餘約 <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - 尚餘 <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - 還需 <xliff:g id="TIME">%2$s</xliff:g>才能完全充電 (透過 AC)"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - 還需 <xliff:g id="TIME">%2$s</xliff:g>才能完全充電 (透過 USB)"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - 還需 <xliff:g id="TIME">%2$s</xliff:g>才能完全充電 (透過無線方式)"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"未開始充電"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"電量已滿"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"已由管理員停用"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"已由管理員啟用"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"已由管理員停用"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"主設定畫面"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-zh-rTW/arrays.xml b/packages/SettingsLib/res/values-zh-rTW/arrays.xml index addc48d927d3..db93cc966bf6 100644 --- a/packages/SettingsLib/res/values-zh-rTW/arrays.xml +++ b/packages/SettingsLib/res/values-zh-rTW/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"僅使用 HDCP 檢查 DRM 內容"</item> <item msgid="45075631231212732">"一律使用 HDCP 檢查"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"AVRCP 1.4 (預設)"</item> + <item msgid="2089555299377409443">"AVRCP 1.5"</item> + <item msgid="2895327394279434278">"AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"avrcp14"</item> + <item msgid="1913619118958233129">"avrcp15"</item> + <item msgid="7142710449249088270">"avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"使用系統選擇 (預設)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"單聲道"</item> <item msgid="8883739882299884241">"立體聲"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"音訊品質最佳化 (990kbps/909kbps)"</item> - <item msgid="2921767058740704969">"兼顧音訊及連線品質 (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"連線品質最佳化 (330kbps/303kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"音訊品質最佳化"</item> - <item msgid="4327143584633311908">"兼顧音訊及連線品質"</item> - <item msgid="4681409244565426925">"連線品質最佳化"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"關閉"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml index 3517c0c4c9ff..0e7c096b90fb 100644 --- a/packages/SettingsLib/res/values-zh-rTW/strings.xml +++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"無法自動連線"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"沒有可用的網際網路連線"</string> <string name="saved_network" msgid="4352716707126620811">"由<xliff:g id="NAME">%1$s</xliff:g>儲存"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"已透過 %1$s 自動連線"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"已透過 %1$s 連線"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"可透過 %1$s 使用"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"極快"</item> <item msgid="9085102246155045744">"最快"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"選擇設定檔"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"個人"</string> <string name="category_work" msgid="8699184680584175622">"公司"</string> <string name="development_settings_title" msgid="215179176067683667">"開發人員選項"</string> @@ -170,16 +170,12 @@ <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> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi-Fi 至行動數據轉換強化"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"一律允許 Wi-Fi 漫遊掃描"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"行動數據連線一律保持啟用狀態"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"停用絕對音量功能"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"藍牙 AVRCP 版本"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"選取藍牙 AVRCP 版本"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"藍牙音訊轉碼器"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"選取藍牙音訊轉碼器"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"藍牙音訊取樣率"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"串流中:<xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"顯示無線螢幕分享認證的選項"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"讓 Wi‑Fi 記錄功能升級,在 Wi‑Fi 選擇器中依每個 SSID RSSI 顯示 Wi‑Fi 詳細紀錄"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"啟用時,Wi-Fi 連線在訊號不穩的情況下會更積極轉換成行動數據連線"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"根據介面中目前的數據流量允許/禁止 Wi-Fi 漫遊掃描"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"紀錄器緩衝區空間"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"選取每個紀錄緩衝區的紀錄器空間"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"已改為<xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"還剩大約 <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"還剩 <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - 約剩 <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - 還剩 <xliff:g id="TIME">%2$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> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <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_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽 (AC 變壓器充電)"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽 (USB 充電)"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽 (無線充電)"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"非充電中"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"電力充足"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"已由管理員停用"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"已由管理員啟用"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"已由管理員停用"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"設定主畫面"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-zu/arrays.xml b/packages/SettingsLib/res/values-zu/arrays.xml index 9d26eeff8c2b..6a0cc420f315 100644 --- a/packages/SettingsLib/res/values-zu/arrays.xml +++ b/packages/SettingsLib/res/values-zu/arrays.xml @@ -58,12 +58,16 @@ <item msgid="3878793616631049349">"Sebenzisa ukuhlola kwe-HDCP kokuqukethwe i-DRM kuphela"</item> <item msgid="45075631231212732">"Sebenzisa njalo ukuhlola kwe-HDPC"</item> </string-array> - <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) --> - <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) --> - <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) --> - <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) --> - <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) --> - <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) --> + <string-array name="bluetooth_avrcp_versions"> + <item msgid="5347678900838034763">"I-AVRCP 1.4 (Okuzenzakalelayo)"</item> + <item msgid="2089555299377409443">"I-AVRCP 1.5"</item> + <item msgid="2895327394279434278">"I-AVRCP 1.6"</item> + </string-array> + <string-array name="bluetooth_avrcp_version_values"> + <item msgid="2838624067805073303">"I-avrcp14"</item> + <item msgid="1913619118958233129">"I-avrcp15"</item> + <item msgid="7142710449249088270">"I-avrcp16"</item> + </string-array> <string-array name="bluetooth_a2dp_codec_titles"> <item msgid="7065842274271279580">"Sebenzisa ukukhetha kwesistimu (Okuzenzakalelayo)"</item> <item msgid="7539690996561263909">"SBC"</item> @@ -116,16 +120,8 @@ <item msgid="8900559293912978337">"Okukodwa"</item> <item msgid="8883739882299884241">"I-Stereo"</item> </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles"> - <item msgid="7158319962230727476">"Kuthuthukiselwe ikhwalithi yomsindo (990kbps/909kbps)"</item> - <item msgid="2921767058740704969">"Umsindo obhalansile nekhwalithi yoxhumo (660kbps/606kbps)"</item> - <item msgid="8860982705384396512">"Kuthuthukiselwe ikhwalithi yoxhumo (330kbps/303kbps)"</item> - </string-array> - <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> - <item msgid="6398189564246596868">"Kuthuthukiselwe ikhwalithi yomsebenzisi"</item> - <item msgid="4327143584633311908">"Umsindo obhalansile nekhwalithi yoxhumo"</item> - <item msgid="4681409244565426925">"Kuthuthukiselwe ikhwalithi yoxhumo"</item> - </string-array> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) --> + <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) --> <string-array name="select_logd_size_titles"> <item msgid="8665206199209698501">"Valiwe"</item> <item msgid="1593289376502312923">"64K"</item> diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml index f3dd8f386f33..42c322bfc02b 100644 --- a/packages/SettingsLib/res/values-zu/strings.xml +++ b/packages/SettingsLib/res/values-zu/strings.xml @@ -32,9 +32,8 @@ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Ngeke ize ixhumeke ngokuzenzakalela"</string> <string name="wifi_no_internet" msgid="3880396223819116454">"Akukho ukufinyelela ku-inthanethi"</string> <string name="saved_network" msgid="4352716707126620811">"Kulondolozwe ngu-<xliff:g id="NAME">%1$s</xliff:g>"</string> - <!-- no translation found for connected_via_network_scorer (5713793306870815341) --> - <skip /> - <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) --> + <string name="connected_via_network_scorer" msgid="5713793306870815341">"Ixhumeke ngokuzenzakalela nge-%1$s"</string> + <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) --> <skip /> <string name="connected_via_passpoint" msgid="2826205693803088747">"Kuxhumeke nge-%1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Iyatholakala nge-%1$s"</string> @@ -141,7 +140,8 @@ <item msgid="5194774745031751806">"Esheshisa kakhulu"</item> <item msgid="9085102246155045744">"Esheshisa kakhulukhulu"</item> </string-array> - <string name="choose_profile" msgid="8229363046053568878">"Khetha iphrofayela"</string> + <!-- no translation found for choose_profile (6921016979430278661) --> + <skip /> <string name="category_personal" msgid="1299663247844969448">"Okomuntu siqu"</string> <string name="category_work" msgid="8699184680584175622">"Umsebenzi"</string> <string name="development_settings_title" msgid="215179176067683667">"Izinketho Zonjiniyela"</string> @@ -170,16 +170,12 @@ <string name="debug_networking_category" msgid="7044075693643009662">"Ukunethiwekha"</string> <string name="wifi_display_certification" msgid="8611569543791307533">"Ukunikezwa isitifiketi sokubukeka okungenantambo"</string> <string name="wifi_verbose_logging" msgid="4203729756047242344">"Nika amandlaukungena kwe-Wi-Fi Verbose"</string> - <!-- no translation found for wifi_aggressive_handover (5309131983693661320) --> - <skip /> + <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Ukudluliselwa okunamandla kakhulu kwe-Wi-Fi ukuya kuselula"</string> <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vumela njalo ukuskena kokuzula kwe-Wi-Fi"</string> - <!-- no translation found for mobile_data_always_on (8774857027458200434) --> - <skip /> + <string name="mobile_data_always_on" msgid="8774857027458200434">"Idatha yeselula ihlala isebenza"</string> <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Khubaza ivolumu ngokuphelele"</string> - <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) --> - <skip /> - <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) --> - <skip /> + <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Inguqulo ye-Bluetooth ye-AVRCP"</string> + <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Khetha inguqulo ye-Bluetooth AVRCP"</string> <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"I-Bluetooth Audio Codec"</string> <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Khetha i-Bluetooth Audio Codec"</string> <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Isilinganiso sesampula yomsindo we-Bluetooth"</string> @@ -193,8 +189,7 @@ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Ukusakaza: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Bonisa izinketho zokunikeza isitifiketi ukubukeka okungenantambo"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"khuphula izinga lokungena le-Wi-Fi, bonisa nge-SSID RSSI engayodwana kusikhethi se-Wi-Fi"</string> - <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) --> - <skip /> + <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Uma inikwe amandla, i-Wi-Fi izoba namandla kakhulu ekudluliseleni ukuxhumeka kwedatha kuselula, uma isignali ye-Wi-Fi iphansi"</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Vumela/Ungavumeli ukuskena kokuzula kwe-Wi-Fi okususelwa kunani ledatha yethrafikhi ekhona ekusebenzisaneni"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Amasayizi weloga ngebhafa"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Khetha amasayizi weloga ngebhafa ngayinye yelogu"</string> @@ -325,21 +320,16 @@ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Igitshezwe ngaphezulu yi-<xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Cishe ngu-<xliff:g id="TIME">%1$s</xliff:g> osele"</string> <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> esisele"</string> - <!-- no translation found for power_discharging_duration (2843747179907396142) --> - <skip /> + <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - cishe ngu-<xliff:g id="TIME">%2$s</xliff:g> osele"</string> <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> okusele"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration (4676999980973411875) --> - <skip /> + <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kuze ligcwale ngokuphelele"</string> <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_ac (7341243578143555689) --> - <skip /> + <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kuze ligcwale ngokuphelele ku-AC"</string> <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_usb (3720632890882121805) --> - <skip /> + <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kuze ligcwale ngokuphelele nge-USB"</string> <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> - <!-- no translation found for power_charging_duration_wireless (5768338238751562058) --> - <skip /> + <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kuze ligcwale ngokuphelele kusukela kokungenantambo"</string> <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<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">"Akwaziwa"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Iyashaja"</string> @@ -353,8 +343,10 @@ <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ayishaji"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Kugcwele"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kulawulwa umqondisi"</string> - <string name="enabled_by_admin" msgid="2386503803463071894">"Kunikwe amandla umqondisi"</string> - <string name="disabled_by_admin" msgid="3669999613095206948">"Ikhutshazwe umlawuli"</string> + <!-- no translation found for enabled_by_admin (5302986023578399263) --> + <skip /> + <!-- no translation found for disabled_by_admin (8505398946020816620) --> + <skip /> <string name="home" msgid="3256884684164448244">"Ikhaya lezilungiselelo"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values/arrays.xml b/packages/SettingsLib/res/values/arrays.xml index 0bf1fa48879b..db3274ab478c 100644 --- a/packages/SettingsLib/res/values/arrays.xml +++ b/packages/SettingsLib/res/values/arrays.xml @@ -124,6 +124,8 @@ <item>aptX</item> <item>aptX HD</item> <item>LDAC</item> + <item>Enable Optional Codecs</item> + <item>Disable Optional Codecs</item> </string-array> <!-- Values for Bluetooth Audio Codec selection preference. --> @@ -134,6 +136,8 @@ <item>2</item> <item>3</item> <item>4</item> + <item>5</item> + <item>6</item> </string-array> <!-- Summaries for Bluetooth Audio Codec selection preference. [CHAR LIMIT=50]--> @@ -144,6 +148,8 @@ <item>aptX</item> <item>aptX HD</item> <item>LDAC</item> + <item>Enable Optional Codecs</item> + <item>Disable Optional Codecs</item> </string-array> <!-- Titles for Bluetooth Audio Codec Sample Rate selection preference. [CHAR LIMIT=50] --> @@ -223,6 +229,7 @@ <item>Optimized for Audio Quality (990kbps/909kbps)</item> <item>Balanced Audio And Connection Quality (660kbps/606kbps)</item> <item>Optimized for Connection Quality (330kbps/303kbps)</item> + <item>Best Effort (Adaptive Bit Rate)</item> </string-array> <!-- Values for Bluetooth Audio Codec LDAC Playback Quaility selection preference. --> @@ -230,6 +237,7 @@ <item>1000</item> <item>1001</item> <item>1002</item> + <item>1003</item> </string-array> <!-- Summaries for Bluetooth Audio Codec LDAC Playback Quality selection preference. [CHAR LIMIT=70]--> @@ -237,6 +245,7 @@ <item>Optimized for Audio Quality</item> <item>Balanced Audio And Connection Quality</item> <item>Optimized for Connection Quality</item> + <item>Best Effort (Adaptive Bit Rate)</item> </string-array> <!-- Titles for logd limit size selection preference. [CHAR LIMIT=14] --> diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml index cc2dc1bb6a7d..f14d0d128e67 100644 --- a/packages/SettingsLib/res/values/strings.xml +++ b/packages/SettingsLib/res/values/strings.xml @@ -76,7 +76,7 @@ <!-- Status message of Wi-Fi when it is automatically connected by a network recommendation provider. [CHAR LIMIT=NONE] --> <string name="connected_via_network_scorer">Automatically connected via %1$s</string> <!-- Status message of Wi-Fi when it is automatically connected by a default network recommendation provider. [CHAR LIMIT=NONE] --> - <string name="connected_via_network_scorer_default">Automatically connected via Network Quality Scorer</string> + <string name="connected_via_network_scorer_default">Automatically connected via network rating provider</string> <!-- Status message of Wi-Fi when it is connected by Passpoint configuration. [CHAR LIMIT=NONE] --> <string name="connected_via_passpoint">Connected via %1$s</string> <!-- Status message of Wi-Fi when network has matching passpoint credentials. [CHAR LIMIT=NONE] --> diff --git a/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java b/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java index 4b0ab59a931c..b54d7e201c85 100644 --- a/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java +++ b/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java @@ -106,11 +106,11 @@ public class SuggestionParser { public SuggestionParser( Context context, SharedPreferences sharedPrefs, int orderXml, String smartDismissControl) { - mContext = context; - mSuggestionList = (List<SuggestionCategory>) new SuggestionOrderInflater(mContext) - .parse(orderXml); - mSharedPrefs = sharedPrefs; - mSmartDismissControl = smartDismissControl; + this( + context, + sharedPrefs, + (List<SuggestionCategory>) new SuggestionOrderInflater(context).parse(orderXml), + smartDismissControl); } public SuggestionParser(Context context, SharedPreferences sharedPrefs, int orderXml) { @@ -118,12 +118,15 @@ public class SuggestionParser { } @VisibleForTesting - public SuggestionParser(Context context, SharedPreferences sharedPrefs) { + public SuggestionParser( + Context context, + SharedPreferences sharedPrefs, + List<SuggestionCategory> suggestionList, + String smartDismissControl) { mContext = context; - mSuggestionList = new ArrayList<SuggestionCategory>(); + mSuggestionList = suggestionList; mSharedPrefs = sharedPrefs; - mSmartDismissControl = DEFAULT_SMART_DISMISS_CONTROL; - Log.wtf(TAG, "Only use this constructor for testing"); + mSmartDismissControl = smartDismissControl; } public List<Tile> getSuggestions() { @@ -134,7 +137,19 @@ public class SuggestionParser { List<Tile> suggestions = new ArrayList<>(); final int N = mSuggestionList.size(); for (int i = 0; i < N; i++) { - readSuggestions(mSuggestionList.get(i), suggestions, isSmartSuggestionEnabled); + final SuggestionCategory category = mSuggestionList.get(i); + if (category.exclusive) { + // If suggestions from an exclusive category are present, parsing is stopped + // and only suggestions from that category are displayed. Note that subsequent + // exclusive categories are also ignored. + List<Tile> exclusiveSuggestions = new ArrayList<>(); + readSuggestions(category, exclusiveSuggestions, isSmartSuggestionEnabled); + if (!exclusiveSuggestions.isEmpty()) { + return exclusiveSuggestions; + } + } else { + readSuggestions(category, suggestions, isSmartSuggestionEnabled); + } } return suggestions; } @@ -368,6 +383,7 @@ public class SuggestionParser { public String category; public String pkg; public boolean multiple; + public boolean exclusive; } private static class SuggestionOrderInflater { @@ -377,6 +393,7 @@ public class SuggestionParser { private static final String ATTR_CATEGORY = "category"; private static final String ATTR_PACKAGE = "package"; private static final String ATTR_MULTIPLE = "multiple"; + private static final String ATTR_EXCLUSIVE = "exclusive"; private final Context mContext; @@ -451,6 +468,9 @@ public class SuggestionParser { category.pkg = attrs.getAttributeValue(null, ATTR_PACKAGE); String multiple = attrs.getAttributeValue(null, ATTR_MULTIPLE); category.multiple = !TextUtils.isEmpty(multiple) && Boolean.parseBoolean(multiple); + String exclusive = attrs.getAttributeValue(null, ATTR_EXCLUSIVE); + category.exclusive = + !TextUtils.isEmpty(exclusive) && Boolean.parseBoolean(exclusive); return category; } else { throw new IllegalArgumentException("Unknown item " + name); diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java index c2ce7c9fd5de..c90daf79972b 100644 --- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java +++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java @@ -1582,6 +1582,21 @@ public class ApplicationsState { } }; + public static final AppFilter FILTER_MOVIES = new AppFilter() { + @Override + public void init() { + } + + @Override + public boolean filterApp(AppEntry entry) { + boolean isMovieApp; + synchronized(entry) { + isMovieApp = entry.info.category == ApplicationInfo.CATEGORY_VIDEO; + } + return isMovieApp; + } + }; + public static final AppFilter FILTER_OTHER_APPS = new AppFilter() { @Override public void init() { @@ -1592,7 +1607,8 @@ public class ApplicationsState { boolean isCategorized; synchronized(entry) { isCategorized = entry.info.category == ApplicationInfo.CATEGORY_AUDIO || - entry.info.category == ApplicationInfo.CATEGORY_GAME; + entry.info.category == ApplicationInfo.CATEGORY_GAME || + entry.info.category == ApplicationInfo.CATEGORY_VIDEO; } return !isCategorized; } diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java b/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java index c7efb07ed310..5a1e603e7fa2 100644 --- a/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java +++ b/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java @@ -23,6 +23,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.os.UserHandle; import android.text.TextUtils; +import android.widget.RemoteViews; import java.util.ArrayList; @@ -84,6 +85,11 @@ public class Tile implements Parcelable { */ public String key; + /** + * Optional remote view which will be displayed instead of the regular title-summary item. + */ + public RemoteViews remoteViews; + public Tile() { // Empty } @@ -119,6 +125,7 @@ public class Tile implements Parcelable { dest.writeInt(priority); dest.writeBundle(metaData); dest.writeString(key); + dest.writeParcelable(remoteViews, flags); } public void readFromParcel(Parcel in) { @@ -139,6 +146,7 @@ public class Tile implements Parcelable { priority = in.readInt(); metaData = in.readBundle(); key = in.readString(); + remoteViews = in.readParcelable(RemoteViews.class.getClassLoader()); } Tile(Parcel in) { diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java index f31c09b104fd..5aeee419a6e0 100644 --- a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java @@ -21,7 +21,6 @@ import android.content.IContentProvider; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Resources; @@ -35,6 +34,7 @@ import android.provider.Settings.Global; import android.text.TextUtils; import android.util.Log; import android.util.Pair; +import android.widget.RemoteViews; import java.util.ArrayList; import java.util.Collections; @@ -153,6 +153,14 @@ public class TileUtils { public static final String META_DATA_PREFERENCE_SUMMARY_URI = "com.android.settings.summary_uri"; + /** + * Name of the meta-data item that should be set in the AndroidManifest.xml to specify the + * custom view which should be displayed for the preference. The custom view will be inflated + * as a remote view. + */ + public static final String META_DATA_PREFERENCE_CUSTOM_VIEW = + "com.android.settings.custom_view"; + public static final String SETTING_PKG = "com.android.settings"; /** @@ -353,6 +361,7 @@ public class TileUtils { String summary = null; String keyHint = null; Uri uri = null; + RemoteViews remoteViews = null; // Get the activity's meta-data try { @@ -385,6 +394,10 @@ public class TileUtils { keyHint = metaData.getString(META_DATA_PREFERENCE_KEYHINT); } } + if (metaData.containsKey(META_DATA_PREFERENCE_CUSTOM_VIEW)) { + int layoutId = metaData.getInt(META_DATA_PREFERENCE_CUSTOM_VIEW); + remoteViews = new RemoteViews(applicationInfo.packageName, layoutId); + } } } catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) { if (DEBUG) Log.d(LOG_TAG, "Couldn't find info", e); @@ -414,6 +427,7 @@ public class TileUtils { activityInfo.name); // Suggest a key for this tile tile.key = keyHint; + tile.remoteViews = remoteViews; return true; } diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java index 6764a6bb7f47..0f443d6791e3 100755 --- a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java +++ b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java @@ -101,7 +101,7 @@ public class BatteryMeterDrawableBase extends Drawable { for (int i=0; i < N; i++) { mColors[2 * i] = levels.getInt(i, 0); if (colors.getType(i) == TypedValue.TYPE_ATTRIBUTE) { - mColors[2 * i + 1] = Utils.getColorAttr(context, colors.getResourceId(i, 0)); + mColors[2 * i + 1] = Utils.getColorAttr(context, colors.getThemeAttributeId(i, 0)); } else { mColors[2 * i + 1] = colors.getColor(i, 0); } diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java index 0280f26e30b1..1f86f8b8d594 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java @@ -526,9 +526,13 @@ public class WifiTracker { // the given ScanResult. This is used for showing that a given AP // (ScanResult) is available via a Passpoint provider (provider friendly // name). - WifiConfiguration config = mWifiManager.getMatchingWifiConfig(result); - if (config != null) { - accessPoint.update(config); + try { + WifiConfiguration config = mWifiManager.getMatchingWifiConfig(result); + if (config != null) { + accessPoint.update(config); + } + } catch (UnsupportedOperationException e) { + // Passpoint not supported on the device. } } diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/applications/ApplicationsStateTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/applications/ApplicationsStateTest.java index e204a3a65c72..203fdc07b85b 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/applications/ApplicationsStateTest.java +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/applications/ApplicationsStateTest.java @@ -136,4 +136,18 @@ public class ApplicationsStateTest { when(mEntry.info.isInstantApp()).thenReturn(true); assertThat(ApplicationsState.FILTER_DISABLED.filterApp(mEntry)).isFalse(); } + + @Test + public void testVideoFilterAcceptsCategorizedVideo() { + mEntry.info.category = ApplicationInfo.CATEGORY_VIDEO; + + assertThat(ApplicationsState.FILTER_MOVIES.filterApp(mEntry)).isTrue(); + } + + @Test + public void testVideosFilterRejectsNotVideo() { + mEntry.info.category = ApplicationInfo.CATEGORY_GAME; + + assertThat(ApplicationsState.FILTER_MOVIES.filterApp(mEntry)).isFalse(); + } } diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java index 46726f2f1438..02deb44d0cd4 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java @@ -20,9 +20,11 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -580,4 +582,40 @@ public class WifiTrackerTest { mWorkerThread.quit(); updateScores(); } + + /** + * Verify that tracking a Passpoint AP on a device with Passpoint disabled doesn't cause + * any crash. + * + * @throws Exception + */ + @Test + public void trackPasspointApWithPasspointDisabled() throws Exception { + WifiTracker tracker = createMockedWifiTracker(); + + // Add a Passpoint AP to the scan results. + List<ScanResult> results = new ArrayList<>(); + ScanResult passpointAp = new ScanResult( + WifiSsid.createFromAsciiEncoded(SSID_1), + BSSID_1, + 0, // hessid + 0, //anqpDomainId + null, // osuProviders + "", // capabilities + RSSI_1, + 0, // frequency + SystemClock.elapsedRealtime() * 1000 /* microsecond timestamp */); + passpointAp.setFlag(ScanResult.FLAG_PASSPOINT_NETWORK); + results.add(passpointAp); + + // Update access point and verify UnsupportedOperationException is being caught for + // call to WifiManager#getMatchingWifiConfig. + when(mockWifiManager.getConfiguredNetworks()) + .thenReturn(new ArrayList<WifiConfiguration>()); + when(mockWifiManager.getScanResults()).thenReturn(results); + doThrow(new UnsupportedOperationException()) + .when(mockWifiManager).getMatchingWifiConfig(any(ScanResult.class)); + tracker.forceUpdate(); + verify(mockWifiManager).getMatchingWifiConfig(any(ScanResult.class)); + } } diff --git a/packages/SettingsLib/tests/robotests/res/xml/suggestion_ordering.xml b/packages/SettingsLib/tests/robotests/res/xml/suggestion_ordering.xml index 1eeafba1bf8f..0e2ce3be55eb 100644 --- a/packages/SettingsLib/tests/robotests/res/xml/suggestion_ordering.xml +++ b/packages/SettingsLib/tests/robotests/res/xml/suggestion_ordering.xml @@ -15,6 +15,8 @@ --> <optional-steps> + <step category="com.android.settings.suggested.category.DEFERRED_SETUP" + exclusive="true" /> <step category="com.android.settings.suggested.category.LOCK_SCREEN" /> <step category="com.android.settings.suggested.category.EMAIL" /> <step category="com.android.settings.suggested.category.PARTNER_ACCOUNT" diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java index 7729dec82e4a..d5341807677d 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java @@ -16,11 +16,12 @@ package com.android.settingslib; +import static com.google.common.truth.Truth.assertThat; + import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; -import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; import android.preference.PreferenceManager; @@ -31,59 +32,59 @@ import com.android.settingslib.drawer.TileUtilsTest; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; +import org.robolectric.res.ResourceLoader; +import org.robolectric.res.builder.DefaultPackageManager; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; -import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - @RunWith(SettingLibRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public class SuggestionParserTest { - @Mock - private PackageManager mPackageManager; private Context mContext; private SuggestionParser mSuggestionParser; - private SuggestionParser.SuggestionCategory mSuggestioCategory; + private SuggestionParser.SuggestionCategory mMultipleCategory; + private SuggestionParser.SuggestionCategory mExclusiveCategory; private List<Tile> mSuggestionsBeforeDismiss; private List<Tile> mSuggestionsAfterDismiss; private SharedPreferences mPrefs; private Tile mSuggestion; - private List<ResolveInfo> mInfo; @Before public void setUp() { - MockitoAnnotations.initMocks(this); - mContext = spy(RuntimeEnvironment.application); - when(mContext.getPackageManager()).thenReturn(mPackageManager); + RuntimeEnvironment.setRobolectricPackageManager( + new TestPackageManager(RuntimeEnvironment.getAppResourceLoader())); + mContext = RuntimeEnvironment.application; mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext); mSuggestion = new Tile(); mSuggestion.intent = new Intent("action"); mSuggestion.intent.setComponent(new ComponentName("pkg", "cls")); mSuggestion.metaData = new Bundle(); + mMultipleCategory = new SuggestionParser.SuggestionCategory(); + mMultipleCategory.category = "category1"; + mMultipleCategory.multiple = true; + mExclusiveCategory = new SuggestionParser.SuggestionCategory(); + mExclusiveCategory.category = "category2"; + mExclusiveCategory.exclusive = true; mSuggestionParser = new SuggestionParser( - mContext, mPrefs, R.xml.suggestion_ordering, "0,0"); - mSuggestioCategory = new SuggestionParser.SuggestionCategory(); - mSuggestioCategory.category = "category1"; - mSuggestioCategory.multiple = true; - mInfo = new ArrayList<>(); + mContext, mPrefs, Arrays.asList(mMultipleCategory, mExclusiveCategory), "0,0"); + ResolveInfo info1 = TileUtilsTest.newInfo(true, "category1"); info1.activityInfo.packageName = "pkg"; ResolveInfo info2 = TileUtilsTest.newInfo(true, "category1"); info2.activityInfo.packageName = "pkg2"; - mInfo.add(info1); - mInfo.add(info2); - when(mPackageManager.queryIntentActivitiesAsUser( - any(Intent.class), anyInt(), anyInt())).thenReturn(mInfo); + ResolveInfo info3 = TileUtilsTest.newInfo(true, "category2"); + info3.activityInfo.packageName = "pkg3"; + + Intent intent1 = new Intent(Intent.ACTION_MAIN).addCategory("category1"); + Intent intent2 = new Intent(Intent.ACTION_MAIN).addCategory("category2"); + RuntimeEnvironment.getRobolectricPackageManager().addResolveInfoForIntent(intent1, info1); + RuntimeEnvironment.getRobolectricPackageManager().addResolveInfoForIntent(intent1, info2); + RuntimeEnvironment.getRobolectricPackageManager().addResolveInfoForIntent(intent2, info3); } @Test @@ -99,30 +100,64 @@ public class SuggestionParserTest { @Test public void testGetSuggestions_withoutSmartSuggestions() { readAndDismissSuggestion(false); - mSuggestionParser.readSuggestions(mSuggestioCategory, mSuggestionsAfterDismiss, false); - assertThat(mSuggestionsBeforeDismiss.size()).isEqualTo(2); - assertThat(mSuggestionsAfterDismiss.size()).isEqualTo(1); + mSuggestionParser.readSuggestions(mMultipleCategory, mSuggestionsAfterDismiss, false); + assertThat(mSuggestionsBeforeDismiss).hasSize(2); + assertThat(mSuggestionsAfterDismiss).hasSize(1); assertThat(mSuggestionsBeforeDismiss.get(1)).isEqualTo(mSuggestionsAfterDismiss.get(0)); } @Test public void testGetSuggestions_withSmartSuggestions() { readAndDismissSuggestion(true); - assertThat(mSuggestionsBeforeDismiss.size()).isEqualTo(2); - assertThat(mSuggestionsAfterDismiss.size()).isEqualTo(2); + assertThat(mSuggestionsBeforeDismiss).hasSize(2); + assertThat(mSuggestionsAfterDismiss).hasSize(2); assertThat(mSuggestionsBeforeDismiss).isEqualTo(mSuggestionsAfterDismiss); } + @Test + public void testGetSuggestion_exclusiveNotAvailable() { + RuntimeEnvironment.getRobolectricPackageManager().removeResolveInfosForIntent( + new Intent(Intent.ACTION_MAIN).addCategory("category2"), + "pkg3"); + + // If exclusive item is not available, the other categories should be shown + final List<Tile> suggestions = mSuggestionParser.getSuggestions(); + assertThat(suggestions).hasSize(2); + assertThat(suggestions.get(0).category).isEqualTo("category1"); + assertThat(suggestions.get(1).category).isEqualTo("category1"); + } + + @Test + public void testGetSuggestions_exclusive() { + final List<Tile> suggestions = mSuggestionParser.getSuggestions(); + assertThat(suggestions).hasSize(1); + assertThat(suggestions.get(0).category).isEqualTo("category2"); + } + private void readAndDismissSuggestion(boolean isSmartSuggestionEnabled) { - mSuggestionsBeforeDismiss = new ArrayList<Tile>(); - mSuggestionsAfterDismiss = new ArrayList<Tile>(); + mSuggestionsBeforeDismiss = new ArrayList<>(); + mSuggestionsAfterDismiss = new ArrayList<>(); mSuggestionParser.readSuggestions( - mSuggestioCategory, mSuggestionsBeforeDismiss, isSmartSuggestionEnabled); - if (mSuggestionParser.dismissSuggestion( - mSuggestionsBeforeDismiss.get(0), isSmartSuggestionEnabled)) { - mInfo.remove(0); + mMultipleCategory, mSuggestionsBeforeDismiss, isSmartSuggestionEnabled); + final Tile suggestion = mSuggestionsBeforeDismiss.get(0); + if (mSuggestionParser.dismissSuggestion(suggestion, isSmartSuggestionEnabled)) { + RuntimeEnvironment.getRobolectricPackageManager().removeResolveInfosForIntent( + new Intent(Intent.ACTION_MAIN).addCategory(suggestion.category), + suggestion.intent.getComponent().getPackageName()); } mSuggestionParser.readSuggestions( - mSuggestioCategory, mSuggestionsAfterDismiss, isSmartSuggestionEnabled); + mMultipleCategory, mSuggestionsAfterDismiss, isSmartSuggestionEnabled); + } + + private static class TestPackageManager extends DefaultPackageManager { + + TestPackageManager(ResourceLoader appResourceLoader) { + super(appResourceLoader); + } + + @Override + public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, int flags, int userId) { + return super.queryIntentActivities(intent, flags); + } } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java index 2d3c4a786f5c..1788666ea842 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java @@ -16,11 +16,22 @@ package com.android.settingslib.drawer; -import android.app.ActivityManager; +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.argThat; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; -import android.content.IContentProvider; +import static org.mockito.Mockito.when; + +import android.app.ActivityManager; import android.content.ContentResolver; import android.content.Context; +import android.content.IContentProvider; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; @@ -38,36 +49,26 @@ import android.text.TextUtils; import android.util.ArrayMap; import android.util.Pair; +import com.android.settingslib.R; import com.android.settingslib.SuggestionParser; import com.android.settingslib.TestConfig; -import com.android.settingslib.drawer.TileUtilsTest; -import static org.mockito.Mockito.atLeastOnce; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.robolectric.shadows.ShadowApplication; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; -import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.argThat; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; -import org.mockito.ArgumentCaptor; - @RunWith(RobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) @@ -179,7 +180,11 @@ public class TileUtilsTest { false /* checkCategory */); assertThat(outTiles.size()).isEqualTo(1); - SuggestionParser parser = new SuggestionParser(mContext, null); + SuggestionParser parser = new SuggestionParser( + mContext, + null, + Collections.emptyList(), + "0,10"); parser.filterSuggestions(outTiles, 0, false); assertThat(outTiles.size()).isEqualTo(0); } @@ -289,6 +294,30 @@ public class TileUtilsTest { assertThat(outTiles.size()).isEqualTo(1); } + @Test + public void getTilesForIntent_shouldShowRemoteViewIfSpecified() { + Intent intent = new Intent(); + Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>(); + List<Tile> outTiles = new ArrayList<>(); + List<ResolveInfo> info = new ArrayList<>(); + ResolveInfo resolveInfo = newInfo(true, null /* category */); + resolveInfo.activityInfo.metaData.putInt("com.android.settings.custom_view", + R.layout.user_preference); + info.add(resolveInfo); + + when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt())) + .thenReturn(info); + + TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache, + null /* defaultCategory */, outTiles, false /* usePriority */, + false /* checkCategory */); + + assertThat(outTiles.size()).isEqualTo(1); + Tile tile = outTiles.get(0); + assertThat(tile.remoteViews).isNotNull(); + assertThat(tile.remoteViews.getLayoutId()).isEqualTo(R.layout.user_preference); + } + public static ResolveInfo newInfo(boolean systemApp, String category) { return newInfo(systemApp, category, null); } diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml index 14bb02d9b376..a8629f84025b 100644 --- a/packages/SettingsProvider/res/values/defaults.xml +++ b/packages/SettingsProvider/res/values/defaults.xml @@ -51,7 +51,7 @@ <bool name="def_wifi_on">false</bool> <!-- 0 == never, 1 == only when plugged in, 2 == always --> <integer name="def_wifi_sleep_policy">2</integer> - <bool name="def_wifi_wakeup_enabled">false</bool> + <bool name="def_wifi_wakeup_enabled">true</bool> <bool name="def_networks_available_notification_on">true</bool> <bool name="def_backup_enabled">false</bool> diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index 1a752f924425..0d0ddf2046a7 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -2798,7 +2798,7 @@ public class SettingsProvider extends ContentProvider { } private final class UpgradeController { - private static final int SETTINGS_VERSION = 142; + private static final int SETTINGS_VERSION = 143; private final int mUserId; @@ -3343,10 +3343,30 @@ public class SettingsProvider extends ContentProvider { currentVersion = 142; } + if (currentVersion == 142) { + // Version 142: Set a default value for Wi-Fi wakeup feature. + if (userId == UserHandle.USER_SYSTEM) { + final SettingsState globalSettings = getGlobalSettingsLocked(); + Setting currentSetting = globalSettings.getSettingLocked( + Settings.Global.WIFI_WAKEUP_ENABLED); + if (currentSetting.isNull()) { + globalSettings.insertSettingLocked( + Settings.Global.WIFI_WAKEUP_ENABLED, + getContext().getResources().getBoolean( + R.bool.def_wifi_wakeup_enabled) ? "1" : "0", + null, true, SettingsState.SYSTEM_PACKAGE_NAME); + } + } + + currentVersion = 143; + } + if (currentVersion != newVersion) { Slog.wtf("SettingsProvider", "warning: upgrading settings database to version " + newVersion + " left it at " - + currentVersion + " instead; this is probably a bug", new Throwable()); + + currentVersion + + " instead; this is probably a bug. Did you update SETTINGS_VERSION?", + new Throwable()); if (DEBUG) { throw new RuntimeException("db upgrade error"); } diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 6bfab78fcd62..2519e029dbd9 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -113,6 +113,7 @@ <uses-permission android:name="android.permission.GET_APP_OPS_STATS" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" /> + <uses-permission android:name="android.permission.START_TASKS_FROM_RECENTS" /> <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" /> <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" /> <uses-permission android:name="android.permission.MANAGE_AUTO_FILL" /> diff --git a/packages/SystemUI/Android.mk b/packages/SystemUI/Android.mk index 1ebfbad6d206..635c96f23778 100644 --- a/packages/SystemUI/Android.mk +++ b/packages/SystemUI/Android.mk @@ -38,7 +38,6 @@ LOCAL_STATIC_ANDROID_LIBRARIES := \ android-support-v17-leanback LOCAL_STATIC_JAVA_LIBRARIES := \ - framework-protos \ SystemUI-tags \ SystemUI-proto diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index e4d71b65ed6a..1147f16f5522 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -181,7 +181,7 @@ <uses-permission android:name="android.permission.MODIFY_ACCESSIBILITY_DATA" /> <!-- to control accessibility volume --> - <uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" /> + <uses-permission android:name="android.permission.CHANGE_ACCESSIBILITY_VOLUME" /> <application android:name=".SystemUIApplication" diff --git a/packages/SystemUI/plugin/Android.mk b/packages/SystemUI/plugin/Android.mk index 05ee6b23c4b7..e22dddb6d565 100644 --- a/packages/SystemUI/plugin/Android.mk +++ b/packages/SystemUI/plugin/Android.mk @@ -36,4 +36,6 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_JAVA_LIBRARIES := SystemUIPluginLib +LOCAL_PROGUARD_ENABLED := disabled + include $(BUILD_PACKAGE) diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginFragment.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginFragment.java index 152dbc5e06be..1bfa567b6630 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginFragment.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginFragment.java @@ -29,8 +29,8 @@ public abstract class PluginFragment extends Fragment implements Plugin { } @Override - public LayoutInflater getLayoutInflater(Bundle savedInstanceState) { - return super.getLayoutInflater(savedInstanceState).cloneInContext(getContext()); + public LayoutInflater onGetLayoutInflater(Bundle savedInstanceState) { + return super.onGetLayoutInflater(savedInstanceState).cloneInContext(getContext()); } @Override diff --git a/packages/SystemUI/res/layout/qs_detail.xml b/packages/SystemUI/res/layout/qs_detail.xml index 25d52263957b..1c087b374a2b 100644 --- a/packages/SystemUI/res/layout/qs_detail.xml +++ b/packages/SystemUI/res/layout/qs_detail.xml @@ -43,6 +43,8 @@ android:alpha="0" android:background="@color/qs_detail_progress_track" android:src="@drawable/indeterminate_anim" + android:scaleType="fitXY" + android:translationY="16dp" /> <com.android.systemui.qs.NonInterceptingScrollView @@ -57,6 +59,6 @@ android:layout_height="match_parent"/> </com.android.systemui.qs.NonInterceptingScrollView> - <include layout="@layout/qs_detail_buttons"/> + <include layout="@layout/qs_detail_buttons" /> </com.android.systemui.qs.QSDetail> diff --git a/packages/SystemUI/res/layout/recents_incompatible_app_overlay.xml b/packages/SystemUI/res/layout/recents_incompatible_app_overlay.xml index d2daa89ff03b..a1c1e5bd32c7 100644 --- a/packages/SystemUI/res/layout/recents_incompatible_app_overlay.xml +++ b/packages/SystemUI/res/layout/recents_incompatible_app_overlay.xml @@ -26,6 +26,6 @@ android:layout_gravity="center" android:drawableTop="@drawable/recents_info_light" android:drawablePadding="8dp" - android:text="@string/recents_incompatible_app_message" + android:text="@string/dock_non_resizeble_failed_to_dock_text" android:textColor="@android:color/white" /> </FrameLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 64cac3c001d1..6a7547050ba5 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -106,7 +106,7 @@ <!-- The default tiles to display in QuickSettings --> <string name="quick_settings_tiles_default" translatable="false"> - wifi,cell,bt,dnd,flashlight,rotation,battery,airplane + wifi,bt,dnd,flashlight,rotation,battery,cell,airplane,cast </string> <!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" --> @@ -209,9 +209,12 @@ <!-- Set to true to enable the user switcher on the keyguard. --> <bool name="config_keyguardUserSwitcher">false</bool> - <!-- Doze: does this device support STATE_DOZE and STATE_DOZE_SUSPEND? --> + <!-- Doze: does this device support STATE_DOZE? --> <bool name="doze_display_state_supported">false</bool> + <!-- Doze: does this device support STATE_DOZE_SUSPEND? --> + <bool name="doze_suspend_display_state_supported">false</bool> + <!-- Doze: should the significant motion sensor be used as a pulse signal? --> <bool name="doze_pulse_on_significant_motion">false</bool> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 5b20716fa41f..a2ec804f08ad 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -789,8 +789,6 @@ <string name="recents_launch_disabled_message"><xliff:g id="app" example="Calendar">%s</xliff:g> is disabled in safe-mode.</string> <!-- Recents: Stack action button string. [CHAR LIMIT=NONE] --> <string name="recents_stack_action_button_label">Clear all</string> - <!-- Recents: Incompatible task message. [CHAR LIMIT=NONE] --> - <string name="recents_incompatible_app_message">App doesn\'t support split screen</string> <!-- Recents: Hint text that shows on the drop targets to start multiwindow. [CHAR LIMIT=NONE] --> <string name="recents_drag_hint_message">Drag here to use split screen</string> @@ -1869,15 +1867,21 @@ <!-- Title of menu shown over picture-in-picture. Used for accessibility. --> <string name="pip_menu_title">Picture in picture menu</string> - <!-- User visible notification channel name for the PiP BTW notification. [CHAR LIMIT=NONE] --> - <string name="pip_notification_channel_name">Picture-in-picture</string> - <!-- PiP BTW notification title. [CHAR LIMIT=50] --> <string name="pip_notification_title"><xliff:g id="name" example="Google Maps">%s</xliff:g> is in picture-in-picture</string> <!-- PiP BTW notification description. [CHAR LIMIT=NONE] --> <string name="pip_notification_message">If you don’t want <xliff:g id="name" example="Google Maps">%s</xliff:g> to use this feature, tap to open settings and turn it off.</string> + <!-- PiP section of the tuner. [CHAR LIMIT=NONE] --> + <string name="picture_in_picture" translatable="false">Picture-in-Picture</string> + + <!-- PiP minimize title. [CHAR LIMIT=NONE]--> + <string name="pip_minimize_title" translatable="false">Minimize</string> + + <!-- PiP minimize description. [CHAR LIMIT=NONE] --> + <string name="pip_minimize_description" translatable="false">Drag or fling the PIP to the edges of the screen to minimize it.</string> + <!-- Tuner string --> <string name="change_theme_reboot" translatable="false">Changing the theme requires a restart.</string> <!-- Tuner string --> diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml index bc3edd58f252..a685c794c5d6 100644 --- a/packages/SystemUI/res/xml/tuner_prefs.xml +++ b/packages/SystemUI/res/xml/tuner_prefs.xml @@ -122,6 +122,18 @@ </PreferenceScreen> <PreferenceScreen + android:key="picture_in_picture" + android:title="@string/picture_in_picture"> + + <com.android.systemui.tuner.TunerSwitch + android:key="pip_minimize" + android:title="@string/pip_minimize_title" + android:summary="@string/pip_minimize_description" + sysui:defValue="false" /> + + </PreferenceScreen> + + <PreferenceScreen android:key="doze" android:title="@string/tuner_doze"> @@ -133,7 +145,7 @@ <com.android.systemui.tuner.TunerSwitch android:key="doze_sensors_wake_up_fully" android:title="@string/tuner_doze_sensors_wake_up_fully" - sysui:defValue="true" /> + sysui:defValue="false" /> </PreferenceScreen> diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java index d058e7837423..79190cbb129f 100644 --- a/packages/SystemUI/src/com/android/systemui/Dependency.java +++ b/packages/SystemUI/src/com/android/systemui/Dependency.java @@ -24,6 +24,7 @@ import android.util.ArrayMap; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.NightDisplayController; +import com.android.internal.logging.MetricsLogger; import com.android.internal.util.Preconditions; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.systemui.assist.AssistManager; @@ -257,6 +258,8 @@ public class Dependency extends SystemUI { mProviders.put(VolumeDialogController.class, () -> new VolumeDialogControllerImpl(mContext)); + mProviders.put(MetricsLogger.class, () -> new MetricsLogger()); + // Put all dependencies above here so the factory can override them if it wants. SystemUIFactory.getInstance().injectDependencies(mProviders, mContext); } diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java index 9a4179f4fef5..6571294cdb92 100644 --- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java @@ -405,17 +405,17 @@ public class ImageWallpaper extends WallpaperService { } } else { drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels); + if (FIXED_SIZED_SURFACE) { + // If the surface is fixed-size, we should only need to + // draw it once and then we'll let the window manager + // position it appropriately. As such, we no longer needed + // the loaded bitmap. Yay! + // hw-accelerated renderer retains bitmap for faster rotation + unloadWallpaper(false /* forgetSize */); + } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIEW); - if (FIXED_SIZED_SURFACE && !mIsHwAccelerated) { - // If the surface is fixed-size, we should only need to - // draw it once and then we'll let the window manager - // position it appropriately. As such, we no longer needed - // the loaded bitmap. Yay! - // hw-accelerated renderer retains bitmap for faster rotation - unloadWallpaper(false /* forgetSize */); - } } } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java index ba8e54aac759..4d8323bf3fbf 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java @@ -50,7 +50,8 @@ public class DozeFactory { WakeLock wakeLock = WakeLock.createPartial(context, "Doze"); DozeMachine machine = new DozeMachine( - DozeScreenStatePreventingAdapter.wrapIfNeeded(dozeService, params), + DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded( + DozeScreenStatePreventingAdapter.wrapIfNeeded(dozeService, params), params), config, wakeLock); machine.setParts(new DozeMachine.Part[]{ diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java index f27521e20bbc..f4984109ed10 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java @@ -87,8 +87,9 @@ public class DozeMachine { case DOZE: return Display.STATE_OFF; case DOZE_PULSING: + return Display.STATE_DOZE; case DOZE_AOD: - return Display.STATE_DOZE; // TODO: use STATE_ON if appropriate. + return Display.STATE_DOZE_SUSPEND; default: return Display.STATE_UNKNOWN; } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapter.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapter.java new file mode 100644 index 000000000000..1e067974e3cc --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapter.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2017 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.doze; + +import android.support.annotation.VisibleForTesting; +import android.view.Display; + +import com.android.systemui.statusbar.phone.DozeParameters; + +/** + * Prevents usage of doze screen states on devices that don't support them. + */ +public class DozeSuspendScreenStatePreventingAdapter implements DozeMachine.Service { + + private final DozeMachine.Service mInner; + + @VisibleForTesting + DozeSuspendScreenStatePreventingAdapter(DozeMachine.Service inner) { + mInner = inner; + } + + @Override + public void finish() { + mInner.finish(); + } + + @Override + public void setDozeScreenState(int state) { + if (state == Display.STATE_DOZE_SUSPEND) { + state = Display.STATE_DOZE; + } + mInner.setDozeScreenState(state); + } + + @Override + public void requestWakeUp() { + mInner.requestWakeUp(); + } + + /** + * If the device supports the doze display state, return {@code inner}. Otherwise + * return a new instance of {@link DozeSuspendScreenStatePreventingAdapter} wrapping {@code inner}. + */ + public static DozeMachine.Service wrapIfNeeded(DozeMachine.Service inner, + DozeParameters params) { + return isNeeded(params) ? new DozeSuspendScreenStatePreventingAdapter(inner) : inner; + } + + private static boolean isNeeded(DozeParameters params) { + return !params.getDozeSuspendDisplayStateSupported(); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java index 6cda0766663d..87f8ddb7f2f2 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java @@ -172,7 +172,8 @@ public class PipManager implements BasePipManager { mInputConsumerController); mTouchHandler = new PipTouchHandler(context, mActivityManager, mMenuController, mInputConsumerController); - mNotificationController = new PipNotificationController(context, mActivityManager); + mNotificationController = new PipNotificationController(context, mActivityManager, + mTouchHandler.getMotionHelper()); } /** 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 ebda2e8a7f57..ec80745f8d26 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java @@ -45,14 +45,12 @@ import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.util.Log; -import android.util.Pair; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.WindowManager.LayoutParams; -import android.view.accessibility.AccessibilityManager; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; @@ -61,6 +59,7 @@ import com.android.systemui.Interpolators; import com.android.systemui.R; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -128,8 +127,9 @@ public class PipMenuActivity extends Activity { break; case MESSAGE_UPDATE_ACTIONS: { final Bundle data = (Bundle) msg.obj; - setActions(data.getParcelable(EXTRA_STACK_BOUNDS), - ((ParceledListSlice) data.getParcelable(EXTRA_ACTIONS)).getList()); + final ParceledListSlice actions = data.getParcelable(EXTRA_ACTIONS); + setActions(data.getParcelable(EXTRA_STACK_BOUNDS), actions != null + ? actions.getList() : Collections.EMPTY_LIST); break; } case MESSAGE_UPDATE_DISMISS_FRACTION: { @@ -260,6 +260,7 @@ public class PipMenuActivity extends Activity { } notifyMenuVisibility(true); updateExpandButtonFromBounds(stackBounds, movementBounds); + setDecorViewVisibility(true); mMenuContainerAnimator = ObjectAnimator.ofFloat(mMenuContainer, View.ALPHA, mMenuContainer.getAlpha(), 1f); mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_IN); @@ -300,9 +301,7 @@ public class PipMenuActivity extends Activity { if (animationFinishedRunnable != null) { animationFinishedRunnable.run(); } - if (getSystemService(AccessibilityManager.class).isEnabled()) { - finish(); - } + setDecorViewVisibility(false); } }); mMenuContainerAnimator.addUpdateListener(mMenuBgUpdateListener); @@ -411,6 +410,7 @@ public class PipMenuActivity extends Activity { } private void updateDismissFraction(float fraction) { + setDecorViewVisibility(true); int alpha; if (mMenuVisible) { mMenuContainer.setAlpha(1-fraction); @@ -497,4 +497,16 @@ public class PipMenuActivity extends Activity { v.removeCallbacks(mFinishRunnable); v.postDelayed(mFinishRunnable, delay); } + + /** + * Sets the visibility of the root view of the window to disable drawing and touches for the + * activity. This differs from {@link Activity#setVisible(boolean)} in that it does not set + * the internal mVisibleFromClient state. + */ + private void setDecorViewVisibility(boolean visible) { + final View decorView = getWindow().getDecorView(); + if (decorView != null) { + decorView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE); + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipNotificationController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipNotificationController.java index bdd6b65026f0..db83b8b918a4 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipNotificationController.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipNotificationController.java @@ -16,15 +16,17 @@ package com.android.systemui.pip.phone; -import static android.app.NotificationManager.IMPORTANCE_MIN; +import static android.app.AppOpsManager.MODE_ALLOWED; +import static android.app.AppOpsManager.OP_PICTURE_IN_PICTURE; import static android.app.PendingIntent.FLAG_CANCEL_CURRENT; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.provider.Settings.ACTION_PICTURE_IN_PICTURE_SETTINGS; +import android.app.AppOpsManager; +import android.app.AppOpsManager.OnOpChangedListener; import android.app.IActivityManager; import android.app.Notification; -import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.ComponentName; @@ -40,6 +42,7 @@ import android.util.Log; import com.android.systemui.R; import com.android.systemui.SystemUI; +import com.android.systemui.util.NotificationChannels; /** * Manages the BTW notification that shows whenever an activity enters or leaves picture-in-picture. @@ -47,64 +50,79 @@ import com.android.systemui.SystemUI; public class PipNotificationController { private static final String TAG = PipNotificationController.class.getSimpleName(); - private static final String CHANNEL_ID = PipNotificationController.class.getName(); - private static final int BTW_NOTIFICATION_ID = 0; + private static final String NOTIFICATION_TAG = PipNotificationController.class.getName(); + private static final int NOTIFICATION_ID = 0; private Context mContext; private IActivityManager mActivityManager; + private AppOpsManager mAppOpsManager; private NotificationManager mNotificationManager; - public PipNotificationController(Context context, IActivityManager activityManager) { + private PipMotionHelper mMotionHelper; + + private AppOpsManager.OnOpChangedListener mAppOpsChangedListener = new OnOpChangedListener() { + @Override + public void onOpChanged(String op, String packageName) { + try { + // Dismiss the PiP once the user disables the app ops setting for that package + final ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfo( + packageName, 0); + if (mAppOpsManager.checkOpNoThrow(OP_PICTURE_IN_PICTURE, appInfo.uid, packageName) + != MODE_ALLOWED) { + mMotionHelper.dismissPip(); + } + } catch (NameNotFoundException e) { + // Unregister the listener if the package can't be found + unregisterAppOpsListener(); + } + } + }; + + public PipNotificationController(Context context, IActivityManager activityManager, + PipMotionHelper motionHelper) { mContext = context; mActivityManager = activityManager; + mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); mNotificationManager = NotificationManager.from(context); - createNotificationChannel(); + mMotionHelper = motionHelper; } public void onActivityPinned(String packageName) { // Clear any existing notification - mNotificationManager.cancel(CHANNEL_ID, BTW_NOTIFICATION_ID); + mNotificationManager.cancel(NOTIFICATION_TAG, NOTIFICATION_ID); // Build a new notification - final Notification.Builder builder = new Notification.Builder(mContext, CHANNEL_ID) - .setLocalOnly(true) - .setOngoing(true) - .setSmallIcon(R.drawable.pip_notification_icon) - .setColor(mContext.getColor( - com.android.internal.R.color.system_notification_accent_color)); + final Notification.Builder builder = + new Notification.Builder(mContext, NotificationChannels.GENERAL) + .setLocalOnly(true) + .setOngoing(true) + .setSmallIcon(R.drawable.pip_notification_icon) + .setColor(mContext.getColor( + com.android.internal.R.color.system_notification_accent_color)); if (updateNotificationForApp(builder, packageName)) { SystemUI.overrideNotificationAppName(mContext, builder); // Show the new notification - mNotificationManager.notify(CHANNEL_ID, BTW_NOTIFICATION_ID, builder.build()); + mNotificationManager.notify(NOTIFICATION_TAG, NOTIFICATION_ID, builder.build()); } + + // Register for changes to the app ops setting for this package while it is in PiP + registerAppOpsListener(packageName); } public void onActivityUnpinned() { + // Unregister for changes to the previously PiP'ed package + unregisterAppOpsListener(); + ComponentName topPipActivity = PipUtils.getTopPinnedActivity(mContext, mActivityManager); if (topPipActivity != null) { onActivityPinned(topPipActivity.getPackageName()); } else { - mNotificationManager.cancel(CHANNEL_ID, BTW_NOTIFICATION_ID); + mNotificationManager.cancel(NOTIFICATION_TAG, NOTIFICATION_ID); } } /** - * Create the notification channel for the PiP BTW notifications if necessary. - */ - private NotificationChannel createNotificationChannel() { - NotificationChannel channel = mNotificationManager.getNotificationChannel(CHANNEL_ID); - if (channel == null) { - channel = new NotificationChannel(CHANNEL_ID, - mContext.getString(R.string.pip_notification_channel_name), IMPORTANCE_MIN); - channel.enableLights(false); - channel.enableVibration(false); - mNotificationManager.createNotificationChannel(channel); - } - return channel; - } - - /** * Updates the notification builder with app-specific information, returning whether it was * successful. */ @@ -139,4 +157,13 @@ public class PipNotificationController { } return false; } + + private void registerAppOpsListener(String packageName) { + mAppOpsManager.startWatchingMode(OP_PICTURE_IN_PICTURE, packageName, + mAppOpsChangedListener); + } + + private void unregisterAppOpsListener() { + mAppOpsManager.stopWatchingMode(mAppOpsChangedListener); + } } diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java index f70d5b41ac3e..a0f491f3ba34 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java @@ -37,8 +37,10 @@ import android.view.accessibility.AccessibilityNodeInfo; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.policy.PipSnapAlgorithm; +import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.statusbar.FlingAnimationUtils; +import com.android.systemui.tuner.TunerService; import java.io.PrintWriter; @@ -46,9 +48,11 @@ import java.io.PrintWriter; * Manages all the touch handling for PIP on the Phone, including moving, dismissing and expanding * the PIP. */ -public class PipTouchHandler { +public class PipTouchHandler implements TunerService.Tunable { private static final String TAG = "PipTouchHandler"; + private static final String TUNER_KEY_MINIMIZE = "pip_minimize"; + // These values are used for metrics and should never change private static final int METRIC_VALUE_DISMISSED_BY_TAP = 0; private static final int METRIC_VALUE_DISMISSED_BY_DRAG = 1; @@ -97,6 +101,9 @@ public class PipTouchHandler { } }; + // Allow the PIP to be dragged to the edge of the screen to be minimized. + private boolean mEnableMinimize = false; + // Behaviour states private boolean mIsMenuVisible; private boolean mIsMinimized; @@ -104,6 +111,8 @@ public class PipTouchHandler { private int mImeHeight; private float mSavedSnapFraction = -1f; private boolean mSendingHoverAccessibilityEvents; + private boolean mMovementWithinMinimize; + private boolean mMovementWithinDismiss; // Touch state private final PipTouchState mTouchState; @@ -167,6 +176,9 @@ public class PipTouchHandler { mExpandedShortestEdgeSize = context.getResources().getDimensionPixelSize( R.dimen.pip_expanded_shortest_edge_size); + // Register any tuner settings changes + Dependency.get(TunerService.class).addTunable(this, TUNER_KEY_MINIMIZE); + // Register the listener for input consumer touch events inputConsumerController.setTouchListener(this::handleTouchEvent); inputConsumerController.setRegistrationListener(this::onRegistrationChanged); @@ -187,6 +199,20 @@ public class PipTouchHandler { } } + @Override + public void onTuningChanged(String key, String newValue) { + if (newValue == null) { + // Reset back to default + mEnableMinimize = false; + return; + } + switch (key) { + case TUNER_KEY_MINIMIZE: + mEnableMinimize = Integer.parseInt(newValue) != 0; + break; + } + } + public void onConfigurationChanged() { mMotionHelper.onConfigurationChanged(); mMotionHelper.synchronizePinnedStackBounds(); @@ -366,6 +392,9 @@ public class PipTouchHandler { * Sets the minimized state. */ void setMinimizedStateInternal(boolean isMinimized) { + if (!mEnableMinimize) { + return; + } setMinimizedState(isMinimized, false /* fromController */); } @@ -373,6 +402,9 @@ public class PipTouchHandler { * Sets the minimized state. */ void setMinimizedState(boolean isMinimized, boolean fromController) { + if (!mEnableMinimize) { + return; + } if (mIsMinimized != isMinimized) { MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_MINIMIZED, isMinimized); @@ -435,6 +467,8 @@ public class PipTouchHandler { * Gesture controlling normal movement of the PIP. */ private PipTouchGesture mDefaultMovementGesture = new PipTouchGesture() { + // Whether the PiP was on the left side of the screen at the start of the gesture + private boolean mStartedOnLeft; @Override public void onDown(PipTouchState touchState) { @@ -442,6 +476,10 @@ public class PipTouchHandler { return; } + mStartedOnLeft = mMotionHelper.getBounds().left < mMovementBounds.centerX(); + mMovementWithinMinimize = true; + mMovementWithinDismiss = touchState.getDownTouchPosition().y >= mMovementBounds.bottom; + // If the menu is still visible, and we aren't minimized, then just poke the menu // so that it will timeout after the user stops touching it if (mMenuController.isMenuVisible() && !mIsMinimized) { @@ -475,7 +513,7 @@ public class PipTouchHandler { final PointF lastDelta = touchState.getLastTouchDelta(); float left = mTmpBounds.left + lastDelta.x; float top = mTmpBounds.top + lastDelta.y; - if (!touchState.allowDraggingOffscreen()) { + if (!touchState.allowDraggingOffscreen() || !mEnableMinimize) { left = Math.max(mMovementBounds.left, Math.min(mMovementBounds.right, left)); } if (ENABLE_DISMISS_DRAG_TO_EDGE) { @@ -493,6 +531,18 @@ public class PipTouchHandler { if (ENABLE_DISMISS_DRAG_TO_EDGE) { updateDismissFraction(); } + + final PointF curPos = touchState.getLastTouchPosition(); + if (mMovementWithinMinimize) { + // Track if movement remains near starting edge to identify swipes to minimize + mMovementWithinMinimize = mStartedOnLeft + ? curPos.x <= mMovementBounds.left + mTmpBounds.width() + : curPos.x >= mMovementBounds.right; + } + if (mMovementWithinDismiss) { + // Track if movement remains near the bottom edge to identify swipe to dismiss + mMovementWithinDismiss = curPos.y >= mMovementBounds.bottom; + } return true; } return false; @@ -526,8 +576,15 @@ public class PipTouchHandler { } if (touchState.isDragging()) { - final boolean onLeft = mMotionHelper.getBounds().left < mMovementBounds.centerX(); - boolean isFlingToBot = isFlingTowardsEdge(touchState, 4 /* bottom */); + final PointF vel = touchState.getVelocity(); + final float velocity = PointF.length(vel.x, vel.y); + final boolean isFling = velocity > mFlingAnimationUtils.getMinVelocityPxPerSecond(); + final boolean isHorizontal = Math.abs(vel.x) > Math.abs(vel.y); + final boolean isFlingToBot = isFling + && !isHorizontal && mMovementWithinDismiss && vel.y > 0; + final boolean isFlingToEdge = isFling && isHorizontal && mMovementWithinMinimize + && (mStartedOnLeft ? vel.x < 0 : vel.x > 0); + if (ENABLE_DISMISS_DRAG_TO_EDGE && (mMotionHelper.shouldDismissPip() || isFlingToBot)) { mMotionHelper.animateDragToEdgeDismiss(mMotionHelper.getBounds(), @@ -536,8 +593,8 @@ public class PipTouchHandler { MetricsEvent.ACTION_PICTURE_IN_PICTURE_DISMISSED, METRIC_VALUE_DISMISSED_BY_DRAG); return true; - } else if (!mIsMinimized && (mMotionHelper.shouldMinimizePip() - || isFlingTowardsEdge(touchState, onLeft ? 2 : 3))) { + } else if (mEnableMinimize && + !mIsMinimized && (mMotionHelper.shouldMinimizePip() || isFlingToEdge)) { // Pip should be minimized setMinimizedStateInternal(true); if (mMenuController.isMenuVisible()) { @@ -563,9 +620,7 @@ public class PipTouchHandler { mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds); } - final PointF vel = mTouchState.getVelocity(); - final float velocity = PointF.length(vel.x, vel.y); - if (velocity > mFlingAnimationUtils.getMinVelocityPxPerSecond()) { + if (isFling) { mMotionHelper.flingToSnapTarget(velocity, vel.x, vel.y, mMovementBounds, mUpdateScrimListener); } else { @@ -585,42 +640,6 @@ public class PipTouchHandler { }; /** - * @return whether the gesture ending in {@param vel} is fast enough to be a fling and towards - * the provided {@param edge} where: - * - * 1 = top - * 2 = left - * 3 = right - * 4 = bottom - */ - private boolean isFlingTowardsEdge(PipTouchState touchState, int edge) { - final PointF vel = touchState.getVelocity(); - final PointF downPos = touchState.getDownTouchPosition(); - final Rect bounds = mMotionHelper.getBounds(); - final boolean isHorizontal = Math.abs(vel.x) > Math.abs(vel.y); - final boolean isFling = - PointF.length(vel.x, vel.y) > mFlingAnimationUtils.getMinVelocityPxPerSecond(); - if (!isFling) { - return false; - } - switch (edge) { - case 1: // top - return !isHorizontal && vel.y < 0 - && downPos.y <= mMovementBounds.top + bounds.height(); - case 2: // left - return isHorizontal && vel.x < 0 - && downPos.x <= mMovementBounds.left + bounds.width(); - case 3: // right - return isHorizontal && vel.x > 0 - && downPos.x >= mMovementBounds.right; - case 4: // bottom - return !isHorizontal && vel.y > 0 - && downPos.y >= mMovementBounds.bottom; - } - return false; - } - - /** * Updates the current movement bounds based on whether the menu is currently visible. */ private void updateMovementBounds(boolean isExpanded) { @@ -643,6 +662,7 @@ public class PipTouchHandler { pw.println(innerPrefix + "mImeHeight=" + mImeHeight); pw.println(innerPrefix + "mSavedSnapFraction=" + mSavedSnapFraction); pw.println(innerPrefix + "mEnableDragToDismiss=" + ENABLE_DISMISS_DRAG_TO_TARGET); + pw.println(innerPrefix + "mEnableMinimize=" + mEnableMinimize); mSnapAlgorithm.dump(pw, innerPrefix); mTouchState.dump(pw, innerPrefix); mMotionHelper.dump(pw, innerPrefix); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java index a30b03b9a411..6b507645e4d0 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java @@ -230,12 +230,8 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha firstPageBuilder.addFloat(brightness, "translationY", heightDiff, 0); mBrightnessAnimator = new TouchAnimator.Builder() .addFloat(brightness, "alpha", 0, 1) - .addFloat(mQsPanel.getPageIndicator(), "alpha", 0, 1) - .addFloat(mQsPanel.getDivider(), "alpha", 0, 1) .setStartDelay(.5f) .build(); - mAllViews.add(mQsPanel.getPageIndicator()); - mAllViews.add(mQsPanel.getDivider()); mAllViews.add(brightness); } else { mBrightnessAnimator = null; @@ -247,7 +243,11 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha mFirstPageDelayedAnimator = new TouchAnimator.Builder() .setStartDelay(EXPANDED_TILE_DELAY) .addFloat(tileLayout, "alpha", 0, 1) + .addFloat(mQsPanel.getPageIndicator(), "alpha", 0, 1) + .addFloat(mQsPanel.getDivider(), "alpha", 0, 1) .addFloat(mQsPanel.getFooter().getView(), "alpha", 0, 1).build(); + mAllViews.add(mQsPanel.getPageIndicator()); + mAllViews.add(mQsPanel.getDivider()); mAllViews.add(mQsPanel.getFooter().getView()); float px = 0; float py = 1; @@ -264,6 +264,8 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha } mNonfirstPageAnimator = new TouchAnimator.Builder() .addFloat(mQuickQsPanel, "alpha", 1, 0) + .addFloat(mQsPanel.getPageIndicator(), "alpha", 0, 1) + .addFloat(mQsPanel.getDivider(), "alpha", 0, 1) .setListener(mNonFirstPageListener) .setEndDelay(.5f) .build(); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java index 1709718b1301..9efe224ff52f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java @@ -14,6 +14,8 @@ package com.android.systemui.qs; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_MORE_SETTINGS; + import android.animation.Animator; import android.animation.Animator.AnimatorListener; import android.animation.AnimatorListenerAdapter; @@ -197,7 +199,7 @@ public class QSDetail extends LinearLayout { mDetailContent.removeAllViews(); mDetailContent.addView(detailView); mDetailViews.put(viewCacheIndex, detailView); - MetricsLogger.visible(mContext, adapter.getMetricsCategory()); + Dependency.get(MetricsLogger.class).visible(adapter.getMetricsCategory()); announceForAccessibility(mContext.getString( R.string.accessibility_quick_settings_detail, adapter.getTitle())); @@ -206,7 +208,7 @@ public class QSDetail extends LinearLayout { setVisibility(View.VISIBLE); } else { if (mDetailAdapter != null) { - MetricsLogger.hidden(mContext, mDetailAdapter.getMetricsCategory()); + Dependency.get(MetricsLogger.class).hidden(mDetailAdapter.getMetricsCategory()); } mClosingDetail = true; mDetailAdapter = null; @@ -238,8 +240,12 @@ public class QSDetail extends LinearLayout { protected void setupDetailFooter(DetailAdapter adapter) { final Intent settingsIntent = adapter.getSettingsIntent(); mDetailSettingsButton.setVisibility(settingsIntent != null ? VISIBLE : GONE); - mDetailSettingsButton.setOnClickListener(v -> Dependency.get(ActivityStarter.class) - .postStartActivityDismissingKeyguard(settingsIntent, 0)); + mDetailSettingsButton.setOnClickListener(v -> { + Dependency.get(MetricsLogger.class).action(ACTION_QS_MORE_SETTINGS, + mDetailAdapter.getMetricsCategory()); + Dependency.get(ActivityStarter.class) + .postStartActivityDismissingKeyguard(settingsIntent, 0); + }); } protected void setupDetailHeader(final DetailAdapter adapter) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java index 2202b5865def..d51fe8a2f690 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java @@ -16,6 +16,8 @@ package com.android.systemui.qs; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_DATE; + import android.app.AlarmManager; import android.app.PendingIntent; import android.content.Context; @@ -49,6 +51,7 @@ import com.android.systemui.qs.TouchAnimator.Builder; import com.android.systemui.statusbar.phone.ExpandableIndicator; import com.android.systemui.statusbar.phone.MultiUserSwitch; import com.android.systemui.statusbar.phone.SettingsButton; +import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.NetworkController.EmergencyListener; import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; @@ -160,11 +163,10 @@ public class QSFooter extends LinearLayout implements final Builder builder = new Builder() .addFloat(mSettingsContainer, "translationX", -(remaining - defSpace), 0) .addFloat(mSettingsButton, "rotation", -120, 0) - .addFloat(mAlarmStatus, "alpha", 0, 1) - .addFloat(mAlarmStatus, "translationX", 0, -mDate.getWidth()) - .addFloat(mAlarmStatusCollapsed, "translationX", 0, -mDate.getWidth()); + .addFloat(mAlarmStatus, "alpha", 0, 1); if (mAlarmShowing) { - builder.addFloat(mDate, "alpha", 1, 0); + builder.addFloat(mDate, "alpha", 1, 0) + .addFloat(mDateTimeGroup, "translationX", 0, -mDate.getWidth()); } mAnimator = builder.build(); setExpansion(mExpansionAmount); @@ -336,6 +338,11 @@ public class QSFooter extends LinearLayout implements @Override public void onClick(View v) { if (v == mSettingsButton) { + if (!Dependency.get(DeviceProvisionedController.class).isCurrentUserSetup()) { + // If user isn't setup just unlock the device and dump them back at SUW. + mActivityStarter.postQSRunnableDismissingKeyguard(() -> { }); + return; + } MetricsLogger.action(mContext, mExpanded ? MetricsProto.MetricsEvent.ACTION_QS_EXPANDED_SETTINGS_LAUNCH : MetricsProto.MetricsEvent.ACTION_QS_COLLAPSED_SETTINGS_LAUNCH); @@ -358,6 +365,8 @@ public class QSFooter extends LinearLayout implements startSettingsActivity(); } } else if (v == mDateTimeGroup) { + Dependency.get(MetricsLogger.class).action(ACTION_QS_DATE, + mNextAlarm != null); if (mNextAlarm != null) { PendingIntent showIntent = mNextAlarm.getShowIntent(); mActivityStarter.startPendingIntentDismissingKeyguard(showIntent); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java index 63563b2e31ed..406f107f9872 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java @@ -21,6 +21,7 @@ import android.app.Fragment; import android.content.res.Configuration; import android.graphics.Rect; import android.os.Bundle; +import android.support.annotation.VisibleForTesting; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -39,6 +40,8 @@ import com.android.systemui.statusbar.stack.StackStateAnimator; public class QSFragment extends Fragment implements QS { private static final String TAG = "QS"; private static final boolean DEBUG = false; + private static final String EXTRA_EXPANDED = "expanded"; + private static final String EXTRA_LISTENING = "listening"; private final Rect mQsBounds = new Rect(); private boolean mQsExpanded; @@ -85,6 +88,35 @@ public class QSFragment extends Fragment implements QS { mQSCustomizer = view.findViewById(R.id.qs_customize); mQSCustomizer.setQs(this); + if (savedInstanceState != null) { + setExpanded(savedInstanceState.getBoolean(EXTRA_EXPANDED)); + setListening(savedInstanceState.getBoolean(EXTRA_LISTENING)); + } + } + + @Override + public void onDestroy() { + super.onDestroy(); + if (mListening) { + setListening(false); + } + } + + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(EXTRA_EXPANDED, mQsExpanded); + outState.putBoolean(EXTRA_LISTENING, mListening); + } + + @VisibleForTesting + boolean isListening() { + return mListening; + } + + @VisibleForTesting + boolean isExpanded() { + return mQsExpanded; } @Override @@ -221,7 +253,7 @@ public class QSFragment extends Fragment implements QS { } // Set bounds on the QS panel so it doesn't run over the header. - mQsBounds.top = (int) (mHeader.getBottom() * (1 - expansion)); + mQsBounds.top = (int) (mQSPanel.getHeight() * (1 - expansion)); mQsBounds.right = mQSPanel.getWidth(); mQsBounds.bottom = mQSPanel.getHeight(); mQSPanel.setClipBounds(mQsBounds); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSHost.java index 29d547cfd5d2..8596b578f030 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSHost.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSHost.java @@ -32,6 +32,8 @@ public interface QSHost { TileServices getTileServices(); void removeTile(String tileSpec); + int indexOf(String tileSpec); + interface Callback { void onTilesChanged(); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index 8298cbb7d7fe..2e6116dba7e9 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -59,6 +59,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback { protected final View mBrightnessView; private final H mHandler = new H(); private final View mPageIndicator; + private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class); private int mPanelPaddingBottom; private int mBrightnessPaddingTop; @@ -259,7 +260,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback { if (!mExpanded && mTileLayout instanceof PagedTileLayout) { ((PagedTileLayout) mTileLayout).setCurrentItem(0, false); } - MetricsLogger.visibility(mContext, MetricsEvent.QS_PANEL, mExpanded); + mMetricsLogger.visibility(MetricsEvent.QS_PANEL, mExpanded); if (!mExpanded) { closeDetail(); } else { @@ -475,7 +476,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback { int newVis = visible ? VISIBLE : INVISIBLE; setVisibility(newVis); if (mGridContentVisible != visible) { - MetricsLogger.visibility(mContext, MetricsEvent.QS_PANEL, newVis); + mMetricsLogger.visibility(MetricsEvent.QS_PANEL, newVis); } mGridContentVisible = visible; } @@ -483,7 +484,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback { private void logTiles() { for (int i = 0; i < mRecords.size(); i++) { TileRecord tileRecord = mRecords.get(i); - MetricsLogger.visible(mContext, tileRecord.tile.getMetricsCategory()); + mMetricsLogger.visible(tileRecord.tile.getMetricsCategory()); } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java index 0ca115e43c07..933054138a8a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java @@ -157,6 +157,10 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory> { return mServices; } + public int indexOf(String spec) { + return mTileSpecs.indexOf(spec); + } + @Override public void onTuningChanged(String key, String newValue) { if (!TILES_SETTING.equals(key)) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java index d8e554254076..596d3bc6e8f6 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java @@ -209,7 +209,7 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene for (String tile : defTiles.split(",")) { tiles.add(tile); } - mTileAdapter.setTileSpecs(tiles); + mTileAdapter.resetTileSpecs(mHost, tiles); } private void setTileSpecs() { diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java index c33d7da2d808..0a0d2ce00a1b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java @@ -114,6 +114,12 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta mCurrentSpecs = newSpecs; } + public void resetTileSpecs(QSTileHost host, List<String> specs) { + // Notify the host so the tiles get removed callbacks. + host.changeTiles(mCurrentSpecs, specs); + setTileSpecs(specs); + } + public void setTileSpecs(List<String> currentSpecs) { if (currentSpecs.equals(mCurrentSpecs)) { return; diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java index 6f35017b893b..b5c1bd9ff9db 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java @@ -22,6 +22,7 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.graphics.drawable.Drawable; +import android.metrics.LogMaker; import android.net.Uri; import android.os.Binder; import android.os.IBinder; @@ -155,6 +156,11 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener return mComponent; } + @Override + protected LogMaker populate(LogMaker logMaker) { + return super.populate(logMaker).setComponentName(mComponent); + } + public Tile getQsTile() { return mTile; } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java index a751ef465147..6e2add493779 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java @@ -84,12 +84,14 @@ public class QSIconViewImpl extends QSIconView { protected void updateIcon(ImageView iv, State state) { if (!Objects.equals(state.icon, iv.getTag(R.id.qs_icon_tag))) { + boolean shouldAnimate = iv.isShown() && mAnimationEnabled + && iv.getDrawable() != null; Drawable d = state.icon != null - ? iv.isShown() && mAnimationEnabled ? state.icon.getDrawable(mContext) + ? shouldAnimate ? state.icon.getDrawable(mContext) : state.icon.getInvisibleDrawable(mContext) : null; int padding = state.icon != null ? state.icon.getPadding() : 0; if (d != null) { - d.setAutoMirrored(true); + d.setAutoMirrored(false); } iv.setImageDrawable(d); iv.setTag(R.id.qs_icon_tag, state.icon); @@ -114,7 +116,7 @@ public class QSIconViewImpl extends QSIconView { if (state.state != mState) { int color = getColor(state.state); mState = state.state; - if (iv.isShown()) { + if (iv.isShown() && mTint != 0) { animateGrayScale(mTint, color, iv); mTint = color; } else { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java index 948954c2bd99..1aa51b1c38bf 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java @@ -14,12 +14,19 @@ package com.android.systemui.qs.tileimpl; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_CLICK; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_LONG_PRESS; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_SECONDARY_CLICK; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_QS_POSITION; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_QS_VALUE; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_ACTION; import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import android.app.ActivityManager; import android.content.Context; import android.content.Intent; import android.graphics.drawable.Drawable; +import android.metrics.LogMaker; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -29,7 +36,6 @@ import android.util.Log; import android.util.SparseArray; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.Utils; import com.android.systemui.Dependency; @@ -58,6 +64,7 @@ public abstract class QSTileImpl<TState extends State> implements QSTile { protected final H mHandler = new H(Dependency.get(Dependency.BG_LOOPER)); protected final Handler mUiHandler = new Handler(Looper.getMainLooper()); private final ArraySet<Object> mListeners = new ArraySet<>(); + private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class); private final ArrayList<Callback> mCallbacks = new ArrayList<>(); protected TState mState = newTileState(); @@ -76,7 +83,7 @@ public abstract class QSTileImpl<TState extends State> implements QSTile { /** * Declare the category of this tile. * - * Categories are defined in {@link com.android.internal.logging.MetricsProto.MetricsEvent} + * Categories are defined in {@link com.android.internal.logging.nano.MetricsProto.MetricsEvent} * by editing frameworks/base/proto/src/metrics_constants.proto. */ abstract public int getMetricsCategory(); @@ -152,17 +159,28 @@ public abstract class QSTileImpl<TState extends State> implements QSTile { } public void click() { + mMetricsLogger.write(populate(new LogMaker(ACTION_QS_CLICK).setType(TYPE_ACTION))); mHandler.sendEmptyMessage(H.CLICK); } public void secondaryClick() { + mMetricsLogger.write(populate(new LogMaker(ACTION_QS_SECONDARY_CLICK).setType(TYPE_ACTION))); mHandler.sendEmptyMessage(H.SECONDARY_CLICK); } public void longClick() { + mMetricsLogger.write(populate(new LogMaker(ACTION_QS_LONG_PRESS).setType(TYPE_ACTION))); mHandler.sendEmptyMessage(H.LONG_CLICK); } + protected LogMaker populate(LogMaker logMaker) { + if (mState instanceof BooleanState) { + logMaker.addTaggedData(FIELD_QS_VALUE, ((BooleanState) mState).value ? 1 : 0); + } + return logMaker.setSubtype(getMetricsCategory()) + .addTaggedData(FIELD_QS_POSITION, mHost.indexOf(mTileSpec)); + } + public void showDetail(boolean show) { mHandler.obtainMessage(H.SHOW_DETAIL, show ? 1 : 0, 0).sendToTarget(); } @@ -224,7 +242,6 @@ public abstract class QSTileImpl<TState extends State> implements QSTile { } protected void handleLongClick() { - MetricsLogger.action(mContext, MetricsEvent.ACTION_QS_LONG_PRESS, getTileSpec()); Dependency.get(ActivityStarter.class).postStartActivityDismissingKeyguard( getLongClickIntent(), 0); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java index c7979d84ebbb..8209ee2d5d99 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java @@ -41,8 +41,8 @@ import com.android.settingslib.graph.UsageView; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.plugins.qs.DetailAdapter; -import com.android.systemui.qs.QSHost; import com.android.systemui.plugins.qs.QSTile.BooleanState; +import com.android.systemui.qs.QSHost; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.policy.BatteryController; @@ -102,7 +102,7 @@ public class BatterySaverTile extends QSTileImpl<BooleanState> implements @Override public CharSequence getTileLabel() { - return mContext.getString(R.string.battery); + return mContext.getString(R.string.battery_detail_switch_title); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java index ed6e6ef439b5..4e4de15567d4 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java @@ -83,7 +83,6 @@ public class BluetoothTile extends QSTileImpl<BooleanState> { protected void handleClick() { // Secondary clicks are header clicks, just toggle. final boolean isEnabled = (Boolean)mState.value; - MetricsLogger.action(mContext, getMetricsCategory(), !isEnabled); mController.setBluetoothEnabled(!isEnabled); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java index a1d3d261c4d8..22b6a634cb9a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java @@ -108,13 +108,11 @@ public class CastTile extends QSTileImpl<BooleanState> { protected void handleClick() { if (mKeyguard.isSecure() && !mKeyguard.canSkipBouncer()) { mActivityStarter.postQSRunnableDismissingKeyguard(() -> { - MetricsLogger.action(mContext, getMetricsCategory()); showDetail(true); mHost.openPanels(); }); return; } - MetricsLogger.action(mContext, getMetricsCategory()); showDetail(true); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java index 4351b2ca6dc0..04be7de644e3 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java @@ -98,7 +98,6 @@ public class CellularTile extends QSTileImpl<SignalState> { @Override protected void handleSecondaryClick() { - MetricsLogger.action(mContext, getMetricsCategory()); if (mDataController.isMobileDataSupported()) { showDetail(true); } else { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java index e33b6808d7dd..5b374b1bc286 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java @@ -84,7 +84,6 @@ public class ColorInversionTile extends QSTileImpl<BooleanState> { @Override protected void handleClick() { - MetricsLogger.action(mContext, getMetricsCategory(), !mState.value); mSetting.setValue(mState.value ? 0 : 1); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java index 7a25140c2fa0..b7964512a2fa 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java @@ -87,7 +87,6 @@ public class DataSaverTile extends QSTileImpl<BooleanState> implements private void toggleDataSaver() { mState.value = !mDataSaverController.isDataSaverEnabled(); - MetricsLogger.action(mContext, getMetricsCategory(), mState.value); mDataSaverController.setDataSaverEnabled(mState.value); refreshState(mState.value); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java index f35de68a837d..3c2e8973cd6e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java @@ -146,7 +146,6 @@ public class DndTile extends QSTileImpl<BooleanState> { Toast.LENGTH_LONG).show(); return; } - MetricsLogger.action(mContext, getMetricsCategory(), !mState.value); showDetail(true); int zen = Prefs.getInt(mContext, Prefs.Key.DND_FAVORITE_ZEN, Global.ZEN_MODE_ALARMS); mController.setZen(zen, null, TAG); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java index 7b0fd73446aa..6d2aa9065cff 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java @@ -87,7 +87,6 @@ public class FlashlightTile extends QSTileImpl<BooleanState> implements if (ActivityManager.isUserAMonkey()) { return; } - MetricsLogger.action(mContext, getMetricsCategory(), !mState.value); boolean newState = !mState.value; refreshState(newState); mFlashlightController.setFlashlight(newState); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java index 66629371b942..5c3f65c471bf 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java @@ -106,7 +106,6 @@ public class HotspotTile extends QSTileImpl<AirplaneBooleanState> { if (!isEnabled && mAirplaneMode.getValue() != 0) { return; } - MetricsLogger.action(mContext, getMetricsCategory(), !isEnabled); mController.setHotspotEnabled(!isEnabled); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java index c9533635d2a5..00cfbfa1eac7 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java @@ -92,7 +92,6 @@ public class IntentTile extends QSTileImpl<State> { @Override protected void handleClick() { - MetricsLogger.action(mContext, getMetricsCategory(), mIntentPackage); sendIntent("click", mOnClick, mOnClickUri); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java index b5c02cb81b04..b11b15a73093 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java @@ -81,13 +81,11 @@ public class LocationTile extends QSTileImpl<BooleanState> { Dependency.get(ActivityStarter.class).postQSRunnableDismissingKeyguard(() -> { final boolean wasEnabled = mState.value; mHost.openPanels(); - MetricsLogger.action(mContext, getMetricsCategory(), !wasEnabled); mController.setLocationEnabled(!wasEnabled); }); return; } final boolean wasEnabled = mState.value; - MetricsLogger.action(mContext, getMetricsCategory(), !wasEnabled); mController.setLocationEnabled(!wasEnabled); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java index 32993391e29f..d147b6968856 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java @@ -85,7 +85,6 @@ public class NfcTile extends QSTileImpl<BooleanState> { @Override protected void handleClick() { if (mAdapter == null) return; - MetricsLogger.action(mContext, getMetricsCategory(), !mState.value); if (!mAdapter.isEnabled()) { mAdapter.enable(); } else { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java index 8b47216f17e4..8aa1e43dc106 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java @@ -54,7 +54,6 @@ public class NightDisplayTile extends QSTileImpl<BooleanState> @Override protected void handleClick() { final boolean activated = !mState.value; - MetricsLogger.action(mContext, getMetricsCategory(), activated); mController.setActivated(activated); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java index 130304f8619e..fb937bd09bc2 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java @@ -79,7 +79,6 @@ public class RotationLockTile extends QSTileImpl<BooleanState> { @Override protected void handleClick() { if (mController == null) return; - MetricsLogger.action(mContext, getMetricsCategory(), !mState.value); final boolean newState = !mState.value; mController.setRotationLocked(!newState); refreshState(newState); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java index fde2e0449c4e..79b4c4a87596 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java @@ -114,7 +114,6 @@ public class WifiTile extends QSTileImpl<SignalState> { protected void handleClick() { // Secondary clicks are header clicks, just toggle. mState.copyTo(mStateBeforeClick); - MetricsLogger.action(mContext, getMetricsCategory(), !mState.value); mController.setWifiEnabled(!mState.value); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java index 5086091f7572..6c89241aebfe 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java @@ -68,7 +68,6 @@ public class WorkModeTile extends QSTileImpl<BooleanState> implements @Override public void handleClick() { - MetricsLogger.action(mContext, getMetricsCategory(), !mState.value); mProfileController.setWorkModeEnabled(!mState.value); } diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java index 6da827240f3a..d3bd89ff2e47 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java +++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java @@ -474,7 +474,7 @@ public class Recents extends SystemUI return true; } else { EventBus.getDefault().send(new ShowUserToastEvent( - R.string.recents_incompatible_app_message, Toast.LENGTH_SHORT)); + R.string.dock_non_resizeble_failed_to_dock_text, Toast.LENGTH_SHORT)); return false; } } else { diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java index a5f78322fca0..b8be5800764a 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java @@ -610,8 +610,8 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks if (mIncompatibleAppToastView == null) { mIncompatibleAppToastView = Utilities.findViewStubById(this, R.id.incompatible_app_toast_stub).inflate(); - TextView msg = (TextView) findViewById(com.android.internal.R.id.message); - msg.setText(R.string.recents_incompatible_app_message); + TextView msg = findViewById(com.android.internal.R.id.message); + msg.setText(R.string.dock_non_resizeble_failed_to_dock_text); } mIncompatibleAppToastView.setVisibility(View.VISIBLE); } else if (mIncompatibleAppToastView != null) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java index 0398f7be4cf1..21a0dc9f24e9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java @@ -76,6 +76,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G private TextView mNumChannelsView; private View mChannelDisabledView; private Switch mChannelEnabledSwitch; + private CheckSaveListener mCheckSaveListener; private NotificationGuts mGutsContainer; @@ -83,6 +84,13 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G super(context, attrs); } + // Specify a CheckSaveListener to override when/if the user's changes are committed. + public interface CheckSaveListener { + // Invoked when importance has changed and the NotificationInfo wants to try to save it. + // Listener should run saveImportance unless the change should be canceled. + void checkSave(Runnable saveImportance); + } + public interface OnSettingsClickListener { void onClick(View v, NotificationChannel channel, int appUid); } @@ -92,11 +100,14 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G final String pkg, final List<NotificationChannel> notificationChannels, OnSettingsClickListener onSettingsClick, - OnClickListener onDoneClick, final Set<String> nonBlockablePkgs) + OnClickListener onDoneClick, + CheckSaveListener checkSaveListener, + final Set<String> nonBlockablePkgs) throws RemoteException { mINotificationManager = iNotificationManager; mPkg = pkg; mNotificationChannels = notificationChannels; + mCheckSaveListener = checkSaveListener; boolean isSingleDefaultChannel = false; if (mNotificationChannels.isEmpty()) { throw new IllegalArgumentException("bindNotification requires at least one channel"); @@ -238,7 +249,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G doneButton.setOnClickListener(onDoneClick); } - public boolean hasImportanceChanged() { + private boolean hasImportanceChanged() { return mSingleNotificationChannel != null && mStartingUserImportance != getSelectedImportance(); } @@ -316,8 +327,12 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G @Override public boolean handleCloseControls(boolean save) { - if (save) { - saveImportance(); + if (save && hasImportanceChanged()) { + if (mCheckSaveListener != null) { + mCheckSaveListener.checkSave(() -> { saveImportance(); }); + } else { + saveImportance(); + } } return false; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java index 8da17fa76bd7..8ba4eb57f079 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java @@ -133,6 +133,7 @@ public class NotificationShelf extends ActivatableNotificationView implements mViewInvertHelper.update(dark); } mShelfIcons.setAmbient(dark); + updateInteractiveness(); } @Override @@ -576,7 +577,8 @@ public class NotificationShelf extends ActivatableNotificationView implements } private void updateInteractiveness() { - mInteractive = mStatusBarState == StatusBarState.KEYGUARD && mHasItemsInStableShelf; + mInteractive = mStatusBarState == StatusBarState.KEYGUARD && mHasItemsInStableShelf + && !mDark; setClickable(mInteractive); setFocusable(mInteractive); setImportantForAccessibility(mInteractive ? View.IMPORTANT_FOR_ACCESSIBILITY_YES diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java index aa0fcbd28650..be162667751b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java @@ -82,6 +82,8 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue mSystemIconArea = mStatusBar.findViewById(R.id.system_icon_area); mSignalClusterView = reinflateSignalCluster(mStatusBar); Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mSignalClusterView); + // Default to showing until we know otherwise. + showSystemIconArea(false); } @Override @@ -119,6 +121,8 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue .removeView(mNotificationIconAreaInner); } notificationIconArea.addView(mNotificationIconAreaInner); + // Default to showing until we know otherwise. + showNotificationIconArea(false); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java index 7b2e9979fb33..bdeab21afc0b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java @@ -80,6 +80,10 @@ public class DozeParameters { return getBoolean("doze.display.supported", R.bool.doze_display_state_supported); } + public boolean getDozeSuspendDisplayStateSupported() { + return mContext.getResources().getBoolean(R.bool.doze_suspend_display_state_supported); + } + public int getPulseDuration(boolean pickup) { return getPulseInDuration(pickup) + getPulseVisibleDuration() + getPulseOutDuration(); } @@ -125,7 +129,7 @@ public class DozeParameters { public boolean getSensorsWakeUpFully() { return mAmbientDisplayConfiguration.alwaysOnAvailable() && Settings.Secure.getIntForUser(mContext.getContentResolver(), - DOZE_SENSORS_WAKE_UP_FULLY, 1, UserHandle.USER_CURRENT) != 0; + DOZE_SENSORS_WAKE_UP_FULLY, 0, UserHandle.USER_CURRENT) != 0; } private boolean getBoolean(String propName, int resId) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java index b5f56c3b8182..4d99a46e2321 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java @@ -22,6 +22,7 @@ import android.util.ArrayMap; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.systemui.Dependency; import com.android.systemui.EventLogConstants; import com.android.systemui.EventLogTags; @@ -33,7 +34,7 @@ public class LockscreenGestureLogger { private ArrayMap<Integer, Integer> mLegacyMap; private LogMaker mLogMaker = new LogMaker(MetricsEvent.VIEW_UNKNOWN) .setType(MetricsEvent.TYPE_ACTION); - private MetricsLogger mMetricsLogger = new MetricsLogger(); + private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class); public LockscreenGestureLogger() { mLegacyMap = new ArrayMap<>(EventLogConstants.METRICS_GESTURE_TYPE_MAP.length); @@ -58,9 +59,4 @@ public class LockscreenGestureLogger { } return value; } - - @VisibleForTesting - void setMetricsLogger(MetricsLogger metricsLogger) { - mMetricsLogger = metricsLogger; - } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index 3f7e340eff21..a5d7c57206be 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -417,7 +417,10 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav getHomeButton().setImageDrawable(mHomeDefaultIcon); } - final boolean showImeButton = ((hints & StatusBarManager.NAVIGATION_HINT_IME_SHOWN) != 0); + // The Accessibility button always overrides the appearance of the IME switcher + final boolean showImeButton = + !mShowAccessibilityButton && ((hints & StatusBarManager.NAVIGATION_HINT_IME_SHOWN) + != 0); getImeSwitchButton().setVisibility(showImeButton ? View.VISIBLE : View.INVISIBLE); getImeSwitchButton().setImageDrawable(mImeIcon); @@ -545,8 +548,9 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav mShowAccessibilityButton = visible; mLongClickableAccessibilityButton = longClickable; if (visible) { - // Accessibility button overrides Menu button. + // Accessibility button overrides Menu and IME switcher buttons. setMenuVisibility(false, true); + getImeSwitchButton().setVisibility(View.INVISIBLE); } getAccessibilityButton().setVisibility(visible ? View.VISIBLE : View.INVISIBLE); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java index bb6c8f2e1e73..53ec8c5048ad 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -127,7 +127,6 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks, private boolean mVolumeVisible; private boolean mCurrentUserSetup; - private boolean mManagedProfileFocused = false; private boolean mManagedProfileIconVisible = false; private boolean mManagedProfileInQuietMode = false; @@ -439,45 +438,30 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks, } } - private void profileChanged(int userId) { - UserInfo user = null; - if (userId == UserHandle.USER_CURRENT) { - try { - user = ActivityManager.getService().getCurrentUser(); - } catch (RemoteException e) { - // Ignore - } - } else { - user = mUserManager.getUserInfo(userId); - } - - mManagedProfileFocused = user != null && user.isManagedProfile(); - if (DEBUG) Log.v(TAG, "profileChanged: mManagedProfileFocused: " + mManagedProfileFocused); - // Actually update the icon later when transition starts. - } - private void updateManagedProfile() { - if (DEBUG) { - Log.v(TAG, "updateManagedProfile: mManagedProfileFocused: " - + mManagedProfileFocused); - } - final boolean showIcon; - if (mManagedProfileFocused && !mKeyguardMonitor.isShowing()) { - showIcon = true; - mIconController.setIcon(mSlotManagedProfile, - R.drawable.stat_sys_managed_profile_status, - mContext.getString(R.string.accessibility_managed_profile)); - } else if (mManagedProfileInQuietMode) { - showIcon = true; - mIconController.setIcon(mSlotManagedProfile, - R.drawable.stat_sys_managed_profile_status_off, - mContext.getString(R.string.accessibility_managed_profile)); - } else { - showIcon = false; - } - if (mManagedProfileIconVisible != showIcon) { - mIconController.setIconVisibility(mSlotManagedProfile, showIcon); - mManagedProfileIconVisible = showIcon; + try { + final boolean showIcon; + final int userId = ActivityManager.getService().getLastResumedActivityUserId(); + if (mUserManager.isManagedProfile(userId) && !mKeyguardMonitor.isShowing()) { + showIcon = true; + mIconController.setIcon(mSlotManagedProfile, + R.drawable.stat_sys_managed_profile_status, + mContext.getString(R.string.accessibility_managed_profile)); + } else if (mManagedProfileInQuietMode) { + showIcon = true; + mIconController.setIcon(mSlotManagedProfile, + R.drawable.stat_sys_managed_profile_status_off, + mContext.getString(R.string.accessibility_managed_profile)); + } else { + showIcon = false; + } + if (mManagedProfileIconVisible != showIcon) { + mIconController.setIconVisibility(mSlotManagedProfile, showIcon); + mManagedProfileIconVisible = showIcon; + } + } catch (RemoteException ex) { + Log.w(TAG, "updateManagedProfile: ", ex); + // ignore } } @@ -556,35 +540,16 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks, new SynchronousUserSwitchObserver() { @Override public void onUserSwitching(int newUserId) throws RemoteException { - mHandler.post(new Runnable() { - @Override - public void run() { - mUserInfoController.reloadUserInfo(); - } - }); + mHandler.post(() -> mUserInfoController.reloadUserInfo()); } @Override public void onUserSwitchComplete(int newUserId) throws RemoteException { - mHandler.post(new Runnable() { - @Override - public void run() { - updateAlarm(); - profileChanged(newUserId); - updateQuietState(); - updateManagedProfile(); - updateForegroundInstantApps(); - } - }); - } - - @Override - public void onForegroundProfileSwitch(int newProfileId) { - mHandler.post(new Runnable() { - @Override - public void run() { - profileChanged(newProfileId); - } + mHandler.post(() -> { + updateAlarm(); + updateQuietState(); + updateManagedProfile(); + updateForegroundInstantApps(); }); } }; 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 c2a7500384b3..035fa1d53322 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -484,7 +484,7 @@ public class StatusBar extends SystemUI implements DemoMode, private ScreenPinningRequest mScreenPinningRequest; - MetricsLogger mMetricsLogger = new MetricsLogger(); + private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class); // ensure quick settings is disabled until the current user makes it through the setup wizard private boolean mUserSetup = false; @@ -748,12 +748,6 @@ public class StatusBar extends SystemUI implements DemoMode, private NavigationBarFragment mNavigationBar; private View mNavigationBarView; - @VisibleForTesting - void setMetricsLogger(MetricsLogger metricsLogger) { - mMetricsLogger = metricsLogger; - mLockscreenGestureLogger.setMetricsLogger(metricsLogger); - } - @Override public void start() { mNetworkController = Dependency.get(NetworkController.class); @@ -993,16 +987,19 @@ public class StatusBar extends SystemUI implements DemoMode, Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mNotificationIconAreaController); FragmentHostManager.get(mStatusBarWindow) .addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> { - CollapsedStatusBarFragment statusBarFragment = (CollapsedStatusBarFragment) fragment; + CollapsedStatusBarFragment statusBarFragment = + (CollapsedStatusBarFragment) fragment; statusBarFragment.initNotificationIconArea(mNotificationIconAreaController); mStatusBarView = (PhoneStatusBarView) fragment.getView(); mStatusBarView.setBar(this); mStatusBarView.setPanel(mNotificationPanel); mStatusBarView.setScrimController(mScrimController); setAreThereNotifications(); + checkBarModes(); }).getFragmentManager() .beginTransaction() - .replace(R.id.status_bar_container, new CollapsedStatusBarFragment(), CollapsedStatusBarFragment.TAG) + .replace(R.id.status_bar_container, new CollapsedStatusBarFragment(), + CollapsedStatusBarFragment.TAG) .commit(); Dependency.get(StatusBarIconController.class).addIconGroup( new IconManager((ViewGroup) mKeyguardStatusBar.findViewById(R.id.statusIcons))); @@ -5785,21 +5782,19 @@ public class StatusBar extends SystemUI implements DemoMode, startAppNotificationSettingsActivity(pkg, appUid, channel); }; final View.OnClickListener onDoneClick = (View v) -> { + saveAndCloseNotificationMenu(info, row, guts, v); + }; + final NotificationInfo.CheckSaveListener checkSaveListener = (Runnable saveImportance) -> { // If the user has security enabled, show challenge if the setting is changed. - if (info.hasImportanceChanged() - && isLockscreenPublicMode(userHandle.getIdentifier()) + if (isLockscreenPublicMode(userHandle.getIdentifier()) && (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) { - OnDismissAction dismissAction = new OnDismissAction() { - @Override - public boolean onDismiss() { - saveAndCloseNotificationMenu(info, row, guts, v); - return true; - } - }; - onLockedNotificationImportanceChange(dismissAction); + onLockedNotificationImportanceChange(() -> { + saveImportance.run(); + return true; + }); } else { - saveAndCloseNotificationMenu(info, row, guts, v); + saveImportance.run(); } }; @@ -5822,7 +5817,7 @@ public class StatusBar extends SystemUI implements DemoMode, } try { info.bindNotification(pmUser, iNotificationManager, pkg, new ArrayList(channels), - onSettingsClick, onDoneClick, mNonBlockablePkgs); + onSettingsClick, onDoneClick, checkSaveListener, mNonBlockablePkgs); } catch (RemoteException e) { Log.e(TAG, e.toString()); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedController.java index 21f9a79fda06..cae76b492527 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedController.java @@ -24,6 +24,10 @@ public interface DeviceProvisionedController extends CallbackController<DevicePr boolean isUserSetup(int currentUser); int getCurrentUser(); + default boolean isCurrentUserSetup() { + return isUserSetup(getCurrentUser()); + } + interface DeviceProvisionedListener { default void onDeviceProvisionedChanged() { } default void onUserSwitched() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java index 3ee01de66fd5..21a96e2ea06a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java @@ -19,6 +19,7 @@ package com.android.systemui.statusbar.policy; import android.annotation.Nullable; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; +import android.view.Gravity; /** * Drawable for {@link KeyButtonView}s which contains an asset for both normal mode and light @@ -40,6 +41,9 @@ public class KeyButtonDrawable extends LayerDrawable { private KeyButtonDrawable(Drawable[] drawables) { super(drawables); + for (int i = 0; i < drawables.length; i++) { + setLayerGravity(i, Gravity.CENTER); + } mutate(); mHasDarkDrawable = drawables.length > 1; setDarkIntensity(0f); diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java index cdbde5e8b0e1..5771b2819f37 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java @@ -228,7 +228,7 @@ public class DozeMachineTest { mMachine.requestState(DOZE_AOD); - assertEquals(Display.STATE_DOZE, mServiceFake.screenState); + assertEquals(Display.STATE_DOZE_SUSPEND, mServiceFake.screenState); } @Test @@ -258,7 +258,7 @@ public class DozeMachineTest { mMachine.requestState(DOZE_AOD); mMachine.requestState(DOZE_REQUEST_PULSE); - assertEquals(Display.STATE_DOZE, mServiceFake.screenState); + assertEquals(Display.STATE_DOZE_SUSPEND, mServiceFake.screenState); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapterTest.java new file mode 100644 index 000000000000..2e3df2ceaefc --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapterTest.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2017 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.doze; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.support.test.filters.SmallTest; +import android.view.Display; + +import com.android.systemui.statusbar.phone.DozeParameters; + +import org.junit.Before; +import org.junit.Test; + +@SmallTest +public class DozeSuspendScreenStatePreventingAdapterTest { + + private DozeMachine.Service mInner; + private DozeSuspendScreenStatePreventingAdapter mWrapper; + + @Before + public void setup() throws Exception { + mInner = mock(DozeMachine.Service.class); + mWrapper = new DozeSuspendScreenStatePreventingAdapter(mInner); + } + + @Test + public void forwards_finish() throws Exception { + mWrapper.finish(); + verify(mInner).finish(); + } + + @Test + public void forwards_setDozeScreenState_on() throws Exception { + mWrapper.setDozeScreenState(Display.STATE_ON); + verify(mInner).setDozeScreenState(Display.STATE_ON); + } + + @Test + public void forwards_setDozeScreenState_off() throws Exception { + mWrapper.setDozeScreenState(Display.STATE_OFF); + verify(mInner).setDozeScreenState(Display.STATE_OFF); + } + + @Test + public void forwards_setDozeScreenState_doze() throws Exception { + mWrapper.setDozeScreenState(Display.STATE_DOZE); + verify(mInner).setDozeScreenState(Display.STATE_DOZE); + } + + @Test + public void forwards_setDozeScreenState_doze_suspend() throws Exception { + mWrapper.setDozeScreenState(Display.STATE_DOZE_SUSPEND); + verify(mInner).setDozeScreenState(Display.STATE_DOZE); + } + + @Test + public void forwards_requestWakeUp() throws Exception { + mWrapper.requestWakeUp(); + verify(mInner).requestWakeUp(); + } + + @Test + public void wrapIfNeeded_needed() throws Exception { + DozeParameters params = mock(DozeParameters.class); + when(params.getDozeSuspendDisplayStateSupported()).thenReturn(false); + + assertEquals(DozeSuspendScreenStatePreventingAdapter.class, + DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded(mInner, params).getClass()); + } + + @Test + public void wrapIfNeeded_not_needed() throws Exception { + DozeParameters params = mock(DozeParameters.class); + when(params.getDozeSuspendDisplayStateSupported()).thenReturn(true); + + assertSame(mInner, DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded(mInner, params)); + } +}
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java new file mode 100644 index 000000000000..c67cccc06169 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2017 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.qs; + +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_MORE_SETTINGS; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; +import android.testing.TestableLooper.RunWithLooper; +import android.testing.ViewUtils; +import android.view.LayoutInflater; +import android.view.View; + +import com.android.internal.logging.MetricsLogger; +import com.android.systemui.R; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.plugins.qs.DetailAdapter; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidTestingRunner.class) +@RunWithLooper +public class QSDetailTest extends SysuiTestCase { + + private MetricsLogger mMetricsLogger; + private QSDetail mQsDetail; + private QSPanel mQsPanel; + private QuickStatusBarHeader mQuickHeader; + private ActivityStarter mActivityStarter; + private DetailAdapter mMockDetailAdapter; + private TestableLooper mTestableLooper; + + @Before + public void setup() throws Exception { + mTestableLooper = TestableLooper.get(this); + mTestableLooper.runWithLooper(() -> { + mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class); + mActivityStarter = mDependency.injectMockDependency(ActivityStarter.class); + mQsDetail = (QSDetail) LayoutInflater.from(mContext).inflate(R.layout.qs_detail, null); + mQsPanel = mock(QSPanel.class); + mQuickHeader = mock(QuickStatusBarHeader.class); + mQsDetail.setQsPanel(mQsPanel, mQuickHeader); + + mMockDetailAdapter = mock(DetailAdapter.class); + when(mMockDetailAdapter.createDetailView(any(), any(), any())) + .thenReturn(mock(View.class)); + }); + } + + @Test + public void testShowDetail_Metrics() { + ViewUtils.attachView(mQsDetail); + mTestableLooper.processAllMessages(); + + mQsDetail.handleShowingDetail(mMockDetailAdapter, 0, 0, false); + verify(mMetricsLogger).visible(eq(mMockDetailAdapter.getMetricsCategory())); + mQsDetail.handleShowingDetail(null, 0, 0, false); + verify(mMetricsLogger).hidden(eq(mMockDetailAdapter.getMetricsCategory())); + + ViewUtils.detachView(mQsDetail); + mTestableLooper.processAllMessages(); + } + + @Test + public void testMoreSettingsButton() { + ViewUtils.attachView(mQsDetail); + mTestableLooper.processAllMessages(); + + mQsDetail.handleShowingDetail(mMockDetailAdapter, 0, 0, false); + mQsDetail.findViewById(android.R.id.button2).performClick(); + + int metricsCategory = mMockDetailAdapter.getMetricsCategory(); + verify(mMetricsLogger).action(eq(ACTION_QS_MORE_SETTINGS), eq(metricsCategory)); + + verify(mActivityStarter).postStartActivityDismissingKeyguard(any(), anyInt()); + + ViewUtils.detachView(mQsDetail); + mTestableLooper.processAllMessages(); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java new file mode 100644 index 000000000000..778ab8ef3bee --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2017 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.qs; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; +import android.testing.TestableLooper.RunWithLooper; +import android.view.LayoutInflater; +import android.view.View; + +import com.android.systemui.R; +import com.android.systemui.R.id; +import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.statusbar.policy.DeviceProvisionedController; +import com.android.systemui.utils.leaks.LeakCheckedTest; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidTestingRunner.class) +@RunWithLooper +public class QSFooterTest extends LeakCheckedTest { + + private QSFooter mFooter; + private ActivityStarter mActivityStarter; + private DeviceProvisionedController mDeviceProvisionedController; + + @Before + public void setup() throws Exception { + injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES); + mActivityStarter = mDependency.injectMockDependency(ActivityStarter.class); + mDeviceProvisionedController = mDependency.injectMockDependency( + DeviceProvisionedController.class); + TestableLooper.get(this).runWithLooper(() -> { + mFooter = (QSFooter) LayoutInflater.from(mContext).inflate(R.layout.qs_footer, null); + }); + } + + @Test + public void testSettings_UserNotSetup() { + View settingsButton = mFooter.findViewById(id.settings_button); + when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(false); + + mFooter.onClick(settingsButton); + // Verify Settings wasn't launched. + verify(mActivityStarter, never()).startActivity(any(), anyBoolean()); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java index deb31dae6840..673ffc5d0fbf 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java @@ -15,14 +15,19 @@ package com.android.systemui.qs; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; +import android.app.FragmentController; +import android.app.FragmentManagerNonConfig; import android.os.Looper; +import com.android.internal.logging.MetricsLogger; import com.android.keyguard.CarrierText; import com.android.systemui.Dependency; import com.android.systemui.R; +import android.os.Parcelable; import android.testing.AndroidTestingRunner; import com.android.systemui.SysuiBaseFragmentTest; @@ -44,12 +49,15 @@ import android.widget.FrameLayout; @RunWithLooper(setAsMainLooper = true) public class QSFragmentTest extends SysuiBaseFragmentTest { + private MetricsLogger mMockMetricsLogger; + public QSFragmentTest() { super(QSFragment.class); } @Before public void addLeakCheckDependencies() { + mMockMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class); mContext.addMockSystemService(Context.LAYOUT_INFLATER_SERVICE, new LayoutInflaterBuilder(mContext) .replace("com.android.systemui.statusbar.policy.SplitClockView", @@ -86,4 +94,23 @@ public class QSFragmentTest extends SysuiBaseFragmentTest { host.destroy(); processAllMessages(); } + + @Test + public void testSaveState() { + QSFragment qs = (QSFragment) mFragment; + + mFragments.dispatchResume(); + processAllMessages(); + + qs.setListening(true); + qs.setExpanded(true); + processAllMessages(); + recreateFragment(); + processAllMessages(); + + // Get the reference to the new fragment. + qs = (QSFragment) mFragment; + assertTrue(qs.isListening()); + assertTrue(qs.isExpanded()); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java new file mode 100644 index 000000000000..49796843af6e --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2017 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.qs; + +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.verify; + +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; +import android.testing.TestableLooper.RunWithLooper; + +import com.android.internal.logging.MetricsLogger; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.qs.customize.QSCustomizer; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Collections; + +@RunWith(AndroidTestingRunner.class) +@RunWithLooper +public class QSPanelTest extends SysuiTestCase { + + private MetricsLogger mMetricsLogger; + private QSPanel mQsPanel; + private QSTileHost mHost; + private QSCustomizer mCustomizer; + + @Before + public void setup() throws Exception { + TestableLooper.get(this).runWithLooper(() -> { + mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class); + mQsPanel = new QSPanel(mContext, null); + mHost = mock(QSTileHost.class); + when(mHost.getTiles()).thenReturn(Collections.emptyList()); + mCustomizer = mock(QSCustomizer.class); + mQsPanel.setHost(mHost, mCustomizer); + }); + } + + @Test + public void testSetExpanded_Metrics() { + mQsPanel.setExpanded(true); + verify(mMetricsLogger).visibility(eq(MetricsEvent.QS_PANEL), eq(true)); + mQsPanel.setExpanded(false); + verify(mMetricsLogger).visibility(eq(MetricsEvent.QS_PANEL), eq(false)); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java new file mode 100644 index 000000000000..6e7d99e49ec1 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2017 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.qs.customize; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; +import android.testing.TestableLooper.RunWithLooper; + +import com.android.systemui.SysuiTestCase; +import com.android.systemui.qs.QSTileHost; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Collections; + +@RunWith(AndroidTestingRunner.class) +@RunWithLooper +public class TileAdapterTest extends SysuiTestCase { + + private TileAdapter mTileAdapter; + + @Before + public void setup() throws Exception { + TestableLooper.get(this).runWithLooper(() -> mTileAdapter = new TileAdapter(mContext)); + } + + @Test + public void testResetNotifiesHost() { + QSTileHost host = mock(QSTileHost.class); + mTileAdapter.resetTileSpecs(host, Collections.emptyList()); + verify(host).changeTiles(any(), any()); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest.java new file mode 100644 index 000000000000..59483f2df5bb --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2017 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.qs.tileimpl; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.res.ColorStateList; +import android.graphics.drawable.Drawable; +import android.service.quicksettings.Tile; +import android.testing.AndroidTestingRunner; +import android.testing.UiThreadTest; +import android.widget.ImageView; + +import com.android.systemui.SysuiTestCase; +import com.android.systemui.plugins.qs.QSTile.Icon; +import com.android.systemui.plugins.qs.QSTile.State; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentMatcher; + +@RunWith(AndroidTestingRunner.class) +@UiThreadTest +public class QSIconViewImplTest extends SysuiTestCase { + + private QSIconViewImpl mIconView; + + @Before + public void setup() { + mIconView = new QSIconViewImpl(mContext); + } + + @Test + public void testNoFirstAnimation() { + ImageView iv = mock(ImageView.class); + State s = new State(); + when(iv.isShown()).thenReturn(true); + + // No current icon, only the static drawable should be used. + s.icon = mock(Icon.class); + when(iv.getDrawable()).thenReturn(null); + mIconView.updateIcon(iv, s); + verify(s.icon, never()).getDrawable(any()); + verify(s.icon).getInvisibleDrawable(any()); + + // Has icon, should use the standard (animated) form. + s.icon = mock(Icon.class); + when(iv.getDrawable()).thenReturn(mock(Drawable.class)); + mIconView.updateIcon(iv, s); + verify(s.icon).getDrawable(any()); + verify(s.icon, never()).getInvisibleDrawable(any()); + } + + @Test + public void testNoFirstFade() { + ImageView iv = mock(ImageView.class); + State s = new State(); + s.state = Tile.STATE_ACTIVE; + int desiredColor = mIconView.getColor(s.state); + when(iv.isShown()).thenReturn(true); + + mIconView.setIcon(iv, s); + verify(iv).setImageTintList(argThat(stateList -> stateList.getColors()[0] == desiredColor)); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java new file mode 100644 index 000000000000..9ed9d28cd96c --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2017 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.qs.tileimpl; + +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_CLICK; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_LONG_PRESS; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_SECONDARY_CLICK; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_QS_POSITION; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_QS_VALUE; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_ACTION; + +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Matchers.argThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Intent; +import android.metrics.LogMaker; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; +import android.testing.TestableLooper.RunWithLooper; + +import com.android.internal.logging.MetricsLogger; +import com.android.systemui.Dependency; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.plugins.qs.QSTile; +import com.android.systemui.qs.QSHost; +import com.android.systemui.qs.QSTileHost; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentMatcher; + +@RunWith(AndroidTestingRunner.class) +@RunWithLooper +public class QSTileImplTest extends SysuiTestCase { + + public static final int POSITION = 14; + private TestableLooper mTestableLooper; + private TileImpl mTile; + private QSTileHost mHost; + private MetricsLogger mMetricsLogger; + + @Before + public void setup() throws Exception { + String spec = "spec"; + mTestableLooper = TestableLooper.get(this); + mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper()); + mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class); + mHost = mock(QSTileHost.class); + when(mHost.indexOf(spec)).thenReturn(POSITION); + mTestableLooper.runWithLooper(() -> { + mTile = new TileImpl(mHost); + mTile.setTileSpec(spec); + }); + } + + @Test + public void testClick_Metrics() { + mTile.click(); + verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_CLICK))); + } + + @Test + public void testSecondaryClick_Metrics() { + mTile.secondaryClick(); + verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_SECONDARY_CLICK))); + } + + @Test + public void testLongClick_Metrics() { + mTile.longClick(); + verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_LONG_PRESS))); + } + + @Test + public void testPopulate() { + LogMaker maker = mock(LogMaker.class); + when(maker.setSubtype(anyInt())).thenReturn(maker); + mTile.getState().value = true; + mTile.populate(maker); + verify(maker).addTaggedData(eq(FIELD_QS_VALUE), eq(1)); + verify(maker).addTaggedData(eq(FIELD_QS_POSITION), eq(POSITION)); + } + + private class TileLogMatcher implements ArgumentMatcher<LogMaker> { + + private final int mCategory; + public String mInvalid; + + public TileLogMatcher(int category) { + mCategory = category; + } + + @Override + public boolean matches(LogMaker arg) { + if (arg.getCategory() != mCategory) { + mInvalid = "Expected category " + mCategory + " but was " + arg.getCategory(); + return false; + } + if (arg.getType() != TYPE_ACTION) { + mInvalid = "Expected type " + TYPE_ACTION + " but was " + arg.getType(); + return false; + } + if (arg.getSubtype() != mTile.getMetricsCategory()) { + mInvalid = "Expected subtype " + mTile.getMetricsCategory() + " but was " + + arg.getSubtype(); + return false; + } + return true; + } + + @Override + public String toString() { + return mInvalid; + } + } + + private static class TileImpl extends QSTileImpl<QSTile.BooleanState> { + protected TileImpl(QSHost host) { + super(host); + } + + @Override + public BooleanState newTileState() { + return new BooleanState(); + } + + @Override + protected void handleClick() { + + } + + @Override + protected void handleUpdateState(BooleanState state, Object arg) { + + } + + @Override + public int getMetricsCategory() { + return 42; + } + + @Override + public Intent getLongClickIntent() { + return null; + } + + @Override + protected void setListening(boolean listening) { + + } + + @Override + public CharSequence getTileLabel() { + return null; + } + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java index 5632b719df23..21930a3d8e8d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java @@ -135,7 +135,7 @@ public class NotificationInfoTest extends SysuiTestCase { public void testBindNotification_SetsTextApplicationName() throws Exception { when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name"); mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, - TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null); + TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null); final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.pkgname); assertTrue(textView.getText().toString().contains("App Name")); } @@ -146,7 +146,7 @@ public class NotificationInfoTest extends SysuiTestCase { when(mMockPackageManager.getApplicationIcon(any(ApplicationInfo.class))) .thenReturn(iconDrawable); mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, - TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null); + TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null); final ImageView iconView = (ImageView) mNotificationInfo.findViewById(R.id.pkgicon); assertEquals(iconDrawable, iconView.getDrawable()); } @@ -154,7 +154,7 @@ public class NotificationInfoTest extends SysuiTestCase { @Test public void testBindNotification_GroupNameHiddenIfNoGroup() throws Exception { mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, - TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null); + TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null); final TextView groupNameView = (TextView) mNotificationInfo.findViewById(R.id.group_name); assertEquals(View.GONE, groupNameView.getVisibility()); final TextView groupDividerView = @@ -171,7 +171,7 @@ public class NotificationInfoTest extends SysuiTestCase { eq("test_group_id"), eq(TEST_PACKAGE_NAME), anyInt())) .thenReturn(notificationChannelGroup); mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, - TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null); + TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null); final TextView groupNameView = (TextView) mNotificationInfo.findViewById(R.id.group_name); assertEquals(View.VISIBLE, groupNameView.getVisibility()); assertEquals("Test Group Name", groupNameView.getText()); @@ -183,7 +183,7 @@ public class NotificationInfoTest extends SysuiTestCase { @Test public void testBindNotification_SetsTextChannelName() throws Exception { mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, - TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null); + TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null); final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.channel_name); assertEquals(TEST_CHANNEL_NAME, textView.getText()); } @@ -196,7 +196,7 @@ public class NotificationInfoTest extends SysuiTestCase { (View v, NotificationChannel c, int appUid) -> { assertEquals(mNotificationChannel, c); latch.countDown(); - }, null, null); + }, null, null, null); final TextView settingsButton = (TextView) mNotificationInfo.findViewById(R.id.more_settings); @@ -214,7 +214,7 @@ public class NotificationInfoTest extends SysuiTestCase { (View v, NotificationChannel c, int appUid) -> { assertEquals(null, c); latch.countDown(); - }, null, null); + }, null, null, null); final TextView settingsButton = (TextView) mNotificationInfo.findViewById(R.id.more_settings); @@ -227,7 +227,7 @@ public class NotificationInfoTest extends SysuiTestCase { public void testBindNotification_SettingsTextWithOneChannel() throws Exception { mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), - (View v, NotificationChannel c, int appUid) -> {}, null, null); + (View v, NotificationChannel c, int appUid) -> {}, null, null, null); final TextView settingsButton = (TextView) mNotificationInfo.findViewById(R.id.more_settings); assertEquals(getStringById(R.string.notification_more_settings), settingsButton.getText()); @@ -239,7 +239,7 @@ public class NotificationInfoTest extends SysuiTestCase { eq(TEST_PACKAGE_NAME), anyInt(), anyBoolean())).thenReturn(2); mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), - (View v, NotificationChannel c, int appUid) -> {}, null, null); + (View v, NotificationChannel c, int appUid) -> {}, null, null, null); final TextView settingsButton = (TextView) mNotificationInfo.findViewById(R.id.more_settings); assertEquals(getStringById(R.string.notification_all_categories), settingsButton.getText()); @@ -251,7 +251,7 @@ public class NotificationInfoTest extends SysuiTestCase { mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, (View v) -> { latch.countDown(); }, - null); + null, null); final TextView doneButton = (TextView) mNotificationInfo.findViewById(R.id.done); doneButton.performClick(); @@ -262,7 +262,8 @@ public class NotificationInfoTest extends SysuiTestCase { @Test public void testBindNotification_NumChannelsTextUniqueWhenDefaultChannel() throws Exception { mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, - TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel), null, null, null); + TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel), + null, null, null, null); final TextView numChannelsView = (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc); assertEquals(View.VISIBLE, numChannelsView.getVisibility()); @@ -274,7 +275,7 @@ public class NotificationInfoTest extends SysuiTestCase { public void testBindNotification_NumChannelsTextDisplaysWhenNotDefaultChannel() throws Exception { mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, - TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null); + TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null); final TextView numChannelsView = (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc); assertEquals(numChannelsView.getVisibility(), View.VISIBLE); @@ -287,7 +288,7 @@ public class NotificationInfoTest extends SysuiTestCase { when(mMockINotificationManager.getNumNotificationChannelsForPackage( eq(TEST_PACKAGE_NAME), anyInt(), anyBoolean())).thenReturn(2); mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, - TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null); + TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null); final TextView numChannelsView = (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc); assertEquals(getNumChannelsDescString(2), numChannelsView.getText()); @@ -299,7 +300,7 @@ public class NotificationInfoTest extends SysuiTestCase { throws Exception { mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel, mDefaultNotificationChannel), - null, null, null); + null, null, null, null); final TextView numChannelsView = (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc); assertEquals(getChannelsListDescString(mNotificationChannel, mDefaultNotificationChannel), @@ -315,7 +316,7 @@ public class NotificationInfoTest extends SysuiTestCase { mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel, mDefaultNotificationChannel, thirdChannel), - null, null, null); + null, null, null, null); final TextView numChannelsView = (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc); assertEquals( @@ -336,7 +337,7 @@ public class NotificationInfoTest extends SysuiTestCase { TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel, mDefaultNotificationChannel, thirdChannel, fourthChannel), - null, null, null); + null, null, null, null); final TextView numChannelsView = (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc); assertEquals( @@ -351,7 +352,7 @@ public class NotificationInfoTest extends SysuiTestCase { throws Exception { mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel, mDefaultNotificationChannel), - null, null, null); + null, null, null, null); final TextView channelNameView = (TextView) mNotificationInfo.findViewById(R.id.channel_name); assertEquals(getNumChannelsString(2), channelNameView.getText()); @@ -362,7 +363,7 @@ public class NotificationInfoTest extends SysuiTestCase { public void testEnabledSwitchInvisibleIfBundleFromDifferentChannels() throws Exception { mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel, mDefaultNotificationChannel), - null, null, null); + null, null, null, null); Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch); assertEquals(View.INVISIBLE, enabledSwitch.getVisibility()); } @@ -370,7 +371,7 @@ public class NotificationInfoTest extends SysuiTestCase { @Test public void testbindNotification_ChannelDisabledTextGoneWhenNotDisabled() throws Exception { mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, - TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null); + TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null); final TextView channelDisabledView = (TextView) mNotificationInfo.findViewById(R.id.channel_disabled); assertEquals(channelDisabledView.getVisibility(), View.GONE); @@ -380,7 +381,7 @@ public class NotificationInfoTest extends SysuiTestCase { public void testbindNotification_ChannelDisabledTextVisibleWhenDisabled() throws Exception { mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_NONE); mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, - TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null); + TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null); final TextView channelDisabledView = (TextView) mNotificationInfo.findViewById(R.id.channel_disabled); assertEquals(channelDisabledView.getVisibility(), View.VISIBLE); @@ -396,35 +397,17 @@ public class NotificationInfoTest extends SysuiTestCase { throws Exception { mDefaultNotificationChannel.setImportance(NotificationManager.IMPORTANCE_NONE); mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, - TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel), null, null, null); + TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel), + null, null, null, null); final TextView channelDisabledView = (TextView) mNotificationInfo.findViewById(R.id.channel_disabled); assertEquals(View.VISIBLE, channelDisabledView.getVisibility()); } @Test - @UiThreadTest - public void testHasImportanceChanged_DefaultsToFalse() throws Exception { - mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, - TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null); - assertFalse(mNotificationInfo.hasImportanceChanged()); - } - - @Test - public void testHasImportanceChanged_ReturnsTrueAfterChannelDisabled() throws Exception { - mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW); - mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, - TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null); - // Find the high button and check it. - Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch); - enabledSwitch.setChecked(false); - assertTrue(mNotificationInfo.hasImportanceChanged()); - } - - @Test public void testBindNotification_DoesNotUpdateNotificationChannel() throws Exception { mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, - TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null); + TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null); verify(mMockINotificationManager, never()).updateNotificationChannelForPackage( anyString(), anyInt(), any()); } @@ -433,7 +416,7 @@ public class NotificationInfoTest extends SysuiTestCase { public void testDoesNotUpdateNotificationChannelAfterImportanceChanged() throws Exception { mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW); mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, - TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null); + TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null); Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch); enabledSwitch.setChecked(false); @@ -445,7 +428,7 @@ public class NotificationInfoTest extends SysuiTestCase { public void testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnchanged() throws Exception { mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, - TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null); + TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null); mNotificationInfo.handleCloseControls(true); verify(mMockINotificationManager, never()).updateNotificationChannelForPackage( @@ -457,7 +440,7 @@ public class NotificationInfoTest extends SysuiTestCase { throws Exception { mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_UNSPECIFIED); mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, - TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null); + TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null); mNotificationInfo.handleCloseControls(true); verify(mMockINotificationManager, never()).updateNotificationChannelForPackage( @@ -468,7 +451,7 @@ public class NotificationInfoTest extends SysuiTestCase { public void testEnabledSwitchOnByDefault() throws Exception { mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW); mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, - TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null); + TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null); Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch); assertTrue(enabledSwitch.isChecked()); @@ -478,7 +461,7 @@ public class NotificationInfoTest extends SysuiTestCase { public void testEnabledButtonOffWhenAlreadyBanned() throws Exception { mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_NONE); mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, - TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null); + TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null); Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch); assertFalse(enabledSwitch.isChecked()); @@ -488,7 +471,7 @@ public class NotificationInfoTest extends SysuiTestCase { public void testEnabledSwitchVisibleByDefault() throws Exception { mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW); mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, - TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null); + TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null); Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch); assertEquals(View.VISIBLE, enabledSwitch.getVisibility()); @@ -498,7 +481,7 @@ public class NotificationInfoTest extends SysuiTestCase { public void testEnabledSwitchInvisibleIfNonBlockable() throws Exception { mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW); mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, - TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, + TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, Collections.singleton(TEST_PACKAGE_NAME)); Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch); @@ -509,7 +492,7 @@ public class NotificationInfoTest extends SysuiTestCase { public void testNonBlockableAppDoesNotBecomeBlocked() throws Exception { mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW); mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, - TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, + TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, Collections.singleton(TEST_PACKAGE_NAME)); mNotificationInfo.handleCloseControls(true); verify(mMockINotificationManager, never()).updateNotificationChannelForPackage( @@ -520,7 +503,7 @@ public class NotificationInfoTest extends SysuiTestCase { public void testEnabledSwitchChangedCallsUpdateNotificationChannel() throws Exception { mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW); mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, - TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, + TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, Collections.singleton(TEST_PACKAGE_NAME)); Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch); @@ -534,7 +517,7 @@ public class NotificationInfoTest extends SysuiTestCase { public void testCloseControlsDoesNotUpdateIfSaveIsFalse() throws Exception { mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW); mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, - TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, + TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, Collections.singleton(TEST_PACKAGE_NAME)); Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch); @@ -543,4 +526,34 @@ public class NotificationInfoTest extends SysuiTestCase { verify(mMockINotificationManager, never()).updateNotificationChannelForPackage( eq(TEST_PACKAGE_NAME), anyInt(), eq(mNotificationChannel)); } + + @Test + public void testCloseControlsDoesNotUpdateIfCheckSaveListenerIsNoOp() throws Exception { + mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW); + mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, + TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, + (Runnable saveImportance) -> {}, + Collections.singleton(TEST_PACKAGE_NAME)); + + Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch); + enabledSwitch.setChecked(false); + mNotificationInfo.handleCloseControls(true); + verify(mMockINotificationManager, never()).updateNotificationChannelForPackage( + eq(TEST_PACKAGE_NAME), anyInt(), eq(mNotificationChannel)); + } + + @Test + public void testCloseControlsUpdatesWhenCheckSaveListenerUsesCallback() throws Exception { + mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW); + mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, + TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, + (Runnable saveImportance) -> { saveImportance.run(); }, + Collections.singleton(TEST_PACKAGE_NAME)); + + Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch); + enabledSwitch.setChecked(false); + mNotificationInfo.handleCloseControls(true); + verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage( + eq(TEST_PACKAGE_NAME), anyInt(), eq(mNotificationChannel)); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java index a9acda305663..6ddbffccaa96 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.phone; import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -104,6 +105,6 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { fragment.disable(0, 0, false); - Mockito.verify(mNotificationAreaInner).setVisibility(eq(View.VISIBLE)); + Mockito.verify(mNotificationAreaInner, atLeast(1)).setVisibility(eq(View.VISIBLE)); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java index f48af7557593..bf6b3946d101 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java @@ -62,9 +62,9 @@ public class StatusBarTest extends SysuiTestCase { mKeyguardIndicationController = mock(KeyguardIndicationController.class); mStackScroller = mock(NotificationStackScrollLayout.class); mMetricsLogger = new FakeMetricsLogger(); + mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger); mStatusBar = new TestableStatusBar(mStatusBarKeyguardViewManager, mUnlockMethodCache, mKeyguardIndicationController, mStackScroller); - mStatusBar.setMetricsLogger(mMetricsLogger); doAnswer(invocation -> { OnDismissAction onDismissAction = (OnDismissAction) invocation.getArguments()[0]; diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto index 783aae7121ad..e8d9b7025498 100644 --- a/proto/src/metrics_constants.proto +++ b/proto/src/metrics_constants.proto @@ -3656,7 +3656,7 @@ message MetricsEvent { ACTION_SETTINGS_MASTER_SWITCH_BLUETOOTH_TOGGLE = 870; // The name of the activity being launched in an app transition event. - APP_TRANSITION_ACTIVITY_NAME = 871; + FIELD_CLASS_NAME = 871; // ACTION: Settings > App detail > Uninstall ACTION_SETTINGS_UNINSTALL_APP = 872; @@ -3874,6 +3874,29 @@ message MetricsEvent { // OPEN: Settings -> System -> Reset options RESET_DASHBOARD = 924; + // ACTION: QS -> Tile clicked + ACTION_QS_CLICK = 925; + + // ACTION: QS -> Secondary click + ACTION_QS_SECONDARY_CLICK = 926; + + // FIELD: Position info in QS clicks + FIELD_QS_POSITION = 927; + + // FIELD: The value of a QS tile when clicked (if applicable) + FIELD_QS_VALUE = 928; + + // ACTION: QS -> Detail panel -> more settings + ACTION_QS_MORE_SETTINGS = 929; + + // ACTION: QS -> Click date + ACTION_QS_DATE = 930; + + // OPEN: Settings > Storage > Movies & TV + // CATEGORY: SETTINGS + // OS: O + APPLICATIONS_STORAGE_MOVIES = 931; + // ---- End O Constants, all O constants go above this line ---- // Add new aosp constants above this line. diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 05c659292e69..acaae7b298dd 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -52,6 +52,7 @@ import android.graphics.Region; import android.hardware.display.DisplayManager; import android.hardware.fingerprint.IFingerprintService; import android.hardware.input.InputManager; +import android.media.AudioManagerInternal; import android.net.Uri; import android.os.Binder; import android.os.Build; @@ -75,6 +76,7 @@ import android.provider.SettingsStringUtil.ComponentNameSet; import android.provider.SettingsStringUtil.SettingStringHelper; import android.text.TextUtils; import android.text.TextUtils.SimpleStringSplitter; +import android.util.IntArray; import android.util.Slog; import android.util.SparseArray; import android.view.Display; @@ -220,6 +222,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { private final List<AccessibilityServiceInfo> mTempAccessibilityServiceInfoList = new ArrayList<>(); + private final IntArray mTempIntArray = new IntArray(0); + private final RemoteCallbackList<IAccessibilityManagerClient> mGlobalClients = new RemoteCallbackList<>(); @@ -1558,6 +1562,21 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } } + final int count = userState.mBoundServices.size(); + mTempIntArray.clear(); + for (int i = 0; i < count; i++) { + final ResolveInfo resolveInfo = + userState.mBoundServices.get(i).mAccessibilityServiceInfo.getResolveInfo(); + if (resolveInfo != null) { + mTempIntArray.add(resolveInfo.serviceInfo.applicationInfo.uid); + } + } + // Calling out with lock held, but to a lower-level service + final AudioManagerInternal audioManager = + LocalServices.getService(AudioManagerInternal.class); + if (audioManager != null) { + audioManager.setAccessibilityServiceUids(mTempIntArray); + } updateAccessibilityEnabledSetting(userState); } diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java index 4d783503cb5f..3d1c2511db27 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java @@ -19,15 +19,10 @@ package com.android.server.autofill; import static android.service.autofill.AutofillService.EXTRA_ACTIVITY_TOKEN; import static android.service.voice.VoiceInteractionSession.KEY_RECEIVER_EXTRAS; import static android.service.voice.VoiceInteractionSession.KEY_STRUCTURE; -import static android.view.autofill.AutofillManager.FLAG_VIEW_ENTERED; -import static android.view.autofill.AutofillManager.FLAG_VIEW_EXITED; import static android.view.autofill.AutofillManager.FLAG_START_SESSION; -import static android.view.autofill.AutofillManager.FLAG_VALUE_CHANGED; -import static android.view.autofill.AutofillManager.FLAG_MANUAL_REQUEST; import static com.android.server.autofill.Helper.DEBUG; import static com.android.server.autofill.Helper.VERBOSE; -import static com.android.server.autofill.Helper.findValue; import android.annotation.NonNull; import android.annotation.Nullable; @@ -35,32 +30,23 @@ import android.app.Activity; import android.app.ActivityManager; import android.app.AppGlobals; import android.app.assist.AssistStructure; -import android.app.assist.AssistStructure.ViewNode; -import android.app.assist.AssistStructure.WindowNode; import android.content.ComponentName; import android.content.Context; -import android.content.Intent; -import android.content.IntentSender; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; import android.graphics.Rect; -import android.metrics.LogMaker; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.os.Looper; -import android.os.Parcelable; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.UserManager; import android.provider.Settings; import android.service.autofill.AutofillService; import android.service.autofill.AutofillServiceInfo; -import android.service.autofill.Dataset; -import android.service.autofill.FillResponse; import android.service.autofill.IAutoFillService; -import android.service.autofill.SaveInfo; import android.text.TextUtils; import android.util.ArrayMap; import android.util.LocalLog; @@ -68,21 +54,16 @@ import android.util.Log; import android.util.PrintWriterPrinter; import android.util.Slog; import android.view.autofill.AutofillId; -import android.view.autofill.AutofillManager; import android.view.autofill.AutofillValue; import android.view.autofill.IAutoFillManagerClient; -import android.view.autofill.IAutofillWindowPresenter; + import com.android.internal.annotations.GuardedBy; -import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.nano.MetricsProto; import com.android.internal.os.HandlerCaller; import com.android.internal.os.IResultReceiver; import com.android.server.autofill.ui.AutoFillUI; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.Map; -import java.util.Map.Entry; /** * Bridge between the {@code system_server}'s {@link AutofillManagerService} and the @@ -93,13 +74,12 @@ final class AutofillManagerServiceImpl { private static final String TAG = "AutofillManagerServiceImpl"; - private static final int MSG_SERVICE_SAVE = 1; + static final int MSG_SERVICE_SAVE = 1; private final int mUserId; private final Context mContext; private final Object mLock; private final AutoFillUI mUi; - private final MetricsLogger mMetricsLogger = new MetricsLogger(); private RemoteCallbackList<IAutoFillManagerClient> mClients; private AutofillServiceInfo mInfo; @@ -358,8 +338,9 @@ final class AutofillManagerServiceImpl { private Session createSessionByTokenLocked(@NonNull IBinder activityToken, @Nullable IBinder windowToken, @NonNull IBinder appCallbackToken, boolean hasCallback, int flags, @NonNull String packageName) { - final Session newSession = new Session(mContext, activityToken, - windowToken, appCallbackToken, hasCallback, flags, packageName); + final Session newSession = new Session(this, mUi, mContext, mHandlerCaller, mUserId, mLock, + activityToken, windowToken, appCallbackToken, hasCallback, flags, + mInfo.getServiceInfo().getComponentName(), packageName); mSessions.put(activityToken, newSession); /* @@ -400,6 +381,10 @@ final class AutofillManagerServiceImpl { session.updateLocked(autofillId, virtualBounds, value, flags); } + void removeSessionLocked(IBinder activityToken) { + mSessions.remove(activityToken); + } + private void handleSessionSave(IBinder activityToken) { synchronized (mLock) { final Session session = mSessions.get(activityToken); @@ -423,6 +408,25 @@ final class AutofillManagerServiceImpl { mSessions.clear(); } + void disableSelf() { + final long identity = Binder.clearCallingIdentity(); + try { + final String autoFillService = Settings.Secure.getStringForUser( + mContext.getContentResolver(), Settings.Secure.AUTOFILL_SERVICE, mUserId); + if (mInfo.getServiceInfo().getComponentName().equals( + ComponentName.unflattenFromString(autoFillService))) { + Settings.Secure.putStringForUser(mContext.getContentResolver(), + Settings.Secure.AUTOFILL_SERVICE, null, mUserId); + } + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + CharSequence getServiceLabel() { + return mInfo.getServiceInfo().loadLabel(mContext.getPackageManager()); + } + void dumpLocked(String prefix, PrintWriter pw) { final String prefix2 = prefix + " "; @@ -495,804 +499,4 @@ final class AutofillManagerServiceImpl { + ", component=" + (mInfo != null ? mInfo.getServiceInfo().getComponentName() : null) + "]"; } - - /** - * State for a given view with a AutofillId. - * - * <p>This class holds state about a view and calls its listener when the fill UI is ready to - * be displayed for the view. - */ - static final class ViewState { - interface Listener { - /** - * Called when the fill UI is ready to be shown for this view. - */ - void onFillReady(FillResponse fillResponse, AutofillId focusedId, - @Nullable AutofillValue value); - } - - final AutofillId mId; - private final Listener mListener; - // TODO(b/33197203): would not need a reference to response and session if it was an inner - // class of Session... - private final Session mSession; - // TODO(b/33197203): encapsulate access so it's not called by UI - FillResponse mResponse; - Intent mAuthIntent; - - private AutofillValue mAutofillValue; - - // Bounds if a virtual view, null otherwise - private Rect mVirtualBounds; - - private boolean mValueUpdated; - - ViewState(Session session, AutofillId id, Listener listener) { - mSession = session; - mId = id; - mListener = listener; - } - - /** - * Response should only be set once. - */ - void setResponse(FillResponse response) { - mResponse = response; - maybeCallOnFillReady(); - } - - /** - * Used when a {@link FillResponse} requires authentication to be unlocked. - */ - void setResponse(FillResponse response, Intent authIntent) { - mAuthIntent = authIntent; - setResponse(response); - } - - CharSequence getServiceName() { - return mSession.getServiceName(); - } - - // TODO(b/33197203): need to refactor / rename / document this method to make it clear that - // it can change the value and update the UI; similarly, should replace code that - // directly sets mAutoFilLValue to use encapsulation. - void update(@Nullable AutofillValue autofillValue, @Nullable Rect virtualBounds) { - if (autofillValue != null) { - mAutofillValue = autofillValue; - } - if (virtualBounds != null) { - mVirtualBounds = virtualBounds; - } - - maybeCallOnFillReady(); - } - - /** - * Calls {@link - * Listener#onFillReady(FillResponse, AutofillId, AutofillValue)} if the - * fill UI is ready to be displayed (i.e. when response and bounds are set). - */ - void maybeCallOnFillReady() { - if (mResponse != null && (mResponse.getAuthentication() != null - || mResponse.getDatasets() != null)) { - mListener.onFillReady(mResponse, mId, mAutofillValue); - } - } - - @Override - public String toString() { - return "ViewState: [id=" + mId + ", value=" + mAutofillValue + ", bounds=" + mVirtualBounds - + ", updated = " + mValueUpdated + "]"; - } - - void dump(String prefix, PrintWriter pw) { - pw.print(prefix); pw.print("id:" ); pw.println(mId); - pw.print(prefix); pw.print("value:" ); pw.println(mAutofillValue); - pw.print(prefix); pw.print("updated:" ); pw.println(mValueUpdated); - pw.print(prefix); pw.print("virtualBounds:" ); pw.println(mVirtualBounds); - pw.print(prefix); pw.print("authIntent:" ); pw.println(mAuthIntent); - } - } - - /** - * A session for a given activity. - * - * <p>This class manages the multiple {@link ViewState}s for each view it has, and keeps track - * of the current {@link ViewState} to display the appropriate UI. - * - * <p>Although the autofill requests and callbacks are stateless from the service's point of - * view, we need to keep state in the framework side for cases such as authentication. For - * example, when service return a {@link FillResponse} that contains all the fields needed - * to fill the activity but it requires authentication first, that response need to be held - * until the user authenticates or it times out. - */ - // TODO(b/33197203): make sure sessions are removed (and tested by CTS): - // - On all authentication scenarios. - // - When user does not interact back after a while. - // - When service is unbound. - final class Session implements RemoteFillService.FillServiceCallbacks, ViewState.Listener, - AutoFillUI.AutoFillUiCallback { - private final IBinder mActivityToken; - private final IBinder mWindowToken; - - /** Package name of the app that is auto-filled */ - @NonNull private final String mPackageName; - - @GuardedBy("mLock") - private final Map<AutofillId, ViewState> mViewStates = new ArrayMap<>(); - - @GuardedBy("mLock") - @Nullable - private ViewState mCurrentViewState; - - private final IAutoFillManagerClient mClient; - - @GuardedBy("mLock") - RemoteFillService mRemoteFillService; - - // TODO(b/33197203): Get a response per view instead of per activity. - @GuardedBy("mLock") - private FillResponse mCurrentResponse; - - /** - * Used to remember which {@link Dataset} filled the session. - */ - // TODO(b/33197203): might need more than one once we support partitions - @GuardedBy("mLock") - private Dataset mAutoFilledDataset; - - /** - * Assist structure sent by the app; it will be updated (sanitized, change values for save) - * before sent to {@link AutofillService}. - */ - @GuardedBy("mLock") - private AssistStructure mStructure; - - /** - * Whether the client has an {@link android.view.autofill.AutofillManager.AutofillCallback}. - */ - private boolean mHasCallback; - - /** - * Flags used to start the session. - */ - private int mFlags; - private Session(@NonNull Context context, @NonNull IBinder activityToken, - @Nullable IBinder windowToken, @NonNull IBinder client, boolean hasCallback, - int flags, @NonNull String packageName) { - mRemoteFillService = new RemoteFillService(context, - mInfo.getServiceInfo().getComponentName(), mUserId, this); - mActivityToken = activityToken; - mWindowToken = windowToken; - mHasCallback = hasCallback; - mFlags = flags; - mPackageName = packageName; - - mClient = IAutoFillManagerClient.Stub.asInterface(client); - try { - client.linkToDeath(() -> { - if (DEBUG) { - Slog.d(TAG, "app binder died"); - } - - removeSelf(); - }, 0); - } catch (RemoteException e) { - Slog.w(TAG, "linkToDeath() on mClient failed: " + e); - } - - mMetricsLogger.action(MetricsProto.MetricsEvent.AUTOFILL_SESSION_STARTED, mPackageName); - } - - // FillServiceCallbacks - @Override - public void onFillRequestSuccess(@Nullable FillResponse response, - @NonNull String servicePackageName) { - if (response == null) { - // Nothing to be done, but need to notify client. - notifyUnavailableToClient(); - removeSelf(); - return; - } - - if ((response.getDatasets() == null || response.getDatasets().isEmpty()) - && response.getAuthentication() == null) { - // Response is "empty" from an UI point of view, need to notify client. - notifyUnavailableToClient(); - } - synchronized (mLock) { - processResponseLocked(response); - } - - LogMaker log = (new LogMaker(MetricsProto.MetricsEvent.AUTOFILL_REQUEST)) - .setType(MetricsProto.MetricsEvent.TYPE_SUCCESS) - .setPackageName(mPackageName) - .addTaggedData(MetricsProto.MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS, - response.getDatasets() == null ? 0 : response.getDatasets().size()) - .addTaggedData(MetricsProto.MetricsEvent.FIELD_AUTOFILL_SERVICE, - servicePackageName); - mMetricsLogger.write(log); - } - - // FillServiceCallbacks - @Override - public void onFillRequestFailure(@Nullable CharSequence message, - @NonNull String servicePackageName) { - LogMaker log = (new LogMaker(MetricsProto.MetricsEvent.AUTOFILL_REQUEST)) - .setType(MetricsProto.MetricsEvent.TYPE_FAILURE) - .setPackageName(mPackageName) - .addTaggedData(MetricsProto.MetricsEvent.FIELD_AUTOFILL_SERVICE, - servicePackageName); - mMetricsLogger.write(log); - - getUiForShowing().showError(message); - removeSelf(); - } - - // FillServiceCallbacks - @Override - public void onSaveRequestSuccess(@NonNull String servicePackageName) { - LogMaker log = (new LogMaker( - MetricsProto.MetricsEvent.AUTOFILL_DATA_SAVE_REQUEST)) - .setType(MetricsProto.MetricsEvent.TYPE_SUCCESS) - .setPackageName(mPackageName) - .addTaggedData(MetricsProto.MetricsEvent.FIELD_AUTOFILL_SERVICE, - servicePackageName); - mMetricsLogger.write(log); - - // Nothing left to do... - removeSelf(); - } - - // FillServiceCallbacks - @Override - public void onSaveRequestFailure(@Nullable CharSequence message, - @NonNull String servicePackageName) { - LogMaker log = (new LogMaker( - MetricsProto.MetricsEvent.AUTOFILL_DATA_SAVE_REQUEST)) - .setType(MetricsProto.MetricsEvent.TYPE_FAILURE) - .setPackageName(mPackageName) - .addTaggedData(MetricsProto.MetricsEvent.FIELD_AUTOFILL_SERVICE, - servicePackageName); - mMetricsLogger.write(log); - - getUiForShowing().showError(message); - removeSelf(); - } - - // FillServiceCallbacks - @Override - public void authenticate(IntentSender intent) { - final Intent fillInIntent; - synchronized (mLock) { - fillInIntent = createAuthFillInIntent(mStructure); - } - mHandlerCaller.getHandler().post(() -> startAuthentication(intent, fillInIntent)); - } - - // FillServiceCallbacks - @Override - public void onDisableSelf() { - final long identity = Binder.clearCallingIdentity(); - try { - final String autoFillService = Settings.Secure.getStringForUser( - mContext.getContentResolver(), - Settings.Secure.AUTOFILL_SERVICE, mUserId); - if (mInfo.getServiceInfo().getComponentName().equals( - ComponentName.unflattenFromString(autoFillService))) { - Settings.Secure.putStringForUser(mContext.getContentResolver(), - Settings.Secure.AUTOFILL_SERVICE, null, mUserId); - } - } finally { - Binder.restoreCallingIdentity(identity); - } - synchronized (mLock) { - removeSelfLocked(); - } - } - - // FillServiceCallbacks - @Override - public void onServiceDied(RemoteFillService service) { - // TODO(b/33197203): implement - } - - // AutoFillUiCallback - @Override - public void fill(Dataset dataset) { - mHandlerCaller.getHandler().post(() -> autoFill(dataset)); - } - - // AutoFillUiCallback - @Override - public void save() { - mHandlerCaller.getHandler().obtainMessage(MSG_SERVICE_SAVE, mActivityToken) - .sendToTarget(); - } - - // AutoFillUiCallback - @Override - public void cancelSave() { - mHandlerCaller.getHandler().post(() -> removeSelf()); - } - - // AutoFillUiCallback - @Override - public void requestShowFillUi(AutofillId id, int width, int height, - IAutofillWindowPresenter presenter) { - try { - mClient.requestShowFillUi(mWindowToken, id, width, height, - mCurrentViewState.mVirtualBounds, presenter); - } catch (RemoteException e) { - Slog.e(TAG, "Error requesting to show fill UI", e); - } - } - - // AutoFillUiCallback - @Override - public void requestHideFillUi(AutofillId id) { - try { - mClient.requestHideFillUi(mWindowToken, id); - } catch (RemoteException e) { - Slog.e(TAG, "Error requesting to hide fill UI", e); - } - } - - public void setAuthenticationResultLocked(Bundle data) { - if (mCurrentResponse == null || data == null) { - removeSelf(); - } else { - Parcelable result = data.getParcelable( - AutofillManager.EXTRA_AUTHENTICATION_RESULT); - if (result instanceof FillResponse) { - mMetricsLogger.action(MetricsProto.MetricsEvent.AUTOFILL_AUTHENTICATED, - mPackageName); - - mCurrentResponse = (FillResponse) result; - processResponseLocked(mCurrentResponse); - } else if (result instanceof Dataset) { - Dataset dataset = (Dataset) result; - final int index = mCurrentResponse.getDatasets().indexOf(mAutoFilledDataset); - if (index >= 0) { - mCurrentResponse.getDatasets().set(index, dataset); - autoFill(dataset); - } - } - } - } - - public void setHasCallback(boolean hasIt) { - mHasCallback = hasIt; - } - - /** - * Shows the save UI, when session can be saved. - * - * @return {@code true} if session is done, or {@code false} if it's pending user action. - */ - public boolean showSaveLocked() { - if (mStructure == null) { - Slog.wtf(TAG, "showSaveLocked(): no mStructure"); - return true; - } - if (mCurrentResponse == null) { - // Happens when the activity / session was finished before the service replied, or - // when the service cannot autofill it (and returned a null response). - if (DEBUG) { - Slog.d(TAG, "showSaveLocked(): no mCurrentResponse"); - } - return true; - } - final SaveInfo saveInfo = mCurrentResponse.getSaveInfo(); - if (DEBUG) { - Slog.d(TAG, "showSaveLocked(): saveInfo=" + saveInfo); - } - - /* - * The Save dialog is only shown if all conditions below are met: - * - * - saveInfo is not null - * - autofillValue of all required ids is not null - * - autofillValue of at least one id (required or optional) has changed. - */ - - if (saveInfo == null) { - return true; - } - - final AutofillId[] requiredIds = saveInfo.getRequiredIds(); - if (requiredIds == null || requiredIds.length == 0) { - Slog.w(TAG, "showSaveLocked(): no required ids on saveInfo"); - return true; - } - - boolean allRequiredAreNotEmpty = true; - boolean atLeastOneChanged = false; - for (int i = 0; i < requiredIds.length; i++) { - final AutofillId id = requiredIds[i]; - final ViewState state = mViewStates.get(id); - if (state == null || state.mAutofillValue == null - || state.mAutofillValue.isEmpty()) { - final ViewNode node = findViewNodeByIdLocked(id); - if (node == null) { - Slog.w(TAG, "Service passed invalid id on SavableInfo: " + id); - allRequiredAreNotEmpty = false; - break; - } - final AutofillValue initialValue = node.getAutofillValue(); - if (initialValue == null || initialValue.isEmpty()) { - if (DEBUG) { - Slog.d(TAG, "finishSessionLocked(): empty initial value for " + id ); - } - allRequiredAreNotEmpty = false; - break; - } - } - if (state.mValueUpdated) { - final AutofillValue filledValue = findValue(mAutoFilledDataset, id); - if (!state.mAutofillValue.equals(filledValue)) { - if (DEBUG) { - Slog.d(TAG, "finishSessionLocked(): found a change on " + id + ": " - + filledValue + " => " + state.mAutofillValue); - } - atLeastOneChanged = true; - } - } else { - if (state.mAutofillValue == null || state.mAutofillValue.isEmpty()) { - if (DEBUG) { - Slog.d(TAG, "finishSessionLocked(): empty value for " + id + ": " - + state.mAutofillValue); - } - allRequiredAreNotEmpty = false; - break; - - } - } - } - - if (allRequiredAreNotEmpty) { - if (!atLeastOneChanged && saveInfo.getOptionalIds() != null) { - for (int i = 0; i < saveInfo.getOptionalIds().length; i++) { - final AutofillId id = saveInfo.getOptionalIds()[i]; - final ViewState state = mViewStates.get(id); - if (state != null && state.mAutofillValue != null && state.mValueUpdated) { - final AutofillValue filledValue = findValue(mAutoFilledDataset, id); - if (!state.mAutofillValue.equals(filledValue)) { - if (DEBUG) { - Slog.d(TAG, "finishSessionLocked(): found a change on optional " - + id + ": " + filledValue + " => " - + state.mAutofillValue); - } - atLeastOneChanged = true; - break; - } - } - } - } - if (atLeastOneChanged) { - getUiForShowing().showSaveUi( - mInfo.getServiceInfo().loadLabel(mContext.getPackageManager()), - saveInfo, mPackageName); - return false; - } - } - // Nothing changed... - if (DEBUG) { - Slog.d(TAG, "showSaveLocked(): with no changes, comes no responsibilities." - + "allRequiredAreNotNull=" + allRequiredAreNotEmpty - + ", atLeastOneChanged=" + atLeastOneChanged); - } - return true; - } - - /** - * Calls service when user requested save. - */ - private void callSaveLocked() { - if (DEBUG) { - Slog.d(TAG, "callSaveLocked(): mViewStates=" + mViewStates); - } - - final Bundle extras = this.mCurrentResponse.getExtras(); - - for (Entry<AutofillId, ViewState> entry : mViewStates.entrySet()) { - final AutofillValue value = entry.getValue().mAutofillValue; - if (value == null) { - if (VERBOSE) { - Slog.v(TAG, "callSaveLocked(): skipping " + entry.getKey()); - } - continue; - } - final AutofillId id = entry.getKey(); - final ViewNode node = findViewNodeByIdLocked(id); - if (node == null) { - Slog.w(TAG, "callSaveLocked(): did not find node with id " + id); - continue; - } - if (VERBOSE) { - Slog.v(TAG, "callSaveLocked(): updating " + id + " to " + value); - } - - node.updateAutofillValue(value); - } - - // Sanitize structure before it's sent to service. - mStructure.sanitizeForParceling(false); - - if (VERBOSE) { - Slog.v(TAG, "Dumping " + mStructure + " before calling service.save()"); - mStructure.dump(); - } - - mRemoteFillService.onSaveRequest(mStructure, extras); - } - - void updateLocked(AutofillId id, Rect virtualBounds, AutofillValue value, int flags) { - if (mAutoFilledDataset != null && (flags & FLAG_VALUE_CHANGED) == 0) { - // TODO(b/33197203): ignoring because we don't support partitions yet - Slog.d(TAG, "updateLocked(): ignoring " + flags + " after app was autofilled"); - return; - } - - ViewState viewState = mViewStates.get(id); - if (viewState == null) { - viewState = new ViewState(this, id, this); - mViewStates.put(id, viewState); - } - - if ((flags & FLAG_START_SESSION) != 0) { - // View is triggering autofill. - mCurrentViewState = viewState; - viewState.update(value, virtualBounds); - return; - } - - if ((flags & FLAG_VALUE_CHANGED) != 0) { - if (value != null && !value.equals(viewState.mAutofillValue)) { - viewState.mValueUpdated = true; - - // Must check if this update was caused by autofilling the view, in which - // case we just update the value, but not the UI. - if (mAutoFilledDataset != null) { - final AutofillValue filledValue = findValue(mAutoFilledDataset, id); - if (value.equals(filledValue)) { - viewState.mAutofillValue = value; - return; - } - } - - // Change value - viewState.mAutofillValue = value; - - // Update the chooser UI - if (value.isText()) { - getUiForShowing().filterFillUi(value.getTextValue().toString()); - } else { - getUiForShowing().filterFillUi(null); - } - } - - return; - } - - if ((flags & FLAG_VIEW_ENTERED) != 0) { - // Remove the UI if the ViewState has changed. - if (mCurrentViewState != viewState) { - mUi.hideFillUi(mCurrentViewState != null ? mCurrentViewState.mId : null); - mCurrentViewState = viewState; - } - - // If the ViewState is ready to be displayed, onReady() will be called. - viewState.update(value, virtualBounds); - - // TODO(b/33197203): Remove when there is a response per activity. - if (mCurrentResponse != null) { - viewState.setResponse(mCurrentResponse); - } - - return; - } - - if ((flags & FLAG_VIEW_EXITED) != 0) { - if (mCurrentViewState == viewState) { - mUi.hideFillUi(viewState.mId); - mCurrentViewState = null; - } - return; - } - - Slog.w(TAG, "updateLocked(): unknown flags " + flags); - } - - @Override - public void onFillReady(FillResponse response, AutofillId filledId, - @Nullable AutofillValue value) { - String filterText = null; - if (value != null && value.isText()) { - filterText = value.getTextValue().toString(); - } - - getUiForShowing().showFillUi(filledId, response, filterText, mPackageName); - } - - private void notifyUnavailableToClient() { - if (mCurrentViewState == null) { - // TODO(b/33197203): temporary sanity check; should never happen - Slog.w(TAG, "notifyUnavailable(): mCurrentViewState is null"); - return; - } - if (!mHasCallback) return; - try { - mClient.notifyNoFillUi(mWindowToken, mCurrentViewState.mId); - } catch (RemoteException e) { - Slog.e(TAG, "Error notifying client no fill UI: windowToken=" + mWindowToken - + " id=" + mCurrentViewState.mId, e); - } - } - - private void processResponseLocked(FillResponse response) { - if (DEBUG) { - Slog.d(TAG, "processResponseLocked(auth=" + response.getAuthentication() - + "):" + response); - } - - if (mCurrentViewState == null) { - // TODO(b/33197203): temporary sanity check; should never happen - Slog.w(TAG, "processResponseLocked(): mCurrentViewState is null"); - return; - } - - mCurrentResponse = response; - - if (mCurrentResponse.getAuthentication() != null) { - // Handle authentication. - final Intent fillInIntent = createAuthFillInIntent(mStructure); - mCurrentViewState.setResponse(mCurrentResponse, fillInIntent); - return; - } - - if ((mFlags & FLAG_MANUAL_REQUEST) != 0 && response.getDatasets() != null - && response.getDatasets().size() == 1) { - Slog.d(TAG, "autofilling manual request directly"); - autoFill(response.getDatasets().get(0)); - return; - } - - mCurrentViewState.setResponse(mCurrentResponse); - } - - void autoFill(Dataset dataset) { - synchronized (mLock) { - mAutoFilledDataset = dataset; - - // Autofill it directly... - if (dataset.getAuthentication() == null) { - autoFillApp(dataset); - return; - } - - // ...or handle authentication. - Intent fillInIntent = createAuthFillInIntent(mStructure); - startAuthentication(dataset.getAuthentication(), fillInIntent); - } - } - - CharSequence getServiceName() { - return AutofillManagerServiceImpl.this.getServiceName(); - } - - private Intent createAuthFillInIntent(AssistStructure structure) { - Intent fillInIntent = new Intent(); - fillInIntent.putExtra(AutofillManager.EXTRA_ASSIST_STRUCTURE, structure); - return fillInIntent; - } - - private void startAuthentication(IntentSender intent, Intent fillInIntent) { - try { - mClient.authenticate(intent, fillInIntent); - } catch (RemoteException e) { - Slog.e(TAG, "Error launching auth intent", e); - } - } - - void dumpLocked(String prefix, PrintWriter pw) { - pw.print(prefix); pw.print("mActivityToken: "); pw.println(mActivityToken); - pw.print(prefix); pw.print("mFlags: "); pw.println(mFlags); - pw.print(prefix); pw.print("mCurrentResponse: "); pw.println(mCurrentResponse); - pw.print(prefix); pw.print("mAutoFilledDataset: "); pw.println(mAutoFilledDataset); - pw.print(prefix); pw.print("mCurrentViewStates: "); pw.println(mCurrentViewState); - pw.print(prefix); pw.print("mViewStates: "); pw.println(mViewStates.size()); - final String prefix2 = prefix + " "; - for (Map.Entry<AutofillId, ViewState> entry : mViewStates.entrySet()) { - pw.print(prefix); pw.print("State for id "); pw.println(entry.getKey()); - entry.getValue().dump(prefix2, pw); - } - if (VERBOSE) { - pw.print(prefix); pw.print("mStructure: " ); - // TODO(b/33197203): add method do dump AssistStructure on pw - if (mStructure != null) { - pw.println("look at logcat" ); - mStructure.dump(); // dumps to logcat - } else { - pw.println("null"); - } - } - pw.print(prefix); pw.print("mHasCallback: "); pw.println(mHasCallback); - mRemoteFillService.dump(prefix, pw); - } - - void autoFillApp(Dataset dataset) { - synchronized (mLock) { - try { - if (DEBUG) { - Slog.d(TAG, "autoFillApp(): the buck is on the app: " + dataset); - } - mClient.autofill(mWindowToken, dataset.getFieldIds(), dataset.getFieldValues()); - } catch (RemoteException e) { - Slog.w(TAG, "Error autofilling activity: " + e); - } - } - } - - private AutoFillUI getUiForShowing() { - synchronized (mLock) { - mUi.setCallback(this); - return mUi; - } - } - - private ViewNode findViewNodeByIdLocked(AutofillId id) { - final int size = mStructure.getWindowNodeCount(); - for (int i = 0; i < size; i++) { - final WindowNode window = mStructure.getWindowNodeAt(i); - final ViewNode root = window.getRootViewNode(); - if (id.equals(root.getAutofillId())) { - return root; - } - final ViewNode child = findViewNodeByIdLocked(root, id); - if (child != null) { - return child; - } - } - return null; - } - - private ViewNode findViewNodeByIdLocked(ViewNode parent, AutofillId id) { - final int childrenSize = parent.getChildCount(); - if (childrenSize > 0) { - for (int i = 0; i < childrenSize; i++) { - final ViewNode child = parent.getChildAt(i); - if (id.equals(child.getAutofillId())) { - return child; - } - final ViewNode grandChild = findViewNodeByIdLocked(child, id); - if (grandChild != null && id.equals(grandChild.getAutofillId())) { - return grandChild; - } - } - } - return null; - } - - private void destroyLocked() { - mRemoteFillService.destroy(); - mUi.setCallback(null); - mMetricsLogger.action(MetricsProto.MetricsEvent.AUTOFILL_SESSION_FINISHED, - mPackageName); - } - - void removeSelf() { - synchronized (mLock) { - removeSelfLocked(); - } - } - - private void removeSelfLocked() { - if (VERBOSE) { - Slog.v(TAG, "removeSelfLocked()"); - } - destroyLocked(); - mSessions.remove(mActivityToken); - } - } } diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java new file mode 100644 index 000000000000..1093e9e27d93 --- /dev/null +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -0,0 +1,764 @@ +/* + * Copyright (C) 2017 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.server.autofill; + +import static android.view.autofill.AutofillManager.FLAG_MANUAL_REQUEST; +import static android.view.autofill.AutofillManager.FLAG_START_SESSION; +import static android.view.autofill.AutofillManager.FLAG_VALUE_CHANGED; +import static android.view.autofill.AutofillManager.FLAG_VIEW_ENTERED; +import static android.view.autofill.AutofillManager.FLAG_VIEW_EXITED; + +import static com.android.server.autofill.Helper.DEBUG; +import static com.android.server.autofill.Helper.VERBOSE; +import static com.android.server.autofill.Helper.findValue; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.app.assist.AssistStructure; +import android.app.assist.AssistStructure.ViewNode; +import android.app.assist.AssistStructure.WindowNode; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.IntentSender; +import android.graphics.Rect; +import android.metrics.LogMaker; +import android.os.Binder; +import android.os.Bundle; +import android.os.IBinder; +import android.os.Parcelable; +import android.os.RemoteException; +import android.provider.Settings; +import android.service.autofill.AutofillService; +import android.service.autofill.Dataset; +import android.service.autofill.FillResponse; +import android.service.autofill.SaveInfo; +import android.util.ArrayMap; +import android.util.Slog; +import android.view.autofill.AutofillId; +import android.view.autofill.AutofillManager; +import android.view.autofill.AutofillValue; +import android.view.autofill.IAutoFillManagerClient; +import android.view.autofill.IAutofillWindowPresenter; + +import com.android.internal.annotations.GuardedBy; +import com.android.internal.logging.MetricsLogger; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.internal.os.HandlerCaller; +import com.android.server.autofill.ui.AutoFillUI; + +import java.io.PrintWriter; +import java.util.Map; +import java.util.Map.Entry; + +/** + * A session for a given activity. + * + * <p>This class manages the multiple {@link ViewState}s for each view it has, and keeps track + * of the current {@link ViewState} to display the appropriate UI. + * + * <p>Although the autofill requests and callbacks are stateless from the service's point of + * view, we need to keep state in the framework side for cases such as authentication. For + * example, when service return a {@link FillResponse} that contains all the fields needed + * to fill the activity but it requires authentication first, that response need to be held + * until the user authenticates or it times out. + */ +// TODO(b/33197203): make sure sessions are removed (and tested by CTS): +// - On all authentication scenarios. +// - When user does not interact back after a while. +// - When service is unbound. +final class Session implements RemoteFillService.FillServiceCallbacks, ViewState.Listener, + AutoFillUI.AutoFillUiCallback { + private static final String TAG = "AutofillSession"; + + private final AutofillManagerServiceImpl mService; + private final IBinder mActivityToken; + private final IBinder mWindowToken; + private final HandlerCaller mHandlerCaller; + private final Object mLock; + private final AutoFillUI mUi; + + private final MetricsLogger mMetricsLogger = new MetricsLogger(); + + /** Package name of the app that is auto-filled */ + @NonNull private final String mPackageName; + + @GuardedBy("mLock") + private final Map<AutofillId, ViewState> mViewStates = new ArrayMap<>(); + + @GuardedBy("mLock") + @Nullable + private ViewState mCurrentViewState; + + private final IAutoFillManagerClient mClient; + + @GuardedBy("mLock") + RemoteFillService mRemoteFillService; + + // TODO(b/33197203): Get a response per view instead of per activity. + @GuardedBy("mLock") + private FillResponse mCurrentResponse; + + /** + * Used to remember which {@link Dataset} filled the session. + */ + // TODO(b/33197203): might need more than one once we support partitions + @GuardedBy("mLock") + private Dataset mAutoFilledDataset; + + /** + * Assist structure sent by the app; it will be updated (sanitized, change values for save) + * before sent to {@link AutofillService}. + */ + @GuardedBy("mLock") AssistStructure mStructure; + + /** + * Whether the client has an {@link android.view.autofill.AutofillManager.AutofillCallback}. + */ + private boolean mHasCallback; + + /** + * Flags used to start the session. + */ + int mFlags; + + Session(@NonNull AutofillManagerServiceImpl service, @NonNull AutoFillUI ui, + @NonNull Context context, @NonNull HandlerCaller handlerCaller, int userId, + @NonNull Object lock, @NonNull IBinder activityToken, + @Nullable IBinder windowToken, @NonNull IBinder client, boolean hasCallback, + int flags, @NonNull ComponentName componentName, @NonNull String packageName) { + mService = service; + mLock = lock; + mUi = ui; + mHandlerCaller = handlerCaller; + mRemoteFillService = new RemoteFillService(context, componentName, userId, this); + mActivityToken = activityToken; + mWindowToken = windowToken; + mHasCallback = hasCallback; + mPackageName = packageName; + mFlags = flags; + + mClient = IAutoFillManagerClient.Stub.asInterface(client); + try { + client.linkToDeath(() -> { + if (DEBUG) { + Slog.d(TAG, "app binder died"); + } + + removeSelf(); + }, 0); + } catch (RemoteException e) { + Slog.w(TAG, "linkToDeath() on mClient failed: " + e); + } + + mMetricsLogger.action(MetricsEvent.AUTOFILL_SESSION_STARTED, mPackageName); + } + + // FillServiceCallbacks + @Override + public void onFillRequestSuccess(@Nullable FillResponse response, + @NonNull String servicePackageName) { + if (response == null) { + // Nothing to be done, but need to notify client. + notifyUnavailableToClient(); + removeSelf(); + return; + } + + if ((response.getDatasets() == null || response.getDatasets().isEmpty()) + && response.getAuthentication() == null) { + // Response is "empty" from an UI point of view, need to notify client. + notifyUnavailableToClient(); + } + synchronized (mLock) { + processResponseLocked(response); + } + + LogMaker log = (new LogMaker(MetricsEvent.AUTOFILL_REQUEST)) + .setType(MetricsEvent.TYPE_SUCCESS) + .setPackageName(mPackageName) + .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS, + response.getDatasets() == null ? 0 : response.getDatasets().size()) + .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, + servicePackageName); + mMetricsLogger.write(log); + } + + // FillServiceCallbacks + @Override + public void onFillRequestFailure(@Nullable CharSequence message, + @NonNull String servicePackageName) { + LogMaker log = (new LogMaker(MetricsEvent.AUTOFILL_REQUEST)) + .setType(MetricsEvent.TYPE_FAILURE) + .setPackageName(mPackageName) + .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, servicePackageName); + mMetricsLogger.write(log); + + getUiForShowing().showError(message); + removeSelf(); + } + + // FillServiceCallbacks + @Override + public void onSaveRequestSuccess(@NonNull String servicePackageName) { + LogMaker log = (new LogMaker( + MetricsEvent.AUTOFILL_DATA_SAVE_REQUEST)) + .setType(MetricsEvent.TYPE_SUCCESS) + .setPackageName(mPackageName) + .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, servicePackageName); + mMetricsLogger.write(log); + + // Nothing left to do... + removeSelf(); + } + + // FillServiceCallbacks + @Override + public void onSaveRequestFailure(@Nullable CharSequence message, + @NonNull String servicePackageName) { + LogMaker log = (new LogMaker( + MetricsEvent.AUTOFILL_DATA_SAVE_REQUEST)) + .setType(MetricsEvent.TYPE_FAILURE) + .setPackageName(mPackageName) + .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, servicePackageName); + mMetricsLogger.write(log); + + getUiForShowing().showError(message); + removeSelf(); + } + + // FillServiceCallbacks + @Override + public void authenticate(IntentSender intent) { + final Intent fillInIntent; + synchronized (mLock) { + fillInIntent = createAuthFillInIntent(mStructure); + } + mHandlerCaller.getHandler().post(() -> startAuthentication(intent, fillInIntent)); + } + + // FillServiceCallbacks + @Override + public void onDisableSelf() { + mService.disableSelf(); + synchronized (mLock) { + removeSelfLocked(); + } + } + + // FillServiceCallbacks + @Override + public void onServiceDied(RemoteFillService service) { + // TODO(b/33197203): implement + } + + // AutoFillUiCallback + @Override + public void fill(Dataset dataset) { + mHandlerCaller.getHandler().post(() -> autoFill(dataset)); + } + + // AutoFillUiCallback + @Override + public void save() { + mHandlerCaller.getHandler() + .obtainMessage(AutofillManagerServiceImpl.MSG_SERVICE_SAVE, mActivityToken) + .sendToTarget(); + } + + // AutoFillUiCallback + @Override + public void cancelSave() { + mHandlerCaller.getHandler().post(() -> removeSelf()); + } + + // AutoFillUiCallback + @Override + public void requestShowFillUi(AutofillId id, int width, int height, + IAutofillWindowPresenter presenter) { + try { + mClient.requestShowFillUi(mWindowToken, id, width, height, + mCurrentViewState.mVirtualBounds, presenter); + } catch (RemoteException e) { + Slog.e(TAG, "Error requesting to show fill UI", e); + } + } + + // AutoFillUiCallback + @Override + public void requestHideFillUi(AutofillId id) { + try { + mClient.requestHideFillUi(mWindowToken, id); + } catch (RemoteException e) { + Slog.e(TAG, "Error requesting to hide fill UI", e); + } + } + + public void setAuthenticationResultLocked(Bundle data) { + if (mCurrentResponse == null || data == null) { + removeSelf(); + } else { + Parcelable result = data.getParcelable( + AutofillManager.EXTRA_AUTHENTICATION_RESULT); + if (result instanceof FillResponse) { + mMetricsLogger.action(MetricsEvent.AUTOFILL_AUTHENTICATED, mPackageName); + + mCurrentResponse = (FillResponse) result; + processResponseLocked(mCurrentResponse); + } else if (result instanceof Dataset) { + Dataset dataset = (Dataset) result; + final int index = mCurrentResponse.getDatasets().indexOf(mAutoFilledDataset); + if (index >= 0) { + mCurrentResponse.getDatasets().set(index, dataset); + autoFill(dataset); + } + } + } + } + + public void setHasCallback(boolean hasIt) { + mHasCallback = hasIt; + } + + /** + * Shows the save UI, when session can be saved. + * + * @return {@code true} if session is done, or {@code false} if it's pending user action. + */ + public boolean showSaveLocked() { + if (mStructure == null) { + Slog.wtf(TAG, "showSaveLocked(): no mStructure"); + return true; + } + if (mCurrentResponse == null) { + // Happens when the activity / session was finished before the service replied, or + // when the service cannot autofill it (and returned a null response). + if (DEBUG) { + Slog.d(TAG, "showSaveLocked(): no mCurrentResponse"); + } + return true; + } + final SaveInfo saveInfo = mCurrentResponse.getSaveInfo(); + if (DEBUG) { + Slog.d(TAG, "showSaveLocked(): saveInfo=" + saveInfo); + } + + /* + * The Save dialog is only shown if all conditions below are met: + * + * - saveInfo is not null + * - autofillValue of all required ids is not null + * - autofillValue of at least one id (required or optional) has changed. + */ + + if (saveInfo == null) { + return true; + } + + final AutofillId[] requiredIds = saveInfo.getRequiredIds(); + if (requiredIds == null || requiredIds.length == 0) { + Slog.w(TAG, "showSaveLocked(): no required ids on saveInfo"); + return true; + } + + boolean allRequiredAreNotEmpty = true; + boolean atLeastOneChanged = false; + for (int i = 0; i < requiredIds.length; i++) { + final AutofillId id = requiredIds[i]; + final ViewState state = mViewStates.get(id); + if (state == null || state.mAutofillValue == null + || state.mAutofillValue.isEmpty()) { + final ViewNode node = findViewNodeByIdLocked(id); + if (node == null) { + Slog.w(TAG, "Service passed invalid id on SavableInfo: " + id); + allRequiredAreNotEmpty = false; + break; + } + final AutofillValue initialValue = node.getAutofillValue(); + if (initialValue == null || initialValue.isEmpty()) { + if (DEBUG) { + Slog.d(TAG, "finishSessionLocked(): empty initial value for " + id ); + } + allRequiredAreNotEmpty = false; + break; + } + } + if (state.mValueUpdated) { + final AutofillValue filledValue = findValue(mAutoFilledDataset, id); + if (!state.mAutofillValue.equals(filledValue)) { + if (DEBUG) { + Slog.d(TAG, "finishSessionLocked(): found a change on " + id + ": " + + filledValue + " => " + state.mAutofillValue); + } + atLeastOneChanged = true; + } + } else { + if (state.mAutofillValue == null || state.mAutofillValue.isEmpty()) { + if (DEBUG) { + Slog.d(TAG, "finishSessionLocked(): empty value for " + id + ": " + + state.mAutofillValue); + } + allRequiredAreNotEmpty = false; + break; + + } + } + } + + if (allRequiredAreNotEmpty) { + if (!atLeastOneChanged && saveInfo.getOptionalIds() != null) { + for (int i = 0; i < saveInfo.getOptionalIds().length; i++) { + final AutofillId id = saveInfo.getOptionalIds()[i]; + final ViewState state = mViewStates.get(id); + if (state != null && state.mAutofillValue != null && state.mValueUpdated) { + final AutofillValue filledValue = findValue(mAutoFilledDataset, id); + if (!state.mAutofillValue.equals(filledValue)) { + if (DEBUG) { + Slog.d(TAG, "finishSessionLocked(): found a change on optional " + + id + ": " + filledValue + " => " + + state.mAutofillValue); + } + atLeastOneChanged = true; + break; + } + } + } + } + if (atLeastOneChanged) { + getUiForShowing().showSaveUi(mService.getServiceLabel(), saveInfo, mPackageName); + return false; + } + } + // Nothing changed... + if (DEBUG) { + Slog.d(TAG, "showSaveLocked(): with no changes, comes no responsibilities." + + "allRequiredAreNotNull=" + allRequiredAreNotEmpty + + ", atLeastOneChanged=" + atLeastOneChanged); + } + return true; + } + + /** + * Calls service when user requested save. + */ + void callSaveLocked() { + if (DEBUG) { + Slog.d(TAG, "callSaveLocked(): mViewStates=" + mViewStates); + } + + final Bundle extras = this.mCurrentResponse.getExtras(); + + for (Entry<AutofillId, ViewState> entry : mViewStates.entrySet()) { + final AutofillValue value = entry.getValue().mAutofillValue; + if (value == null) { + if (VERBOSE) { + Slog.v(TAG, "callSaveLocked(): skipping " + entry.getKey()); + } + continue; + } + final AutofillId id = entry.getKey(); + final ViewNode node = findViewNodeByIdLocked(id); + if (node == null) { + Slog.w(TAG, "callSaveLocked(): did not find node with id " + id); + continue; + } + if (VERBOSE) { + Slog.v(TAG, "callSaveLocked(): updating " + id + " to " + value); + } + + node.updateAutofillValue(value); + } + + // Sanitize structure before it's sent to service. + mStructure.sanitizeForParceling(false); + + if (VERBOSE) { + Slog.v(TAG, "Dumping " + mStructure + " before calling service.save()"); + mStructure.dump(); + } + + mRemoteFillService.onSaveRequest(mStructure, extras); + } + + void updateLocked(AutofillId id, Rect virtualBounds, AutofillValue value, int flags) { + if (mAutoFilledDataset != null && (flags & FLAG_VALUE_CHANGED) == 0) { + // TODO(b/33197203): ignoring because we don't support partitions yet + Slog.d(TAG, "updateLocked(): ignoring " + flags + " after app was autofilled"); + return; + } + + ViewState viewState = mViewStates.get(id); + if (viewState == null) { + viewState = new ViewState(this, id, this); + mViewStates.put(id, viewState); + } + + if ((flags & FLAG_START_SESSION) != 0) { + // View is triggering autofill. + mCurrentViewState = viewState; + viewState.update(value, virtualBounds); + return; + } + + if ((flags & FLAG_VALUE_CHANGED) != 0) { + if (value != null && !value.equals(viewState.mAutofillValue)) { + viewState.mValueUpdated = true; + + // Must check if this update was caused by autofilling the view, in which + // case we just update the value, but not the UI. + if (mAutoFilledDataset != null) { + final AutofillValue filledValue = findValue(mAutoFilledDataset, id); + if (value.equals(filledValue)) { + viewState.mAutofillValue = value; + return; + } + } + + // Change value + viewState.mAutofillValue = value; + + // Update the chooser UI + if (value.isText()) { + getUiForShowing().filterFillUi(value.getTextValue().toString()); + } else { + getUiForShowing().filterFillUi(null); + } + } + + return; + } + + if ((flags & FLAG_VIEW_ENTERED) != 0) { + // Remove the UI if the ViewState has changed. + if (mCurrentViewState != viewState) { + mUi.hideFillUi(mCurrentViewState != null ? mCurrentViewState.mId : null); + mCurrentViewState = viewState; + } + + // If the ViewState is ready to be displayed, onReady() will be called. + viewState.update(value, virtualBounds); + + // TODO(b/33197203): Remove when there is a response per activity. + if (mCurrentResponse != null) { + viewState.setResponse(mCurrentResponse); + } + + return; + } + + if ((flags & FLAG_VIEW_EXITED) != 0) { + if (mCurrentViewState == viewState) { + mUi.hideFillUi(viewState.mId); + mCurrentViewState = null; + } + return; + } + + Slog.w(TAG, "updateLocked(): unknown flags " + flags); + } + + @Override + public void onFillReady(FillResponse response, AutofillId filledId, + @Nullable AutofillValue value) { + String filterText = null; + if (value != null && value.isText()) { + filterText = value.getTextValue().toString(); + } + + getUiForShowing().showFillUi(filledId, response, filterText, mPackageName); + } + + private void notifyUnavailableToClient() { + if (mCurrentViewState == null) { + // TODO(b/33197203): temporary sanity check; should never happen + Slog.w(TAG, "notifyUnavailable(): mCurrentViewState is null"); + return; + } + if (!mHasCallback) return; + try { + mClient.notifyNoFillUi(mWindowToken, mCurrentViewState.mId); + } catch (RemoteException e) { + Slog.e(TAG, "Error notifying client no fill UI: windowToken=" + mWindowToken + + " id=" + mCurrentViewState.mId, e); + } + } + + private void processResponseLocked(FillResponse response) { + if (DEBUG) { + Slog.d(TAG, "processResponseLocked(auth=" + response.getAuthentication() + + "):" + response); + } + + if (mCurrentViewState == null) { + // TODO(b/33197203): temporary sanity check; should never happen + Slog.w(TAG, "processResponseLocked(): mCurrentViewState is null"); + return; + } + + mCurrentResponse = response; + + if (mCurrentResponse.getAuthentication() != null) { + // Handle authentication. + final Intent fillInIntent = createAuthFillInIntent(mStructure); + mCurrentViewState.setResponse(mCurrentResponse, fillInIntent); + return; + } + + if ((mFlags & FLAG_MANUAL_REQUEST) != 0 && response.getDatasets() != null + && response.getDatasets().size() == 1) { + Slog.d(TAG, "autofilling manual request directly"); + autoFill(response.getDatasets().get(0)); + return; + } + + mCurrentViewState.setResponse(mCurrentResponse); + } + + void autoFill(Dataset dataset) { + synchronized (mLock) { + mAutoFilledDataset = dataset; + + // Autofill it directly... + if (dataset.getAuthentication() == null) { + autoFillApp(dataset); + return; + } + + // ...or handle authentication. + Intent fillInIntent = createAuthFillInIntent(mStructure); + startAuthentication(dataset.getAuthentication(), fillInIntent); + } + } + + CharSequence getServiceName() { + return mService.getServiceName(); + } + + private Intent createAuthFillInIntent(AssistStructure structure) { + Intent fillInIntent = new Intent(); + fillInIntent.putExtra(AutofillManager.EXTRA_ASSIST_STRUCTURE, structure); + return fillInIntent; + } + + private void startAuthentication(IntentSender intent, Intent fillInIntent) { + try { + mClient.authenticate(intent, fillInIntent); + } catch (RemoteException e) { + Slog.e(TAG, "Error launching auth intent", e); + } + } + + void dumpLocked(String prefix, PrintWriter pw) { + pw.print(prefix); pw.print("mActivityToken: "); pw.println(mActivityToken); + pw.print(prefix); pw.print("mFlags: "); pw.println(mFlags); + pw.print(prefix); pw.print("mCurrentResponse: "); pw.println(mCurrentResponse); + pw.print(prefix); pw.print("mAutoFilledDataset: "); pw.println(mAutoFilledDataset); + pw.print(prefix); pw.print("mCurrentViewStates: "); pw.println(mCurrentViewState); + pw.print(prefix); pw.print("mViewStates: "); pw.println(mViewStates.size()); + final String prefix2 = prefix + " "; + for (Map.Entry<AutofillId, ViewState> entry : mViewStates.entrySet()) { + pw.print(prefix); pw.print("State for id "); pw.println(entry.getKey()); + entry.getValue().dump(prefix2, pw); + } + if (VERBOSE) { + pw.print(prefix); pw.print("mStructure: " ); + // TODO(b/33197203): add method do dump AssistStructure on pw + if (mStructure != null) { + pw.println("look at logcat" ); + mStructure.dump(); // dumps to logcat + } else { + pw.println("null"); + } + } + pw.print(prefix); pw.print("mHasCallback: "); pw.println(mHasCallback); + mRemoteFillService.dump(prefix, pw); + } + + void autoFillApp(Dataset dataset) { + synchronized (mLock) { + try { + if (DEBUG) { + Slog.d(TAG, "autoFillApp(): the buck is on the app: " + dataset); + } + mClient.autofill(mWindowToken, dataset.getFieldIds(), dataset.getFieldValues()); + } catch (RemoteException e) { + Slog.w(TAG, "Error autofilling activity: " + e); + } + } + } + + private AutoFillUI getUiForShowing() { + synchronized (mLock) { + mUi.setCallback(this); + return mUi; + } + } + + private ViewNode findViewNodeByIdLocked(AutofillId id) { + final int size = mStructure.getWindowNodeCount(); + for (int i = 0; i < size; i++) { + final WindowNode window = mStructure.getWindowNodeAt(i); + final ViewNode root = window.getRootViewNode(); + if (id.equals(root.getAutofillId())) { + return root; + } + final ViewNode child = findViewNodeByIdLocked(root, id); + if (child != null) { + return child; + } + } + return null; + } + + private ViewNode findViewNodeByIdLocked(ViewNode parent, AutofillId id) { + final int childrenSize = parent.getChildCount(); + if (childrenSize > 0) { + for (int i = 0; i < childrenSize; i++) { + final ViewNode child = parent.getChildAt(i); + if (id.equals(child.getAutofillId())) { + return child; + } + final ViewNode grandChild = findViewNodeByIdLocked(child, id); + if (grandChild != null && id.equals(grandChild.getAutofillId())) { + return grandChild; + } + } + } + return null; + } + + void destroyLocked() { + mRemoteFillService.destroy(); + mUi.setCallback(null); + mMetricsLogger.action(MetricsEvent.AUTOFILL_SESSION_FINISHED, mPackageName); + } + + void removeSelf() { + synchronized (mLock) { + removeSelfLocked(); + } + } + + void removeSelfLocked() { + if (VERBOSE) { + Slog.v(TAG, "removeSelfLocked()"); + } + destroyLocked(); + mService.removeSessionLocked(mActivityToken); + } +}
\ No newline at end of file diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java new file mode 100644 index 000000000000..d31dcfd061c0 --- /dev/null +++ b/services/autofill/java/com/android/server/autofill/ViewState.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2017 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.server.autofill; + +import android.annotation.Nullable; +import android.content.Intent; +import android.graphics.Rect; +import android.service.autofill.FillResponse; +import android.view.autofill.AutofillId; +import android.view.autofill.AutofillValue; + +import java.io.PrintWriter; + +/** + * State for a given view with a AutofillId. + * + * <p>This class holds state about a view and calls its listener when the fill UI is ready to + * be displayed for the view. + */ +final class ViewState { + interface Listener { + /** + * Called when the fill UI is ready to be shown for this view. + */ + void onFillReady(FillResponse fillResponse, AutofillId focusedId, + @Nullable AutofillValue value); + } + + final AutofillId mId; + private final Listener mListener; + // TODO(b/33197203): would not need a reference to response and session if it was an inner + // class of Session... + private final Session mSession; + private FillResponse mResponse; + private Intent mAuthIntent; + + // TODO(b/33197203): encapsulate access so it's not called by UI + AutofillValue mAutofillValue; + + // TODO(b/33197203): encapsulate access so it's not called by UI + // Bounds if a virtual view, null otherwise + Rect mVirtualBounds; + + boolean mValueUpdated; + + ViewState(Session session, AutofillId id, Listener listener) { + mSession = session; + mId = id; + mListener = listener; + } + + /** + * Response should only be set once. + */ + void setResponse(FillResponse response) { + mResponse = response; + maybeCallOnFillReady(); + } + + /** + * Used when a {@link FillResponse} requires authentication to be unlocked. + */ + void setResponse(FillResponse response, Intent authIntent) { + mAuthIntent = authIntent; + setResponse(response); + } + + CharSequence getServiceName() { + return mSession.getServiceName(); + } + + // TODO(b/33197203): need to refactor / rename / document this method to make it clear that + // it can change the value and update the UI; similarly, should replace code that + // directly sets mAutoFilLValue to use encapsulation. + void update(@Nullable AutofillValue autofillValue, @Nullable Rect virtualBounds) { + if (autofillValue != null) { + mAutofillValue = autofillValue; + } + if (virtualBounds != null) { + mVirtualBounds = virtualBounds; + } + + maybeCallOnFillReady(); + } + + /** + * Calls {@link + * Listener#onFillReady(FillResponse, AutofillId, AutofillValue)} if the + * fill UI is ready to be displayed (i.e. when response and bounds are set). + */ + void maybeCallOnFillReady() { + if (mResponse != null && (mResponse.getAuthentication() != null + || mResponse.getDatasets() != null)) { + mListener.onFillReady(mResponse, mId, mAutofillValue); + } + } + + @Override + public String toString() { + return "ViewState: [id=" + mId + ", value=" + mAutofillValue + ", bounds=" + mVirtualBounds + + ", updated = " + mValueUpdated + "]"; + } + + void dump(String prefix, PrintWriter pw) { + pw.print(prefix); pw.print("id:" ); pw.println(mId); + pw.print(prefix); pw.print("value:" ); pw.println(mAutofillValue); + pw.print(prefix); pw.print("updated:" ); pw.println(mValueUpdated); + pw.print(prefix); pw.print("virtualBounds:" ); pw.println(mVirtualBounds); + pw.print(prefix); pw.print("authIntent:" ); pw.println(mAuthIntent); + } +}
\ No newline at end of file diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java index 037804e0c5e9..57d357044e5f 100644 --- a/services/backup/java/com/android/server/backup/BackupManagerService.java +++ b/services/backup/java/com/android/server/backup/BackupManagerService.java @@ -3537,21 +3537,23 @@ public class BackupManagerService { return; } mCancelAll = cancelAll; - // Whoops, the current agent timed out running doBackup(). Tidy up and restage - // it for the next time we run a backup pass. - // !!! TODO: keep track of failure counts per agent, and blacklist those which - // fail repeatedly (i.e. have proved themselves to be buggy). - Slog.e(TAG, "Cancel backing up " + mCurrentPackage.packageName); - EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, mCurrentPackage.packageName); + final String logPackageName = (mCurrentPackage != null) + ? mCurrentPackage.packageName + : "no_package_yet"; + Slog.i(TAG, "Cancel backing up " + logPackageName); + EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, logPackageName); + addBackupTrace("cancel of " + logPackageName + ", cancelAll=" + cancelAll); mMonitor = monitorEvent(mMonitor, BackupManagerMonitor.LOG_EVENT_ID_KEY_VALUE_BACKUP_CANCEL, mCurrentPackage, BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT, putMonitoringExtra(null, BackupManagerMonitor.EXTRA_LOG_CANCEL_ALL, mCancelAll)); - addBackupTrace( - "cancel of " + mCurrentPackage.packageName + ", cancelAll=" + cancelAll); errorCleanup(); if (!cancelAll) { + // The current agent either timed out or was cancelled running doBackup(). + // Restage it for the next time we run a backup pass. + // !!! TODO: keep track of failure counts per agent, and blacklist those which + // fail repeatedly (i.e. have proved themselves to be buggy). executeNextState( mQueue.isEmpty() ? BackupState.FINAL : BackupState.RUNNING_QUEUE); dataChangedImpl(mCurrentPackage.packageName); diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java index 98242f9b393a..fd44794b043c 100644 --- a/services/core/java/com/android/server/BatteryService.java +++ b/services/core/java/com/android/server/BatteryService.java @@ -679,7 +679,7 @@ public final class BatteryService extends SystemService { pw.println("Battery service (battery) commands:"); pw.println(" help"); pw.println(" Print this help text."); - pw.println(" set [-f] [ac|usb|wireless|status|level|present|invalid] <value>"); + pw.println(" set [-f] [ac|usb|wireless|status|level|temp|present|invalid] <value>"); pw.println(" Force a battery property value, freezing battery state."); pw.println(" -f: force a battery change broadcast be sent, prints new sequence."); pw.println(" unplug [-f]"); @@ -767,6 +767,9 @@ public final class BatteryService extends SystemService { case "level": mBatteryProps.batteryLevel = Integer.parseInt(value); break; + case "temp": + mBatteryProps.batteryTemperature = Integer.parseInt(value); + break; case "invalid": mInvalidCharger = Integer.parseInt(value); break; diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index d02b72660709..003530e43173 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -96,7 +96,6 @@ import android.os.Process; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.SystemClock; -import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; @@ -208,6 +207,8 @@ public class ConnectivityService extends IConnectivityManager.Stub // See Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS private final int mReleasePendingIntentDelayMs; + private MockableSystemProperties mSystemProperties; + private Tethering mTethering; private final PermissionMonitor mPermissionMonitor; @@ -691,6 +692,8 @@ public class ConnectivityService extends IConnectivityManager.Stub IpConnectivityLog logger) { if (DBG) log("ConnectivityService starting up"); + mSystemProperties = getSystemProperties(); + mMetricsLog = logger; mDefaultRequest = createInternetRequestForTransport(-1, NetworkRequest.Type.REQUEST); NetworkRequestInfo defaultNRI = new NetworkRequestInfo(null, mDefaultRequest, new Binder()); @@ -708,7 +711,7 @@ public class ConnectivityService extends IConnectivityManager.Stub mReleasePendingIntentDelayMs = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, 5_000); - mLingerDelayMs = SystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS); + mLingerDelayMs = mSystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS); mContext = checkNotNull(context, "missing Context"); mNetd = checkNotNull(netManager, "missing INetworkManagementService"); @@ -735,7 +738,7 @@ public class ConnectivityService extends IConnectivityManager.Stub mNetConfigs = new NetworkConfig[ConnectivityManager.MAX_NETWORK_TYPE+1]; // TODO: What is the "correct" way to do determine if this is a wifi only device? - boolean wifiOnly = SystemProperties.getBoolean("ro.radio.noril", false); + boolean wifiOnly = mSystemProperties.getBoolean("ro.radio.noril", false); log("wifiOnly=" + wifiOnly); String[] naStrings = context.getResources().getStringArray( com.android.internal.R.array.networkAttributes); @@ -788,8 +791,8 @@ public class ConnectivityService extends IConnectivityManager.Stub } } - mTestMode = SystemProperties.get("cm.test.mode").equals("true") - && SystemProperties.get("ro.build.type").equals("eng"); + mTestMode = mSystemProperties.get("cm.test.mode").equals("true") + && mSystemProperties.get("ro.build.type").equals("eng"); mTethering = new Tethering(mContext, mNetd, statsService, mPolicyManager, IoThread.get().getLooper(), new MockableSystemProperties()); @@ -1814,8 +1817,8 @@ public class ConnectivityService extends IConnectivityManager.Stub // Overridden for testing purposes to avoid writing to SystemProperties. @VisibleForTesting - protected int getDefaultTcpRwnd() { - return SystemProperties.getInt(DEFAULT_TCP_RWND_KEY, 0); + protected MockableSystemProperties getSystemProperties() { + return new MockableSystemProperties(); } private void updateTcpBufferSizes(NetworkAgentInfo nai) { @@ -1853,10 +1856,11 @@ public class ConnectivityService extends IConnectivityManager.Stub } Integer rwndValue = Settings.Global.getInt(mContext.getContentResolver(), - Settings.Global.TCP_DEFAULT_INIT_RWND, getDefaultTcpRwnd()); + Settings.Global.TCP_DEFAULT_INIT_RWND, + mSystemProperties.getInt("net.tcp.default_init_rwnd", 0)); final String sysctlKey = "sys.sysctl.tcp_def_init_rwnd"; if (rwndValue != 0) { - SystemProperties.set(sysctlKey, rwndValue.toString()); + mSystemProperties.set(sysctlKey, rwndValue.toString()); } } @@ -1880,7 +1884,7 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public int getRestoreDefaultNetworkDelay(int networkType) { - String restoreDefaultNetworkDelayStr = SystemProperties.get( + String restoreDefaultNetworkDelayStr = mSystemProperties.get( NETWORK_RESTORE_DELAY_PROP_NAME); if(restoreDefaultNetworkDelayStr != null && restoreDefaultNetworkDelayStr.length() != 0) { @@ -3081,7 +3085,7 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public boolean isTetheringSupported() { enforceTetherAccessPermission(); - int defaultVal = (SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1); + int defaultVal = (mSystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1); boolean tetherEnabledInSettings = (Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.TETHER_SUPPORTED, defaultVal) != 0) && !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING); @@ -3736,8 +3740,6 @@ public class ConnectivityService extends IConnectivityManager.Stub vpn.setAlwaysOnPackage(null, false); return false; } - - vpn.saveAlwaysOnPackage(); } return true; } @@ -3898,15 +3900,6 @@ public class ConnectivityService extends IConnectivityManager.Stub } userVpn = new Vpn(mHandler.getLooper(), mContext, mNetd, userId); mVpns.put(userId, userVpn); - - final ContentResolver cr = mContext.getContentResolver(); - String alwaysOnPackage = Settings.Secure.getStringForUser(cr, - Settings.Secure.ALWAYS_ON_VPN_APP, userId); - final boolean alwaysOnLockdown = Settings.Secure.getIntForUser(cr, - Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN, /* default */ 0, userId) != 0; - if (alwaysOnPackage != null) { - userVpn.setAlwaysOnPackage(alwaysOnPackage, alwaysOnLockdown); - } } if (mUserManager.getUserInfo(userId).isPrimary() && LockdownVpnTracker.isEnabled()) { updateLockdownVpn(); @@ -4580,11 +4573,11 @@ public class ConnectivityService extends IConnectivityManager.Stub ++last; String key = "net.dns" + last; String value = dns.getHostAddress(); - SystemProperties.set(key, value); + mSystemProperties.set(key, value); } for (int i = last + 1; i <= mNumDnsEntries; ++i) { String key = "net.dns" + i; - SystemProperties.set(key, ""); + mSystemProperties.set(key, ""); } mNumDnsEntries = last; } diff --git a/services/core/java/com/android/server/FontManagerService.java b/services/core/java/com/android/server/FontManagerService.java index 55a945a6fce1..f1726473c591 100644 --- a/services/core/java/com/android/server/FontManagerService.java +++ b/services/core/java/com/android/server/FontManagerService.java @@ -18,6 +18,7 @@ package com.android.server; import android.content.Context; import android.graphics.FontListParser; +import android.net.Uri; import android.os.ParcelFileDescriptor; import android.text.FontConfig; import android.util.Slog; @@ -34,6 +35,7 @@ import java.io.IOException; public class FontManagerService extends IFontManager.Stub { private static final String TAG = "FontManagerService"; private static final String FONTS_CONFIG = "/system/etc/fonts.xml"; + private static final String SYSTEM_FONT_DIR = "/system/fonts/"; @GuardedBy("mLock") private FontConfig mConfig; @@ -63,28 +65,22 @@ public class FontManagerService extends IFontManager.Stub { public FontConfig getSystemFonts() { synchronized (mLock) { if (mConfig != null) { - return new FontConfig(mConfig); + return mConfig; } - FontConfig config = loadFromSystem(); - if (config == null) { + mConfig = loadFromSystem(); + if (mConfig == null) { return null; } - for (FontConfig.Family family : config.getFamilies()) { + for (FontConfig.Family family : mConfig.getFamilies()) { for (FontConfig.Font font : family.getFonts()) { - File fontFile = new File(font.getFontName()); - try { - font.setFd(ParcelFileDescriptor.open( - fontFile, ParcelFileDescriptor.MODE_READ_ONLY)); - } catch (IOException e) { - Slog.e(TAG, "Error opening font file " + font.getFontName(), e); - } + File fontFile = new File(SYSTEM_FONT_DIR, font.getFontName()); + font.setUri(Uri.fromFile(fontFile)); } } - mConfig = config; - return new FontConfig(mConfig); + return mConfig; } } diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java new file mode 100644 index 000000000000..994adc480fb5 --- /dev/null +++ b/services/core/java/com/android/server/IpSecService.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2017 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.server; + +import static android.Manifest.permission.DUMP; + +import android.content.Context; +import android.net.IIpSecService; +import android.net.INetd; +import android.net.util.NetdService; +import android.os.RemoteException; +import android.util.Log; +import android.util.Slog; + +import java.io.FileDescriptor; +import java.io.PrintWriter; + +/** @hide */ +public class IpSecService extends IIpSecService.Stub { + private static final String TAG = "IpSecService"; + private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG); + private static final String NETD_SERVICE_NAME = "netd"; + + /** Binder context for this service */ + private final Context mContext; + + private Object mLock = new Object(); + + private static final int NETD_FETCH_TIMEOUT = 5000; //ms + + /** + * Constructs a new IpSecService instance + * + * @param context Binder context for this service + */ + private IpSecService(Context context) { + mContext = context; + } + + static IpSecService create(Context context) throws InterruptedException { + final IpSecService service = new IpSecService(context); + service.connectNativeNetdService(); + return service; + } + + public void systemReady() { + if (isNetdAlive()) { + Slog.d(TAG, "IpSecService is ready"); + } else { + Slog.wtf(TAG, "IpSecService not ready: failed to connect to NetD Native Service!"); + } + } + + private void connectNativeNetdService() { + // Avoid blocking the system server to do this + Thread t = + new Thread( + new Runnable() { + @Override + public void run() { + synchronized (mLock) { + NetdService.get(NETD_FETCH_TIMEOUT); + } + } + }); + t.run(); + } + + INetd getNetdInstance() { + final INetd netd = NetdService.getInstance(); + if (netd == null) { + throw new RemoteException("Failed to Get Netd Instance").rethrowFromSystemServer(); + } + return netd; + } + + boolean isNetdAlive() { + synchronized (mLock) { + final INetd netd = getNetdInstance(); + if (netd == null) { + return false; + } + + try { + return netd.isAlive(); + } catch (RemoteException re) { + return false; + } + } + } + + @Override + protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + mContext.enforceCallingOrSelfPermission(DUMP, TAG); + + pw.println("IpSecService Log:"); + pw.println("NetdNativeService Connection: " + (isNetdAlive() ? "alive" : "dead")); + pw.println(); + } +} diff --git a/services/core/java/com/android/server/NetworkScorerAppManager.java b/services/core/java/com/android/server/NetworkScorerAppManager.java index 5b627d934209..1a3bb357eb7b 100644 --- a/services/core/java/com/android/server/NetworkScorerAppManager.java +++ b/services/core/java/com/android/server/NetworkScorerAppManager.java @@ -88,9 +88,12 @@ public class NetworkScorerAppManager { final String serviceLabel = getRecommendationServiceLabel(serviceInfo, pm); final ComponentName useOpenWifiNetworksActivity = findUseOpenWifiNetworksActivity(serviceInfo); + final String networkAvailableNotificationChannelId = + getNetworkAvailableNotificationChannelId(serviceInfo); appDataList.add( new NetworkScorerAppData(serviceInfo.applicationInfo.uid, - serviceComponentName, serviceLabel, useOpenWifiNetworksActivity)); + serviceComponentName, serviceLabel, useOpenWifiNetworksActivity, + networkAvailableNotificationChannelId)); } else { if (VERBOSE) Log.v(TAG, serviceInfo.packageName + " is NOT a valid scorer/recommender."); @@ -145,6 +148,20 @@ public class NetworkScorerAppManager { return null; } + @Nullable + private static String getNetworkAvailableNotificationChannelId(ServiceInfo serviceInfo) { + if (serviceInfo.metaData == null) { + if (DEBUG) { + Log.d(TAG, "No metadata found on " + serviceInfo.getComponentName()); + } + return null; + } + + return serviceInfo.metaData.getString( + NetworkScoreManager.NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID_META_DATA); + } + + /** * Get the application to use for scoring networks. * diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 457c5f8e1f65..c68000ab00d4 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -98,6 +98,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.app.IMediaContainerService; import com.android.internal.os.AppFuseMount; import com.android.internal.os.FuseAppLoop; +import com.android.internal.os.FuseUnavailableMountException; import com.android.internal.os.SomeArgs; import com.android.internal.os.Zygote; import com.android.internal.util.ArrayUtils; @@ -3007,32 +3008,36 @@ class StorageManagerService extends IStorageManager.Stub } } - private ParcelFileDescriptor mountAppFuse(int uid, int mountId) - throws NativeDaemonConnectorException { - final NativeDaemonEvent event = StorageManagerService.this.mConnector.execute( - "appfuse", "mount", uid, Process.myPid(), mountId); - if (event.getFileDescriptors() == null || - event.getFileDescriptors().length == 0) { - throw new NativeDaemonConnectorException("Cannot obtain device FD"); + class AppFuseMountScope extends AppFuseBridge.MountScope { + boolean opened = false; + + public AppFuseMountScope(int uid, int pid, int mountId) { + super(uid, pid, mountId); } - return new ParcelFileDescriptor(event.getFileDescriptors()[0]); - } - class AppFuseMountScope extends AppFuseBridge.MountScope { - public AppFuseMountScope(int uid, int pid, int mountId) - throws NativeDaemonConnectorException { - super(uid, pid, mountId, mountAppFuse(uid, mountId)); + @Override + public ParcelFileDescriptor open() throws NativeDaemonConnectorException { + final NativeDaemonEvent event = StorageManagerService.this.mConnector.execute( + "appfuse", "mount", uid, Process.myPid(), mountId); + opened = true; + if (event.getFileDescriptors() == null || + event.getFileDescriptors().length == 0) { + throw new NativeDaemonConnectorException("Cannot obtain device FD"); + } + return new ParcelFileDescriptor(event.getFileDescriptors()[0]); } @Override public void close() throws Exception { - super.close(); - mConnector.execute("appfuse", "unmount", uid, Process.myPid(), mountId); + if (opened) { + mConnector.execute("appfuse", "unmount", uid, Process.myPid(), mountId); + opened = false; + } } } @Override - public AppFuseMount mountProxyFileDescriptorBridge() throws RemoteException { + public @Nullable AppFuseMount mountProxyFileDescriptorBridge() { Slog.v(TAG, "mountProxyFileDescriptorBridge"); final int uid = Binder.getCallingUid(); final int pid = Binder.getCallingPid(); @@ -3049,12 +3054,12 @@ class StorageManagerService extends IStorageManager.Stub final int name = mNextAppFuseName++; try { return new AppFuseMount( - name, - mAppFuseBridge.addBridge(new AppFuseMountScope(uid, pid, name))); - } catch (AppFuseBridge.BridgeException e) { + name, mAppFuseBridge.addBridge(new AppFuseMountScope(uid, pid, name))); + } catch (FuseUnavailableMountException e) { if (newlyCreated) { // If newly created bridge fails, it's a real error. - throw new RemoteException(e.getMessage()); + Slog.e(TAG, "", e); + return null; } // It seems the thread of mAppFuseBridge has already been terminated. mAppFuseBridge = null; @@ -3067,19 +3072,21 @@ class StorageManagerService extends IStorageManager.Stub } @Override - public ParcelFileDescriptor openProxyFileDescriptor(int mountId, int fileId, int mode) - throws RemoteException { - Slog.v(TAG, "mountProxyFileDescriptorBridge"); + public @Nullable ParcelFileDescriptor openProxyFileDescriptor( + int mountId, int fileId, int mode) { + Slog.v(TAG, "mountProxyFileDescriptor"); final int pid = Binder.getCallingPid(); try { synchronized (mAppFuseLock) { if (mAppFuseBridge == null) { - throw new RemoteException("Cannot find mount point"); + Slog.e(TAG, "FuseBridge has not been created"); + return null; } return mAppFuseBridge.openFile(pid, mountId, fileId, mode); } - } catch (FileNotFoundException | SecurityException | InterruptedException error) { - throw new RemoteException(error.getMessage()); + } catch (FuseUnavailableMountException | InterruptedException error) { + Slog.v(TAG, "The mount point has already been invalid", error); + return null; } } diff --git a/services/core/java/com/android/server/UiThread.java b/services/core/java/com/android/server/UiThread.java index 1bc6250d699a..fd88d2609c25 100644 --- a/services/core/java/com/android/server/UiThread.java +++ b/services/core/java/com/android/server/UiThread.java @@ -17,6 +17,7 @@ package com.android.server; import android.os.Handler; +import android.os.Looper; import android.os.Process; import android.os.Trace; @@ -26,20 +27,28 @@ import android.os.Trace; * on it to avoid UI jank. */ public final class UiThread extends ServiceThread { + private static final long SLOW_DISPATCH_THRESHOLD_MS = 100; private static UiThread sInstance; private static Handler sHandler; private UiThread() { super("android.ui", Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); + } + + @Override + public void run() { // Make sure UiThread is in the fg stune boost group Process.setThreadGroup(Process.myTid(), Process.THREAD_GROUP_TOP_APP); + super.run(); } private static void ensureThreadLocked() { if (sInstance == null) { sInstance = new UiThread(); sInstance.start(); - sInstance.getLooper().setTraceTag(Trace.TRACE_TAG_ACTIVITY_MANAGER); + final Looper looper = sInstance.getLooper(); + looper.setTraceTag(Trace.TRACE_TAG_ACTIVITY_MANAGER); + looper.setSlowDispatchThresholdMs(SLOW_DISPATCH_THRESHOLD_MS); sHandler = new Handler(sInstance.getLooper()); } } diff --git a/services/core/java/com/android/server/accounts/AccountManagerBackupHelper.java b/services/core/java/com/android/server/accounts/AccountManagerBackupHelper.java index c3b7e15e43b6..6380da5e2af8 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerBackupHelper.java +++ b/services/core/java/com/android/server/accounts/AccountManagerBackupHelper.java @@ -100,18 +100,20 @@ public final class AccountManagerBackupHelper { Account account = null; AccountManagerService.UserAccounts accounts = mAccountManagerService .getUserAccounts(userId); - synchronized (accounts.cacheLock) { - for (Account[] accountsPerType : accounts.accountCache.values()) { - for (Account accountPerType : accountsPerType) { - if (accountDigest.equals(PackageUtils.computeSha256Digest( - accountPerType.name.getBytes()))) { - account = accountPerType; + synchronized (accounts.dbLock) { + synchronized (accounts.cacheLock) { + for (Account[] accountsPerType : accounts.accountCache.values()) { + for (Account accountPerType : accountsPerType) { + if (accountDigest.equals(PackageUtils.computeSha256Digest( + accountPerType.name.getBytes()))) { + account = accountPerType; + break; + } + } + if (account != null) { break; } } - if (account != null) { - break; - } } } if (account == null) { @@ -141,49 +143,52 @@ public final class AccountManagerBackupHelper { public byte[] backupAccountAccessPermissions(int userId) { final AccountManagerService.UserAccounts accounts = mAccountManagerService .getUserAccounts(userId); - synchronized (accounts.cacheLock) { - List<Pair<String, Integer>> allAccountGrants = accounts.accountsDb - .findAllAccountGrants(); - if (allAccountGrants.isEmpty()) { - return null; - } - try { - ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); - final XmlSerializer serializer = new FastXmlSerializer(); - serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); - serializer.startDocument(null, true); - serializer.startTag(null, TAG_PERMISSIONS); + synchronized (accounts.dbLock) { + synchronized (accounts.cacheLock) { + List<Pair<String, Integer>> allAccountGrants = accounts.accountsDb + .findAllAccountGrants(); + if (allAccountGrants.isEmpty()) { + return null; + } + try { + ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); + final XmlSerializer serializer = new FastXmlSerializer(); + serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); + serializer.startDocument(null, true); + serializer.startTag(null, TAG_PERMISSIONS); - PackageManager packageManager = mAccountManagerService.mContext.getPackageManager(); - for (Pair<String, Integer> grant : allAccountGrants) { - final String accountName = grant.first; - final int uid = grant.second; + PackageManager packageManager = mAccountManagerService.mContext + .getPackageManager(); + for (Pair<String, Integer> grant : allAccountGrants) { + final String accountName = grant.first; + final int uid = grant.second; - final String[] packageNames = packageManager.getPackagesForUid(uid); - if (packageNames == null) { - continue; - } + final String[] packageNames = packageManager.getPackagesForUid(uid); + if (packageNames == null) { + continue; + } - for (String packageName : packageNames) { - String digest = PackageUtils.computePackageCertSha256Digest( - packageManager, packageName, userId); - if (digest != null) { - serializer.startTag(null, TAG_PERMISSION); - serializer.attribute(null, ATTR_ACCOUNT_SHA_256, - PackageUtils.computeSha256Digest(accountName.getBytes())); - serializer.attribute(null, ATTR_PACKAGE, packageName); - serializer.attribute(null, ATTR_DIGEST, digest); - serializer.endTag(null, TAG_PERMISSION); + for (String packageName : packageNames) { + String digest = PackageUtils.computePackageCertSha256Digest( + packageManager, packageName, userId); + if (digest != null) { + serializer.startTag(null, TAG_PERMISSION); + serializer.attribute(null, ATTR_ACCOUNT_SHA_256, + PackageUtils.computeSha256Digest(accountName.getBytes())); + serializer.attribute(null, ATTR_PACKAGE, packageName); + serializer.attribute(null, ATTR_DIGEST, digest); + serializer.endTag(null, TAG_PERMISSION); + } } } + serializer.endTag(null, TAG_PERMISSIONS); + serializer.endDocument(); + serializer.flush(); + return dataStream.toByteArray(); + } catch (IOException e) { + Log.e(TAG, "Error backing up account access grants", e); + return null; } - serializer.endTag(null, TAG_PERMISSIONS); - serializer.endDocument(); - serializer.flush(); - return dataStream.toByteArray(); - } catch (IOException e) { - Log.e(TAG, "Error backing up account access grants", e); - return null; } } } diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index 8e3e3eaa1a60..0ccaf8e914b8 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -114,7 +114,6 @@ import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; -import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -201,17 +200,19 @@ public class AccountManagerService private final HashMap<Account, Integer> signinRequiredNotificationIds = new HashMap<Account, Integer>(); final Object cacheLock = new Object(); + final Object dbLock = new Object(); // if needed, dbLock must be obtained before cacheLock /** protected by the {@link #cacheLock} */ - final HashMap<String, Account[]> accountCache = - new LinkedHashMap<>(); + final HashMap<String, Account[]> accountCache = new LinkedHashMap<>(); /** protected by the {@link #cacheLock} */ private final Map<Account, Map<String, String>> userDataCache = new HashMap<>(); /** protected by the {@link #cacheLock} */ private final Map<Account, Map<String, String>> authTokenCache = new HashMap<>(); /** protected by the {@link #cacheLock} */ private final TokenCache accountTokenCaches = new TokenCache(); + /** protected by the {@link #cacheLock} */ + private final Map<Account, Map<String, Integer>> visibilityCache = new HashMap<>(); - /** protected by the {@link #mReceiversForType} + /** protected by the {@link #mReceiversForType}, * type -> (packageName -> number of active receivers) * type == null is used to get notifications about all account types */ @@ -237,8 +238,10 @@ public class AccountManagerService UserAccounts(Context context, int userId, File preNDbFile, File deDbFile) { this.userId = userId; - synchronized (cacheLock) { - accountsDb = AccountsDb.create(context, userId, preNDbFile, deDbFile); + synchronized (dbLock) { + synchronized (cacheLock) { + accountsDb = AccountsDb.create(context, userId, preNDbFile, deDbFile); + } } } } @@ -499,12 +502,14 @@ public class AccountManagerService Map<Account, Integer> result = new LinkedHashMap<>(); for (String accountType : accountTypes) { - synchronized (accounts.cacheLock) { - final Account[] accountsOfType = accounts.accountCache.get(accountType); - if (accountsOfType != null) { - for (Account account : accountsOfType) { - result.put(account, - resolveAccountVisibility(account, packageName, accounts)); + synchronized (accounts.dbLock) { + synchronized (accounts.cacheLock) { + final Account[] accountsOfType = accounts.accountCache.get(accountType); + if (accountsOfType != null) { + for (Account account : accountsOfType) { + result.put(account, + resolveAccountVisibility(account, packageName, accounts)); + } } } } @@ -524,25 +529,31 @@ public class AccountManagerService String.format("uid %s cannot get secrets for account %s", callingUid, account); throw new SecurityException(msg); } - return getPackagesAndVisibilityForAccount(account, accounts); + synchronized (accounts.dbLock) { + synchronized (accounts.cacheLock) { + return getPackagesAndVisibilityForAccountLocked(account, accounts); + } + } } /** - * Returns all package names and visibility values, which were set for given account. + * Returns Map with all package names and visibility values for given account. + * The method and returned map must be guarded by accounts.cacheLock * * @param account Account to get visibility values. * @param accounts UserAccount that currently hosts the account and application * - * @return Map from package names to visibility. + * @return Map with cache for package names to visibility. */ - private Map<String, Integer> getPackagesAndVisibilityForAccount(Account account, + private @NonNull Map<String, Integer> getPackagesAndVisibilityForAccountLocked(Account account, UserAccounts accounts) { - final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); - try { - return accounts.accountsDb.findAllVisibilityValuesForAccount(account); - } finally { - StrictMode.setThreadPolicy(oldPolicy); + Map<String, Integer> accountVisibility = accounts.visibilityCache.get(account); + if (accountVisibility == null) { + Log.d(TAG, "Visibility was not initialized"); + accountVisibility = new HashMap<>(); + accounts.visibilityCache.put(account, accountVisibility); } + return accountVisibility; } @Override @@ -572,14 +583,13 @@ public class AccountManagerService * @return Visibility value, AccountManager.VISIBILITY_UNDEFINED if no value was stored. * */ - private int getAccountVisibility(Account account, String packageName, UserAccounts accounts) { - final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); - try { - Integer visibility = - accounts.accountsDb.findAccountVisibility(account, packageName); + private int getAccountVisibilityFromCache(Account account, String packageName, + UserAccounts accounts) { + synchronized (accounts.cacheLock) { + Map<String, Integer> accountVisibility = + getPackagesAndVisibilityForAccountLocked(account, accounts); + Integer visibility = accountVisibility.get(packageName); return visibility != null ? visibility : AccountManager.VISIBILITY_UNDEFINED; - } finally { - StrictMode.setThreadPolicy(oldPolicy); } } @@ -595,9 +605,7 @@ public class AccountManagerService */ private Integer resolveAccountVisibility(Account account, @NonNull String packageName, UserAccounts accounts) { - Preconditions.checkNotNull(packageName, "packageName cannot be null"); - int uid = -1; try { long identityToken = clearCallingIdentity(); @@ -630,7 +638,7 @@ public class AccountManagerService } // Return stored value if it was set. - int visibility = getAccountVisibility(account, packageName, accounts); + int visibility = getAccountVisibilityFromCache(account, packageName, accounts); if (AccountManager.VISIBILITY_UNDEFINED != visibility) { return visibility; @@ -652,13 +660,13 @@ public class AccountManagerService || canReadContacts || isPrivileged) { // Use legacy for preO apps with GET_ACCOUNTS permission or pre/postO with signature // match. - visibility = getAccountVisibility(account, + visibility = getAccountVisibilityFromCache(account, AccountManager.PACKAGE_NAME_KEY_LEGACY_VISIBLE, accounts); if (AccountManager.VISIBILITY_UNDEFINED == visibility) { visibility = AccountManager.VISIBILITY_USER_MANAGED_VISIBLE; } } else { - visibility = getAccountVisibility(account, + visibility = getAccountVisibilityFromCache(account, AccountManager.PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE, accounts); if (AccountManager.VISIBILITY_UNDEFINED == visibility) { visibility = AccountManager.VISIBILITY_USER_MANAGED_NOT_VISIBLE; @@ -727,57 +735,73 @@ public class AccountManagerService */ private boolean setAccountVisibility(Account account, String packageName, int newVisibility, boolean notify, UserAccounts accounts) { - synchronized (accounts.cacheLock) { - Map<String, Integer> packagesToVisibility; - if (notify) { - if (isSpecialPackageKey(packageName)) { - packagesToVisibility = - getRequestingPackages(account, accounts); + synchronized (accounts.dbLock) { + synchronized (accounts.cacheLock) { + Map<String, Integer> packagesToVisibility; + if (notify) { + if (isSpecialPackageKey(packageName)) { + packagesToVisibility = + getRequestingPackages(account, accounts); + } else { + if (!packageExistsForUser(packageName, accounts.userId)) { + return false; // package is not installed. + } + packagesToVisibility = new HashMap<>(); + packagesToVisibility.put(packageName, + resolveAccountVisibility(account, packageName, accounts)); + } } else { - if (!packageExistsForUser(packageName, accounts.userId)) { - return false; // package is not installed. + // Notifications will not be send. + if (!isSpecialPackageKey(packageName) && + !packageExistsForUser(packageName, accounts.userId)) { + // package is not installed and not meta value. + return false; } packagesToVisibility = new HashMap<>(); - packagesToVisibility.put(packageName, - resolveAccountVisibility(account, packageName, accounts)); } - } else { - // Notifications will not be send. - if (!isSpecialPackageKey(packageName) && - !packageExistsForUser(packageName, accounts.userId)) { - // package is not installed and not meta value. - return false; - } - packagesToVisibility = new HashMap<>(); - } - - final long accountId = accounts.accountsDb.findDeAccountId(account); - if (accountId < 0) { - return false; - } - final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); - try { - if (!accounts.accountsDb.setAccountVisibility(accountId, packageName, - newVisibility)) { + if (!updateAccountVisibilityLocked(account, packageName, newVisibility, accounts)) { return false; } - } finally { - StrictMode.setThreadPolicy(oldPolicy); - } - if (notify) { - for (Entry<String, Integer> packageToVisibility : packagesToVisibility.entrySet()) { - if (packageToVisibility.getValue() != AccountManager.VISIBILITY_NOT_VISIBLE) { - notifyPackage(packageToVisibility.getKey(), accounts); + if (notify) { + for (Entry<String, Integer> packageToVisibility : packagesToVisibility + .entrySet()) { + if (packageToVisibility.getValue() + != AccountManager.VISIBILITY_NOT_VISIBLE) { + notifyPackage(packageToVisibility.getKey(), accounts); + } } + sendAccountsChangedBroadcast(accounts.userId); } - sendAccountsChangedBroadcast(accounts.userId); + return true; } - return true; } } + // Update account visibility in cache and database. + private boolean updateAccountVisibilityLocked(Account account, String packageName, + int newVisibility, UserAccounts accounts) { + final long accountId = accounts.accountsDb.findDeAccountId(account); + if (accountId < 0) { + return false; + } + + final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); + try { + if (!accounts.accountsDb.setAccountVisibility(accountId, packageName, + newVisibility)) { + return false; + } + } finally { + StrictMode.setThreadPolicy(oldPolicy); + } + Map<String, Integer> accountVisibility = + getPackagesAndVisibilityForAccountLocked(account, accounts); + accountVisibility.put(packageName, newVisibility); + return true; + } + @Override public void registerAccountListener(String[] accountTypes, String opPackageName) { int callingUid = Binder.getCallingUid(); @@ -956,23 +980,24 @@ public class AccountManagerService mAuthenticatorCache, accounts.userId); boolean userUnlocked = isLocalUnlockedUser(accounts.userId); - synchronized (accounts.cacheLock) { - boolean accountDeleted = false; - - // Get a map of stored authenticator types to UID - final AccountsDb accountsDb = accounts.accountsDb; - Map<String, Integer> metaAuthUid = accountsDb.findMetaAuthUid(); - // Create a list of authenticator type whose previous uid no longer exists - HashSet<String> obsoleteAuthType = Sets.newHashSet(); - SparseBooleanArray knownUids = null; - for (Entry<String, Integer> authToUidEntry : metaAuthUid.entrySet()) { - String type = authToUidEntry.getKey(); - int uid = authToUidEntry.getValue(); - Integer knownUid = knownAuth.get(type); - if (knownUid != null && uid == knownUid) { - // Remove it from the knownAuth list if it's unchanged. - knownAuth.remove(type); - } else { + synchronized (accounts.dbLock) { + synchronized (accounts.cacheLock) { + boolean accountDeleted = false; + + // Get a map of stored authenticator types to UID + final AccountsDb accountsDb = accounts.accountsDb; + Map<String, Integer> metaAuthUid = accountsDb.findMetaAuthUid(); + // Create a list of authenticator type whose previous uid no longer exists + HashSet<String> obsoleteAuthType = Sets.newHashSet(); + SparseBooleanArray knownUids = null; + for (Entry<String, Integer> authToUidEntry : metaAuthUid.entrySet()) { + String type = authToUidEntry.getKey(); + int uid = authToUidEntry.getValue(); + Integer knownUid = knownAuth.get(type); + if (knownUid != null && uid == knownUid) { + // Remove it from the knownAuth list if it's unchanged. + knownAuth.remove(type); + } else { /* * The authenticator is presently not cached and should only be triggered * when we think an authenticator has been removed (or is being updated). @@ -989,87 +1014,95 @@ public class AccountManagerService * uninstalled while the authenticator's package is being updated. * */ - if (knownUids == null) { - knownUids = getUidsOfInstalledOrUpdatedPackagesAsUser(accounts.userId); - } - if (!knownUids.get(uid)) { - // The authenticator is not presently available to the cache. And the - // package no longer has a data directory (so we surmise it isn't updating). - // So purge its data from the account databases. - obsoleteAuthType.add(type); - // And delete it from the TABLE_META - accountsDb.deleteMetaByAuthTypeAndUid(type, uid); + if (knownUids == null) { + knownUids = getUidsOfInstalledOrUpdatedPackagesAsUser(accounts.userId); + } + if (!knownUids.get(uid)) { + // The authenticator is not presently available to the cache. And the + // package no longer has a data directory (so we surmise it isn't + // updating). So purge its data from the account databases. + obsoleteAuthType.add(type); + // And delete it from the TABLE_META + accountsDb.deleteMetaByAuthTypeAndUid(type, uid); + } } } - } - // Add the newly registered authenticator to TABLE_META. If old authenticators have - // been re-enabled (after being updated for example), then we just overwrite the old - // values. - for (Entry<String, Integer> entry : knownAuth.entrySet()) { - accountsDb.insertOrReplaceMetaAuthTypeAndUid(entry.getKey(), entry.getValue()); - } + // Add the newly registered authenticator to TABLE_META. If old authenticators have + // been re-enabled (after being updated for example), then we just overwrite the old + // values. + for (Entry<String, Integer> entry : knownAuth.entrySet()) { + accountsDb.insertOrReplaceMetaAuthTypeAndUid(entry.getKey(), entry.getValue()); + } - final Map<Long, Account> accountsMap = accountsDb.findAllDeAccounts(); - try { - accounts.accountCache.clear(); - final HashMap<String, ArrayList<String>> accountNamesByType = new LinkedHashMap<>(); - for (Entry<Long, Account> accountEntry : accountsMap.entrySet()) { - final long accountId = accountEntry.getKey(); - final Account account = accountEntry.getValue(); - if (obsoleteAuthType.contains(account.type)) { - Slog.w(TAG, "deleting account " + account.name + " because type " - + account.type + "'s registered authenticator no longer exist."); - Map<String, Integer> packagesToVisibility = - getRequestingPackages(account, accounts); - accountsDb.beginTransaction(); - try { - accountsDb.deleteDeAccount(accountId); - // Also delete from CE table if user is unlocked; if user is currently - // locked the account will be removed later by syncDeCeAccountsLocked - if (userUnlocked) { - accountsDb.deleteCeAccount(accountId); + final Map<Long, Account> accountsMap = accountsDb.findAllDeAccounts(); + try { + accounts.accountCache.clear(); + final HashMap<String, ArrayList<String>> accountNamesByType + = new LinkedHashMap<>(); + for (Entry<Long, Account> accountEntry : accountsMap.entrySet()) { + final long accountId = accountEntry.getKey(); + final Account account = accountEntry.getValue(); + if (obsoleteAuthType.contains(account.type)) { + Slog.w(TAG, "deleting account " + account.name + " because type " + + account.type + + "'s registered authenticator no longer exist."); + Map<String, Integer> packagesToVisibility = + getRequestingPackages(account, accounts); + accountsDb.beginTransaction(); + try { + accountsDb.deleteDeAccount(accountId); + // Also delete from CE table if user is unlocked; if user is + // currently locked the account will be removed later by + // syncDeCeAccountsLocked + if (userUnlocked) { + accountsDb.deleteCeAccount(accountId); + } + accountsDb.setTransactionSuccessful(); + } finally { + accountsDb.endTransaction(); } - accountsDb.setTransactionSuccessful(); - } finally { - accountsDb.endTransaction(); - } - accountDeleted = true; + accountDeleted = true; - logRecord(AccountsDb.DEBUG_ACTION_AUTHENTICATOR_REMOVE, - AccountsDb.TABLE_ACCOUNTS, accountId, accounts); + logRecord(AccountsDb.DEBUG_ACTION_AUTHENTICATOR_REMOVE, + AccountsDb.TABLE_ACCOUNTS, accountId, accounts); - accounts.userDataCache.remove(account); - accounts.authTokenCache.remove(account); - accounts.accountTokenCaches.remove(account); + accounts.userDataCache.remove(account); + accounts.authTokenCache.remove(account); + accounts.accountTokenCaches.remove(account); + accounts.visibilityCache.remove(account); - for (Entry<String, Integer> packageToVisibility : packagesToVisibility.entrySet()) { - if (packageToVisibility.getValue() != AccountManager.VISIBILITY_NOT_VISIBLE) { - notifyPackage(packageToVisibility.getKey(), accounts); + for (Entry<String, Integer> packageToVisibility : + packagesToVisibility.entrySet()) { + if (packageToVisibility.getValue() + != AccountManager.VISIBILITY_NOT_VISIBLE) { + notifyPackage(packageToVisibility.getKey(), accounts); + } } + } else { + ArrayList<String> accountNames = accountNamesByType.get(account.type); + if (accountNames == null) { + accountNames = new ArrayList<>(); + accountNamesByType.put(account.type, accountNames); + } + accountNames.add(account.name); } - } else { - ArrayList<String> accountNames = accountNamesByType.get(account.type); - if (accountNames == null) { - accountNames = new ArrayList<>(); - accountNamesByType.put(account.type, accountNames); + } + for (Map.Entry<String, ArrayList<String>> cur : accountNamesByType.entrySet()) { + final String accountType = cur.getKey(); + final ArrayList<String> accountNames = cur.getValue(); + final Account[] accountsForType = new Account[accountNames.size()]; + for (int i = 0; i < accountsForType.length; i++) { + accountsForType[i] = new Account(accountNames.get(i), accountType, + UUID.randomUUID().toString()); } - accountNames.add(account.name); + accounts.accountCache.put(accountType, accountsForType); } - } - for (Map.Entry<String, ArrayList<String>> cur : accountNamesByType.entrySet()) { - final String accountType = cur.getKey(); - final ArrayList<String> accountNames = cur.getValue(); - final Account[] accountsForType = new Account[accountNames.size()]; - for (int i = 0; i < accountsForType.length; i++) { - accountsForType[i] = new Account(accountNames.get(i), accountType, - UUID.randomUUID().toString()); + accounts.visibilityCache.putAll(accountsDb.findAllVisibilityValues()); + } finally { + if (accountDeleted) { + sendAccountsChangedBroadcast(accounts.userId); } - accounts.accountCache.put(accountType, accountsForType); - } - } finally { - if (accountDeleted) { - sendAccountsChangedBroadcast(accounts.userId); } } } @@ -1129,9 +1162,11 @@ public class AccountManagerService // open CE database if necessary if (!accounts.accountsDb.isCeDatabaseAttached() && mLocalUnlockedUsers.get(userId)) { Log.i(TAG, "User " + userId + " is unlocked - opening CE database"); - synchronized (accounts.cacheLock) { - File ceDatabaseFile = new File(mInjector.getCeDatabaseName(userId)); - accounts.accountsDb.attachCeDatabase(ceDatabaseFile); + synchronized (accounts.dbLock) { + synchronized (accounts.cacheLock) { + File ceDatabaseFile = new File(mInjector.getCeDatabaseName(userId)); + accounts.accountsDb.attachCeDatabase(ceDatabaseFile); + } } syncDeCeAccountsLocked(accounts); } @@ -1166,34 +1201,50 @@ public class AccountManagerService } private void purgeOldGrants(UserAccounts accounts) { - synchronized (accounts.cacheLock) { - List<Integer> uids = accounts.accountsDb.findAllUidGrants(); - for (int uid : uids) { - final boolean packageExists = mPackageManager.getPackagesForUid(uid) != null; - if (packageExists) { - continue; + synchronized (accounts.dbLock) { + synchronized (accounts.cacheLock) { + List<Integer> uids = accounts.accountsDb.findAllUidGrants(); + for (int uid : uids) { + final boolean packageExists = mPackageManager.getPackagesForUid(uid) != null; + if (packageExists) { + continue; + } + Log.d(TAG, "deleting grants for UID " + uid + + " because its package is no longer installed"); + accounts.accountsDb.deleteGrantsByUid(uid); } - Log.d(TAG, "deleting grants for UID " + uid - + " because its package is no longer installed"); - accounts.accountsDb.deleteGrantsByUid(uid); } } } private void removeVisibilityValuesForPackage(String packageName) { + if (isSpecialPackageKey(packageName)) { + return; + } synchronized (mUsers) { - for (int i = 0; i < mUsers.size(); i++) { - UserAccounts accounts = mUsers.valueAt(i); - try { - int uid = mPackageManager.getPackageUidAsUser(packageName, accounts.userId); - } catch (NameNotFoundException e) { - // package does not exist - remove visibility values - accounts.accountsDb.deleteAccountVisibilityForPackage(packageName); + int numberOfUsers = mUsers.size(); + for (int i = 0; i < numberOfUsers; i++) { + UserAccounts accounts = mUsers.valueAt(i); + try { + mPackageManager.getPackageUidAsUser(packageName, accounts.userId); + } catch (NameNotFoundException e) { + // package does not exist - remove visibility values + accounts.accountsDb.deleteAccountVisibilityForPackage(packageName); + synchronized (accounts.dbLock) { + synchronized (accounts.cacheLock) { + for (Account account : accounts.visibilityCache.keySet()) { + Map<String, Integer> accountVisibility = + getPackagesAndVisibilityForAccountLocked(account, accounts); + accountVisibility.remove(packageName); + } + } + } } } } } + private void onCleanupUser(int userId) { Log.i(TAG, "onCleanupUser " + userId); UserAccounts accounts; @@ -1203,8 +1254,10 @@ public class AccountManagerService mLocalUnlockedUsers.delete(userId); } if (accounts != null) { - synchronized (accounts.cacheLock) { - accounts.accountsDb.close(); + synchronized (accounts.dbLock) { + synchronized (accounts.cacheLock) { + accounts.accountsDb.close(); + } } } } @@ -1284,8 +1337,11 @@ public class AccountManagerService return null; } - synchronized (accounts.cacheLock) { - return accounts.accountsDb.findAccountPasswordByNameAndType(account.name, account.type); + synchronized (accounts.dbLock) { + synchronized (accounts.cacheLock) { + return accounts.accountsDb + .findAccountPasswordByNameAndType(account.name, account.type); + } } } @@ -1311,15 +1367,17 @@ public class AccountManagerService if (account == null) { return null; } - synchronized (accounts.cacheLock) { - AtomicReference<String> previousNameRef = accounts.previousNameCache.get(account); - if (previousNameRef == null) { - String previousName = accounts.accountsDb.findDeAccountPreviousName(account); - previousNameRef = new AtomicReference<>(previousName); - accounts.previousNameCache.put(account, previousNameRef); - return previousName; - } else { - return previousNameRef.get(); + synchronized (accounts.dbLock) { + synchronized (accounts.cacheLock) { + AtomicReference<String> previousNameRef = accounts.previousNameCache.get(account); + if (previousNameRef == null) { + String previousName = accounts.accountsDb.findDeAccountPreviousName(account); + previousNameRef = new AtomicReference<>(previousName); + accounts.previousNameCache.put(account, previousNameRef); + return previousName; + } else { + return previousNameRef.get(); + } } } } @@ -1349,11 +1407,13 @@ public class AccountManagerService long identityToken = clearCallingIdentity(); try { UserAccounts accounts = getUserAccounts(userId); - synchronized (accounts.cacheLock) { - if (!accountExistsCacheLocked(accounts, account)) { - return null; + synchronized (accounts.dbLock) { + synchronized (accounts.cacheLock) { + if (!accountExistsCacheLocked(accounts, account)) { + return null; + } + return readUserDataInternalLocked(accounts, account, key); } - return readUserDataInternalLocked(accounts, account, key); } } finally { restoreCallingIdentity(identityToken); @@ -1512,8 +1572,10 @@ public class AccountManagerService private boolean updateLastAuthenticatedTime(Account account) { final UserAccounts accounts = getUserAccountsForCaller(); - synchronized (accounts.cacheLock) { - return accounts.accountsDb.updateAccountLastAuthenticatedTime(account); + synchronized (accounts.dbLock) { + synchronized (accounts.cacheLock) { + return accounts.accountsDb.updateAccountLastAuthenticatedTime(account); + } } } @@ -1536,13 +1598,15 @@ public class AccountManagerService public void run() throws RemoteException { // Confirm that the owner's account still exists before this step. UserAccounts owner = getUserAccounts(parentUserId); - synchronized (owner.cacheLock) { - for (Account acc : getAccounts(parentUserId, - mContext.getOpPackageName())) { - if (acc.equals(account)) { - mAuthenticator.addAccountFromCredentials( - this, account, accountCredentials); - break; + synchronized (owner.dbLock) { + synchronized (owner.cacheLock) { + for (Account acc : getAccounts(parentUserId, + mContext.getOpPackageName())) { + if (acc.equals(account)) { + mAuthenticator.addAccountFromCredentials( + this, account, accountCredentials); + break; + } } } } @@ -1583,51 +1647,55 @@ public class AccountManagerService + " is locked. callingUid=" + callingUid); return false; } - synchronized (accounts.cacheLock) { - accounts.accountsDb.beginTransaction(); - try { - if (accounts.accountsDb.findCeAccountId(account) >= 0) { - Log.w(TAG, "insertAccountIntoDatabase: " + account - + ", skipping since the account already exists"); - return false; - } - long accountId = accounts.accountsDb.insertCeAccount(account, password); - if (accountId < 0) { - Log.w(TAG, "insertAccountIntoDatabase: " + account - + ", skipping the DB insert failed"); - return false; - } - // Insert into DE table - if (accounts.accountsDb.insertDeAccount(account, accountId) < 0) { - Log.w(TAG, "insertAccountIntoDatabase: " + account - + ", skipping the DB insert failed"); - return false; - } - if (extras != null) { - for (String key : extras.keySet()) { - final String value = extras.getString(key); - if (accounts.accountsDb.insertExtra(accountId, key, value) < 0) { - Log.w(TAG, "insertAccountIntoDatabase: " + account - + ", skipping since insertExtra failed for key " + key); - return false; + synchronized (accounts.dbLock) { + synchronized (accounts.cacheLock) { + accounts.accountsDb.beginTransaction(); + try { + if (accounts.accountsDb.findCeAccountId(account) >= 0) { + Log.w(TAG, "insertAccountIntoDatabase: " + account + + ", skipping since the account already exists"); + return false; + } + long accountId = accounts.accountsDb.insertCeAccount(account, password); + if (accountId < 0) { + Log.w(TAG, "insertAccountIntoDatabase: " + account + + ", skipping the DB insert failed"); + return false; + } + // Insert into DE table + if (accounts.accountsDb.insertDeAccount(account, accountId) < 0) { + Log.w(TAG, "insertAccountIntoDatabase: " + account + + ", skipping the DB insert failed"); + return false; + } + if (extras != null) { + for (String key : extras.keySet()) { + final String value = extras.getString(key); + if (accounts.accountsDb.insertExtra(accountId, key, value) < 0) { + Log.w(TAG, "insertAccountIntoDatabase: " + account + + ", skipping since insertExtra failed for key " + key); + return false; + } } } - } - if (packageToVisibility != null) { - for (Entry<String, Integer> entry : packageToVisibility.entrySet()) { - setAccountVisibility(account, entry.getKey() /* package */, - entry.getValue() /* visibility */, false /* notify */, accounts); + if (packageToVisibility != null) { + for (Entry<String, Integer> entry : packageToVisibility.entrySet()) { + setAccountVisibility(account, entry.getKey() /* package */, + entry.getValue() /* visibility */, false /* notify */, + accounts); + } } - } - accounts.accountsDb.setTransactionSuccessful(); + accounts.accountsDb.setTransactionSuccessful(); - logRecord(AccountsDb.DEBUG_ACTION_ACCOUNT_ADD, AccountsDb.TABLE_ACCOUNTS, accountId, - accounts, callingUid); + logRecord(AccountsDb.DEBUG_ACTION_ACCOUNT_ADD, AccountsDb.TABLE_ACCOUNTS, + accountId, + accounts, callingUid); - insertAccountIntoCacheLocked(accounts, account); - } finally { - accounts.accountsDb.endTransaction(); + insertAccountIntoCacheLocked(accounts, account); + } finally { + accounts.accountsDb.endTransaction(); + } } } if (getUserManager().getUserInfo(accounts.userId).canHaveProfile()) { @@ -1812,72 +1880,76 @@ public class AccountManagerService } } } - synchronized (accounts.cacheLock) { - accounts.accountsDb.beginTransaction(); - Account renamedAccount = new Account(newName, accountToRename.type); - if ((accounts.accountsDb.findCeAccountId(renamedAccount) >= 0)) { - Log.e(TAG, "renameAccount failed - account with new name already exists"); - return null; - } - try { - final long accountId = accounts.accountsDb.findDeAccountId(accountToRename); - if (accountId >= 0) { - accounts.accountsDb.renameCeAccount(accountId, newName); - if (accounts.accountsDb.renameDeAccount( - accountId, newName, accountToRename.name)) { - accounts.accountsDb.setTransactionSuccessful(); + synchronized (accounts.dbLock) { + synchronized (accounts.cacheLock) { + accounts.accountsDb.beginTransaction(); + Account renamedAccount = new Account(newName, accountToRename.type); + if ((accounts.accountsDb.findCeAccountId(renamedAccount) >= 0)) { + Log.e(TAG, "renameAccount failed - account with new name already exists"); + return null; + } + try { + final long accountId = accounts.accountsDb.findDeAccountId(accountToRename); + if (accountId >= 0) { + accounts.accountsDb.renameCeAccount(accountId, newName); + if (accounts.accountsDb.renameDeAccount( + accountId, newName, accountToRename.name)) { + accounts.accountsDb.setTransactionSuccessful(); + } else { + Log.e(TAG, "renameAccount failed"); + return null; + } } else { - Log.e(TAG, "renameAccount failed"); + Log.e(TAG, "renameAccount failed - old account does not exist"); return null; } - } else { - Log.e(TAG, "renameAccount failed - old account does not exist"); - return null; + } finally { + accounts.accountsDb.endTransaction(); } - } finally { - accounts.accountsDb.endTransaction(); - } /* * Database transaction was successful. Clean up cached * data associated with the account in the user profile. */ - renamedAccount = insertAccountIntoCacheLocked(accounts, renamedAccount); + renamedAccount = insertAccountIntoCacheLocked(accounts, renamedAccount); /* * Extract the data and token caches before removing the * old account to preserve the user data associated with * the account. */ - Map<String, String> tmpData = accounts.userDataCache.get(accountToRename); - Map<String, String> tmpTokens = accounts.authTokenCache.get(accountToRename); - removeAccountFromCacheLocked(accounts, accountToRename); + Map<String, String> tmpData = accounts.userDataCache.get(accountToRename); + Map<String, String> tmpTokens = accounts.authTokenCache.get(accountToRename); + Map<String, Integer> tmpVisibility = accounts.visibilityCache.get(accountToRename); + removeAccountFromCacheLocked(accounts, accountToRename); /* * Update the cached data associated with the renamed * account. */ - accounts.userDataCache.put(renamedAccount, tmpData); - accounts.authTokenCache.put(renamedAccount, tmpTokens); - accounts.previousNameCache.put( - renamedAccount, - new AtomicReference<>(accountToRename.name)); - resultAccount = renamedAccount; - - int parentUserId = accounts.userId; - if (canHaveProfile(parentUserId)) { + accounts.userDataCache.put(renamedAccount, tmpData); + accounts.authTokenCache.put(renamedAccount, tmpTokens); + accounts.visibilityCache.put(renamedAccount, tmpVisibility); + accounts.previousNameCache.put( + renamedAccount, + new AtomicReference<>(accountToRename.name)); + resultAccount = renamedAccount; + + int parentUserId = accounts.userId; + if (canHaveProfile(parentUserId)) { /* * Owner or system user account was renamed, rename the account for * those users with which the account was shared. */ - List<UserInfo> users = getUserManager().getUsers(true); - for (UserInfo user : users) { - if (user.isRestricted() - && (user.restrictedProfileParentId == parentUserId)) { - renameSharedAccountAsUser(accountToRename, newName, user.id); + List<UserInfo> users = getUserManager().getUsers(true); + for (UserInfo user : users) { + if (user.isRestricted() + && (user.restrictedProfileParentId == parentUserId)) { + renameSharedAccountAsUser(accountToRename, newName, user.id); + } } } - } - sendNotificationAccountUpdated(resultAccount, accounts); - sendAccountsChangedBroadcast(accounts.userId); + sendNotificationAccountUpdated(resultAccount, accounts); + sendAccountsChangedBroadcast(accounts.userId); + } } return resultAccount; } @@ -2075,42 +2147,47 @@ public class AccountManagerService Slog.i(TAG, "Removing account " + account + " while user "+ accounts.userId + " is still locked. CE data will be removed later"); } - synchronized (accounts.cacheLock) { - Map<String, Integer> packagesToVisibility = getRequestingPackages(account, accounts); - accounts.accountsDb.beginTransaction(); - // Set to a dummy value, this will only be used if the database - // transaction succeeds. - long accountId = -1; - try { - accountId = accounts.accountsDb.findDeAccountId(account); - if (accountId >= 0) { - isChanged = accounts.accountsDb.deleteDeAccount(accountId); - } - // always delete from CE table if CE storage is available - // DE account could be removed while CE was locked - if (userUnlocked) { - long ceAccountId = accounts.accountsDb.findCeAccountId(account); - if (ceAccountId >= 0) { - accounts.accountsDb.deleteCeAccount(ceAccountId); + synchronized (accounts.dbLock) { + synchronized (accounts.cacheLock) { + Map<String, Integer> packagesToVisibility = getRequestingPackages(account, + accounts); + accounts.accountsDb.beginTransaction(); + // Set to a dummy value, this will only be used if the database + // transaction succeeds. + long accountId = -1; + try { + accountId = accounts.accountsDb.findDeAccountId(account); + if (accountId >= 0) { + isChanged = accounts.accountsDb.deleteDeAccount(accountId); } - } - accounts.accountsDb.setTransactionSuccessful(); - } finally { - accounts.accountsDb.endTransaction(); - } - if (isChanged) { - removeAccountFromCacheLocked(accounts, account); - for (Entry<String, Integer> packageToVisibility : packagesToVisibility.entrySet()) { - if (packageToVisibility.getValue() != AccountManager.VISIBILITY_NOT_VISIBLE) { - notifyPackage(packageToVisibility.getKey(), accounts); + // always delete from CE table if CE storage is available + // DE account could be removed while CE was locked + if (userUnlocked) { + long ceAccountId = accounts.accountsDb.findCeAccountId(account); + if (ceAccountId >= 0) { + accounts.accountsDb.deleteCeAccount(ceAccountId); + } } + accounts.accountsDb.setTransactionSuccessful(); + } finally { + accounts.accountsDb.endTransaction(); } + if (isChanged) { + removeAccountFromCacheLocked(accounts, account); + for (Entry<String, Integer> packageToVisibility : packagesToVisibility + .entrySet()) { + if (packageToVisibility.getValue() + != AccountManager.VISIBILITY_NOT_VISIBLE) { + notifyPackage(packageToVisibility.getKey(), accounts); + } + } - // Only broadcast LOGIN_ACCOUNTS_CHANGED if a change occurred. - sendAccountsChangedBroadcast(accounts.userId); - String action = userUnlocked ? AccountsDb.DEBUG_ACTION_ACCOUNT_REMOVE - : AccountsDb.DEBUG_ACTION_ACCOUNT_REMOVE_DE; - logRecord(action, AccountsDb.TABLE_ACCOUNTS, accountId, accounts); + // Only broadcast LOGIN_ACCOUNTS_CHANGED if a change occurred. + sendAccountsChangedBroadcast(accounts.userId); + String action = userUnlocked ? AccountsDb.DEBUG_ACTION_ACCOUNT_REMOVE + : AccountsDb.DEBUG_ACTION_ACCOUNT_REMOVE_DE; + logRecord(action, AccountsDb.TABLE_ACCOUNTS, accountId, accounts); + } } } long id = Binder.clearCallingIdentity(); @@ -2160,53 +2237,48 @@ public class AccountManagerService long identityToken = clearCallingIdentity(); try { UserAccounts accounts = getUserAccounts(userId); - synchronized (accounts.cacheLock) { + List<Pair<Account, String>> deletedTokens; + synchronized (accounts.dbLock) { accounts.accountsDb.beginTransaction(); try { - invalidateAuthTokenLocked(accounts, accountType, authToken); - invalidateCustomTokenLocked(accounts, accountType, authToken); + deletedTokens = invalidateAuthTokenLocked(accounts, accountType, authToken); accounts.accountsDb.setTransactionSuccessful(); } finally { accounts.accountsDb.endTransaction(); } + synchronized (accounts.cacheLock) { + for (Pair<Account, String> tokenInfo : deletedTokens) { + Account act = tokenInfo.first; + String tokenType = tokenInfo.second; + writeAuthTokenIntoCacheLocked(accounts, act, tokenType, null); + } + // wipe out cached token in memory. + accounts.accountTokenCaches.remove(accountType, authToken); + } } } finally { restoreCallingIdentity(identityToken); } } - private void invalidateCustomTokenLocked( - UserAccounts accounts, - String accountType, - String authToken) { - if (authToken == null || accountType == null) { - return; - } - // Also wipe out cached token in memory. - accounts.accountTokenCaches.remove(accountType, authToken); - } - - private void invalidateAuthTokenLocked(UserAccounts accounts, String accountType, + private List<Pair<Account, String>> invalidateAuthTokenLocked(UserAccounts accounts, String accountType, String authToken) { - if (authToken == null || accountType == null) { - return; - } + // TODO Move to AccountsDB + List<Pair<Account, String>> results = new ArrayList<>(); Cursor cursor = accounts.accountsDb.findAuthtokenForAllAccounts(accountType, authToken); + try { while (cursor.moveToNext()) { String authTokenId = cursor.getString(0); String accountName = cursor.getString(1); String authTokenType = cursor.getString(2); accounts.accountsDb.deleteAuthToken(authTokenId); - writeAuthTokenIntoCacheLocked( - accounts, - new Account(accountName, accountType), - authTokenType, - null); + results.add(Pair.create(new Account(accountName, accountType), authTokenType)); } } finally { cursor.close(); } + return results; } private void saveCachedToken( @@ -2236,8 +2308,9 @@ public class AccountManagerService } cancelNotification(getSigninRequiredNotificationId(accounts, account), UserHandle.of(accounts.userId)); - synchronized (accounts.cacheLock) { + synchronized (accounts.dbLock) { accounts.accountsDb.beginTransaction(); + boolean updateCache = false; try { long accountId = accounts.accountsDb.findDeAccountId(account); if (accountId < 0) { @@ -2246,12 +2319,17 @@ public class AccountManagerService accounts.accountsDb.deleteAuthtokensByAccountIdAndType(accountId, type); if (accounts.accountsDb.insertAuthToken(accountId, type, authToken) >= 0) { accounts.accountsDb.setTransactionSuccessful(); - writeAuthTokenIntoCacheLocked(accounts, account, type, authToken); + updateCache = true; return true; } return false; } finally { accounts.accountsDb.endTransaction(); + if (updateCache) { + synchronized (accounts.cacheLock) { + writeAuthTokenIntoCacheLocked(accounts, account, type, authToken); + } + } } } } @@ -2349,31 +2427,35 @@ public class AccountManagerService return; } boolean isChanged = false; - synchronized (accounts.cacheLock) { - accounts.accountsDb.beginTransaction(); - try { - final long accountId = accounts.accountsDb.findDeAccountId(account); - if (accountId >= 0) { - accounts.accountsDb.updateCeAccountPassword(accountId, password); - accounts.accountsDb.deleteAuthTokensByAccountId(accountId); - accounts.authTokenCache.remove(account); - accounts.accountTokenCaches.remove(account); - accounts.accountsDb.setTransactionSuccessful(); - // If there is an account whose password will be updated and the database - // transactions succeed, then we say that a change has occured. Even if the - // new password is the same as the old and there were no authtokens to delete. - isChanged = true; - String action = (password == null || password.length() == 0) ? - AccountsDb.DEBUG_ACTION_CLEAR_PASSWORD - : AccountsDb.DEBUG_ACTION_SET_PASSWORD; - logRecord(action, AccountsDb.TABLE_ACCOUNTS, accountId, accounts, callingUid); - } - } finally { - accounts.accountsDb.endTransaction(); - if (isChanged) { - // Send LOGIN_ACCOUNTS_CHANGED only if the something changed. - sendNotificationAccountUpdated(account, accounts); - sendAccountsChangedBroadcast(accounts.userId); + synchronized (accounts.dbLock) { + synchronized (accounts.cacheLock) { + accounts.accountsDb.beginTransaction(); + try { + final long accountId = accounts.accountsDb.findDeAccountId(account); + if (accountId >= 0) { + accounts.accountsDb.updateCeAccountPassword(accountId, password); + accounts.accountsDb.deleteAuthTokensByAccountId(accountId); + accounts.authTokenCache.remove(account); + accounts.accountTokenCaches.remove(account); + accounts.accountsDb.setTransactionSuccessful(); + // If there is an account whose password will be updated and the database + // transactions succeed, then we say that a change has occured. Even if the + // new password is the same as the old and there were no authtokens to + // delete. + isChanged = true; + String action = (password == null || password.length() == 0) ? + AccountsDb.DEBUG_ACTION_CLEAR_PASSWORD + : AccountsDb.DEBUG_ACTION_SET_PASSWORD; + logRecord(action, AccountsDb.TABLE_ACCOUNTS, accountId, accounts, + callingUid); + } + } finally { + accounts.accountsDb.endTransaction(); + if (isChanged) { + // Send LOGIN_ACCOUNTS_CHANGED only if the something changed. + sendNotificationAccountUpdated(account, accounts); + sendAccountsChangedBroadcast(accounts.userId); + } } } } @@ -2427,11 +2509,13 @@ public class AccountManagerService long identityToken = clearCallingIdentity(); try { UserAccounts accounts = getUserAccounts(userId); - synchronized (accounts.cacheLock) { - if (!accountExistsCacheLocked(accounts, account)) { - return; + synchronized (accounts.dbLock) { + synchronized (accounts.cacheLock) { + if (!accountExistsCacheLocked(accounts, account)) { + return; + } + setUserdataInternalLocked(accounts, account, key, value); } - setUserdataInternalLocked(accounts, account, key, value); } } finally { restoreCallingIdentity(identityToken); @@ -3855,10 +3939,8 @@ public class AccountManagerService @Override public void run() throws RemoteException { - synchronized (mAccounts.cacheLock) { - mAccountsOfType = getAccountsFromCacheLocked(mAccounts, mAccountType, mCallingUid, - mPackageName, false /* include managed not visible*/); - } + mAccountsOfType = getAccountsFromCache(mAccounts, mAccountType, + mCallingUid, mPackageName, false /* include managed not visible*/); // check whether each account matches the requested features mAccountsWithFeatures = new ArrayList<>(mAccountsOfType.length); mCurrentAccount = 0; @@ -4002,16 +4084,14 @@ public class AccountManagerService for (int userId : userIds) { UserAccounts userAccounts = getUserAccounts(userId); if (userAccounts == null) continue; - synchronized (userAccounts.cacheLock) { - Account[] accounts = getAccountsFromCacheLocked( - userAccounts, - null /* type */, - Binder.getCallingUid(), - null /* packageName */, - false /* include managed not visible*/); - for (int a = 0; a < accounts.length; a++) { - runningAccounts.add(new AccountAndUser(accounts[a], userId)); - } + Account[] accounts = getAccountsFromCache( + userAccounts, + null /* type */, + Binder.getCallingUid(), + null /* packageName */, + false /* include managed not visible*/); + for (Account account : accounts) { + runningAccounts.add(new AccountAndUser(account, userId)); } } @@ -4097,22 +4177,20 @@ public class AccountManagerService String callingPackage, List<String> visibleAccountTypes, boolean includeUserManagedNotVisible) { - synchronized (userAccounts.cacheLock) { - ArrayList<Account> visibleAccounts = new ArrayList<>(); - for (String visibleType : visibleAccountTypes) { - Account[] accountsForType = getAccountsFromCacheLocked( - userAccounts, visibleType, callingUid, callingPackage, - includeUserManagedNotVisible); - if (accountsForType != null) { - visibleAccounts.addAll(Arrays.asList(accountsForType)); - } - } - Account[] result = new Account[visibleAccounts.size()]; - for (int i = 0; i < visibleAccounts.size(); i++) { - result[i] = visibleAccounts.get(i); + ArrayList<Account> visibleAccounts = new ArrayList<>(); + for (String visibleType : visibleAccountTypes) { + Account[] accountsForType = getAccountsFromCache( + userAccounts, visibleType, callingUid, callingPackage, + includeUserManagedNotVisible); + if (accountsForType != null) { + visibleAccounts.addAll(Arrays.asList(accountsForType)); } - return result; } + Account[] result = new Account[visibleAccounts.size()]; + for (int i = 0; i < visibleAccounts.size(); i++) { + result[i] = visibleAccounts.get(i); + } + return result; } @Override @@ -4178,10 +4256,12 @@ public class AccountManagerService public Account[] getSharedAccountsAsUser(int userId) { userId = handleIncomingUser(userId); UserAccounts accounts = getUserAccounts(userId); - List<Account> accountList = accounts.accountsDb.getSharedAccounts(); - Account[] accountArray = new Account[accountList.size()]; - accountList.toArray(accountArray); - return accountArray; + synchronized (accounts.dbLock) { + List<Account> accountList = accounts.accountsDb.getSharedAccounts(); + Account[] accountArray = new Account[accountList.size()]; + accountList.toArray(accountArray); + return accountArray; + } } @Override @@ -4261,11 +4341,8 @@ public class AccountManagerService try { UserAccounts userAccounts = getUserAccounts(userId); if (features == null || features.length == 0) { - Account[] accounts; - synchronized (userAccounts.cacheLock) { - accounts = getAccountsFromCacheLocked( - userAccounts, type, callingUid, opPackageName, false); - } + Account[] accounts = getAccountsFromCache(userAccounts, type, callingUid, + opPackageName, false); Bundle result = new Bundle(); result.putParcelableArray(AccountManager.KEY_ACCOUNTS, accounts); onResult(response, result); @@ -4821,33 +4898,36 @@ public class AccountManagerService private void dumpUser(UserAccounts userAccounts, FileDescriptor fd, PrintWriter fout, String[] args, boolean isCheckinRequest) { - synchronized (userAccounts.cacheLock) { - if (isCheckinRequest) { - // This is a checkin request. *Only* upload the account types and the count of each. + if (isCheckinRequest) { + // This is a checkin request. *Only* upload the account types and the count of + // each. + synchronized (userAccounts.dbLock) { userAccounts.accountsDb.dumpDeAccountsTable(fout); - } else { - Account[] accounts = getAccountsFromCacheLocked(userAccounts, null /* type */, - Process.SYSTEM_UID, null /* packageName */, false); - fout.println("Accounts: " + accounts.length); - for (Account account : accounts) { - fout.println(" " + account); - } + } + } else { + Account[] accounts = getAccountsFromCache(userAccounts, null /* type */, + Process.SYSTEM_UID, null /* packageName */, false); + fout.println("Accounts: " + accounts.length); + for (Account account : accounts) { + fout.println(" " + account); + } - // Add debug information. - fout.println(); + // Add debug information. + fout.println(); + synchronized (userAccounts.dbLock) { userAccounts.accountsDb.dumpDebugTable(fout); - fout.println(); - synchronized (mSessions) { - final long now = SystemClock.elapsedRealtime(); - fout.println("Active Sessions: " + mSessions.size()); - for (Session session : mSessions.values()) { - fout.println(" " + session.toDebugString(now)); - } + } + fout.println(); + synchronized (mSessions) { + final long now = SystemClock.elapsedRealtime(); + fout.println("Active Sessions: " + mSessions.size()); + for (Session session : mSessions.values()) { + fout.println(" " + session.toDebugString(now)); } - - fout.println(); - mAuthenticatorCache.dump(fd, fout, args, userAccounts.userId); } + + fout.println(); + mAuthenticatorCache.dump(fd, fout, args, userAccounts.userId); } } @@ -5160,26 +5240,28 @@ public class AccountManagerService return true; } UserAccounts accounts = getUserAccounts(UserHandle.getUserId(callerUid)); - synchronized (accounts.cacheLock) { - long grantsCount; - if (authTokenType != null) { - grantsCount = accounts.accountsDb.findMatchingGrantsCount(callerUid, authTokenType, - account); - } else { - grantsCount = accounts.accountsDb.findMatchingGrantsCountAnyToken(callerUid, - account); - } - final boolean permissionGranted = grantsCount > 0; - - if (!permissionGranted && ActivityManager.isRunningInTestHarness()) { - // TODO: Skip this check when running automated tests. Replace this - // with a more general solution. - Log.d(TAG, "no credentials permission for usage of " + account + ", " - + authTokenType + " by uid " + callerUid - + " but ignoring since device is in test harness."); - return true; + synchronized (accounts.dbLock) { + synchronized (accounts.cacheLock) { + long grantsCount; + if (authTokenType != null) { + grantsCount = accounts.accountsDb + .findMatchingGrantsCount(callerUid, authTokenType, account); + } else { + grantsCount = accounts.accountsDb.findMatchingGrantsCountAnyToken(callerUid, + account); + } + final boolean permissionGranted = grantsCount > 0; + + if (!permissionGranted && ActivityManager.isRunningInTestHarness()) { + // TODO: Skip this check when running automated tests. Replace this + // with a more general solution. + Log.d(TAG, "no credentials permission for usage of " + account + ", " + + authTokenType + " by uid " + callerUid + + " but ignoring since device is in test harness."); + return true; + } + return permissionGranted; } - return permissionGranted; } } @@ -5293,15 +5375,18 @@ public class AccountManagerService return; } UserAccounts accounts = getUserAccounts(UserHandle.getUserId(uid)); - synchronized (accounts.cacheLock) { - long accountId = accounts.accountsDb.findDeAccountId(account); - if (accountId >= 0) { - accounts.accountsDb.insertGrant(accountId, authTokenType, uid); - } - cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid), - UserHandle.of(accounts.userId)); + synchronized (accounts.dbLock) { + synchronized (accounts.cacheLock) { + long accountId = accounts.accountsDb.findDeAccountId(account); + if (accountId >= 0) { + accounts.accountsDb.insertGrant(accountId, authTokenType, uid); + } + cancelNotification( + getCredentialPermissionNotificationId(account, authTokenType, uid), + UserHandle.of(accounts.userId)); - cancelAccountAccessRequestNotificationIfNeeded(account, uid, true); + cancelAccountAccessRequestNotificationIfNeeded(account, uid, true); + } } // Listeners are a final CopyOnWriteArrayList, hence no lock needed. @@ -5325,21 +5410,24 @@ public class AccountManagerService return; } UserAccounts accounts = getUserAccounts(UserHandle.getUserId(uid)); - synchronized (accounts.cacheLock) { - accounts.accountsDb.beginTransaction(); - try { - long accountId = accounts.accountsDb.findDeAccountId(account); - if (accountId >= 0) { - accounts.accountsDb.deleteGrantsByAccountIdAuthTokenTypeAndUid( - accountId, authTokenType, uid); - accounts.accountsDb.setTransactionSuccessful(); + synchronized (accounts.dbLock) { + synchronized (accounts.cacheLock) { + accounts.accountsDb.beginTransaction(); + try { + long accountId = accounts.accountsDb.findDeAccountId(account); + if (accountId >= 0) { + accounts.accountsDb.deleteGrantsByAccountIdAuthTokenTypeAndUid( + accountId, authTokenType, uid); + accounts.accountsDb.setTransactionSuccessful(); + } + } finally { + accounts.accountsDb.endTransaction(); } - } finally { - accounts.accountsDb.endTransaction(); - } - cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid), - new UserHandle(accounts.userId)); + cancelNotification( + getCredentialPermissionNotificationId(account, authTokenType, uid), + UserHandle.of(accounts.userId)); + } } // Listeners are a final CopyOnWriteArrayList, hence no lock needed. @@ -5369,6 +5457,7 @@ public class AccountManagerService accounts.userDataCache.remove(account); accounts.authTokenCache.remove(account); accounts.previousNameCache.remove(account); + accounts.visibilityCache.remove(account); } /** @@ -5496,12 +5585,20 @@ public class AccountManagerService /* * packageName can be null. If not null, it should be used to filter out restricted accounts * that the package is not allowed to access. + * + * <p>The method shouldn't be called with UserAccounts#cacheLock held, otherwise it will cause a + * deadlock */ @NonNull - protected Account[] getAccountsFromCacheLocked(UserAccounts userAccounts, String accountType, + protected Account[] getAccountsFromCache(UserAccounts userAccounts, String accountType, int callingUid, @Nullable String callingPackage, boolean includeManagedNotVisible) { + Preconditions.checkState(!Thread.holdsLock(userAccounts.cacheLock), + "Method should not be called with cacheLock"); if (accountType != null) { - final Account[] accounts = userAccounts.accountCache.get(accountType); + Account[] accounts; + synchronized (userAccounts.cacheLock) { + accounts = userAccounts.accountCache.get(accountType); + } if (accounts == null) { return EMPTY_ACCOUNT_ARRAY; } else { @@ -5510,20 +5607,23 @@ public class AccountManagerService } } else { int totalLength = 0; - for (Account[] accounts : userAccounts.accountCache.values()) { - totalLength += accounts.length; - } - if (totalLength == 0) { - return EMPTY_ACCOUNT_ARRAY; - } - Account[] accounts = new Account[totalLength]; - totalLength = 0; - for (Account[] accountsOfType : userAccounts.accountCache.values()) { - System.arraycopy(accountsOfType, 0, accounts, totalLength, - accountsOfType.length); - totalLength += accountsOfType.length; + Account[] accountsArray; + synchronized (userAccounts.cacheLock) { + for (Account[] accounts : userAccounts.accountCache.values()) { + totalLength += accounts.length; + } + if (totalLength == 0) { + return EMPTY_ACCOUNT_ARRAY; + } + accountsArray = new Account[totalLength]; + totalLength = 0; + for (Account[] accountsOfType : userAccounts.accountCache.values()) { + System.arraycopy(accountsOfType, 0, accountsArray, totalLength, + accountsOfType.length); + totalLength += accountsOfType.length; + } } - return filterAccounts(userAccounts, accounts, callingUid, callingPackage, + return filterAccounts(userAccounts, accountsArray, callingUid, callingPackage, includeManagedNotVisible); } } @@ -5548,12 +5648,15 @@ public class AccountManagerService String tokenType, String callingPackage, byte[] pkgSigDigest) { - synchronized (accounts.cacheLock) { - return accounts.accountTokenCaches.get( - account, tokenType, callingPackage, pkgSigDigest); + synchronized (accounts.dbLock) { + synchronized (accounts.cacheLock) { + return accounts.accountTokenCaches.get( + account, tokenType, callingPackage, pkgSigDigest); + } } } + /** protected by the {@code dbLock}, {@code cacheLock} */ protected void writeAuthTokenIntoCacheLocked(UserAccounts accounts, Account account, String key, String value) { Map<String, String> authTokensForAccount = accounts.authTokenCache.get(account); @@ -5570,14 +5673,24 @@ public class AccountManagerService protected String readAuthTokenInternal(UserAccounts accounts, Account account, String authTokenType) { + // Fast path - check if account is already cached synchronized (accounts.cacheLock) { Map<String, String> authTokensForAccount = accounts.authTokenCache.get(account); - if (authTokensForAccount == null) { - // need to populate the cache for this account - authTokensForAccount = accounts.accountsDb.findAuthTokensByAccount(account); - accounts.authTokenCache.put(account, authTokensForAccount); + if (authTokensForAccount != null) { + return authTokensForAccount.get(authTokenType); + } + } + // If not cached yet - do slow path and sync with db if necessary + synchronized (accounts.dbLock) { + synchronized (accounts.cacheLock) { + Map<String, String> authTokensForAccount = accounts.authTokenCache.get(account); + if (authTokensForAccount == null) { + // need to populate the cache for this account + authTokensForAccount = accounts.accountsDb.findAuthTokensByAccount(account); + accounts.authTokenCache.put(account, authTokensForAccount); + } + return authTokensForAccount.get(authTokenType); } - return authTokensForAccount.get(authTokenType); } } diff --git a/services/core/java/com/android/server/accounts/AccountsDb.java b/services/core/java/com/android/server/accounts/AccountsDb.java index 22543cb9e022..8ca7ea1768b9 100644 --- a/services/core/java/com/android/server/accounts/AccountsDb.java +++ b/services/core/java/com/android/server/accounts/AccountsDb.java @@ -909,7 +909,7 @@ class AccountsDb implements AutoCloseable { } Integer findAccountVisibility(Account account, String packageName) { - SQLiteDatabase db = mDeDatabase.getWritableDatabase(); + SQLiteDatabase db = mDeDatabase.getReadableDatabase(); final Cursor cursor = db.query(TABLE_VISIBILITY, new String[] {VISIBILITY_VALUE}, SELECTION_ACCOUNTS_ID_BY_ACCOUNT + " AND " + VISIBILITY_PACKAGE + "=? ", new String[] {account.name, account.type, packageName}, null, null, null); @@ -924,7 +924,7 @@ class AccountsDb implements AutoCloseable { } Integer findAccountVisibility(long accountId, String packageName) { - SQLiteDatabase db = mDeDatabase.getWritableDatabase(); + SQLiteDatabase db = mDeDatabase.getReadableDatabase(); final Cursor cursor = db.query(TABLE_VISIBILITY, new String[] {VISIBILITY_VALUE}, VISIBILITY_ACCOUNTS_ID + "=? AND " + VISIBILITY_PACKAGE + "=? ", new String[] {String.valueOf(accountId), packageName}, null, null, null); @@ -972,6 +972,41 @@ class AccountsDb implements AutoCloseable { return result; } + /** + * Returns a map account -> (package -> visibility) + */ + Map <Account, Map<String, Integer>> findAllVisibilityValues() { + SQLiteDatabase db = mDeDatabase.getReadableDatabase(); + Map<Account, Map<String, Integer>> result = new HashMap<>(); + Cursor cursor = db.rawQuery( + "SELECT " + TABLE_VISIBILITY + "." + VISIBILITY_PACKAGE + + ", " + TABLE_VISIBILITY + "." + VISIBILITY_VALUE + + ", " + TABLE_ACCOUNTS + "." + ACCOUNTS_NAME + + ", " + TABLE_ACCOUNTS + "." + ACCOUNTS_TYPE + + " FROM " + TABLE_VISIBILITY + + " JOIN " + TABLE_ACCOUNTS + + " ON " + TABLE_ACCOUNTS + "." + ACCOUNTS_ID + + " = " + TABLE_VISIBILITY + "." + VISIBILITY_ACCOUNTS_ID, null); + try { + while (cursor.moveToNext()) { + String packageName = cursor.getString(0); + Integer visibility = cursor.getInt(1); + String accountName = cursor.getString(2); + String accountType = cursor.getString(3); + Account account = new Account(accountName, accountType); + Map <String, Integer> accountVisibility = result.get(account); + if (accountVisibility == null) { + accountVisibility = new HashMap<>(); + result.put(account, accountVisibility); + } + accountVisibility.put(packageName, visibility); + } + } finally { + cursor.close(); + } + return result; + } + boolean deleteAccountVisibilityForPackage(String packageName) { SQLiteDatabase db = mDeDatabase.getWritableDatabase(); return db.delete(TABLE_VISIBILITY, VISIBILITY_PACKAGE + "=? ", diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index b4f8f61971f8..8b0665c6d312 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -17,7 +17,6 @@ package com.android.server.am; import static android.content.pm.PackageManager.PERMISSION_GRANTED; -import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import static com.android.server.am.ActivityManagerDebugConfig.*; import java.io.FileDescriptor; @@ -96,6 +95,10 @@ public final class ActiveServices { // How long we wait for a service to finish executing. static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10; + // How long the startForegroundService() grace period is to get around to + // calling startForeground() before we ANR + stop it. + static final int SERVICE_START_FOREGROUND_TIMEOUT = 5*1000; + // How long a service needs to be running until restarting its process // is no longer considered to be a relaunch of the service. static final int SERVICE_RESTART_DURATION = 1*1000; @@ -307,8 +310,8 @@ public final class ActiveServices { } ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, - int id, Notification notification, - int callingPid, int callingUid, String callingPackage, final int userId) + int id, Notification notification, int callingPid, int callingUid, + boolean fgRequired, String callingPackage, final int userId) throws TransactionTooLargeException { if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "startService: " + service + " type=" + resolvedType + " args=" + service.getExtras()); @@ -345,8 +348,9 @@ public final class ActiveServices { return null; } - // Non-null notification means this is a start directly into the foreground - if (!r.startRequested && notification == null) { + // If this isn't a direct-to-foreground start, check our ability to kick off an + // arbitrary service + if (!r.startRequested && !fgRequired) { final long token = Binder.clearCallingIdentity(); try { // Before going further -- if this app is not allowed to start services in the @@ -392,12 +396,13 @@ public final class ActiveServices { r.lastActivity = SystemClock.uptimeMillis(); r.startRequested = true; r.delayedStop = false; + r.fgRequired = fgRequired; r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), service, neededGrants)); final ServiceMap smap = getServiceMapLocked(r.userId); boolean addToStarting = false; - if (!callerFg && r.app == null + if (!callerFg && !fgRequired && r.app == null && mAm.mUserController.hasStartedUserState(r.userId)) { ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false); if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) { @@ -449,9 +454,9 @@ public final class ActiveServices { Slog.v(TAG_SERVICE, sb.toString()); } } else if (DEBUG_DELAYED_STARTS) { - if (callerFg) { + if (callerFg || fgRequired) { Slog.v(TAG_SERVICE, "Not potential delay (callerFg=" + callerFg + " uid=" - + callingUid + " pid=" + callingPid + "): " + r); + + callingUid + " pid=" + callingPid + " fgRequired=" + fgRequired + "): " + r); } else if (r.app != null) { Slog.v(TAG_SERVICE, "Not potential delay (cur app=" + r.app + "): " + r); } else { @@ -461,6 +466,7 @@ public final class ActiveServices { } ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting); + // STOPSHIP deprecated; remove when NotificationManager.startServiceInForeground is retired if (notification != null) { setServiceForegroundInnerLocked(r, id, notification, 0); } @@ -540,7 +546,7 @@ public final class ActiveServices { if (first) { smap.rescheduleDelayedStartsLocked(); } - } else if (callerFg) { + } else if (callerFg || r.fgRequired) { smap.ensureNotStartingBackgroundLocked(r); } @@ -756,8 +762,17 @@ public final class ActiveServices { } } } + if (r.fgRequired) { + if (DEBUG_BACKGROUND_CHECK) { + Slog.i(TAG, "Service called startForeground() as required: " + r); + } + r.fgRequired = false; + r.fgWaiting = false; + mAm.mHandler.removeMessages( + ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG, r); + } if (r.foregroundId != id) { - cancelForegroudNotificationLocked(r); + cancelForegroundNotificationLocked(r); r.foregroundId = id; } notification.flags |= Notification.FLAG_FOREGROUND_SERVICE; @@ -779,7 +794,7 @@ public final class ActiveServices { } } if ((flags & Service.STOP_FOREGROUND_REMOVE) != 0) { - cancelForegroudNotificationLocked(r); + cancelForegroundNotificationLocked(r); r.foregroundId = 0; r.foregroundNoti = null; } else if (r.appInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) { @@ -792,7 +807,7 @@ public final class ActiveServices { } } - private void cancelForegroudNotificationLocked(ServiceRecord r) { + private void cancelForegroundNotificationLocked(ServiceRecord r) { if (r.foregroundId != 0) { // First check to see if this app has any other active foreground services // with the same notification ID. If so, we shouldn't actually cancel it, @@ -1631,7 +1646,7 @@ public final class ActiveServices { r.makeRestarting(mAm.mProcessStats.getMemFactorLocked(), now); } - cancelForegroudNotificationLocked(r); + cancelForegroundNotificationLocked(r); mAm.mHandler.removeCallbacks(r.restarter); mAm.mHandler.postAtTime(r.restarter, r.nextRestartTime); @@ -1718,7 +1733,9 @@ public final class ActiveServices { return null; } - if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bringing up " + r + " " + r.intent); + if (DEBUG_SERVICE) { + Slog.v(TAG_SERVICE, "Bringing up " + r + " " + r.intent + " fg=" + r.fgRequired); + } // We are now bringing the service up, so no longer in the // restarting state. @@ -1944,8 +1961,10 @@ public final class ActiveServices { ServiceRecord.StartItem si = null; try { si = r.pendingStarts.remove(0); - if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Sending arguments to: " - + r + " " + r.intent + " args=" + si.intent); + if (DEBUG_SERVICE) { + Slog.v(TAG_SERVICE, "Sending arguments to: " + + r + " " + r.intent + " args=" + si.intent); + } if (si.intent == null && N > 1) { // If somehow we got a dummy null intent in the middle, // then skip it. DO NOT skip a null intent when it is @@ -1966,6 +1985,19 @@ public final class ActiveServices { oomAdjusted = true; mAm.updateOomAdjLocked(r.app); } + if (r.fgRequired && !r.fgWaiting) { + if (!r.isForeground) { + if (DEBUG_BACKGROUND_CHECK) { + Slog.i(TAG, "Launched service must call startForeground() within timeout: " + r); + } + scheduleServiceForegroundTransitionTimeoutLocked(r); + } else { + if (DEBUG_BACKGROUND_CHECK) { + Slog.i(TAG, "Service already foreground; no new timeout: " + r); + } + r.fgRequired = false; + } + } int flags = 0; if (si.deliveryCount > 1) { flags |= Service.START_FLAG_RETRY; @@ -2101,7 +2133,7 @@ public final class ActiveServices { } } - cancelForegroudNotificationLocked(r); + cancelForegroundNotificationLocked(r); r.isForeground = false; r.foregroundId = 0; r.foregroundNoti = null; @@ -2925,23 +2957,53 @@ public final class ActiveServices { } } + void serviceForegroundTimeout(ServiceRecord r) { + ProcessRecord app; + synchronized (mAm) { + if (!r.fgRequired) { + return; + } + + if (DEBUG_BACKGROUND_CHECK) { + Slog.i(TAG, "Service foreground-required timeout for " + r); + } + app = r.app; + r.fgWaiting = false; + stopServiceLocked(r); + } + + if (app != null) { + mAm.mAppErrors.appNotResponding(app, null, null, false, + "Context.startForegroundService() did not then call Service.startForeground()"); + } + } + void scheduleServiceTimeoutLocked(ProcessRecord proc) { if (proc.executingServices.size() == 0 || proc.thread == null) { return; } - long now = SystemClock.uptimeMillis(); Message msg = mAm.mHandler.obtainMessage( ActivityManagerService.SERVICE_TIMEOUT_MSG); msg.obj = proc; - mAm.mHandler.sendMessageAtTime(msg, - proc.execServicesFg ? (now+SERVICE_TIMEOUT) : (now+ SERVICE_BACKGROUND_TIMEOUT)); + mAm.mHandler.sendMessageDelayed(msg, + proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT); + } + + void scheduleServiceForegroundTransitionTimeoutLocked(ServiceRecord r) { + if (r.app.executingServices.size() == 0 || r.app.thread == null) { + return; + } + Message msg = mAm.mHandler.obtainMessage( + ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG); + msg.obj = r; + r.fgWaiting = true; + mAm.mHandler.sendMessageDelayed(msg, SERVICE_START_FOREGROUND_TIMEOUT); } final class ServiceDumper { private final FileDescriptor fd; private final PrintWriter pw; private final String[] args; - private final int opti; private final boolean dumpAll; private final String dumpPackage; private final ItemMatcher matcher; @@ -2962,7 +3024,6 @@ public final class ActiveServices { this.fd = fd; this.pw = pw; this.args = args; - this.opti = opti; this.dumpAll = dumpAll; this.dumpPackage = dumpPackage; matcher = new ItemMatcher(); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 272fbf86aedd..b4da152a18ae 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -1726,6 +1726,7 @@ public class ActivityManagerService extends IActivityManager.Stub static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63; static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64; static final int NOTIFY_VR_SLEEPING_MSG = 65; + static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66; static final int START_USER_SWITCH_FG_MSG = 712; static final int FIRST_ACTIVITY_STACK_MSG = 100; @@ -1991,6 +1992,9 @@ public class ActivityManagerService extends IActivityManager.Stub } mServices.serviceTimeout((ProcessRecord)msg.obj); } break; + case SERVICE_FOREGROUND_TIMEOUT_MSG: { + mServices.serviceForegroundTimeout((ServiceRecord)msg.obj); + } break; case UPDATE_TIME_ZONE: { synchronized (ActivityManagerService.this) { for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { @@ -2743,6 +2747,7 @@ public class ActivityManagerService extends IActivityManager.Stub @VisibleForTesting public ActivityManagerService(Injector injector) { mInjector = injector; + mContext = mInjector.getContext(); GL_ES_VERSION = 0; mActivityStarter = null; mAppErrors = null; @@ -3211,18 +3216,18 @@ public class ActivityManagerService extends IActivityManager.Stub } } - mWindowManager.setFocusedApp(r.appToken, true); - - applyUpdateLockStateLocked(r); - applyUpdateVrModeLocked(r); if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) { mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG); mHandler.obtainMessage( FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget(); } - mLastResumedActivity = r; + mWindowManager.setFocusedApp(r.appToken, true); + + applyUpdateLockStateLocked(r); + applyUpdateVrModeLocked(r); + EventLogTags.writeAmSetResumedActivity( r == null ? -1 : r.userId, r == null ? "NULL" : r.shortComponentName, @@ -3928,8 +3933,13 @@ public class ActivityManagerService extends IActivityManager.Stub if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { // Debuggable apps may include a wrapper script with their library directory. String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh"; - if (new File(wrapperFileName).exists()) { - invokeWith = "/system/bin/logwrapper " + wrapperFileName; + StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); + try { + if (new File(wrapperFileName).exists()) { + invokeWith = "/system/bin/logwrapper " + wrapperFileName; + } + } finally { + StrictMode.setThreadPolicy(oldPolicy); } } @@ -6590,6 +6600,7 @@ public class ActivityManagerService extends IActivityManager.Stub mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); if (app.isolated) { mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); + getPackageManagerInternalLocked().removeIsolatedUid(app.uid); } boolean willRestart = false; if (app.persistent && !app.isolated) { @@ -12083,6 +12094,7 @@ public class ActivityManagerService extends IActivityManager.Stub // the uid of the isolated process is specified by the caller. uid = isolatedUid; } + getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid); // Register the isolated UID with this application so BatteryStats knows to // attribute resource usage to the application. @@ -17890,7 +17902,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public ComponentName startService(IApplicationThread caller, Intent service, - String resolvedType, int id, Notification notification, + String resolvedType, int id, Notification notification, boolean requireForeground, String callingPackage, int userId) throws TransactionTooLargeException { enforceNotIsolatedCaller("startService"); @@ -17904,28 +17916,28 @@ public class ActivityManagerService extends IActivityManager.Stub } if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, - "startService: " + service + " type=" + resolvedType); + "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground); synchronized(this) { final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); ComponentName res = mServices.startServiceLocked(caller, service, - resolvedType, id, notification, - callingPid, callingUid, callingPackage, userId); + resolvedType, id, notification, callingPid, callingUid, + requireForeground, callingPackage, userId); Binder.restoreCallingIdentity(origId); return res; } } ComponentName startServiceInPackage(int uid, Intent service, String resolvedType, - String callingPackage, int userId) + boolean fgRequired, String callingPackage, int userId) throws TransactionTooLargeException { synchronized(this) { if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "startServiceInPackage: " + service + " type=" + resolvedType); final long origId = Binder.clearCallingIdentity(); ComponentName res = mServices.startServiceLocked(null, service, - resolvedType, 0, null, -1, uid, callingPackage, userId); + resolvedType, 0, null, -1, uid, fgRequired, callingPackage, userId); Binder.restoreCallingIdentity(origId); return res; } @@ -18276,6 +18288,10 @@ public class ActivityManagerService extends IActivityManager.Stub return record.info.isInstantApp(); } // Otherwise check with PackageManager. + if (callerPackage == null) { + Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name"); + throw new IllegalArgumentException("Calling application did not provide package name"); + } mAppOpsService.checkPackage(uid, callerPackage); try { IPackageManager pm = AppGlobals.getPackageManager(); @@ -23589,6 +23605,21 @@ public class ActivityManagerService extends IActivityManager.Stub } } + /** + * Return the user id of the last resumed activity. + */ + @Override + public @UserIdInt int getLastResumedActivityUserId() { + enforceCallingPermission( + permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()"); + synchronized (this) { + if (mLastResumedActivity == null) { + return mUserController.getCurrentUserIdLocked(); + } + return mLastResumedActivity.userId; + } + } + private final class SleepTokenImpl extends SleepToken { private final String mTag; private final long mAcquireTime; @@ -23875,6 +23906,10 @@ public class ActivityManagerService extends IActivityManager.Stub public static class Injector { private NetworkManagementInternal mNmi; + public Context getContext() { + return null; + } + public AppOpsService getAppOpsService(File file, Handler handler) { return new AppOpsService(file, handler); } diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index aaad12c1f289..a9bd87227929 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -82,6 +82,8 @@ import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; import static android.app.ActivityManager.StackId.INVALID_STACK_ID; import static android.view.Display.INVALID_DISPLAY; +import static com.android.server.am.TaskRecord.INVALID_TASK_ID; + final class ActivityManagerShellCommand extends ShellCommand { public static final String NO_CLASS_ERROR_CODE = "Error type 3"; private static final String SHELL_PACKAGE_NAME = "com.android.shell"; @@ -118,6 +120,8 @@ final class ActivityManagerShellCommand extends ShellCommand { private boolean mStreaming; // Streaming the profiling output to a file. private int mDisplayId; private int mStackId; + private int mTaskId; + private boolean mIsTaskOverlay; final boolean mDumping; @@ -263,6 +267,8 @@ final class ActivityManagerShellCommand extends ShellCommand { mUserId = defUser; mDisplayId = INVALID_DISPLAY; mStackId = INVALID_STACK_ID; + mTaskId = INVALID_TASK_ID; + mIsTaskOverlay = false; return Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() { @Override @@ -297,6 +303,10 @@ final class ActivityManagerShellCommand extends ShellCommand { mDisplayId = Integer.parseInt(getNextArgRequired()); } else if (opt.equals("--stack")) { mStackId = Integer.parseInt(getNextArgRequired()); + } else if (opt.equals("--task")) { + mTaskId = Integer.parseInt(getNextArgRequired()); + } else if (opt.equals("--task-overlay")) { + mIsTaskOverlay = true; } else { return false; } @@ -380,6 +390,14 @@ final class ActivityManagerShellCommand extends ShellCommand { options = ActivityOptions.makeBasic(); options.setLaunchStackId(mStackId); } + if (mTaskId != INVALID_TASK_ID) { + options = ActivityOptions.makeBasic(); + options.setLaunchTaskId(mTaskId); + + if (mIsTaskOverlay) { + options.setTaskOverlay(true, true /* canResume */); + } + } if (mWaitOption) { result = mInterface.startActivityAndWait(null, null, intent, mimeType, null, null, 0, mStartFlags, profilerInfo, @@ -501,7 +519,7 @@ final class ActivityManagerShellCommand extends ShellCommand { pw.println("Starting service: " + intent); pw.flush(); ComponentName cn = mInterface.startService(null, intent, intent.getType(), - -1, null, SHELL_PACKAGE_NAME, mUserId); + -1, null, false, SHELL_PACKAGE_NAME, mUserId); if (cn == null) { err.println("Error: Not found; no service started."); return -1; diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java index 04a09fe4305e..5edfb0651fe7 100644 --- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java +++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java @@ -10,8 +10,8 @@ import static android.app.ActivityManager.StackId.INVALID_STACK_ID; import static android.app.ActivityManager.StackId.PINNED_STACK_ID; import static android.app.ActivityManagerInternal.APP_TRANSITION_TIMEOUT; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION; -import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_ACTIVITY_NAME; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_CALLING_PACKAGE_NAME; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CLASS_NAME; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_DELAY_MS; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_DEVICE_UPTIME_SECONDS; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_IS_EPHEMERAL; @@ -313,7 +313,7 @@ class ActivityMetricsLogger { final LogMaker builder = new LogMaker(APP_TRANSITION); builder.setPackageName(info.launchedActivity.packageName); builder.setType(type); - builder.addTaggedData(APP_TRANSITION_ACTIVITY_NAME, info.launchedActivity.info.name); + builder.addTaggedData(FIELD_CLASS_NAME, info.launchedActivity.info.name); if (info.launchedActivity.launchedFromPackage != null) { builder.addTaggedData(APP_TRANSITION_CALLING_PACKAGE_NAME, info.launchedActivity.launchedFromPackage); diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 9a1cd8c3884b..2f61038bc230 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -1820,14 +1820,22 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo } @Override - public boolean keyDispatchingTimedOut(String reason) { + public boolean keyDispatchingTimedOut(String reason, int windowPid) { ActivityRecord anrActivity; ProcessRecord anrApp; + boolean windowFromSameProcessAsActivity; synchronized (service) { anrActivity = getWaitingHistoryRecordLocked(); anrApp = app; + windowFromSameProcessAsActivity = app == null || app.pid == windowPid; + } + if (windowFromSameProcessAsActivity) { + return service.inputDispatchingTimedOut(anrApp, anrActivity, this, false, reason); + } else { + // In this case another process added windows using this activity token. So, we call the + // generic service input dispatch timed out method so that the right process is blamed. + return service.inputDispatchingTimedOut(windowPid, false /* aboveSystem */, reason) < 0; } - return service.inputDispatchingTimedOut(anrApp, anrActivity, this, false, reason); } private ActivityRecord getWaitingHistoryRecordLocked() { diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 9a4f804cb1b3..498de63d11d8 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -67,7 +67,9 @@ import static com.android.server.am.ActivityRecord.ASSISTANT_ACTIVITY_TYPE; import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE; import static com.android.server.am.ActivityStackSupervisor.FindTaskResult; import static com.android.server.am.ActivityStackSupervisor.ON_TOP; +import static com.android.server.am.ActivityStackSupervisor.PAUSE_IMMEDIATELY; import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS; +import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS; import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_CLOSE; import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN; import static com.android.server.wm.AppTransition.TRANSIT_NONE; @@ -121,7 +123,6 @@ import com.android.server.am.ActivityManagerService.ItemMatcher; import com.android.server.am.ActivityStackSupervisor.ActivityContainer; import com.android.server.wm.StackWindowController; import com.android.server.wm.StackWindowListener; -import com.android.server.wm.TaskStack; import com.android.server.wm.WindowManagerService; import java.io.FileDescriptor; @@ -759,6 +760,12 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } } + final void removeActivitiesFromLRUListLocked(TaskRecord task) { + for (ActivityRecord r : task.mActivities) { + mLRUActivities.remove(r); + } + } + final boolean updateLRUListLocked(ActivityRecord r) { final boolean hadit = mLRUActivities.remove(r); mLRUActivities.add(r); @@ -1179,13 +1186,13 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai * @param resuming The activity we are currently trying to resume or null if this is not being * called as part of resuming the top activity, so we shouldn't try to instigate * a resume here if not null. - * @param dontWait True if the caller does not want to wait for the pause to complete. If - * set to true, we will immediately complete the pause here before returning. + * @param pauseImmediately True if the caller does not want to wait for the activity callback to + * complete pausing. * @return Returns true if an activity now is in the PAUSING state, and we are waiting for * it to tell us when it is done. */ final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, - ActivityRecord resuming, boolean dontWait) { + ActivityRecord resuming, boolean pauseImmediately) { if (mPausingActivity != null) { Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity + " state=" + mPausingActivity.state); @@ -1207,7 +1214,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai if (mActivityContainer.mParentActivity == null) { // Top level stack, not a child. Look for child stacks. - mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping, resuming, dontWait); + mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping, resuming, + pauseImmediately); } if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSING: " + prev); @@ -1237,7 +1245,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai prev.shortComponentName); mService.updateUsageStats(prev, false); prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing, - userLeaving, prev.configChangeFlags, dontWait); + userLeaving, prev.configChangeFlags, pauseImmediately); } catch (Exception e) { // Ignore exception, if process died other code will cleanup. Slog.w(TAG, "Exception thrown during pause", e); @@ -1268,7 +1276,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off"); } - if (dontWait) { + if (pauseImmediately) { // If the caller said they don't want to wait for the pause, then complete // the pause now. completePauseLocked(false, resuming); @@ -3482,11 +3490,19 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } /** + * See {@link #finishActivityLocked(ActivityRecord, int, Intent, String, boolean, boolean)} + */ + final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData, + String reason, boolean oomAdj) { + return finishActivityLocked(r, resultCode, resultData, reason, oomAdj, !PAUSE_IMMEDIATELY); + } + + /** * @return Returns true if this activity has been removed from the history * list, or false if it is still in the list and will be removed later. */ final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData, - String reason, boolean oomAdj) { + String reason, boolean oomAdj, boolean pauseImmediately) { if (r.finishing) { Slog.w(TAG, "Duplicate finish request for " + r); return false; @@ -3523,9 +3539,10 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai if (mResumedActivity == r) { if (DEBUG_VISIBILITY || DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare close transition: finishing " + r); - if (endTask) { - mService.mTaskChangeNotificationController.notifyTaskRemovalStarted(task.taskId); - } + if (endTask) { + mService.mTaskChangeNotificationController.notifyTaskRemovalStarted( + task.taskId); + } mWindowManager.prepareAppTransition(transit, false); // Tell window manager to prepare for this one to be removed. @@ -3535,7 +3552,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + r); if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING, "finish() => pause with userLeaving=false"); - startPausingLocked(false, false, null, false); + startPausingLocked(false, false, null, pauseImmediately); } if (endTask) { @@ -3546,15 +3563,30 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai // it is done pausing; else we can just directly finish it here. if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish not pausing: " + r); if (r.visible) { - mWindowManager.prepareAppTransition(transit, false); - r.setVisibility(false); - mWindowManager.executeAppTransition(); - if (!mStackSupervisor.mWaitingVisibleActivities.contains(r)) { - mStackSupervisor.mWaitingVisibleActivities.add(r); + prepareActivityHideTransitionAnimation(r, transit); + } + + final int finishMode = (r.visible || r.nowVisible) ? FINISH_AFTER_VISIBLE + : FINISH_AFTER_PAUSE; + final boolean removedActivity = finishCurrentActivityLocked(r, finishMode, oomAdj) + == null; + + // The following code is an optimization. When the last non-task overlay activity + // is removed from the task, we remove the entire task from the stack. However, + // since that is done after the scheduled destroy callback from the activity, that + // call to change the visibility of the task overlay activities would be out of + // sync with the activitiy visibility being set for this finishing activity above. + // In this case, we can set the visibility of all the task overlay activities when + // we detect the last one is finishing to keep them in sync. + if (task.onlyHasTaskOverlayActivities(true /* excludeFinishing */)) { + for (ActivityRecord taskOverlay : task.mActivities) { + if (!taskOverlay.mTaskOverlay) { + continue; + } + prepareActivityHideTransitionAnimation(taskOverlay, transit); } } - return finishCurrentActivityLocked(r, (r.visible || r.nowVisible) ? - FINISH_AFTER_VISIBLE : FINISH_AFTER_PAUSE, oomAdj) == null; + return removedActivity; } else { if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + r); } @@ -3565,6 +3597,15 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } } + private void prepareActivityHideTransitionAnimation(ActivityRecord r, int transit) { + mWindowManager.prepareAppTransition(transit, false); + r.setVisibility(false); + mWindowManager.executeAppTransition(); + if (!mStackSupervisor.mWaitingVisibleActivities.contains(r)) { + mStackSupervisor.mWaitingVisibleActivities.add(r); + } + } + static final int FINISH_IMMEDIATELY = 0; static final int FINISH_AFTER_PAUSE = 1; static final int FINISH_AFTER_VISIBLE = 2; @@ -3858,15 +3899,23 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai r.removeWindowContainer(); final TaskRecord task = r.task; final boolean lastActivity = task != null ? task.removeActivity(r) : false; + // If we are removing the last activity in the task, not including task overlay activities, + // then fall through into the block below to remove the entire task itself + final boolean onlyHasTaskOverlays = task != null + ? task.onlyHasTaskOverlayActivities(false /* excludingFinishing */) : false; + + if (lastActivity || onlyHasTaskOverlays) { + if (DEBUG_STACK) { + Slog.i(TAG_STACK, + "removeActivityFromHistoryLocked: last activity removed from " + this + + " onlyHasTaskOverlays=" + onlyHasTaskOverlays); + } - if (lastActivity) { - if (DEBUG_STACK) Slog.i(TAG_STACK, - "removeActivityFromHistoryLocked: last activity removed from " + this); if (mStackSupervisor.isFocusedStack(this) && task == topTask() && task.isOverHomeStack()) { mStackSupervisor.moveHomeStackTaskToTop(reason); } - removeTask(task, reason); + removeTask(task, reason, REMOVE_TASK_MODE_DESTROYING); } cleanUpActivityServicesLocked(r); r.removeUriPermissionsLocked(); @@ -4917,10 +4966,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai return starting; } - void removeTask(TaskRecord task, String reason) { - removeTask(task, reason, REMOVE_TASK_MODE_DESTROYING); - } - /** * Removes the input task from this stack. * @param task to remove. @@ -4930,6 +4975,10 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai */ void removeTask(TaskRecord task, String reason, int mode) { if (mode == REMOVE_TASK_MODE_DESTROYING) { + // When destroying a task, tell the supervisor to remove it so that any activity it has + // can be cleaned up correctly + mStackSupervisor.removeTaskByIdLocked(task.taskId, false /* killProcess */, + !REMOVE_FROM_RECENTS, PAUSE_IMMEDIATELY); task.removeWindowContainer(); } @@ -4947,6 +4996,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } } mTaskHistory.remove(task); + removeActivitiesFromLRUListLocked(task); updateTaskMovement(task, true); if (mode == REMOVE_TASK_MODE_DESTROYING && task.mActivities.isEmpty()) { @@ -5114,6 +5164,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai // Apps may depend on onResume()/onPause() being called in pairs. if (setResume) { mResumedActivity = r; + updateLRUListLocked(r); } // If the activity was previously pausing, then ensure we transfer that as well if (setPause) { diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 27b8e91981c0..b623b2f2b180 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -254,6 +254,10 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D // Used to indicate that a task is removed it should also be removed from recents. static final boolean REMOVE_FROM_RECENTS = true; + // Used to indicate that pausing an activity should occur immediately without waiting for + // the activity callback indicating that it has completed pausing + static final boolean PAUSE_IMMEDIATELY = true; + /** * The modes which affect which tasks are returned when calling * {@link ActivityStackSupervisor#anyTaskForIdLocked(int)}. @@ -2536,18 +2540,28 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } /** + * See {@link #removeTaskByIdLocked(int, boolean, boolean, boolean)} + */ + boolean removeTaskByIdLocked(int taskId, boolean killProcess, boolean removeFromRecents) { + return removeTaskByIdLocked(taskId, killProcess, removeFromRecents, !PAUSE_IMMEDIATELY); + } + + /** * Removes the task with the specified task id. * * @param taskId Identifier of the task to be removed. * @param killProcess Kill any process associated with the task if possible. * @param removeFromRecents Whether to also remove the task from recents. + * @param pauseImmediately Pauses all task activities immediately without waiting for the + * pause-complete callback from the activity. * @return Returns true if the given task was found and removed. */ - boolean removeTaskByIdLocked(int taskId, boolean killProcess, boolean removeFromRecents) { + boolean removeTaskByIdLocked(int taskId, boolean killProcess, boolean removeFromRecents, + boolean pauseImmediately) { final TaskRecord tr = anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID); if (tr != null) { - tr.removeTaskActivitiesLocked(); + tr.removeTaskActivitiesLocked(pauseImmediately); cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents); if (tr.isPersistable) { mService.notifyTaskPersisterLocked(null, true); @@ -3555,8 +3569,16 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D stackHeader.append(" mFullscreen=" + stack.mFullscreen); stackHeader.append("\n"); stackHeader.append(" mBounds=" + stack.mBounds); - printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, - needSep, stackHeader.toString()); + + final boolean printedStackHeader = stack.dumpActivitiesLocked(fd, pw, dumpAll, + dumpClient, dumpPackage, needSep, stackHeader.toString()); + printed |= printedStackHeader; + if (!printedStackHeader) { + // Ensure we always dump the stack header even if there are no activities + pw.println(); + pw.println(stackHeader); + } + printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, !dumpAll, false, dumpPackage, true, " Running activities (most recent first):", null); diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java index 4bd06b76e92e..9258539f4268 100644 --- a/services/core/java/com/android/server/am/ActivityStarter.java +++ b/services/core/java/com/android/server/am/ActivityStarter.java @@ -640,6 +640,18 @@ class ActivityStarter { final Intent ephemeralIntent = new Intent(intent); // Don't modify the client's object! intent = new Intent(intent); + if (componentSpecified + && intent.getData() != null + && Intent.ACTION_VIEW.equals(intent.getAction()) + && intent.hasCategory(Intent.CATEGORY_BROWSABLE) + && mService.getPackageManagerInternalLocked() + .isInstantAppInstallerComponent(intent.getComponent())) { + // intercept intents targeted directly to the ephemeral installer the + // ephemeral installer should never be started with a raw URL; instead + // adjust the intent so it looks like a "normal" instant app launch + intent.setComponent(null /*component*/); + componentSpecified = false; + } ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId); if (rInfo == null) { @@ -1453,6 +1465,12 @@ class ActivityStarter { return intentActivity; } + /** + * Figure out which task and activity to bring to front when we have found an existing matching + * activity record in history. May also clear the task if needed. + * @param intentActivity Existing matching activity. + * @return {@link ActivityRecord} brought to front. + */ private ActivityRecord setTargetStackAndMoveToFrontIfNeeded(ActivityRecord intentActivity) { mTargetStack = intentActivity.getStack(); mTargetStack.mLastPausedActivity = null; @@ -1514,6 +1532,14 @@ class ActivityStarter { "bringToFrontInsteadOfAdjacentLaunch"); } mMovedToFront = true; + } else if (launchStack.mDisplayId != mTargetStack.mDisplayId) { + // Target and computed stacks are on different displays and we've + // found a matching task - move the existing instance to that display and + // move it to front. + intentActivity.task.reparent(launchStack.mStackId, ON_TOP, + REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME, + "reparentToDisplay"); + mMovedToFront = true; } mOptions = null; diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java index 7b1af38da9ed..c10f77cefbe4 100644 --- a/services/core/java/com/android/server/am/AppErrors.java +++ b/services/core/java/com/android/server/am/AppErrors.java @@ -870,7 +870,7 @@ class AppErrors { nativeProcs = NATIVE_STACKS_OF_INTEREST; } - int[] pids = Process.getPidsForCommands(nativeProcs); + int[] pids = nativeProcs == null ? null : Process.getPidsForCommands(nativeProcs); ArrayList<Integer> nativePids = null; if (pids != null) { diff --git a/services/core/java/com/android/server/am/LockTaskNotify.java b/services/core/java/com/android/server/am/LockTaskNotify.java index 8c18c462e956..0412db5e49c9 100644 --- a/services/core/java/com/android/server/am/LockTaskNotify.java +++ b/services/core/java/com/android/server/am/LockTaskNotify.java @@ -20,6 +20,8 @@ import android.app.ActivityManager; import android.content.Context; import android.os.Handler; import android.os.Message; +import android.os.SystemClock; +import android.util.Slog; import android.view.WindowManager; import android.widget.Toast; @@ -31,10 +33,12 @@ import com.android.internal.R; */ public class LockTaskNotify { private static final String TAG = "LockTaskNotify"; + private static final long SHOW_TOAST_MINIMUM_INTERVAL = 1000; private final Context mContext; private final H mHandler; private Toast mLastToast; + private long mLastShowToastTime; public LockTaskNotify(Context context) { mContext = context; @@ -55,10 +59,16 @@ public class LockTaskNotify { if (text == null) { return; } + long showToastTime = SystemClock.elapsedRealtime(); + if ((showToastTime - mLastShowToastTime) < SHOW_TOAST_MINIMUM_INTERVAL) { + Slog.i(TAG, "Ignore toast since it is requested in very short interval."); + return; + } if (mLastToast != null) { mLastToast.cancel(); } mLastToast = makeAllUserToastAndShow(text); + mLastShowToastTime = showToastTime; } public void show(boolean starting) { diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java index c494171fbfbb..f05bfb6174d3 100644 --- a/services/core/java/com/android/server/am/PendingIntentRecord.java +++ b/services/core/java/com/android/server/am/PendingIntentRecord.java @@ -175,6 +175,8 @@ final class PendingIntentRecord extends IIntentSender.Stub { return "broadcastIntent"; case ActivityManager.INTENT_SENDER_SERVICE: return "startService"; + case ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE: + return "startForegroundService"; case ActivityManager.INTENT_SENDER_ACTIVITY_RESULT: return "activityResult"; } @@ -318,9 +320,11 @@ final class PendingIntentRecord extends IIntentSender.Stub { } break; case ActivityManager.INTENT_SENDER_SERVICE: + case ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE: try { - owner.startServiceInPackage(uid, finalIntent, - resolvedType, key.packageName, userId); + owner.startServiceInPackage(uid, finalIntent, resolvedType, + key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE, + key.packageName, userId); } catch (RuntimeException e) { Slog.w(TAG, "Unable to send startService intent", e); } catch (TransactionTooLargeException e) { diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index dfbe59f1c8f2..44ebf50eb31a 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -92,6 +92,8 @@ final class ServiceRecord extends Binder { ServiceState restartTracker; // tracking service restart boolean whitelistManager; // any bindings to this service have BIND_ALLOW_WHITELIST_MANAGEMENT? boolean delayed; // are we waiting to start this service in the background? + boolean fgRequired; // is the service required to go foreground after starting? + boolean fgWaiting; // is a timeout for going foreground already scheduled? boolean isForeground; // is service currently in foreground mode? int foregroundId; // Notification ID of last foreground req. Notification foregroundNoti; // Notification record of foreground state. diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index fd65c101919d..ce32f8413468 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -112,6 +112,7 @@ import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE; import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE; import static com.android.server.am.ActivityRecord.STARTING_WINDOW_SHOWN; import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING; +import static com.android.server.am.ActivityStackSupervisor.PAUSE_IMMEDIATELY; import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS; import static java.lang.Integer.MAX_VALUE; @@ -617,15 +618,15 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta boolean kept = true; try { final ActivityRecord r = topRunningActivityLocked(); - final boolean wasFocused = supervisor.isFocusedStack(sourceStack) + final boolean wasFocused = r != null && supervisor.isFocusedStack(sourceStack) && (topRunningActivityLocked() == r); - final boolean wasResumed = sourceStack.mResumedActivity == r; - final boolean wasPaused = sourceStack.mPausingActivity == r; + final boolean wasResumed = r != null && sourceStack.mResumedActivity == r; + final boolean wasPaused = r != null && sourceStack.mPausingActivity == r; // In some cases the focused stack isn't the front stack. E.g. pinned stack. // Whenever we are moving the top activity from the front stack we want to make sure to // move the stack to the front. - final boolean wasFront = supervisor.isFrontStackOnDisplay(sourceStack) + final boolean wasFront = r != null && supervisor.isFrontStackOnDisplay(sourceStack) && (sourceStack.topRunningActivityLocked() == r); // Adjust the position for the new parent stack as needed. @@ -667,8 +668,10 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta // new stack by moving the stack to the front. final boolean moveStackToFront = moveStackMode == REPARENT_MOVE_STACK_TO_FRONT || (moveStackMode == REPARENT_KEEP_STACK_AT_FRONT && (wasFocused || wasFront)); - toStack.moveToFrontAndResumeStateIfNeeded(r, moveStackToFront, wasResumed, wasPaused, - reason); + if (r != null) { + toStack.moveToFrontAndResumeStateIfNeeded(r, moveStackToFront, wasResumed, + wasPaused, reason); + } if (!animate) { toStack.mNoAnimActivities.add(topActivity); } @@ -1278,6 +1281,26 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta return false; } + /** + * @return whether or not there are ONLY task overlay activities in the stack. + * If {@param excludeFinishing} is set, then ignore finishing activities in the check. + * If there are no task overlay activities, this call returns false. + */ + boolean onlyHasTaskOverlayActivities(boolean excludeFinishing) { + int count = 0; + for (int i = mActivities.size() - 1; i >= 0; i--) { + final ActivityRecord r = mActivities.get(i); + if (excludeFinishing && r.finishing) { + continue; + } + if (!r.mTaskOverlay) { + return false; + } + count++; + } + return count > 0; + } + boolean autoRemoveFromRecents() { // We will automatically remove the task either if it has explicitly asked for // this, or it is empty and has never contained an activity that got shown to @@ -1289,7 +1312,7 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta * Completely remove all activities associated with an existing * task starting at a specified index. */ - final void performClearTaskAtIndexLocked(int activityNdx) { + final void performClearTaskAtIndexLocked(int activityNdx, boolean pauseImmediately) { int numActivities = mActivities.size(); for ( ; activityNdx < numActivities; ++activityNdx) { final ActivityRecord r = mActivities.get(activityNdx); @@ -1302,8 +1325,8 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta mActivities.remove(activityNdx); --activityNdx; --numActivities; - } else if (mStack.finishActivityLocked( - r, Activity.RESULT_CANCELED, null, "clear-task-index", false)) { + } else if (mStack.finishActivityLocked(r, Activity.RESULT_CANCELED, null, + "clear-task-index", false, pauseImmediately)) { --activityNdx; --numActivities; } @@ -1315,7 +1338,7 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta */ final void performClearTaskLocked() { mReuseTask = true; - performClearTaskAtIndexLocked(0); + performClearTaskAtIndexLocked(0, !PAUSE_IMMEDIATELY); mReuseTask = false; } @@ -1399,9 +1422,9 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta return taskThumbnail; } - void removeTaskActivitiesLocked() { + void removeTaskActivitiesLocked(boolean pauseImmediately) { // Just remove the entire task. - performClearTaskAtIndexLocked(0); + performClearTaskAtIndexLocked(0, pauseImmediately); } String lockTaskAuthToString() { diff --git a/services/core/java/com/android/server/am/UserState.java b/services/core/java/com/android/server/am/UserState.java index 6710bdc3cd2d..9970c82e2c75 100644 --- a/services/core/java/com/android/server/am/UserState.java +++ b/services/core/java/com/android/server/am/UserState.java @@ -88,7 +88,7 @@ public final class UserState { state = newState; } - static String stateToString(int state) { + public static String stateToString(int state) { switch (state) { case STATE_BOOTING: return "BOOTING"; case STATE_RUNNING_LOCKED: return "RUNNING_LOCKED"; diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 333d27bd5360..49d1521e378f 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -106,6 +106,7 @@ import android.text.TextUtils; import android.util.AndroidRuntimeException; import android.util.ArrayMap; import android.util.ArraySet; +import android.util.IntArray; import android.util.Log; import android.util.MathUtils; import android.util.Slog; @@ -126,6 +127,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -575,6 +577,10 @@ public class AudioService extends IAudioService.Stub private VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT; private long mLoweredFromNormalToVibrateTime; + // Array of Uids of valid accessibility services to check if caller is one of them + private int[] mAccessibilityServiceUids; + private final Object mAccessibilityServiceUidsLock = new Object(); + // Intent "extra" data keys. public static final String CONNECT_INTENT_KEY_PORT_NAME = "portName"; public static final String CONNECT_INTENT_KEY_STATE = "state"; @@ -1241,11 +1247,9 @@ public class AudioService extends IAudioService.Stub /** @see AudioManager#adjustStreamVolume(int, int, int) */ public void adjustStreamVolume(int streamType, int direction, int flags, String callingPackage) { - if ( streamType == AudioManager.STREAM_ACCESSIBILITY - && (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( - android.Manifest.permission.BIND_ACCESSIBILITY_SERVICE))) { + if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) { Log.w(TAG, "Trying to call adjustStreamVolume() for a11y without" - + "BIND_ACCESSIBILITY_SERVICE / callingPackage=" + callingPackage); + + "CHANGE_ACCESSIBILITY_VOLUME / callingPackage=" + callingPackage); return; } adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage, @@ -1559,17 +1563,33 @@ public class AudioService extends IAudioService.Stub /** @see AudioManager#setStreamVolume(int, int, int) */ public void setStreamVolume(int streamType, int index, int flags, String callingPackage) { - if ( streamType == AudioManager.STREAM_ACCESSIBILITY - && (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( - android.Manifest.permission.BIND_ACCESSIBILITY_SERVICE))) { + if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) { Log.w(TAG, "Trying to call setStreamVolume() for a11y without" - + " BIND_ACCESSIBILITY_SERVICE callingPackage=" + callingPackage); + + " CHANGE_ACCESSIBILITY_VOLUME callingPackage=" + callingPackage); return; } setStreamVolume(streamType, index, flags, callingPackage, callingPackage, Binder.getCallingUid()); } + private boolean canChangeAccessibilityVolume() { + synchronized (mAccessibilityServiceUidsLock) { + if (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( + android.Manifest.permission.CHANGE_ACCESSIBILITY_VOLUME)) { + return true; + } + if (mAccessibilityServiceUids != null) { + int callingUid = Binder.getCallingUid(); + for (int i = 0; i < mAccessibilityServiceUids.length; i++) { + if (mAccessibilityServiceUids[i] == callingUid) { + return true; + } + } + } + return false; + } + } + private void setStreamVolume(int streamType, int index, int flags, String callingPackage, String caller, int uid) { if (DEBUG_VOL) { @@ -6380,6 +6400,29 @@ public class AudioService extends IAudioService.Stub } } } + + @Override + public void setAccessibilityServiceUids(IntArray uids) { + synchronized (mAccessibilityServiceUidsLock) { + if (uids.size() == 0) { + mAccessibilityServiceUids = null; + } else { + boolean changed = (mAccessibilityServiceUids == null) + || (mAccessibilityServiceUids.length != uids.size()); + if (!changed) { + for (int i = 0; i < mAccessibilityServiceUids.length; i++) { + if (uids.get(i) != mAccessibilityServiceUids[i]) { + changed = true; + break; + } + } + } + if (changed) { + mAccessibilityServiceUids = uids.toArray(); + } + } + } + } } //========================================================================================== @@ -6555,7 +6598,7 @@ public class AudioService extends IAudioService.Stub public void registerPlaybackCallback(IPlaybackConfigDispatcher pcdb) { final boolean isPrivileged = - (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission( + (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( android.Manifest.permission.MODIFY_AUDIO_ROUTING)); mPlaybackMonitor.registerPlaybackCallback(pcdb, isPrivileged); } @@ -6566,7 +6609,7 @@ public class AudioService extends IAudioService.Stub public List<AudioPlaybackConfiguration> getActivePlaybackConfigurations() { final boolean isPrivileged = - (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission( + (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( android.Manifest.permission.MODIFY_AUDIO_ROUTING)); return mPlaybackMonitor.getActivePlaybackConfigurations(isPrivileged); } diff --git a/services/core/java/com/android/server/connectivity/MockableSystemProperties.java b/services/core/java/com/android/server/connectivity/MockableSystemProperties.java index 4f68652d412c..77b86d8e4355 100644 --- a/services/core/java/com/android/server/connectivity/MockableSystemProperties.java +++ b/services/core/java/com/android/server/connectivity/MockableSystemProperties.java @@ -19,7 +19,20 @@ package com.android.server.connectivity; import android.os.SystemProperties; public class MockableSystemProperties { + + public String get(String key) { + return SystemProperties.get(key); + } + + public int getInt(String key, int def) { + return SystemProperties.getInt(key, def); + } + public boolean getBoolean(String key, boolean def) { return SystemProperties.getBoolean(key, def); } + + public void set(String key, String value) { + SystemProperties.set(key, value); + } } diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index 9fc2fc7bb31e..248f96994314 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -32,7 +32,6 @@ import android.app.NotificationManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.ComponentName; -import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; @@ -139,6 +138,7 @@ public class Vpn { private NetworkAgent mNetworkAgent; private final Looper mLooper; private final NetworkCapabilities mNetworkCapabilities; + private final SystemServices mSystemServices; /** * Whether to keep the connection active after rebooting, or upgrading or reinstalling. This @@ -206,7 +206,7 @@ public class Vpn { final boolean isPackageRemoved = !intent.getBooleanExtra( Intent.EXTRA_REPLACING, false); if (isPackageRemoved) { - setAndSaveAlwaysOnPackage(null, false); + setAlwaysOnPackage(null, false); } break; } @@ -217,11 +217,18 @@ public class Vpn { private boolean mIsPackageIntentReceiverRegistered = false; public Vpn(Looper looper, Context context, INetworkManagementService netService, - int userHandle) { + @UserIdInt int userHandle) { + this(looper, context, netService, userHandle, new SystemServices(context)); + } + + @VisibleForTesting + protected Vpn(Looper looper, Context context, INetworkManagementService netService, + int userHandle, SystemServices systemServices) { mContext = context; mNetd = netService; mUserHandle = userHandle; mLooper = looper; + mSystemServices = systemServices; mPackage = VpnConfig.LEGACY_VPN; mOwnerUID = getAppUid(mPackage, mUserHandle); @@ -237,6 +244,8 @@ public class Vpn { mNetworkCapabilities = new NetworkCapabilities(); mNetworkCapabilities.addTransportType(NetworkCapabilities.TRANSPORT_VPN); mNetworkCapabilities.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN); + + loadAlwaysOnPackage(); } /** @@ -275,6 +284,26 @@ public class Vpn { */ public synchronized boolean setAlwaysOnPackage(String packageName, boolean lockdown) { enforceControlPermissionOrInternalCaller(); + + if (setAlwaysOnPackageInternal(packageName, lockdown)) { + saveAlwaysOnPackage(); + return true; + } + return false; + } + + /** + * Configures an always-on VPN connection through a specific application, the same as + * {@link #setAlwaysOnPackage}. + * + * Does not perform permission checks. Does not persist any of the changes to storage. + * + * @param packageName the package to designate as always-on VPN supplier. + * @param lockdown whether to prevent traffic outside of a VPN, for example while connecting. + * @return {@code true} if the package has been set as always-on, {@code false} otherwise. + */ + @GuardedBy("this") + private boolean setAlwaysOnPackageInternal(String packageName, boolean lockdown) { if (VpnConfig.LEGACY_VPN.equals(packageName)) { Log.w(TAG, "Not setting legacy VPN \"" + packageName + "\" as always-on."); return false; @@ -347,13 +376,13 @@ public class Vpn { /** * Save the always-on package and lockdown config into Settings.Secure */ - public synchronized void saveAlwaysOnPackage() { + @GuardedBy("this") + private void saveAlwaysOnPackage() { final long token = Binder.clearCallingIdentity(); try { - final ContentResolver cr = mContext.getContentResolver(); - Settings.Secure.putStringForUser(cr, Settings.Secure.ALWAYS_ON_VPN_APP, + mSystemServices.settingsSecurePutStringForUser(Settings.Secure.ALWAYS_ON_VPN_APP, getAlwaysOnPackage(), mUserHandle); - Settings.Secure.putIntForUser(cr, Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN, + mSystemServices.settingsSecurePutIntForUser(Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN, (mLockdown ? 1 : 0), mUserHandle); } finally { Binder.restoreCallingIdentity(token); @@ -361,18 +390,19 @@ public class Vpn { } /** - * Set and save always-on package and lockdown config - * @see Vpn#setAlwaysOnPackage(String, boolean) - * @see Vpn#saveAlwaysOnPackage() - * - * @return result of Vpn#setAndSaveAlwaysOnPackage(String, boolean) + * Load the always-on package and lockdown config from Settings.Secure */ - private synchronized boolean setAndSaveAlwaysOnPackage(String packageName, boolean lockdown) { - if (setAlwaysOnPackage(packageName, lockdown)) { - saveAlwaysOnPackage(); - return true; - } else { - return false; + @GuardedBy("this") + private void loadAlwaysOnPackage() { + final long token = Binder.clearCallingIdentity(); + try { + final String alwaysOnPackage = mSystemServices.settingsSecureGetStringForUser( + Settings.Secure.ALWAYS_ON_VPN_APP, mUserHandle); + final boolean alwaysOnLockdown = mSystemServices.settingsSecureGetIntForUser( + Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN, 0 /*default*/, mUserHandle) != 0; + setAlwaysOnPackageInternal(alwaysOnPackage, alwaysOnLockdown); + } finally { + Binder.restoreCallingIdentity(token); } } @@ -1276,11 +1306,7 @@ public class Vpn { private void updateAlwaysOnNotification(DetailedState networkState) { final boolean visible = (mAlwaysOn && networkState != DetailedState.CONNECTED); - updateAlwaysOnNotificationInternal(visible); - } - @VisibleForTesting - protected void updateAlwaysOnNotificationInternal(boolean visible) { final UserHandle user = UserHandle.of(mUserHandle); final long token = Binder.clearCallingIdentity(); try { @@ -1290,10 +1316,8 @@ public class Vpn { return; } final Intent intent = new Intent(Settings.ACTION_VPN_SETTINGS); - final PendingIntent configIntent = PendingIntent.getActivityAsUser( - mContext, /* request */ 0, intent, - PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT, - null, user); + final PendingIntent configIntent = mSystemServices.pendingIntentGetActivityAsUser( + intent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT, user); final Notification.Builder builder = new Notification.Builder(mContext, SystemNotificationChannels.VPN) .setSmallIcon(R.drawable.vpn_connected) @@ -1310,6 +1334,58 @@ public class Vpn { } } + /** + * Facade for system service calls that change, or depend on, state outside of + * {@link ConnectivityService} and have hard-to-mock interfaces. + * + * @see com.android.server.connectivity.VpnTest + */ + @VisibleForTesting + public static class SystemServices { + private final Context mContext; + + public SystemServices(@NonNull Context context) { + mContext = context; + } + + /** + * @see PendingIntent#getActivityAsUser() + */ + public PendingIntent pendingIntentGetActivityAsUser( + Intent intent, int flags, UserHandle user) { + return PendingIntent.getActivityAsUser(mContext, 0 /*request*/, intent, flags, + null /*options*/, user); + } + + /** + * @see Settings.Secure#putStringForUser + */ + public void settingsSecurePutStringForUser(String key, String value, int userId) { + Settings.Secure.putStringForUser(mContext.getContentResolver(), key, value, userId); + } + + /** + * @see Settings.Secure#putIntForUser + */ + public void settingsSecurePutIntForUser(String key, int value, int userId) { + Settings.Secure.putIntForUser(mContext.getContentResolver(), key, value, userId); + } + + /** + * @see Settings.Secure#getStringForUser + */ + public String settingsSecureGetStringForUser(String key, int userId) { + return Settings.Secure.getStringForUser(mContext.getContentResolver(), key, userId); + } + + /** + * @see Settings.Secure#getIntForUser + */ + public int settingsSecureGetIntForUser(String key, int def, int userId) { + return Settings.Secure.getIntForUser(mContext.getContentResolver(), key, def, userId); + } + } + private native int jniCreate(int mtu); private native String jniGetName(int tun); private native int jniSetAddresses(String interfaze, String addresses); diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index bbad493a913f..1a27a39bd1bf 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -907,7 +907,12 @@ public class SyncManager { Bundle finalExtras = new Bundle(extras); String packageName = syncAdapterInfo.componentName.getPackageName(); // If the app did not run and has no account access, done - if (!mPackageManagerInternal.wasPackageEverLaunched(packageName, userId)) { + try { + if (!mPackageManagerInternal.wasPackageEverLaunched(packageName, userId)) { + continue; + } + } catch (IllegalArgumentException e) { + // Package not found, race with an uninstall continue; } mAccountManagerInternal.requestAccountAccess(account.account, diff --git a/services/core/java/com/android/server/fingerprint/EnumerateClient.java b/services/core/java/com/android/server/fingerprint/EnumerateClient.java index 1b8b89c8bc37..34f245f19d12 100644 --- a/services/core/java/com/android/server/fingerprint/EnumerateClient.java +++ b/services/core/java/com/android/server/fingerprint/EnumerateClient.java @@ -58,7 +58,7 @@ public abstract class EnumerateClient extends ClientMonitor { public int stop(boolean initiatedByClient) { IBiometricsFingerprint daemon = getFingerprintDaemon(); if (daemon == null) { - Slog.w(TAG, "stopEnumeration: no fingerprint HAL!"); + Slog.w(TAG, "stopAuthentication: no fingerprint HAL!"); return ERROR_ESRCH; } try { @@ -102,12 +102,12 @@ public abstract class EnumerateClient extends ClientMonitor { @Override public boolean onEnrollResult(int fingerId, int groupId, int rem) { if (DEBUG) Slog.w(TAG, "onEnrollResult() called for enumerate!"); - return true; // Invalid for Enumerate. + return true; // Invalid for Remove } @Override public boolean onRemoved(int fingerId, int groupId, int remaining) { if (DEBUG) Slog.w(TAG, "onRemoved() called for enumerate!"); - return true; // Invalid for Enumerate. + return true; // Invalid for Authenticate } } diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java index b6e7932bdec4..7d97ce41e8f3 100644 --- a/services/core/java/com/android/server/fingerprint/FingerprintService.java +++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java @@ -85,7 +85,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; -import java.util.LinkedList; /** * A service to manage multiple clients that want to access the fingerprint HAL API. @@ -135,20 +134,6 @@ public class FingerprintService extends SystemService implements IHwBinder.Death private ClientMonitor mPendingClient; private PerformanceStats mPerformanceStats; - - private IBinder mToken = new Binder(); // used for internal FingerprintService enumeration - private LinkedList<Integer> mEnumeratingUserIds = new LinkedList<>(); - private ArrayList<UserFingerprint> mUnknownFingerprints = new ArrayList<>(); // hw finterprints - - private class UserFingerprint { - Fingerprint f; - int userId; - public UserFingerprint(Fingerprint f, int userId) { - this.f = f; - this.userId = userId; - } - } - // Normal fingerprint authentications are tracked by mPerformanceMap. private HashMap<Integer, PerformanceStats> mPerformanceMap = new HashMap<>(); @@ -272,12 +257,10 @@ public class FingerprintService extends SystemService implements IHwBinder.Death // This operation can be expensive, so keep track of the elapsed time. Might need to move to // background if it takes too long. long t = System.currentTimeMillis(); + mAuthenticatorIds.clear(); - mEnumeratingUserIds.clear(); - mUnknownFingerprints.clear(); for (UserInfo user : UserManager.get(mContext).getUsers(true /* excludeDying */)) { int userId = getUserOrWorkProfileId(null, user.id); - mEnumeratingUserIds.add(userId); if (!mAuthenticatorIds.containsKey(userId)) { updateActiveGroup(userId, null); } @@ -287,70 +270,12 @@ public class FingerprintService extends SystemService implements IHwBinder.Death if (t > 1000) { Slog.w(TAG, "loadAuthenticatorIds() taking too long: " + t + "ms"); } - - if (!mEnumeratingUserIds.isEmpty()) { - enumerateNextUser(); - } - } - - private void enumerateNextUser() { - int nextUser = mEnumeratingUserIds.getFirst(); - updateActiveGroup(nextUser, null); - boolean restricted = !hasPermission(MANAGE_FINGERPRINT); - - if (DEBUG) Slog.v(TAG, "Enumerating user id " + nextUser + " of " - + mEnumeratingUserIds.size() + " remaining users"); - - startEnumerate(mToken, nextUser, null, restricted, true /* internal */); - } - - // Remove unknown fingerprints from hardware - private void cleanupUnknownFingerprints() { - if (!mUnknownFingerprints.isEmpty()) { - Slog.w(TAG, "unknown fingerprint size: " + mUnknownFingerprints.size()); - UserFingerprint uf = mUnknownFingerprints.get(0); - mUnknownFingerprints.remove(uf); - boolean restricted = !hasPermission(MANAGE_FINGERPRINT); - updateActiveGroup(uf.userId, null); - startRemove(mToken, uf.f.getFingerId(), uf.f.getGroupId(), uf.userId, null, - restricted, true /* internal */); - } } protected void handleEnumerate(long deviceId, int fingerId, int groupId, int remaining) { - if (DEBUG) Slog.w(TAG, "Enumerate: fid=" + fingerId - + ", gid=" + groupId - + ", dev=" + deviceId - + ", rem=" + remaining); - - ClientMonitor client = mCurrentClient; - - if (client != null) { - client.onEnumerationResult(fingerId, groupId, remaining); - } - - // All fingerprints in hardware for this user were enumerated - if (remaining == 0) { - mEnumeratingUserIds.poll(); - - if (client instanceof InternalEnumerateClient) { - List<Fingerprint> enrolled = ((InternalEnumerateClient) client).getEnumeratedList(); - Slog.w(TAG, "Added " + enrolled.size() + " enumerated fingerprints for deletion"); - for (Fingerprint f : enrolled) { - mUnknownFingerprints.add(new UserFingerprint(f, client.getTargetUserId())); - } - } - - removeClient(client); - - if (!mEnumeratingUserIds.isEmpty()) { - enumerateNextUser(); - } else if (client instanceof InternalEnumerateClient) { - if (DEBUG) Slog.v(TAG, "Finished enumerating all users"); - // This will start a chain of InternalRemovalClients - cleanupUnknownFingerprints(); - } - } + if (DEBUG) Slog.w(TAG, "Enumerate: fid=" + fingerId + ", gid=" + + groupId + "rem=" + remaining); + // TODO: coordinate names with framework } protected void handleError(long deviceId, int error, int vendorCode) { @@ -379,18 +304,10 @@ public class FingerprintService extends SystemService implements IHwBinder.Death } protected void handleRemoved(long deviceId, int fingerId, int groupId, int remaining) { - if (DEBUG) Slog.w(TAG, "Removed: fid=" + fingerId - + ", gid=" + groupId - + ", dev=" + deviceId - + ", rem=" + remaining); - ClientMonitor client = mCurrentClient; if (client != null && client.onRemoved(fingerId, groupId, remaining)) { removeClient(client); } - if (client instanceof InternalRemovalClient && !mUnknownFingerprints.isEmpty()) { - cleanupUnknownFingerprints(); - } } protected void handleAuthenticated(long deviceId, int fingerId, int groupId, @@ -517,15 +434,7 @@ public class FingerprintService extends SystemService implements IHwBinder.Death ClientMonitor currentClient = mCurrentClient; if (currentClient != null) { if (DEBUG) Slog.v(TAG, "request stop current client " + currentClient.getOwnerString()); - if (currentClient instanceof InternalEnumerateClient || - currentClient instanceof InternalRemovalClient) { - // This condition means we're currently running internal diagnostics to - // remove extra fingerprints in the hardware and/or the software - // TODO: design an escape hatch in case client never finishes - } - else { - currentClient.stop(initiatedByClient); - } + currentClient.stop(initiatedByClient); mPendingClient = newClient; mHandler.removeCallbacks(mResetClientState); mHandler.postDelayed(mResetClientState, CANCEL_TIMEOUT_LIMIT); @@ -542,86 +451,47 @@ public class FingerprintService extends SystemService implements IHwBinder.Death } void startRemove(IBinder token, int fingerId, int groupId, int userId, - IFingerprintServiceReceiver receiver, boolean restricted, boolean internal) { + IFingerprintServiceReceiver receiver, boolean restricted) { IBiometricsFingerprint daemon = getFingerprintDaemon(); if (daemon == null) { Slog.w(TAG, "startRemove: no fingerprint HAL!"); return; } + RemovalClient client = new RemovalClient(getContext(), mHalDeviceId, token, + receiver, fingerId, groupId, userId, restricted, token.toString()) { + @Override + public void notifyUserActivity() { + FingerprintService.this.userActivity(); + } - if (internal) { - Context context = getContext(); - InternalRemovalClient client = new InternalRemovalClient(context, mHalDeviceId, - token, receiver, fingerId, groupId, userId, restricted, - context.getOpPackageName()) { - @Override - public void notifyUserActivity() { - - } - @Override - public IBiometricsFingerprint getFingerprintDaemon() { - return FingerprintService.this.getFingerprintDaemon(); - } - }; - startClient(client, true); - } - else { - RemovalClient client = new RemovalClient(getContext(), mHalDeviceId, token, - receiver, fingerId, groupId, userId, restricted, token.toString()) { - @Override - public void notifyUserActivity() { - FingerprintService.this.userActivity(); - } - - @Override - public IBiometricsFingerprint getFingerprintDaemon() { - return FingerprintService.this.getFingerprintDaemon(); - } - }; - startClient(client, true); - } + @Override + public IBiometricsFingerprint getFingerprintDaemon() { + return FingerprintService.this.getFingerprintDaemon(); + } + }; + startClient(client, true); } void startEnumerate(IBinder token, int userId, - IFingerprintServiceReceiver receiver, boolean restricted, boolean internal) { + IFingerprintServiceReceiver receiver, boolean restricted) { IBiometricsFingerprint daemon = getFingerprintDaemon(); if (daemon == null) { Slog.w(TAG, "startEnumerate: no fingerprint HAL!"); return; } - if (internal) { - List<Fingerprint> enrolledList = getEnrolledFingerprints(userId); - Context context = getContext(); - InternalEnumerateClient client = new InternalEnumerateClient(context, mHalDeviceId, - token, receiver, userId, userId, restricted, context.getOpPackageName(), - enrolledList) { - @Override - public void notifyUserActivity() { - - } - - @Override - public IBiometricsFingerprint getFingerprintDaemon() { - return FingerprintService.this.getFingerprintDaemon(); - } - }; - startClient(client, true); - } - else { - EnumerateClient client = new EnumerateClient(getContext(), mHalDeviceId, token, - receiver, userId, userId, restricted, token.toString()) { - @Override - public void notifyUserActivity() { - FingerprintService.this.userActivity(); - } + EnumerateClient client = new EnumerateClient(getContext(), mHalDeviceId, token, + receiver, userId, userId, restricted, token.toString()) { + @Override + public void notifyUserActivity() { + FingerprintService.this.userActivity(); + } - @Override - public IBiometricsFingerprint getFingerprintDaemon() { - return FingerprintService.this.getFingerprintDaemon(); - } - }; - startClient(client, true); - } + @Override + public IBiometricsFingerprint getFingerprintDaemon() { + return FingerprintService.this.getFingerprintDaemon(); + } + }; + startClient(client, true); } public List<Fingerprint> getEnrolledFingerprints(int userId) { @@ -1108,14 +978,12 @@ public class FingerprintService extends SystemService implements IHwBinder.Death mHandler.post(new Runnable() { @Override public void run() { - startRemove(token, fingerId, groupId, userId, receiver, - restricted, false /* internal */); + startRemove(token, fingerId, groupId, userId, receiver, restricted); } }); } - @Override // Binder call public void enumerate(final IBinder token, final int userId, final IFingerprintServiceReceiver receiver) { checkPermission(MANAGE_FINGERPRINT); // TODO: Maybe have another permission @@ -1123,7 +991,7 @@ public class FingerprintService extends SystemService implements IHwBinder.Death mHandler.post(new Runnable() { @Override public void run() { - startEnumerate(token, userId, receiver, restricted, false /* internal */); + startEnumerate(token, userId, receiver, restricted); } }); diff --git a/services/core/java/com/android/server/fingerprint/InternalEnumerateClient.java b/services/core/java/com/android/server/fingerprint/InternalEnumerateClient.java deleted file mode 100644 index f4d2596c85bf..000000000000 --- a/services/core/java/com/android/server/fingerprint/InternalEnumerateClient.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2017 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.server.fingerprint; - -import android.content.Context; -import android.hardware.fingerprint.Fingerprint; -import android.hardware.fingerprint.IFingerprintServiceReceiver; -import android.os.IBinder; -import android.util.Slog; -import java.util.ArrayList; -import java.util.List; - -/** - * An internal class to help clean up unknown fingerprints in the hardware and software - */ -public abstract class InternalEnumerateClient extends EnumerateClient { - - private List<Fingerprint> mEnrolledList; - private List<Fingerprint> mEnumeratedList = new ArrayList<>(); // list of fp to delete - - public InternalEnumerateClient(Context context, long halDeviceId, IBinder token, - IFingerprintServiceReceiver receiver, int groupId, int userId, - boolean restricted, String owner, List<Fingerprint> enrolledList) { - - super(context, halDeviceId, token, receiver, userId, groupId, restricted, owner); - mEnrolledList = enrolledList; - } - - private void handleEnumeratedFingerprint(int fingerId, int groupId, int remaining) { - - boolean matched = false; - for (int i=0; i<mEnrolledList.size(); i++) { - if (mEnrolledList.get(i).getFingerId() == fingerId) { - mEnrolledList.remove(i); - matched = true; - Slog.e(TAG, "Matched fingerprint fid=" + fingerId); - break; - } - } - - // fingerId 0 means no fingerprints are in hardware - if (!matched && fingerId != 0) { - Fingerprint fingerprint = new Fingerprint("", groupId, fingerId, getHalDeviceId()); - mEnumeratedList.add(fingerprint); - } - } - - private void doFingerprintCleanup() { - - if (mEnrolledList == null) { - return; - } - - for (Fingerprint f : mEnrolledList) { - Slog.e(TAG, "Internal Enumerate: Removing dangling enrolled fingerprint: " - + f.getName() + " " + f.getFingerId() + " " + f.getGroupId() - + " " + f.getDeviceId()); - - FingerprintUtils.getInstance().removeFingerprintIdForUser(getContext(), - f.getFingerId(), getTargetUserId()); - } - mEnrolledList.clear(); - } - - public List<Fingerprint> getEnumeratedList() { - return mEnumeratedList; - } - - @Override - public boolean onEnumerationResult(int fingerId, int groupId, int remaining) { - - handleEnumeratedFingerprint(fingerId, groupId, remaining); - if (remaining == 0) { - doFingerprintCleanup(); - } - - return fingerId == 0; // done when id hits 0 - } - -} diff --git a/services/core/java/com/android/server/fingerprint/InternalRemovalClient.java b/services/core/java/com/android/server/fingerprint/InternalRemovalClient.java deleted file mode 100644 index 19f61feac1f4..000000000000 --- a/services/core/java/com/android/server/fingerprint/InternalRemovalClient.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2017 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.server.fingerprint; - -import android.content.Context; -import android.os.IBinder; -import android.hardware.fingerprint.IFingerprintServiceReceiver; -import com.android.server.fingerprint.RemovalClient; - -public abstract class InternalRemovalClient extends RemovalClient { - - public InternalRemovalClient(Context context, long halDeviceId, IBinder token, - IFingerprintServiceReceiver receiver, int fingerId, int groupId, int userId, - boolean restricted, String owner) { - - super(context, halDeviceId, token, receiver, fingerId, groupId, userId, restricted, owner); - - } -} diff --git a/services/core/java/com/android/server/media/AudioPlaybackMonitor.java b/services/core/java/com/android/server/media/AudioPlaybackMonitor.java new file mode 100644 index 000000000000..c6dc11c53393 --- /dev/null +++ b/services/core/java/com/android/server/media/AudioPlaybackMonitor.java @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2017 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.server.media; + +import android.content.Context; +import android.media.AudioManager.AudioPlaybackCallback; +import android.media.AudioPlaybackConfiguration; +import android.media.IAudioService; +import android.media.IPlaybackConfigDispatcher; +import android.os.Binder; +import android.os.RemoteException; +import android.os.UserHandle; +import android.util.IntArray; +import android.util.Log; +import android.util.SparseArray; + +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Monitors changes in audio playback and notify the newly started audio playback through the + * {@link OnAudioPlaybackStartedListener}. + */ +class AudioPlaybackMonitor extends IPlaybackConfigDispatcher.Stub { + private static boolean DEBUG = MediaSessionService.DEBUG; + private static String TAG = "AudioPlaybackMonitor"; + + /** + * Called when audio playback is started for a given UID. + */ + interface OnAudioPlaybackStartedListener { + void onAudioPlaybackStarted(int uid); + } + + private final Object mLock = new Object(); + private final Context mContext; + private final OnAudioPlaybackStartedListener mListener; + + private Set<Integer> mActiveAudioPlaybackPlayerInterfaceIds = new HashSet<>(); + private Set<Integer> mActiveAudioPlaybackClientUids = new HashSet<>(); + + // Sorted array of UIDs that had active audio playback. (i.e. playing an audio/video) + // The UID whose audio playback becomes active at the last comes first. + // TODO(b/35278867): Find and use unique identifier for apps because apps may share the UID. + private final IntArray mSortedAudioPlaybackClientUids = new IntArray(); + + AudioPlaybackMonitor(Context context, IAudioService audioService, + OnAudioPlaybackStartedListener listener) { + mContext = context; + mListener = listener; + try { + audioService.registerPlaybackCallback(this); + } catch (RemoteException e) { + Log.wtf(TAG, "Failed to register playback callback", e); + } + } + + /** + * Called when the {@link AudioPlaybackConfiguration} is updated. + * <p>If an app starts audio playback, the app's local media session will be the media button + * session. If the app has multiple media sessions, the playback active local session will be + * picked. + * + * @param configs List of the current audio playback configuration + */ + @Override + public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs) { + final long token = Binder.clearCallingIdentity(); + try { + Set<Integer> newActiveAudioPlaybackPlayerInterfaceIds = new HashSet<>(); + List<Integer> newActiveAudioPlaybackClientUids = new ArrayList<>(); + synchronized (mLock) { + mActiveAudioPlaybackClientUids.clear(); + for (AudioPlaybackConfiguration config : configs) { + // Ignore inactive (i.e. not playing) or PLAYER_TYPE_JAM_SOUNDPOOL + // (i.e. playback from the SoundPool class which is only for sound effects) + // playback. + // Note that we shouldn't ignore PLAYER_TYPE_UNKNOWN because it might be OEM + // specific audio/video players. + if (!config.isActive() + || config.getPlayerType() + == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) { + continue; + } + mActiveAudioPlaybackClientUids.add(config.getClientUid()); + + newActiveAudioPlaybackPlayerInterfaceIds.add(config.getPlayerInterfaceId()); + if (!mActiveAudioPlaybackPlayerInterfaceIds.contains( + config.getPlayerInterfaceId())) { + if (DEBUG) { + Log.d(TAG, "Found a new active media playback. " + + AudioPlaybackConfiguration.toLogFriendlyString(config)); + } + // New active audio playback. + newActiveAudioPlaybackClientUids.add(config.getClientUid()); + int index = mSortedAudioPlaybackClientUids.indexOf(config.getClientUid()); + if (index == 0) { + // It's the lastly played music app already. Skip updating. + continue; + } else if (index > 0) { + mSortedAudioPlaybackClientUids.remove(index); + } + mSortedAudioPlaybackClientUids.add(0, config.getClientUid()); + } + } + mActiveAudioPlaybackPlayerInterfaceIds.clear(); + mActiveAudioPlaybackPlayerInterfaceIds = newActiveAudioPlaybackPlayerInterfaceIds; + } + for (int uid : newActiveAudioPlaybackClientUids) { + mListener.onAudioPlaybackStarted(uid); + } + } finally { + Binder.restoreCallingIdentity(token); + } + } + + /** + * Returns the sorted list of UIDs that have had active audio playback. (i.e. playing an + * audio/video) The UID whose audio playback becomes active at the last comes first. + */ + public IntArray getSortedAudioPlaybackClientUids() { + IntArray sortedAudioPlaybackClientUids = new IntArray(); + synchronized (mLock) { + sortedAudioPlaybackClientUids.addAll(mSortedAudioPlaybackClientUids); + } + return sortedAudioPlaybackClientUids; + } + + /** + * Returns if the audio playback is active for the uid. + */ + public boolean isPlaybackActive(int uid) { + synchronized (mLock) { + return mActiveAudioPlaybackClientUids.contains(uid); + } + } + + /** + * Cleans up the sorted list of audio playback client UIDs with given {@param + * mediaButtonSessionUid}. + * <p>UIDs whose audio playback started after the media button session's audio playback + * cannot be the lastly played media app. So they won't needed anymore. + * + * @param mediaButtonSessionUid UID of the media button session. + */ + public void cleanUpAudioPlaybackUids(int mediaButtonSessionUid) { + synchronized (mLock) { + int userId = UserHandle.getUserId(mediaButtonSessionUid); + for (int i = mSortedAudioPlaybackClientUids.size() - 1; i >= 0; i--) { + if (mSortedAudioPlaybackClientUids.get(i) == mediaButtonSessionUid) { + break; + } + if (userId == UserHandle.getUserId(mSortedAudioPlaybackClientUids.get(i))) { + // Clean up unnecessary UIDs. + // It doesn't need to be managed profile aware because it's just to prevent + // the list from increasing indefinitely. The media button session updating + // shouldn't be affected by cleaning up. + mSortedAudioPlaybackClientUids.remove(i); + } + } + } + } + + /** + * Dumps {@link AudioPlaybackMonitor}. + */ + public void dump(PrintWriter pw, String prefix) { + synchronized (mLock) { + pw.println(prefix + "Audio playback (lastly played comes first)"); + String indent = prefix + " "; + for (int i = 0; i < mSortedAudioPlaybackClientUids.size(); i++) { + int uid = mSortedAudioPlaybackClientUids.get(i); + pw.print(indent + "uid=" + uid + " packages="); + String[] packages = mContext.getPackageManager().getPackagesForUid(uid); + if (packages != null && packages.length > 0) { + for (int j = 0; j < packages.length; j++) { + pw.print(packages[j] + " "); + } + } + pw.println(); + } + } + } +} diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java index 20663a09699d..53a8092fa558 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecord.java +++ b/services/core/java/com/android/server/media/MediaSessionRecord.java @@ -66,12 +66,6 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); /** - * The length of time a session will still be considered active after - * pausing in ms. - */ - private static final int ACTIVE_BUFFER = 30000; - - /** * The amount of time we'll send an assumed volume after the last volume * command before reverting to the last reported volume. */ @@ -109,7 +103,6 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { private int mRatingType; private int mRepeatMode; private boolean mShuffleModeEnabled; - private long mLastActiveTime; // End TransportPerformer fields // Volume handling fields @@ -130,7 +123,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { private String mCallingPackage; public MediaSessionRecord(int ownerPid, int ownerUid, int userId, String ownerPackageName, - ISessionCallback cb, String tag, MediaSessionService service, Handler handler) { + ISessionCallback cb, String tag, MediaSessionService service, Looper handlerLooper) { mOwnerPid = ownerPid; mOwnerUid = ownerUid; mUserId = userId; @@ -140,7 +133,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { mSession = new SessionStub(); mSessionCb = new SessionCb(cb); mService = service; - mHandler = new MessageHandler(handler.getLooper()); + mHandler = new MessageHandler(handlerLooper); mAudioManager = (AudioManager) service.getContext().getSystemService(Context.AUDIO_SERVICE); mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class); mAudioAttrs = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build(); @@ -211,6 +204,15 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { } /** + * Get the UID this session was created for. + * + * @return The UID for this session. + */ + public int getUid() { + return mOwnerUid; + } + + /** * Get the user id this session was created for. * * @return The user id for this session. @@ -244,7 +246,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { public void adjustVolume(int direction, int flags, String packageName, int uid, boolean useSuggested) { int previousFlagPlaySound = flags & AudioManager.FLAG_PLAY_SOUND; - if (isPlaybackActive(false) || hasFlag(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY)) { + if (isPlaybackActive() || hasFlag(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY)) { flags &= ~AudioManager.FLAG_PLAY_SOUND; } if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) { @@ -320,25 +322,13 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { } /** - * Check if the session is currently performing playback. This will also - * return true if the session was recently paused. + * Check if the session is currently performing playback. * - * @param includeRecentlyActive True if playback that was recently paused - * should count, false if it shouldn't. * @return True if the session is performing playback, false otherwise. */ - public boolean isPlaybackActive(boolean includeRecentlyActive) { - int state = mPlaybackState == null ? 0 : mPlaybackState.getState(); - if (MediaSession.isActiveState(state)) { - return true; - } - if (includeRecentlyActive && state == mPlaybackState.STATE_PAUSED) { - long inactiveTime = SystemClock.uptimeMillis() - mLastActiveTime; - if (inactiveTime < ACTIVE_BUFFER) { - return true; - } - } - return false; + public boolean isPlaybackActive() { + int state = mPlaybackState == null ? PlaybackState.STATE_NONE : mPlaybackState.getState(); + return MediaSession.isActiveState(state); } /** @@ -456,7 +446,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { @Override public String toString() { - return mPackageName + "/" + mTag + " (uid=" + mUserId + ")"; + return mPackageName + "/" + mTag + " (userId=" + mUserId + ")"; } private void postAdjustLocalVolume(final int stream, final int direction, final int flags, @@ -782,7 +772,12 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { private final class SessionStub extends ISession.Stub { @Override public void destroy() { - mService.destroySession(MediaSessionRecord.this); + final long token = Binder.clearCallingIdentity(); + try { + mService.destroySession(MediaSessionRecord.this); + } finally { + Binder.restoreCallingIdentity(token); + } } @Override @@ -817,6 +812,12 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { @Override public void setMediaButtonReceiver(PendingIntent pi) { mMediaButtonReceiver = pi; + final long token = Binder.clearCallingIdentity(); + try { + mService.onMediaButtonReceiverChanged(MediaSessionRecord.this); + } finally { + Binder.restoreCallingIdentity(token); + } } @Override @@ -842,15 +843,19 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { @Override public void setPlaybackState(PlaybackState state) { - int oldState = mPlaybackState == null ? 0 : mPlaybackState.getState(); - int newState = state == null ? 0 : state.getState(); - if (MediaSession.isActiveState(oldState) && newState == PlaybackState.STATE_PAUSED) { - mLastActiveTime = SystemClock.elapsedRealtime(); - } + int oldState = mPlaybackState == null + ? PlaybackState.STATE_NONE : mPlaybackState.getState(); + int newState = state == null + ? PlaybackState.STATE_NONE : state.getState(); synchronized (mLock) { mPlaybackState = state; } - mService.onSessionPlaystateChange(MediaSessionRecord.this, oldState, newState); + final long token = Binder.clearCallingIdentity(); + try { + mService.onSessionPlaystateChanged(MediaSessionRecord.this, oldState, newState); + } finally { + Binder.restoreCallingIdentity(token); + } mHandler.post(MessageHandler.MSG_UPDATE_PLAYBACK_STATE); } diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index ea9128fd6e2f..4bf9d8f5ff53 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -57,11 +57,13 @@ import android.os.Process; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ServiceManager; +import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import android.speech.RecognizerIntent; import android.text.TextUtils; +import android.util.IntArray; import android.util.Log; import android.util.Slog; import android.util.SparseArray; @@ -85,7 +87,7 @@ import java.util.List; */ public class MediaSessionService extends SystemService implements Monitor { private static final String TAG = "MediaSessionService"; - private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); // Leave log for key event always. private static final boolean DEBUG_KEY_EVENT = true; @@ -114,6 +116,7 @@ public class MediaSessionService extends SystemService implements Monitor { // It's always not null after the MediaSessionService is started. private FullUserRecord mCurrentFullUserRecord; private MediaSessionRecord mGlobalPrioritySession; + private AudioPlaybackMonitor mAudioPlaybackMonitor; // Used to notify system UI when remote volume was changed. TODO find a // better way to handle this. @@ -134,6 +137,19 @@ public class MediaSessionService extends SystemService implements Monitor { mKeyguardManager = (KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE); mAudioService = getAudioService(); + mAudioPlaybackMonitor = new AudioPlaybackMonitor(getContext(), mAudioService, + new AudioPlaybackMonitor.OnAudioPlaybackStartedListener() { + @Override + public void onAudioPlaybackStarted(int uid) { + synchronized (mLock) { + FullUserRecord user = + getFullUserRecordLocked(UserHandle.getUserId(uid)); + if (user != null) { + user.mPriorityStack.updateMediaButtonSessionIfNeeded(); + } + } + } + }); mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class); mContentResolver = getContext().getContentResolver(); mSettingsObserver = new SettingsObserver(); @@ -161,9 +177,10 @@ public class MediaSessionService extends SystemService implements Monitor { user.mPriorityStack.onSessionStateChange(record); if ((record.getFlags() & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) != 0) { mGlobalPrioritySession = record; + user.pushAddressedPlayerChangedLocked(); } + mHandler.postSessionsChanged(record.getUserId()); } - mHandler.post(MessageHandler.MSG_SESSIONS_CHANGED, record.getUserId(), 0); } /** @@ -180,18 +197,14 @@ public class MediaSessionService extends SystemService implements Monitor { } } - public void onSessionPlaystateChange(MediaSessionRecord record, int oldState, int newState) { - boolean updateSessions = false; + public void onSessionPlaystateChanged(MediaSessionRecord record, int oldState, int newState) { synchronized (mLock) { FullUserRecord user = getFullUserRecordLocked(record.getUserId()); if (user == null || !user.mPriorityStack.contains(record)) { Log.d(TAG, "Unknown session changed playback state. Ignoring."); return; } - updateSessions = user.mPriorityStack.onPlaystateChange(record, oldState, newState); - } - if (updateSessions) { - mHandler.post(MessageHandler.MSG_SESSIONS_CHANGED, record.getUserId(), 0); + user.mPriorityStack.onPlaystateChanged(record, oldState, newState); } } @@ -332,6 +345,9 @@ public class MediaSessionService extends SystemService implements Monitor { } if (mGlobalPrioritySession == session) { mGlobalPrioritySession = null; + if (session.isActive() && user != null) { + user.pushAddressedPlayerChangedLocked(); + } } try { @@ -340,8 +356,7 @@ public class MediaSessionService extends SystemService implements Monitor { // ignore exceptions while destroying a session. } session.onDestroy(); - - mHandler.post(MessageHandler.MSG_SESSIONS_CHANGED, session.getUserId(), 0); + mHandler.postSessionsChanged(session.getUserId()); } private void enforcePackageName(String packageName, int uid) { @@ -461,7 +476,7 @@ public class MediaSessionService extends SystemService implements Monitor { } final MediaSessionRecord session = new MediaSessionRecord(callerPid, callerUid, userId, - callerPackageName, cb, tag, this, mHandler); + callerPackageName, cb, tag, this, mHandler.getLooper()); try { cb.asBinder().linkToDeath(session, 0); } catch (RemoteException e) { @@ -469,8 +484,7 @@ public class MediaSessionService extends SystemService implements Monitor { } user.addSessionLocked(session); - - mHandler.post(MessageHandler.MSG_SESSIONS_CHANGED, userId, 0); + mHandler.postSessionsChanged(userId); if (DEBUG) { Log.d(TAG, "Created session for " + callerPackageName + " with tag " + tag); @@ -496,10 +510,6 @@ public class MediaSessionService extends SystemService implements Monitor { } List<MediaSessionRecord> records = user.mPriorityStack.getActiveSessions(userId); int size = records.size(); - if (size > 0 && records.get(0).isPlaybackActive(false)) { - user.rememberMediaButtonReceiverLocked(records.get(0)); - } - user.pushAddressedPlayerChangedLocked(); ArrayList<MediaSession.Token> tokens = new ArrayList<MediaSession.Token>(); for (int i = 0; i < size; i++) { tokens.add(new MediaSession.Token(records.get(i).getControllerBinder())); @@ -536,6 +546,22 @@ public class MediaSessionService extends SystemService implements Monitor { } } + /** + * Called when the media button receiver for the {@param record} is changed. + * + * @param record the media session whose media button receiver is updated. + */ + public void onMediaButtonReceiverChanged(MediaSessionRecord record) { + synchronized (mLock) { + FullUserRecord user = getFullUserRecordLocked(record.getUserId()); + MediaSessionRecord mediaButtonSession = + user.mPriorityStack.getMediaButtonSession(); + if (record == mediaButtonSession) { + user.rememberMediaButtonReceiverLocked(mediaButtonSession); + } + } + } + private String getCallingPackageName(int uid) { String[] packages = getContext().getPackageManager().getPackagesForUid(uid); if (packages != null && packages.length > 0) { @@ -568,10 +594,10 @@ public class MediaSessionService extends SystemService implements Monitor { * place makes more sense and increases the readability.</p> * <p>The contents of this object is guarded by {@link #mLock}. */ - final class FullUserRecord { + final class FullUserRecord implements MediaSessionStack.OnMediaButtonSessionChangedListener { private static final String COMPONENT_NAME_USER_ID_DELIM = ","; private final int mFullUserId; - private final MediaSessionStack mPriorityStack = new MediaSessionStack(); + private final MediaSessionStack mPriorityStack; private PendingIntent mLastMediaButtonReceiver; private ComponentName mRestoredMediaButtonReceiver; private int mRestoredMediaButtonReceiverUserId; @@ -588,6 +614,7 @@ public class MediaSessionService extends SystemService implements Monitor { public FullUserRecord(int fullUserId) { mFullUserId = fullUserId; + mPriorityStack = new MediaSessionStack(mAudioPlaybackMonitor, this); // Restore the remembered media button receiver before the boot. String mediaButtonReceiver = Settings.Secure.getStringForUser(mContentResolver, Settings.System.MEDIA_BUTTON_RECEIVER, mFullUserId); @@ -603,15 +630,14 @@ public class MediaSessionService extends SystemService implements Monitor { } public void destroySessionsForUserLocked(int userId) { - List<MediaSessionRecord> sessions = mPriorityStack.getPriorityList(false, 0, userId); + List<MediaSessionRecord> sessions = mPriorityStack.getPriorityList(false, userId); for (MediaSessionRecord session : sessions) { MediaSessionService.this.destroySessionLocked(session); } } public void addSessionLocked(MediaSessionRecord session) { - mPriorityStack.addSession(session, - mFullUserId == mFullUserIds.get(session.getUserId())); + mPriorityStack.addSession(session); } public void removeSessionLocked(MediaSessionRecord session) { @@ -642,21 +668,41 @@ public class MediaSessionService extends SystemService implements Monitor { mPriorityStack.dump(pw, indent); } - // Remember the media button receiver and keep it in the persistent storage. - private void rememberMediaButtonReceiverLocked(MediaSessionRecord record) { - PendingIntent receiver = record.getMediaButtonReceiver(); - if (receiver == null) { - return; + @Override + public void onMediaButtonSessionChanged(MediaSessionRecord oldMediaButtonSession, + MediaSessionRecord newMediaButtonSession) { + if (DEBUG_KEY_EVENT) { + Log.d(TAG, "Media button session will be changed to " + newMediaButtonSession); + } + synchronized (mLock) { + if (oldMediaButtonSession != null) { + mHandler.postSessionsChanged(oldMediaButtonSession.getUserId()); + } + if (newMediaButtonSession != null) { + rememberMediaButtonReceiverLocked(newMediaButtonSession); + mHandler.postSessionsChanged(newMediaButtonSession.getUserId()); + } + pushAddressedPlayerChangedLocked(); } + } + + // Remember media button receiver and keep it in the persistent storage. + public void rememberMediaButtonReceiverLocked(MediaSessionRecord record) { + PendingIntent receiver = record.getMediaButtonReceiver(); mLastMediaButtonReceiver = receiver; - ComponentName component = receiver.getIntent().getComponent(); - if (component != null && record.getPackageName().equals(component.getPackageName())) { - String componentName = component.flattenToString(); - Settings.Secure.putStringForUser(mContentResolver, - Settings.System.MEDIA_BUTTON_RECEIVER, - componentName + COMPONENT_NAME_USER_ID_DELIM + record.getUserId(), - mFullUserId); + mRestoredMediaButtonReceiver = null; + String componentName = ""; + if (receiver != null) { + ComponentName component = receiver.getIntent().getComponent(); + if (component != null + && record.getPackageName().equals(component.getPackageName())) { + componentName = component.flattenToString(); + } } + Settings.Secure.putStringForUser(mContentResolver, + Settings.System.MEDIA_BUTTON_RECEIVER, + componentName + COMPONENT_NAME_USER_ID_DELIM + record.getUserId(), + mFullUserId); } private void pushAddressedPlayerChangedLocked() { @@ -682,14 +728,8 @@ public class MediaSessionService extends SystemService implements Monitor { } private MediaSessionRecord getMediaButtonSessionLocked() { - if (isGlobalPriorityActiveLocked()) { - return mGlobalPrioritySession; - } - // If we don't have a media button receiver to fall back on - // include non-playing sessions for dispatching. - boolean useNotPlayingSessions = (mLastMediaButtonReceiver == null - && mRestoredMediaButtonReceiver == null); - return mPriorityStack.getDefaultMediaButtonSession(useNotPlayingSessions); + return isGlobalPriorityActiveLocked() + ? mGlobalPrioritySession : mPriorityStack.getMediaButtonSession(); } } @@ -1262,6 +1302,7 @@ public class MediaSessionService extends SystemService implements Monitor { for (int i = 0; i < count; i++) { mUserRecords.valueAt(i).dumpLocked(pw, ""); } + mAudioPlaybackMonitor.dump(pw, ""); } } @@ -1390,7 +1431,7 @@ public class MediaSessionService extends SystemService implements Monitor { PendingIntent receiver = mCurrentFullUserRecord.mLastMediaButtonReceiver; if (DEBUG_KEY_EVENT) { Log.d(TAG, "Sending " + keyEvent - + " to the last known pendingIntent " + receiver); + + " to the last known PendingIntent " + receiver); } receiver.send(getContext(), needWakeLock ? mKeyEventReceiver.mLastTimeoutId : -1, @@ -1413,7 +1454,8 @@ public class MediaSessionService extends SystemService implements Monitor { } mediaButtonIntent.setComponent(receiver); getContext().sendBroadcastAsUser(mediaButtonIntent, - UserHandle.of(mCurrentFullUserRecord.mRestoredMediaButtonReceiverUserId)); + UserHandle.of(mCurrentFullUserRecord + .mRestoredMediaButtonReceiverUserId)); if (mCurrentFullUserRecord.mCallback != null) { mCurrentFullUserRecord.mCallback .onMediaKeyEventDispatchedToMediaButtonReceiver( @@ -1426,23 +1468,6 @@ public class MediaSessionService extends SystemService implements Monitor { } catch (RemoteException e) { Log.w(TAG, "Failed to send callback", e); } - } else { - if (DEBUG) { - Log.d(TAG, "Sending media key ordered broadcast"); - } - if (needWakeLock) { - mMediaEventWakeLock.acquire(); - } - // Fallback to legacy behavior - Intent keyIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null); - keyIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); - keyIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent); - if (needWakeLock) { - keyIntent.putExtra(EXTRA_WAKELOCK_ACQUIRED, WAKELOCK_RELEASE_ON_FINISHED); - } - // Send broadcast only to the full user. - getContext().sendOrderedBroadcastAsUser(keyIntent, UserHandle.CURRENT, - null, mKeyEventDone, mHandler, Activity.RESULT_OK, null, null); } } @@ -1637,12 +1662,13 @@ public class MediaSessionService extends SystemService implements Monitor { final class MessageHandler extends Handler { private static final int MSG_SESSIONS_CHANGED = 1; private static final int MSG_VOLUME_INITIAL_DOWN = 2; + private final SparseArray<Integer> mIntegerCache = new SparseArray<>(); @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_SESSIONS_CHANGED: - pushSessionsChanged(msg.arg1); + pushSessionsChanged((int) msg.obj); break; case MSG_VOLUME_INITIAL_DOWN: synchronized (mLock) { @@ -1657,8 +1683,15 @@ public class MediaSessionService extends SystemService implements Monitor { } } - public void post(int what, int arg1, int arg2) { - obtainMessage(what, arg1, arg2).sendToTarget(); + public void postSessionsChanged(int userId) { + // Use object instead of the arguments when posting message to remove pending requests. + Integer userIdInteger = mIntegerCache.get(userId); + if (userIdInteger == null) { + userIdInteger = Integer.valueOf(userId); + mIntegerCache.put(userId, userIdInteger); + } + removeMessages(MSG_SESSIONS_CHANGED, userIdInteger); + obtainMessage(MSG_SESSIONS_CHANGED, userIdInteger).sendToTarget(); } } } diff --git a/services/core/java/com/android/server/media/MediaSessionStack.java b/services/core/java/com/android/server/media/MediaSessionStack.java index 8b8073454f8c..b0d8adcc122e 100644 --- a/services/core/java/com/android/server/media/MediaSessionStack.java +++ b/services/core/java/com/android/server/media/MediaSessionStack.java @@ -16,12 +16,13 @@ package com.android.server.media; -import android.app.ActivityManager; import android.media.session.MediaController.PlaybackInfo; -import android.media.session.PlaybackState; import android.media.session.MediaSession; -import android.os.RemoteException; +import android.media.session.PlaybackState; +import android.os.Debug; import android.os.UserHandle; +import android.util.IntArray; +import android.util.Log; import java.io.PrintWriter; import java.util.ArrayList; @@ -33,6 +34,20 @@ import java.util.List; * <p>This class isn't thread-safe. The caller should take care of the synchronization. */ class MediaSessionStack { + private static final boolean DEBUG = MediaSessionService.DEBUG; + private static final String TAG = "MediaSessionStack"; + + /** + * Listens the change in the media button session. + */ + interface OnMediaButtonSessionChangedListener { + /** + * Called when the media button session is changed. + */ + void onMediaButtonSessionChanged(MediaSessionRecord oldMediaButtonSession, + MediaSessionRecord newMediaButtonSession); + } + /** * These are states that usually indicate the user took an action and should * bump priority regardless of the old state. @@ -51,57 +66,45 @@ class MediaSessionStack { PlaybackState.STATE_CONNECTING, PlaybackState.STATE_PLAYING }; - private final ArrayList<MediaSessionRecord> mSessions = new ArrayList<MediaSessionRecord>(); + /** + * Sorted list of the media sessions. + * The session of which PlaybackState is changed to ALWAYS_PRIORITY_STATES or + * TRANSITION_PRIORITY_STATES comes first. + * @see #shouldUpdatePriority + */ + private final List<MediaSessionRecord> mSessions = new ArrayList<MediaSessionRecord>(); + + private final AudioPlaybackMonitor mAudioPlaybackMonitor; + private final OnMediaButtonSessionChangedListener mOnMediaButtonSessionChangedListener; + + /** + * The media button session which receives media key events. + * It could be null if the previous media buttion session is released. + */ + private MediaSessionRecord mMediaButtonSession; - // The last record that either entered one of the playing states or was - // added. - private MediaSessionRecord mLastInterestingRecord; - private MediaSessionRecord mCachedButtonReceiver; private MediaSessionRecord mCachedDefault; private MediaSessionRecord mCachedVolumeDefault; private ArrayList<MediaSessionRecord> mCachedActiveList; - private ArrayList<MediaSessionRecord> mCachedTransportControlList; - /** - * Checks if a media session is created from the most recent app. - * - * @param record A media session record to be examined. - * @return {@code true} if the media session's package name equals to the most recent app, false - * otherwise. - */ - private static boolean isFromMostRecentApp(MediaSessionRecord record) { - try { - List<ActivityManager.RecentTaskInfo> tasks = - ActivityManager.getService().getRecentTasks(1, - ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS | - ActivityManager.RECENT_IGNORE_UNAVAILABLE | - ActivityManager.RECENT_INCLUDE_PROFILES | - ActivityManager.RECENT_WITH_EXCLUDED, record.getUserId()).getList(); - if (tasks != null && !tasks.isEmpty()) { - ActivityManager.RecentTaskInfo recentTask = tasks.get(0); - if (recentTask.userId == record.getUserId() && recentTask.baseIntent != null) { - return recentTask.baseIntent.getComponent().getPackageName() - .equals(record.getPackageName()); - } - } - } catch (RemoteException e) { - return false; - } - return false; + MediaSessionStack(AudioPlaybackMonitor monitor, OnMediaButtonSessionChangedListener listener) { + mAudioPlaybackMonitor = monitor; + mOnMediaButtonSessionChangedListener = listener; } /** * Add a record to the priority tracker. * * @param record The record to add. - * @param fromForegroundUser {@code true} if the session is created by the foreground user. */ - public void addSession(MediaSessionRecord record, boolean fromForegroundUser) { + public void addSession(MediaSessionRecord record) { mSessions.add(record); clearCache(); - if (fromForegroundUser && isFromMostRecentApp(record)) { - mLastInterestingRecord = record; - } + + // Update the media button session. + // The added session could be the session from the package with the audio playback. + // This can happen if an app starts audio playback before creating media session. + updateMediaButtonSessionIfNeeded(); } /** @@ -111,6 +114,11 @@ class MediaSessionStack { */ public void removeSession(MediaSessionRecord record) { mSessions.remove(record); + if (mMediaButtonSession == record) { + // When the media button session is gone, try to find the alternative media session + // in the media button session app. + onMediaSessionChangeInMediaButtonSessionApp(); + } clearCache(); } @@ -122,32 +130,33 @@ class MediaSessionStack { } /** - * Notify the priority tracker that a session's state changed. + * Notify the priority tracker that a session's playback state changed. * * @param record The record that changed. * @param oldState Its old playback state. * @param newState Its new playback state. - * @return true if the priority order was updated, false otherwise. */ - public boolean onPlaystateChange(MediaSessionRecord record, int oldState, int newState) { + public void onPlaystateChanged(MediaSessionRecord record, int oldState, int newState) { if (shouldUpdatePriority(oldState, newState)) { mSessions.remove(record); mSessions.add(0, record); clearCache(); - // This becomes the last interesting record since it entered a - // playing state - mLastInterestingRecord = record; - return true; } else if (!MediaSession.isActiveState(newState)) { // Just clear the volume cache when a state goes inactive mCachedVolumeDefault = null; } - return false; + + // In most cases, playback state isn't needed for finding media buttion session, + // but we only use it as a hint if an app has multiple local media sessions. + // In that case, we pick the media session whose PlaybackState matches + // the audio playback configuration. + if (mMediaButtonSession != null && mMediaButtonSession.getUid() == record.getUid()) { + onMediaSessionChangeInMediaButtonSessionApp(); + } } /** - * Handle any stack changes that need to occur in response to a session - * state change. TODO add the old and new session state as params + * Handle the change in activeness for a session. * * @param record The record that changed. */ @@ -158,6 +167,81 @@ class MediaSessionStack { } /** + * Update the media button session if needed. + * <p>The media button session is the session that will receive the media button events. + * <p>We send the media button events to the lastly played app. If the app has the media + * session, the session will receive the media button events. + */ + public void updateMediaButtonSessionIfNeeded() { + if (DEBUG) { + Log.d(TAG, "updateMediaButtonSessionIfNeeded, callers=" + Debug.getCallers(2)); + } + IntArray audioPlaybackUids = mAudioPlaybackMonitor.getSortedAudioPlaybackClientUids(); + for (int i = 0; i < audioPlaybackUids.size(); i++) { + MediaSessionRecord mediaButtonSession = + findMediaButtonSession(audioPlaybackUids.get(i)); + if (mediaButtonSession != null) { + // Found the media button session. + mAudioPlaybackMonitor.cleanUpAudioPlaybackUids(mediaButtonSession.getUid()); + if (mMediaButtonSession != mediaButtonSession) { + mOnMediaButtonSessionChangedListener.onMediaButtonSessionChanged( + mMediaButtonSession, mediaButtonSession); + mMediaButtonSession = mediaButtonSession; + } + return; + } + } + } + + /** + * Handle the change in a media session in the media button session app. + * <p>If the app has multiple media sessions, change in a media sesion in the app may change + * the media button session. + * @see #findMediaButtonSession + */ + private void onMediaSessionChangeInMediaButtonSessionApp() { + MediaSessionRecord newMediaButtonSession = + findMediaButtonSession(mMediaButtonSession.getUid()); + if (newMediaButtonSession != mMediaButtonSession) { + mOnMediaButtonSessionChangedListener.onMediaButtonSessionChanged(mMediaButtonSession, + newMediaButtonSession); + mMediaButtonSession = newMediaButtonSession; + } + } + + /** + * Find the media button session with the given {@param uid}. + * If the app has multiple media sessions, the media session matches the audio playback state + * becomes the media button session. + * + * @return The media button session. Returns {@code null} if the app doesn't have a media + * session. + */ + private MediaSessionRecord findMediaButtonSession(int uid) { + MediaSessionRecord mediaButtonSession = null; + for (MediaSessionRecord session : mSessions) { + // Since the media buttons come with the headset/speaker, users will expect changes in + // the headset/speaker when they press media buttons. So only consider local playback + // for the media button session. + if (uid == session.getUid() + && session.getPlaybackType() == PlaybackInfo.PLAYBACK_TYPE_LOCAL) { + if (session.isPlaybackActive() == + mAudioPlaybackMonitor.isPlaybackActive(session.getUid())) { + // If there's a media session whose PlaybackState matches + // the audio playback state, return it immediately. + return session; + } + if (mediaButtonSession == null) { + // Among the media sessions whose PlaybackState doesn't match + // the audio playback state, pick the top priority. + mediaButtonSession = session; + } + } + } + return mediaButtonSession; + } + + /** * Get the current priority sorted list of active sessions. The most * important session is at index 0 and the least important at size - 1. * @@ -166,57 +250,29 @@ class MediaSessionStack { */ public ArrayList<MediaSessionRecord> getActiveSessions(int userId) { if (mCachedActiveList == null) { - mCachedActiveList = getPriorityList(true, 0, userId); + mCachedActiveList = getPriorityList(true, userId); } return mCachedActiveList; } /** - * Get the highest priority session that can handle media buttons. + * Get the media button session which receives the media button events. * - * @param includeNotPlaying Return a non-playing session if nothing else is - * available - * @return The default media button session or null. + * @return The media button session or null. */ - public MediaSessionRecord getDefaultMediaButtonSession(boolean includeNotPlaying) { - if (mCachedButtonReceiver != null) { - return mCachedButtonReceiver; - } - ArrayList<MediaSessionRecord> records = getPriorityList(true, - MediaSession.FLAG_HANDLES_MEDIA_BUTTONS, UserHandle.USER_ALL); - if (records.size() > 0) { - MediaSessionRecord record = records.get(0); - if (record.isPlaybackActive(false)) { - // Since we're going to send a button event to this record make - // it the last interesting one. - mLastInterestingRecord = record; - mCachedButtonReceiver = record; - } else if (mLastInterestingRecord != null) { - if (records.contains(mLastInterestingRecord)) { - mCachedButtonReceiver = mLastInterestingRecord; - } else { - // That record is no longer used. Clear its reference. - mLastInterestingRecord = null; - } - } - if (includeNotPlaying && mCachedButtonReceiver == null) { - // If we really want a record and we didn't find one yet use the - // highest priority session even if it's not playing. - mCachedButtonReceiver = record; - } - } - return mCachedButtonReceiver; + public MediaSessionRecord getMediaButtonSession() { + return mMediaButtonSession; } public MediaSessionRecord getDefaultVolumeSession() { if (mCachedVolumeDefault != null) { return mCachedVolumeDefault; } - ArrayList<MediaSessionRecord> records = getPriorityList(true, 0, UserHandle.USER_ALL); + ArrayList<MediaSessionRecord> records = getPriorityList(true, UserHandle.USER_ALL); int size = records.size(); for (int i = 0; i < size; i++) { MediaSessionRecord record = records.get(i); - if (record.isPlaybackActive(false)) { + if (record.isPlaybackActive()) { mCachedVolumeDefault = record; return record; } @@ -225,7 +281,7 @@ class MediaSessionStack { } public MediaSessionRecord getDefaultRemoteSession(int userId) { - ArrayList<MediaSessionRecord> records = getPriorityList(true, 0, userId); + ArrayList<MediaSessionRecord> records = getPriorityList(true, userId); int size = records.size(); for (int i = 0; i < size; i++) { @@ -238,9 +294,10 @@ class MediaSessionStack { } public void dump(PrintWriter pw, String prefix) { - ArrayList<MediaSessionRecord> sortedSessions = getPriorityList(false, 0, + ArrayList<MediaSessionRecord> sortedSessions = getPriorityList(false, UserHandle.USER_ALL); int count = sortedSessions.size(); + pw.println(prefix + "Media button session is " + mMediaButtonSession); pw.println(prefix + "Sessions Stack - have " + count + " sessions:"); String indent = prefix + " "; for (int i = 0; i < count; i++) { @@ -252,22 +309,23 @@ class MediaSessionStack { /** * Get a priority sorted list of sessions. Can filter to only return active - * sessions or sessions with specific flags. + * sessions or sessions. + * <p>Here's the priority order. + * <li>System priority session (session with FLAG_EXCLUSIVE_GLOBAL_PRIORITY)</li> + * <li>Active sessions whose PlaybackState is active</li> + * <li>Active sessions whose PlaybackState is inactive</li> + * <li>Inactive sessions</li> * * @param activeOnly True to only return active sessions, false to return * all sessions. - * @param withFlags Only return sessions with all the specified flags set. 0 - * returns all sessions. * @param userId The user to get sessions for. {@link UserHandle#USER_ALL} * will return sessions for all users. * @return The priority sorted list of sessions. */ - public ArrayList<MediaSessionRecord> getPriorityList(boolean activeOnly, int withFlags, - int userId) { + public ArrayList<MediaSessionRecord> getPriorityList(boolean activeOnly, int userId) { ArrayList<MediaSessionRecord> result = new ArrayList<MediaSessionRecord>(); - int lastLocalIndex = 0; + int lastPlaybackActiveIndex = 0; int lastActiveIndex = 0; - int lastPublishedIndex = 0; int size = mSessions.size(); for (int i = 0; i < size; i++) { @@ -277,10 +335,7 @@ class MediaSessionStack { // Filter out sessions for the wrong user continue; } - if ((session.getFlags() & withFlags) != withFlags) { - // Filter out sessions with the wrong flags - continue; - } + if (!session.isActive()) { if (!activeOnly) { // If we're getting unpublished as well always put them at @@ -294,28 +349,13 @@ class MediaSessionStack { // System priority sessions are special and always go at the // front. We expect there to only be one of these at a time. result.add(0, session); - lastLocalIndex++; + lastPlaybackActiveIndex++; + lastActiveIndex++; + } else if (session.isPlaybackActive()) { + result.add(lastPlaybackActiveIndex++, session); lastActiveIndex++; - lastPublishedIndex++; - } else if (session.isPlaybackActive(true)) { - // TODO this with real local route check - if (true) { - // Active local sessions get top priority - result.add(lastLocalIndex, session); - lastLocalIndex++; - lastActiveIndex++; - lastPublishedIndex++; - } else { - // Then active remote sessions - result.add(lastActiveIndex, session); - lastActiveIndex++; - lastPublishedIndex++; - } } else { - // inactive sessions go at the end in order of whoever last did - // something. - result.add(lastPublishedIndex, session); - lastPublishedIndex++; + result.add(lastActiveIndex++, session); } } @@ -345,8 +385,6 @@ class MediaSessionStack { private void clearCache() { mCachedDefault = null; mCachedVolumeDefault = null; - mCachedButtonReceiver = null; mCachedActiveList = null; - mCachedTransportControlList = null; } } diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index fc45344b2f4d..f180c5089aa1 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -75,6 +75,9 @@ import static android.net.wifi.WifiManager.EXTRA_CHANGE_REASON; import static android.net.wifi.WifiManager.EXTRA_NETWORK_INFO; import static android.net.wifi.WifiManager.EXTRA_WIFI_CONFIGURATION; import static android.net.wifi.WifiManager.EXTRA_WIFI_INFO; +import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED; +import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT; +import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED; import static android.text.format.DateUtils.DAY_IN_MILLIS; import static com.android.internal.util.ArrayUtils.appendInt; @@ -141,6 +144,7 @@ import android.os.IDeviceIdleController; import android.os.INetworkManagementService; import android.os.Message; import android.os.MessageQueue.IdleHandler; +import android.os.PersistableBundle; import android.os.PowerManager; import android.os.PowerManagerInternal; import android.os.Process; @@ -153,6 +157,7 @@ import android.os.Trace; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; +import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.text.TextUtils; @@ -174,12 +179,14 @@ import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.notification.SystemNotificationChannels; +import com.android.internal.telephony.PhoneConstants; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.IndentingPrintWriter; import com.android.server.DeviceIdleController; import com.android.server.EventLogTags; import com.android.server.LocalServices; +import com.android.server.ServiceThread; import com.android.server.SystemConfig; import com.android.server.power.BatterySaverPolicy.ServiceType; @@ -204,6 +211,7 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Calendar; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -310,6 +318,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private static final int MSG_SET_FIREWALL_RULES = 14; private static final int MSG_RESET_FIREWALL_RULES_BY_UID = 15; + private static final int UID_MSG_STATE_CHANGED = 100; + private static final int UID_MSG_GONE = 101; + private final Context mContext; private final IActivityManager mActivityManager; private final INetworkStatsService mNetworkStats; @@ -317,6 +328,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private UsageStatsManagerInternal mUsageStats; private final TrustedTime mTime; private final UserManager mUserManager; + private final CarrierConfigManager mCarrierConfigManager; private IConnectivityManager mConnManager; private INotificationManager mNotifManager; @@ -420,6 +432,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mListeners = new RemoteCallbackList<>(); final Handler mHandler; + @VisibleForTesting + public final Handler mUidEventHandler; + + private final ServiceThread mUidEventThread; @GuardedBy("allLocks") private final AtomicFile mPolicyFile; @@ -465,12 +481,19 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { Context.DEVICE_IDLE_CONTROLLER)); mTime = checkNotNull(time, "missing TrustedTime"); mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); + mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class); mIPm = pm; HandlerThread thread = new HandlerThread(TAG); thread.start(); mHandler = new Handler(thread.getLooper(), mHandlerCallback); + // We create another thread for the UID events, which are more time-critical. + mUidEventThread = new ServiceThread(TAG + ".uid", Process.THREAD_PRIORITY_FOREGROUND, + /*allowIo=*/ false); + mUidEventThread.start(); + mUidEventHandler = new Handler(mUidEventThread.getLooper(), mUidEventHandlerCallback); + mSuppressDefaultPolicy = suppressDefaultPolicy; mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml")); @@ -743,6 +766,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { WifiManager.NETWORK_STATE_CHANGED_ACTION); mContext.registerReceiver(mWifiStateReceiver, wifiStateFilter, null, mHandler); + // listen for carrier config changes to update data cycle information + final IntentFilter carrierConfigFilter = new IntentFilter( + ACTION_CARRIER_CONFIG_CHANGED); + mContext.registerReceiver(mCarrierConfigReceiver, carrierConfigFilter, null, mHandler); + mUsageStats.addAppIdleStateChangeListener(new AppIdleStateChangeListener()); // tell systemReady() that the service has been initialized initCompleteSignal.countDown(); @@ -774,26 +802,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final private IUidObserver mUidObserver = new IUidObserver.Stub() { @Override public void onUidStateChanged(int uid, int procState, long procStateSeq) throws RemoteException { - Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidStateChanged"); - try { - synchronized (mUidRulesFirstLock) { - // We received a uid state change callback, add it to the history so that it - // will be useful for debugging. - mObservedHistory.addProcStateSeqUL(uid, procStateSeq); - // Now update the network policy rules as per the updated uid state. - updateUidStateUL(uid, procState); - // Updating the network rules is done, so notify AMS about this. - mActivityManagerInternal.notifyNetworkPolicyRulesUpdated(uid, procStateSeq); - } - } finally { - Trace.traceEnd(Trace.TRACE_TAG_NETWORK); - } + mUidEventHandler.obtainMessage(UID_MSG_STATE_CHANGED, + uid, procState, procStateSeq).sendToTarget(); } @Override public void onUidGone(int uid, boolean disabled) throws RemoteException { - synchronized (mUidRulesFirstLock) { - removeUidStateUL(uid); - } + mUidEventHandler.obtainMessage(UID_MSG_GONE, uid, 0).sendToTarget(); } @Override public void onUidActive(int uid) throws RemoteException { @@ -1293,6 +1307,213 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { }; /** + * Update mobile policies with data cycle information from {@link CarrierConfigManager} + * if necessary. + * + * @param subId that has its associated NetworkPolicy updated if necessary + * @return if any policies were updated + */ + private boolean maybeUpdateMobilePolicyCycleNL(int subId) { + if (LOGV) Slog.v(TAG, "maybeUpdateMobilePolicyCycleNL()"); + final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId); + + if (config == null) { + return false; + } + + boolean policyUpdated = false; + final String subscriberId = TelephonyManager.from(mContext).getSubscriberId(subId); + + // find and update the mobile NetworkPolicy for this subscriber id + final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE, + TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true); + for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) { + final NetworkTemplate template = mNetworkPolicy.keyAt(i); + if (template.matches(probeIdent)) { + NetworkPolicy policy = mNetworkPolicy.valueAt(i); + + // only update the policy if the user didn't change any of the defaults. + if (!policy.inferred) { + // TODO: inferred could be split, so that if a user changes their data limit or + // warning, it doesn't prevent their cycle date from being updated. + if (LOGD) Slog.v(TAG, "Didn't update NetworkPolicy because policy.inferred"); + continue; + } + + final int cycleDay = getCycleDayFromCarrierConfig(config, policy.cycleDay); + final long warningBytes = getWarningBytesFromCarrierConfig(config, + policy.warningBytes); + final long limitBytes = getLimitBytesFromCarrierConfig(config, + policy.limitBytes); + + if (policy.cycleDay == cycleDay && + policy.warningBytes == warningBytes && + policy.limitBytes == limitBytes) { + continue; + } + + policyUpdated = true; + policy.cycleDay = cycleDay; + policy.warningBytes = warningBytes; + policy.limitBytes = limitBytes; + + if (LOGD) { + Slog.d(TAG, "Updated NetworkPolicy " + policy + " which matches subscriber " + + NetworkIdentity.scrubSubscriberId(subscriberId) + + " from CarrierConfigManager"); + } + } + } + + return policyUpdated; + } + + /** + * Returns the cycle day that should be used for a mobile NetworkPolicy. + * + * It attempts to get an appropriate cycle day from the passed in CarrierConfig. If it's unable + * to do so, it returns the fallback value. + * + * @param config The CarrierConfig to read the value from. + * @param fallbackCycleDay to return if the CarrierConfig can't be read. + * @return cycleDay to use in the mobile NetworkPolicy. + */ + @VisibleForTesting + public int getCycleDayFromCarrierConfig(@Nullable PersistableBundle config, + int fallbackCycleDay) { + if (config == null) { + return fallbackCycleDay; + } + int cycleDay = + config.getInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT); + if (cycleDay == DATA_CYCLE_USE_PLATFORM_DEFAULT) { + return fallbackCycleDay; + } + // validate cycleDay value + final Calendar cal = Calendar.getInstance(); + if (cycleDay < cal.getMinimum(Calendar.DAY_OF_MONTH) || + cycleDay > cal.getMaximum(Calendar.DAY_OF_MONTH)) { + Slog.e(TAG, "Invalid date in " + + "CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT: " + cycleDay); + return fallbackCycleDay; + } + return cycleDay; + } + + /** + * Returns the warning bytes that should be used for a mobile NetworkPolicy. + * + * It attempts to get an appropriate value from the passed in CarrierConfig. If it's unable + * to do so, it returns the fallback value. + * + * @param config The CarrierConfig to read the value from. + * @param fallbackWarningBytes to return if the CarrierConfig can't be read. + * @return warningBytes to use in the mobile NetworkPolicy. + */ + @VisibleForTesting + public long getWarningBytesFromCarrierConfig(@Nullable PersistableBundle config, + long fallbackWarningBytes) { + if (config == null) { + return fallbackWarningBytes; + } + long warningBytes = + config.getLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG); + + if (warningBytes == DATA_CYCLE_THRESHOLD_DISABLED) { + return WARNING_DISABLED; + } else if (warningBytes == DATA_CYCLE_USE_PLATFORM_DEFAULT) { + return getPlatformDefaultWarningBytes(); + } else if (warningBytes < 0) { + Slog.e(TAG, "Invalid value in " + + "CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG; expected a " + + "non-negative value but got: " + warningBytes); + return fallbackWarningBytes; + } + + return warningBytes; + } + + /** + * Returns the limit bytes that should be used for a mobile NetworkPolicy. + * + * It attempts to get an appropriate value from the passed in CarrierConfig. If it's unable + * to do so, it returns the fallback value. + * + * @param config The CarrierConfig to read the value from. + * @param fallbackLimitBytes to return if the CarrierConfig can't be read. + * @return limitBytes to use in the mobile NetworkPolicy. + */ + @VisibleForTesting + public long getLimitBytesFromCarrierConfig(@Nullable PersistableBundle config, + long fallbackLimitBytes) { + if (config == null) { + return fallbackLimitBytes; + } + long limitBytes = + config.getLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG); + + if (limitBytes == DATA_CYCLE_THRESHOLD_DISABLED) { + return LIMIT_DISABLED; + } else if (limitBytes == DATA_CYCLE_USE_PLATFORM_DEFAULT) { + return getPlatformDefaultLimitBytes(); + } else if (limitBytes < 0) { + Slog.e(TAG, "Invalid value in " + + "CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG; expected a " + + "non-negative value but got: " + limitBytes); + return fallbackLimitBytes; + } + return limitBytes; + } + + /** + * Receiver that watches for {@link CarrierConfigManager} to be changed. + */ + private BroadcastReceiver mCarrierConfigReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + // No need to do a permission check, because the ACTION_CARRIER_CONFIG_CHANGED + // broadcast is protected and can't be spoofed. Runs on a background handler thread. + + if (!intent.hasExtra(PhoneConstants.SUBSCRIPTION_KEY)) { + return; + } + final int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, -1); + final TelephonyManager tele = TelephonyManager.from(mContext); + final String subscriberId = tele.getSubscriberId(subId); + + maybeRefreshTrustedTime(); + synchronized (mUidRulesFirstLock) { + synchronized (mNetworkPoliciesSecondLock) { + final boolean added = ensureActiveMobilePolicyNL(subId, subscriberId); + if (added) return; + final boolean updated = maybeUpdateMobilePolicyCycleNL(subId); + if (!updated) return; + // update network and notification rules, as the data cycle changed and it's + // possible that we should be triggering warnings/limits now + handleNetworkPoliciesUpdateAL(true); + } + } + } + }; + + /** + * Handles all tasks that need to be run after a new network policy has been set, or an existing + * one has been updated. + * + * @param shouldNormalizePolicies true iff network policies need to be normalized after the + * update. + */ + void handleNetworkPoliciesUpdateAL(boolean shouldNormalizePolicies) { + if (shouldNormalizePolicies) { + normalizePoliciesNL(); + } + updateNetworkEnabledNL(); + updateNetworkRulesNL(); + updateNotificationsNL(); + writePolicyAL(); + } + + /** * Proactively control network data connections when they exceed * {@link NetworkPolicy#limitBytes}. */ @@ -1517,11 +1738,19 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final int[] subIds = sub.getActiveSubscriptionIdList(); for (int subId : subIds) { final String subscriberId = tele.getSubscriberId(subId); - ensureActiveMobilePolicyNL(subscriberId); + ensureActiveMobilePolicyNL(subId, subscriberId); } } - private void ensureActiveMobilePolicyNL(String subscriberId) { + /** + * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we + * have at least a default mobile policy defined. + * + * @param subId to build a default policy for + * @param subscriberId that we check for an existing policy + * @return true if a mobile network policy was added, or false one already existed. + */ + private boolean ensureActiveMobilePolicyNL(int subId, String subscriberId) { // Poke around to see if we already have a policy final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true); @@ -1532,33 +1761,51 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { Slog.d(TAG, "Found template " + template + " which matches subscriber " + NetworkIdentity.scrubSubscriberId(subscriberId)); } - return; + return false; } } Slog.i(TAG, "No policy for subscriber " + NetworkIdentity.scrubSubscriberId(subscriberId) + "; generating default policy"); + final NetworkPolicy policy = buildDefaultMobilePolicy(subId, subscriberId); + addNetworkPolicyNL(policy); + return true; + } - // Build default mobile policy, and assume usage cycle starts today + private long getPlatformDefaultWarningBytes() { final int dataWarningConfig = mContext.getResources().getInteger( com.android.internal.R.integer.config_networkPolicyDefaultWarning); - final long warningBytes; if (dataWarningConfig == WARNING_DISABLED) { - warningBytes = WARNING_DISABLED; + return WARNING_DISABLED; } else { - warningBytes = dataWarningConfig * MB_IN_BYTES; + return dataWarningConfig * MB_IN_BYTES; } + } + private long getPlatformDefaultLimitBytes() { + return LIMIT_DISABLED; + } + + @VisibleForTesting + public NetworkPolicy buildDefaultMobilePolicy(int subId, String subscriberId) { + PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId); + + // assume usage cycle starts today final Time time = new Time(); time.setToNow(); - final int cycleDay = time.monthDay; final String cycleTimezone = time.timezone; + final int cycleDay = getCycleDayFromCarrierConfig(config, time.monthDay); + final long warningBytes = getWarningBytesFromCarrierConfig(config, + getPlatformDefaultWarningBytes()); + final long limitBytes = getLimitBytesFromCarrierConfig(config, + getPlatformDefaultLimitBytes()); + final NetworkTemplate template = buildTemplateMobileAll(subscriberId); final NetworkPolicy policy = new NetworkPolicy(template, cycleDay, cycleTimezone, - warningBytes, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, true, true); - addNetworkPolicyNL(policy); + warningBytes, limitBytes, SNOOZE_NEVER, SNOOZE_NEVER, true, true); + return policy; } private void readPolicyAL() { @@ -2026,10 +2273,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { synchronized (mUidRulesFirstLock) { synchronized (mNetworkPoliciesSecondLock) { normalizePoliciesNL(policies); - updateNetworkEnabledNL(); - updateNetworkRulesNL(); - updateNotificationsNL(); - writePolicyAL(); + handleNetworkPoliciesUpdateAL(false); } } } finally { @@ -2126,11 +2370,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { throw new IllegalArgumentException("unexpected type"); } - normalizePoliciesNL(); - updateNetworkEnabledNL(); - updateNetworkRulesNL(); - updateNotificationsNL(); - writePolicyAL(); + handleNetworkPoliciesUpdateAL(true); } } } @@ -2361,11 +2601,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mNetworkPolicy.valueAt(i).clearSnooze(); } - normalizePoliciesNL(); - updateNetworkEnabledNL(); - updateNetworkRulesNL(); - updateNotificationsNL(); - writePolicyAL(); + handleNetworkPoliciesUpdateAL(true); fout.println("Cleared snooze timestamps"); return; @@ -3317,7 +3553,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } - private Handler.Callback mHandlerCallback = new Handler.Callback() { + private final Handler.Callback mHandlerCallback = new Handler.Callback() { @Override public boolean handleMessage(Message msg) { switch (msg.what) { @@ -3441,9 +3677,61 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } } + }; + + private final Handler.Callback mUidEventHandlerCallback = new Handler.Callback() { + @Override + public boolean handleMessage(Message msg) { + switch (msg.what) { + case UID_MSG_STATE_CHANGED: { + final int uid = msg.arg1; + final int procState = msg.arg2; + final long procStateSeq = (Long) msg.obj; + + handleUidChanged(uid, procState, procStateSeq); + return true; + } + case UID_MSG_GONE: { + final int uid = msg.arg1; + handleUidGone(uid); + return true; + } + default: { + return false; + } + } + } }; + void handleUidChanged(int uid, int procState, long procStateSeq) { + Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidStateChanged"); + try { + synchronized (mUidRulesFirstLock) { + // We received a uid state change callback, add it to the history so that it + // will be useful for debugging. + mObservedHistory.addProcStateSeqUL(uid, procStateSeq); + // Now update the network policy rules as per the updated uid state. + updateUidStateUL(uid, procState); + // Updating the network rules is done, so notify AMS about this. + mActivityManagerInternal.notifyNetworkPolicyRulesUpdated(uid, procStateSeq); + } + } finally { + Trace.traceEnd(Trace.TRACE_TAG_NETWORK); + } + } + + void handleUidGone(int uid) { + Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidGone"); + try { + synchronized (mUidRulesFirstLock) { + removeUidStateUL(uid); + } + } finally { + Trace.traceEnd(Trace.TRACE_TAG_NETWORK); + } + } + private void broadcastRestrictBackgroundChanged(int uid, Boolean changed) { final PackageManager pm = mContext.getPackageManager(); final String[] packages = pm.getPackagesForUid(uid); diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index ede5a5e8e337..7468b956af4e 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -90,6 +90,7 @@ import android.media.AudioManagerInternal; import android.media.IRingtonePlayer; import android.net.Uri; import android.os.Binder; +import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.Handler; @@ -3126,8 +3127,9 @@ public class NotificationManagerService extends SystemService { + ", incomingUserId=" + incomingUserId + ", notificationUid=" + notificationUid + ", notification=" + notification; - // STOPSHIP TODO: should throw instead of logging. - // throw new IllegalArgumentException(noChannelStr); + if (Build.IS_DEBUGGABLE) { + throw new IllegalArgumentException(noChannelStr); + } Log.e(TAG, noChannelStr); return; } diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java index db133f876d17..5bdef9ea7d49 100644 --- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java +++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java @@ -102,7 +102,8 @@ final class OverlayManagerServiceImpl { if (oi == null) { // This overlay does not exist in our settings. - if (mDefaultOverlays.contains(overlayPackage.packageName)) { + if (overlayPackage.isStaticOverlay || + mDefaultOverlays.contains(overlayPackage.packageName)) { // Enable this overlay by default. mSettings.setEnabled(overlayPackage.packageName, newUserId, true); } diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java index 126f8c408e22..6245ffc64009 100644 --- a/services/core/java/com/android/server/pm/OtaDexoptService.java +++ b/services/core/java/com/android/server/pm/OtaDexoptService.java @@ -135,16 +135,7 @@ public class OtaDexoptService extends IOtaDexopt.Stub { } for (PackageParser.Package p : important) { - // Make sure that core apps are optimized according to their own "reason". - // If the core apps are not preopted in the B OTA, and REASON_AB_OTA is not speed - // (by default is speed-profile) they will be interepreted/JITed. This in itself is - // not a problem as we will end up doing profile guided compilation. However, some - // core apps may be loaded by system server which doesn't JIT and we need to make - // sure we don't interpret-only - int compilationReason = p.coreApp - ? PackageManagerService.REASON_CORE_APP - : PackageManagerService.REASON_AB_OTA; - mDexoptCommands.addAll(generatePackageDexopts(p, compilationReason)); + mDexoptCommands.addAll(generatePackageDexopts(p, PackageManagerService.REASON_AB_OTA)); } for (PackageParser.Package p : others) { // We assume here that there are no core apps left. diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 8cc937502592..f633d7d940a1 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -537,12 +537,9 @@ public class PackageManagerService extends IPackageManager.Stub { public static final int REASON_INSTALL = 2; public static final int REASON_BACKGROUND_DEXOPT = 3; public static final int REASON_AB_OTA = 4; - public static final int REASON_NON_SYSTEM_LIBRARY = 5; - public static final int REASON_SHARED_APK = 6; - public static final int REASON_FORCED_DEXOPT = 7; - public static final int REASON_CORE_APP = 8; + public static final int REASON_FORCED_DEXOPT = 5; - public static final int REASON_LAST = REASON_CORE_APP; + public static final int REASON_LAST = REASON_FORCED_DEXOPT; /** All dangerous permission names in the same order as the events in MetricsEvent */ private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList( @@ -653,6 +650,11 @@ public class PackageManagerService extends IPackageManager.Stub { final ArrayMap<String, Set<String>> mKnownCodebase = new ArrayMap<String, Set<String>>(); + // Keys are isolated uids and values are the uid of the application + // that created the isolated proccess. + @GuardedBy("mPackages") + final SparseIntArray mIsolatedOwners = new SparseIntArray(); + // List of APK paths to load for each user and package. This data is never // persisted by the package manager. Instead, the overlay manager will // ensure the data is up-to-date in runtime. @@ -842,6 +844,8 @@ public class PackageManagerService extends IPackageManager.Stub { /** Component used to install ephemeral applications */ ComponentName mInstantAppInstallerComponent; + /** Component used to show resolver settings for Instant Apps */ + ComponentName mInstantAppResolverSettingsComponent; ActivityInfo mInstantAppInstallerActivity; final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo(); @@ -2376,59 +2380,6 @@ public class PackageManagerService extends IPackageManager.Stub { Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!"); } - final List<String> allInstructionSets = InstructionSets.getAllInstructionSets(); - final String[] dexCodeInstructionSets = - getDexCodeInstructionSets( - allInstructionSets.toArray(new String[allInstructionSets.size()])); - - /** - * Ensure all external libraries have had dexopt run on them. - */ - if (mSharedLibraries.size() > 0) { - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); - // NOTE: For now, we're compiling these system "shared libraries" - // (and framework jars) into all available architectures. It's possible - // to compile them only when we come across an app that uses them (there's - // already logic for that in scanPackageLI) but that adds some complexity. - for (String dexCodeInstructionSet : dexCodeInstructionSets) { - final int libCount = mSharedLibraries.size(); - for (int i = 0; i < libCount; i++) { - SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i); - final int versionCount = versionedLib.size(); - for (int j = 0; j < versionCount; j++) { - SharedLibraryEntry libEntry = versionedLib.valueAt(j); - final String libPath = libEntry.path != null - ? libEntry.path : libEntry.apk; - if (libPath == null) { - continue; - } - try { - // Shared libraries do not have profiles so we perform a full - // AOT compilation (if needed). - int dexoptNeeded = DexFile.getDexOptNeeded( - libPath, dexCodeInstructionSet, - getCompilerFilterForReason(REASON_SHARED_APK), - false /* newProfile */); - if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { - mInstaller.dexopt(libPath, Process.SYSTEM_UID, "*", - dexCodeInstructionSet, dexoptNeeded, null, - DEXOPT_PUBLIC, - getCompilerFilterForReason(REASON_SHARED_APK), - StorageManager.UUID_PRIVATE_INTERNAL, - PackageDexOptimizer.SKIP_SHARED_LIBRARY_CHECK); - } - } catch (FileNotFoundException e) { - Slog.w(TAG, "Library not found: " + libPath); - } catch (IOException | InstallerException e) { - Slog.w(TAG, "Cannot dexopt " + libPath + "; is it an APK or JAR? " - + e.getMessage()); - } - } - } - } - Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); - } - File frameworkDir = new File(Environment.getRootDirectory(), "framework"); final VersionInfo ver = mSettings.getInternalVersion(); @@ -2817,41 +2768,6 @@ public class PackageManagerService extends IPackageManager.Stub { mSettings.writeLPr(); Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); - // Perform dexopt on all apps that mark themselves as coreApps. We do this pretty - // early on (before the package manager declares itself as early) because other - // components in the system server might ask for package contexts for these apps. - // - // Note that "onlyCore" in this context means the system is encrypted or encrypting - // (i.e, that the data partition is unavailable). - if ((isFirstBoot() || isUpgrade() || VMRuntime.didPruneDalvikCache()) && !onlyCore) { - long start = System.nanoTime(); - List<PackageParser.Package> coreApps = new ArrayList<>(); - for (PackageParser.Package pkg : mPackages.values()) { - if (pkg.coreApp) { - coreApps.add(pkg); - } - } - - int[] stats = performDexOptUpgrade(coreApps, false, - getCompilerFilterForReason(REASON_CORE_APP)); - - final int elapsedTimeSeconds = - (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start); - MetricsLogger.histogram(mContext, "opt_coreapps_time_s", elapsedTimeSeconds); - - if (DEBUG_DEXOPT) { - Slog.i(TAG, "Dex-opt core apps took : " + elapsedTimeSeconds + " seconds (" + - stats[0] + ", " + stats[1] + ", " + stats[2] + ")"); - } - - - // TODO: Should we log these stats to tron too ? - // MetricsLogger.histogram(mContext, "opt_coreapps_num_dexopted", stats[0]); - // MetricsLogger.histogram(mContext, "opt_coreapps_num_skipped", stats[1]); - // MetricsLogger.histogram(mContext, "opt_coreapps_num_failed", stats[2]); - // MetricsLogger.histogram(mContext, "opt_coreapps_num_total", coreApps.size()); - } - EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, SystemClock.uptimeMillis()); @@ -2890,6 +2806,7 @@ public class PackageManagerService extends IPackageManager.Stub { mInstantAppResolverConnection = null; } updateInstantAppInstallerLocked(); + mInstantAppResolverSettingsComponent = getEphemeralResolverSettingsLPr(); // Read and update the usage of dex files. // Do this at the end of PM init so that all the packages have their @@ -3196,6 +3113,37 @@ public class PackageManagerService extends IPackageManager.Stub { } } + private @Nullable ComponentName getEphemeralResolverSettingsLPr() { + final Intent intent = new Intent(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS); + intent.addCategory(Intent.CATEGORY_DEFAULT); + final int resolveFlags = + MATCH_DIRECT_BOOT_AWARE + | MATCH_DIRECT_BOOT_UNAWARE + | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0); + final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, + resolveFlags, UserHandle.USER_SYSTEM); + Iterator<ResolveInfo> iter = matches.iterator(); + while (iter.hasNext()) { + final ResolveInfo rInfo = iter.next(); + final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName); + if (ps != null) { + final PermissionsState permissionsState = ps.getPermissionsState(); + if (permissionsState.hasPermission(Manifest.permission.ACCESS_INSTANT_APPS, 0)) { + continue; + } + } + iter.remove(); + } + if (matches.size() == 0) { + return null; + } else if (matches.size() == 1) { + return matches.get(0).getComponentInfo().getComponentName(); + } else { + throw new RuntimeException( + "There must be at most one ephemeral resolver settings; found " + matches); + } + } + private void primeDomainVerificationsLPw(int userId) { if (DEBUG_DOMAIN_VERIFICATION) { Slog.d(TAG, "Priming domain verifications in user " + userId); @@ -5788,6 +5736,10 @@ public class PackageManagerService extends IPackageManager.Stub { return false; } if (ps.getInstantApp(userId)) { + if (DEBUG_EPHEMERAL) { + Slog.v(TAG, "DENY instant app installed;" + + " pkg: " + packageName); + } return false; } } @@ -6174,6 +6126,10 @@ public class PackageManagerService extends IPackageManager.Stub { * instant, returns {@code null}. */ private String getInstantAppPackageName(int callingUid) { + // If the caller is an isolated app use the owner's uid for the lookup. + if (Process.isIsolated(callingUid)) { + callingUid = mIsolatedOwners.get(callingUid); + } final int appId = UserHandle.getAppId(callingUid); synchronized (mPackages) { final Object obj = mSettings.getUserIdLPr(appId); @@ -6267,7 +6223,6 @@ public class PackageManagerService extends IPackageManager.Stub { intent, resolvedType, flags, userId), userId); addEphemeral = !ephemeralDisabled && isEphemeralAllowed(intent, result, userId, false /*skipPackageCheck*/); - // Check for cross profile results. boolean hasNonNegativePriorityResult = hasNonNegativePriority(result); xpResolveInfo = queryCrossProfileIntents( @@ -6323,7 +6278,7 @@ public class PackageManagerService extends IPackageManager.Stub { } else { // the caller wants to resolve for a particular package; however, there // were no installed results, so, try to find an ephemeral result - addEphemeral = !ephemeralDisabled + addEphemeral = !ephemeralDisabled && isEphemeralAllowed( intent, null /*result*/, userId, true /*skipPackageCheck*/); result = new ArrayList<ResolveInfo>(); @@ -7347,17 +7302,22 @@ public class PackageManagerService extends IPackageManager.Stub { if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { return false; } + int uid = Binder.getCallingUid(); + if (Process.isIsolated(uid)) { + uid = mIsolatedOwners.get(uid); + } synchronized (mPackages) { final PackageSetting ps = mSettings.mPackages.get(packageName); + PackageParser.Package pkg = mPackages.get(packageName); final boolean returnAllowed = ps != null - && (isCallerSameApp(packageName) + && (isCallerSameApp(packageName, uid) || mContext.checkCallingOrSelfPermission( android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED || mInstantAppRegistry.isInstantAccessGranted( - userId, UserHandle.getAppId(Binder.getCallingUid()), ps.appId)); + userId, UserHandle.getAppId(uid), ps.appId)); if (returnAllowed) { return ps.getInstantApp(userId); } @@ -7374,7 +7334,7 @@ public class PackageManagerService extends IPackageManager.Stub { enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */, false /* checkShell */, "getInstantAppCookie"); - if (!isCallerSameApp(packageName)) { + if (!isCallerSameApp(packageName, Binder.getCallingUid())) { return null; } synchronized (mPackages) { @@ -7392,7 +7352,7 @@ public class PackageManagerService extends IPackageManager.Stub { enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */, true /* checkShell */, "setInstantAppCookie"); - if (!isCallerSameApp(packageName)) { + if (!isCallerSameApp(packageName, Binder.getCallingUid())) { return false; } synchronized (mPackages) { @@ -7420,10 +7380,10 @@ public class PackageManagerService extends IPackageManager.Stub { } } - private boolean isCallerSameApp(String packageName) { + private boolean isCallerSameApp(String packageName, int uid) { PackageParser.Package pkg = mPackages.get(packageName); return pkg != null - && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid; + && UserHandle.getAppId(uid) == pkg.applicationInfo.uid; } @Override @@ -8460,19 +8420,23 @@ public class PackageManagerService extends IPackageManager.Stub { ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer) : mPackageDexOptimizer; - // Optimize all dependencies first. Note: we ignore the return value and march on + // Dexopt all dependencies first. Note: we ignore the return value and march on // on errors. + // Note that we are going to call performDexOpt on those libraries as many times as + // they are referenced in packages. When we do a batch of performDexOpt (for example + // at boot, or background job), the passed 'targetCompilerFilter' stays the same, + // and the first package that uses the library will dexopt it. The + // others will see that the compiled code for the library is up to date. Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p); final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo); if (!deps.isEmpty()) { for (PackageParser.Package depPackage : deps) { // TODO: Analyze and investigate if we (should) profile libraries. - // Currently this will do a full compilation of the library by default. pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets, false /* checkProfiles */, - getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY), + targetCompilerFilter, getOrCreateCompilerPackageStats(depPackage), - mDexManager.isUsedByOtherApps(p.packageName)); + true /* isUsedByOtherApps */); } } return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles, @@ -12950,7 +12914,7 @@ public class PackageManagerService extends IPackageManager.Stub { IActivityManager am = ActivityManager.getService(); if (am != null) { try { - am.startService(null, intent, null, -1, null, mContext.getOpPackageName(), + am.startService(null, intent, null, -1, null, false, mContext.getOpPackageName(), UserHandle.USER_SYSTEM); } catch (RemoteException e) { } @@ -16884,6 +16848,15 @@ public class PackageManagerService extends IPackageManager.Stub { return; } + // Shared libraries for the package need to be updated. + synchronized (mPackages) { + try { + updateSharedLibrariesLPr(pkg, null); + } catch (PackageManagerException e) { + Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); + } + } + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); // Do not run PackageDexOptimizer through the local performDexOpt // method because `pkg` may not be in `mPackages` yet. @@ -16932,6 +16905,7 @@ public class PackageManagerService extends IPackageManager.Stub { args.user, installerPackageName, volumeUuid, res, args.installReason); } } + synchronized (mPackages) { final PackageSetting ps = mSettings.mPackages.get(pkgName); if (ps != null) { @@ -23073,6 +23047,13 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); } @Override + public boolean isInstantAppInstallerComponent(ComponentName component) { + synchronized (mPackages) { + return component != null && component.equals(mInstantAppInstallerComponent); + } + } + + @Override public void pruneInstantApps() { synchronized (mPackages) { mInstantAppRegistry.pruneInstantAppsLPw(); @@ -23176,6 +23157,21 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); return resolveIntentInternal( intent, resolvedType, flags, userId, true /*includeInstantApp*/); } + + + @Override + public void addIsolatedUid(int isolatedUid, int ownerUid) { + synchronized (mPackages) { + mIsolatedOwners.put(isolatedUid, ownerUid); + } + } + + @Override + public void removeIsolatedUid(int isolatedUid) { + synchronized (mPackages) { + mIsolatedOwners.delete(isolatedUid); + } + } } @Override @@ -23313,4 +23309,9 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); } return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED; } + + @Override + public ComponentName getInstantAppResolverSettingsComponent() { + return mInstantAppResolverSettingsComponent; + } } diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java index 0634dac8de4e..f6872e4373fd 100644 --- a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java +++ b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java @@ -26,8 +26,7 @@ import dalvik.system.DexFile; public class PackageManagerServiceCompilerMapping { // Names for compilation reasons. static final String REASON_STRINGS[] = { - "first-boot", "boot", "install", "bg-dexopt", "ab-ota", "nsys-library", "shared-apk", - "forced-dexopt", "core-app" + "first-boot", "boot", "install", "bg-dexopt", "ab-ota", "forced-dexopt" }; // Static block to ensure the strings array is of the right length. @@ -57,7 +56,6 @@ public class PackageManagerServiceCompilerMapping { // Ensure that some reasons are not mapped to profile-guided filters. switch (reason) { - case PackageManagerService.REASON_SHARED_APK: case PackageManagerService.REASON_FORCED_DEXOPT: if (DexFile.isProfileGuidedCompilerFilter(sysPropValue)) { throw new IllegalStateException("\"" + sysPropValue + "\" is profile-guided, " diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index a31258c39341..8ecf6f74bc8f 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -3389,6 +3389,12 @@ public class UserManagerService extends IUserManager.Stub { pw.print(" <partial>"); } pw.println(); + pw.print(" State: "); + final int state; + synchronized (mUserStates) { + state = mUserStates.get(userId, -1); + } + pw.println(UserState.stateToString(state)); pw.print(" Created: "); if (userInfo.creationTime == 0) { pw.println("<unknown>"); diff --git a/services/core/java/com/android/server/storage/AppFuseBridge.java b/services/core/java/com/android/server/storage/AppFuseBridge.java index 904d9159e578..6a0b6489f470 100644 --- a/services/core/java/com/android/server/storage/AppFuseBridge.java +++ b/services/core/java/com/android/server/storage/AppFuseBridge.java @@ -21,7 +21,9 @@ import android.system.ErrnoException; import android.system.Os; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; +import com.android.internal.os.FuseUnavailableMountException; import com.android.internal.util.Preconditions; +import com.android.server.NativeDaemonConnectorException; import libcore.io.IoUtils; import java.io.File; import java.io.FileNotFoundException; @@ -54,17 +56,17 @@ public class AppFuseBridge implements Runnable { } public ParcelFileDescriptor addBridge(MountScope mountScope) - throws BridgeException { + throws FuseUnavailableMountException, NativeDaemonConnectorException { try { synchronized (this) { Preconditions.checkArgument(mScopes.indexOfKey(mountScope.mountId) < 0); if (mNativeLoop == 0) { - throw new BridgeException("The thread has already been terminated"); + throw new FuseUnavailableMountException(mountScope.mountId); } final int fd = native_add_bridge( - mNativeLoop, mountScope.mountId, mountScope.deviceFd.detachFd()); + mNativeLoop, mountScope.mountId, mountScope.open().detachFd()); if (fd == -1) { - throw new BridgeException("Failed to invoke native_add_bridge"); + throw new FuseUnavailableMountException(mountScope.mountId); } final ParcelFileDescriptor result = ParcelFileDescriptor.adoptFd(fd); mScopes.put(mountScope.mountId, mountScope); @@ -86,12 +88,12 @@ public class AppFuseBridge implements Runnable { } public ParcelFileDescriptor openFile(int pid, int mountId, int fileId, int mode) - throws FileNotFoundException, SecurityException, InterruptedException { + throws FuseUnavailableMountException, InterruptedException { final MountScope scope; synchronized (this) { scope = mScopes.get(mountId); if (scope == null) { - throw new FileNotFoundException("Cannot find mount point"); + throw new FuseUnavailableMountException(mountId); } } if (scope.pid != pid) { @@ -99,17 +101,14 @@ public class AppFuseBridge implements Runnable { } final boolean result = scope.waitForMount(); if (result == false) { - throw new FileNotFoundException("Mount failed"); + throw new FuseUnavailableMountException(mountId); } try { - if (Os.stat(scope.mountPoint.getPath()).st_ino != 1) { - throw new FileNotFoundException("Could not find bridge mount point."); - } - } catch (ErrnoException e) { - throw new FileNotFoundException( - "Failed to stat mount point: " + scope.mountPoint.getParent()); + return ParcelFileDescriptor.open( + new File(scope.mountPoint, String.valueOf(fileId)), mode); + } catch (FileNotFoundException error) { + throw new FuseUnavailableMountException(mountId); } - return ParcelFileDescriptor.open(new File(scope.mountPoint, String.valueOf(fileId)), mode); } // Used by com_android_server_storage_AppFuse.cpp. @@ -130,20 +129,18 @@ public class AppFuseBridge implements Runnable { } } - public static class MountScope implements AutoCloseable { + public static abstract class MountScope implements AutoCloseable { public final int uid; public final int pid; public final int mountId; - public final ParcelFileDescriptor deviceFd; public final File mountPoint; private final CountDownLatch mMounted = new CountDownLatch(1); private boolean mMountResult = false; - public MountScope(int uid, int pid, int mountId, ParcelFileDescriptor deviceFd) { + public MountScope(int uid, int pid, int mountId) { this.uid = uid; this.pid = pid; this.mountId = mountId; - this.deviceFd = deviceFd; this.mountPoint = new File(String.format(APPFUSE_MOUNT_NAME_TEMPLATE, uid, mountId)); } @@ -161,16 +158,7 @@ public class AppFuseBridge implements Runnable { return mMountResult; } - @Override - public void close() throws Exception { - deviceFd.close(); - } - } - - public static class BridgeException extends Exception { - public BridgeException(String message) { - super(message); - } + public abstract ParcelFileDescriptor open() throws NativeDaemonConnectorException; } private native long native_new(); diff --git a/services/core/java/com/android/server/storage/CacheQuotaStrategy.java b/services/core/java/com/android/server/storage/CacheQuotaStrategy.java index 41c5331e77b0..82dd9ace6a5e 100644 --- a/services/core/java/com/android/server/storage/CacheQuotaStrategy.java +++ b/services/core/java/com/android/server/storage/CacheQuotaStrategy.java @@ -197,7 +197,7 @@ public class CacheQuotaStrategy implements RemoteCallback.OnResultListener { .setQuota(CacheQuotaHint.QUOTA_NOT_SET) .build()); } catch (PackageManager.NameNotFoundException e) { - Slog.w(TAG, "Unable to find package for quota calculation", e); + // This may happen if an app has a recorded usage, but has been uninstalled. continue; } } diff --git a/services/core/java/com/android/server/tv/TvInputHal.java b/services/core/java/com/android/server/tv/TvInputHal.java index ebbb8b315d00..42f12eb23d39 100644 --- a/services/core/java/com/android/server/tv/TvInputHal.java +++ b/services/core/java/com/android/server/tv/TvInputHal.java @@ -16,6 +16,7 @@ package com.android.server.tv; +import android.hardware.tv.input.V1_0.Constants; import android.media.tv.TvInputHardwareInfo; import android.media.tv.TvStreamConfig; import android.os.Handler; @@ -41,9 +42,10 @@ final class TvInputHal implements Handler.Callback { public final static int ERROR_STALE_CONFIG = -2; public final static int ERROR_UNKNOWN = -3; - public static final int EVENT_DEVICE_AVAILABLE = 1; - public static final int EVENT_DEVICE_UNAVAILABLE = 2; - public static final int EVENT_STREAM_CONFIGURATION_CHANGED = 3; + public static final int EVENT_DEVICE_AVAILABLE = Constants.EVENT_DEVICE_AVAILABLE; + public static final int EVENT_DEVICE_UNAVAILABLE = Constants.EVENT_DEVICE_UNAVAILABLE; + public static final int EVENT_STREAM_CONFIGURATION_CHANGED = + Constants.EVENT_STREAM_CONFIGURATIONS_CHANGED; public static final int EVENT_FIRST_FRAME_CAPTURED = 4; public interface Callback { diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java index 5abc4e4d2e56..f138add7ba09 100644 --- a/services/core/java/com/android/server/wm/AccessibilityController.java +++ b/services/core/java/com/android/server/wm/AccessibilityController.java @@ -222,11 +222,10 @@ final class AccessibilityController { || mWindowsForAccessibilityObserver != null); } - /** NOTE: This has to be called within a surface transaction. */ public void setForceShowMagnifiableBoundsLocked(boolean show) { if (mDisplayMagnifier != null) { mDisplayMagnifier.setForceShowMagnifiableBoundsLocked(show); - mDisplayMagnifier.drawMagnifiedRegionBorderIfNeededLocked(); + mDisplayMagnifier.showMagnificationBoundsIfNeeded(); } } @@ -440,6 +439,12 @@ final class AccessibilityController { mMagnifedViewport.destroyWindow(); } + // Can be called outside of a surface transaction + public void showMagnificationBoundsIfNeeded() { + mHandler.obtainMessage(MyHandler.MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED) + .sendToTarget(); + } + /** NOTE: This has to be called within a surface transaction. */ public void drawMagnifiedRegionBorderIfNeededLocked() { mMagnifedViewport.drawWindowIfNeededLocked(); diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java index e60295de4876..4b4be40880ee 100644 --- a/services/core/java/com/android/server/wm/AppWindowContainerController.java +++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java @@ -706,8 +706,8 @@ public class AppWindowContainerController } /** Calls directly into activity manager so window manager lock shouldn't held. */ - boolean keyDispatchingTimedOut(String reason) { - return mListener != null && mListener.keyDispatchingTimedOut(reason); + boolean keyDispatchingTimedOut(String reason, int windowPid) { + return mListener != null && mListener.keyDispatchingTimedOut(reason, windowPid); } @Override diff --git a/services/core/java/com/android/server/wm/AppWindowContainerListener.java b/services/core/java/com/android/server/wm/AppWindowContainerListener.java index 9d459cfccc09..26537f27bce8 100644 --- a/services/core/java/com/android/server/wm/AppWindowContainerListener.java +++ b/services/core/java/com/android/server/wm/AppWindowContainerListener.java @@ -33,6 +33,10 @@ public interface AppWindowContainerListener extends WindowContainerListener { /** * Called when the key dispatching to a window associated with the app window container * timed-out. + * + * @param reason The reason for the key dispatching time out. + * @param windowPid The pid of the window key dispatching timed out on. + * @return True if input dispatching should be aborted. */ - boolean keyDispatchingTimedOut(String reason); + boolean keyDispatchingTimedOut(String reason, int windowPid); } diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index 72ae90d71a9e..1decf4e19e9f 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -19,6 +19,7 @@ package com.android.server.wm; import static android.app.ActivityManager.StackId; import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION; import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE; +import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD; @@ -1204,12 +1205,23 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree * in anyway. */ @Override - int getOrientation() { + int getOrientation(int candidate) { + if (!fillsParent()) { + // Can't specify orientation if app doesn't fill parent. + return SCREEN_ORIENTATION_UNSET; + } + + if (candidate == SCREEN_ORIENTATION_BEHIND) { + // Allow app to specify orientation regardless of its visibility state if the current + // candidate want us to use orientation behind. I.e. the visible app on-top of this one + // wants us to use the orientation of the app behind it. + return mOrientation; + } + // The {@link AppWindowToken} should only specify an orientation when it is not closing or // going to the bottom. Allowing closing {@link AppWindowToken} to participate can lead to // an Activity in another task being started in the wrong orientation during the transition. - if (fillsParent() - && !(sendingToBottom || mService.mClosingApps.contains(this)) + if (!(sendingToBottom || mService.mClosingApps.contains(this)) && (isVisible() || mService.mOpeningApps.contains(this))) { return mOrientation; } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 8f391a718269..aa8557490f25 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -175,6 +175,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo private boolean mTmpRecoveringMemory; private boolean mUpdateImeTarget; private boolean mTmpInitial; + private int mMaxUiWidth; // Mapping from a token IBinder to a WindowToken object on this display. private final HashMap<IBinder, WindowToken> mTokenMap = new HashMap(); @@ -1559,6 +1560,39 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } } + /** Sets the maximum width the screen resolution can be */ + void setMaxUiWidth(int width) { + if (DEBUG_DISPLAY) { + Slog.v(TAG_WM, "Setting max ui width:" + width + " on display:" + getDisplayId()); + } + + mMaxUiWidth = width; + + // Update existing metrics. + updateBaseDisplayMetrics(mBaseDisplayWidth, mBaseDisplayHeight, mBaseDisplayDensity); + } + + /** Update base (override) display metrics. */ + void updateBaseDisplayMetrics(int baseWidth, int baseHeight, int baseDensity) { + mBaseDisplayWidth = baseWidth; + mBaseDisplayHeight = baseHeight; + mBaseDisplayDensity = baseDensity; + + if (mMaxUiWidth > 0 && mBaseDisplayWidth > mMaxUiWidth) { + mBaseDisplayHeight = (mMaxUiWidth * mBaseDisplayHeight) / mBaseDisplayWidth; + mBaseDisplayDensity = (mMaxUiWidth * mBaseDisplayDensity) / mBaseDisplayWidth; + mBaseDisplayWidth = mMaxUiWidth; + + if (DEBUG_DISPLAY) { + Slog.v(TAG_WM, "Applying config restraints:" + mBaseDisplayWidth + "x" + + mBaseDisplayHeight + " at density:" + mBaseDisplayDensity + + " on display:" + getDisplayId()); + } + } + + mBaseDisplayRect.set(0, 0, mBaseDisplayWidth, mBaseDisplayHeight); + } + void getContentRect(Rect out) { out.set(mContentRect); } diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index d041c111a888..aae216e0d47c 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -258,7 +258,8 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { // Notify the activity manager about the timeout and let it decide whether // to abort dispatching or keep waiting. final AppWindowContainerController controller = appWindowToken.getController(); - final boolean abort = controller != null && controller.keyDispatchingTimedOut(reason); + final boolean abort = controller != null + && controller.keyDispatchingTimedOut(reason, windowState.mSession.mPid); if (!abort) { // The activity manager declined to abort dispatching. // Wait a bit longer and timeout again later. @@ -281,7 +282,7 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { return 0; // abort dispatching } - void addInputWindowHandle(final InputWindowHandle windowHandle) { + private void addInputWindowHandle(final InputWindowHandle windowHandle) { if (mInputWindowHandles == null) { mInputWindowHandles = new InputWindowHandle[16]; } diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java index 012480e0410d..3ce61f027b4c 100644 --- a/services/core/java/com/android/server/wm/PinnedStackController.java +++ b/services/core/java/com/android/server/wm/PinnedStackController.java @@ -195,7 +195,8 @@ class PinnedStackController { * @return whether the given {@param aspectRatio} is valid. */ public boolean isValidPictureInPictureAspectRatio(float aspectRatio) { - return mMinAspectRatio <= aspectRatio && aspectRatio <= mMaxAspectRatio; + return Float.compare(mMinAspectRatio, aspectRatio) <= 0 && + Float.compare(aspectRatio, mMaxAspectRatio) <= 0; } /** diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 68d0f2496d5a..b0e3e3221415 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -152,8 +152,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> { } WindowState computeFocusedWindow() { - final int count = mChildren.size(); - for (int i = 0; i < count; i++) { + for (int i = mChildren.size() - 1; i >= 0; i--) { final DisplayContent dc = mChildren.get(i); final WindowState win = dc.findFocusedWindow(); if (win != null) { diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 2a02359cc529..84ba139ee5a9 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -516,14 +516,22 @@ class WindowContainer<E extends WindowContainer> implements Comparable<WindowCon mOrientation = orientation; } + int getOrientation() { + return getOrientation(mOrientation); + } + /** * Returns the specified orientation for this window container or one of its children is there * is one set, or {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_UNSET} if no * specification is set. * NOTE: {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_UNSPECIFIED} is a * specification... + * + * @param candidate The current orientation candidate that will be returned if we don't find a + * better match. + * @return The orientation as specified by this branch or the window hierarchy. */ - int getOrientation() { + int getOrientation(int candidate) { if (!fillsParent()) { // Ignore containers that don't completely fill their parents. return SCREEN_ORIENTATION_UNSET; @@ -537,12 +545,14 @@ class WindowContainer<E extends WindowContainer> implements Comparable<WindowCon && mOrientation != SCREEN_ORIENTATION_UNSPECIFIED) { return mOrientation; } - int candidate = mOrientation; for (int i = mChildren.size() - 1; i >= 0; --i) { final WindowContainer wc = mChildren.get(i); - final int orientation = wc.getOrientation(); + // TODO: Maybe mOrientation should default to SCREEN_ORIENTATION_UNSET vs. + // SCREEN_ORIENTATION_UNSPECIFIED? + final int orientation = wc.getOrientation(candidate == SCREEN_ORIENTATION_BEHIND + ? SCREEN_ORIENTATION_BEHIND : SCREEN_ORIENTATION_UNSET); if (orientation == SCREEN_ORIENTATION_BEHIND) { // container wants us to use the orientation of the container behind it. See if we // can find one. Else return SCREEN_ORIENTATION_BEHIND so the caller can choose to diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index fa9c2a7edae2..0dc74d72635b 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -385,6 +385,7 @@ public class WindowManagerService extends IWindowManager.Stub final boolean mAllowBootMessages; final boolean mLimitedAlphaCompositing; + final int mMaxUiWidth; final WindowManagerPolicy mPolicy; @@ -949,6 +950,8 @@ public class WindowManagerService extends IWindowManager.Stub com.android.internal.R.integer.config_drawLockTimeoutMillis); mAllowAnimationsInLowPowerMode = context.getResources().getBoolean( com.android.internal.R.bool.config_allowAnimationsInLowPowerMode); + mMaxUiWidth = context.getResources().getInteger( + com.android.internal.R.integer.config_maxUiWidth); mInputManager = inputManager; // Must be before createDisplayContentLocked. mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); mDisplaySettings = new DisplaySettings(); @@ -4572,6 +4575,9 @@ public class WindowManagerService extends IWindowManager.Stub synchronized(mWindowMap) { final DisplayContent displayContent = getDefaultDisplayContentLocked(); + if (mMaxUiWidth > 0) { + displayContent.setMaxUiWidth(mMaxUiWidth); + } readForcedDisplayPropertiesLocked(displayContent); mDisplayReady = true; } diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 826fb455b6e2..1eedc28fbad4 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -591,6 +591,17 @@ class WindowStateAnimator { } } + private int getLayerStack() { + return mWin.getDisplayContent().getDisplay().getLayerStack(); + } + + void updateLayerStackInTransaction() { + if (mSurfaceController != null) { + mSurfaceController.setLayerStackInTransaction( + getLayerStack()); + } + } + WindowSurfaceController createSurfaceLocked(int windowType, int ownerUid) { final WindowState w = mWin; if (w.restoreSavedSurface()) { @@ -703,8 +714,7 @@ class WindowStateAnimator { } // Start a new transaction and apply position & offset. - final int layerStack = w.getDisplayContent().getDisplay().getLayerStack(); - mSurfaceController.setPositionAndLayer(mTmpSize.left, mTmpSize.top, layerStack, mAnimLayer); + mSurfaceController.setPositionAndLayer(mTmpSize.left, mTmpSize.top, getLayerStack(), mAnimLayer); mLastHidden = true; if (WindowManagerService.localLOGV) Slog.v(TAG, "Created surface " + this); @@ -1435,7 +1445,6 @@ class WindowStateAnimator { WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); w.applyDimLayerIfNeeded(); } - } void prepareSurfaceLocked(final boolean recoveringMemory) { diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java index b08bb70ca0b9..fb40a65005f0 100644 --- a/services/core/java/com/android/server/wm/WindowSurfaceController.java +++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java @@ -276,6 +276,12 @@ class WindowSurfaceController { } } + void setLayerStackInTransaction(int layerStack) { + if (mSurfaceControl != null) { + mSurfaceControl.setLayerStack(layerStack); + } + } + void setPositionInTransaction(float left, float top, boolean recoveringMemory) { final boolean surfaceMoved = mSurfaceX != left || mSurfaceY != top; if (surfaceMoved) { @@ -357,7 +363,8 @@ class WindowSurfaceController { return false; } - boolean prepareToShowInTransaction(float alpha, int layer, float dsdx, float dtdx, float dsdy, + boolean prepareToShowInTransaction(float alpha, int layer, + float dsdx, float dtdx, float dsdy, float dtdy, boolean recoveringMemory) { if (mSurfaceControl != null) { try { @@ -371,7 +378,6 @@ class WindowSurfaceController { mLastDtdy = dtdy; mSurfaceControl.setMatrix( dsdx, dtdx, dsdy, dtdy); - } catch (RuntimeException e) { Slog.w(TAG, "Error updating surface in " + title, e); if (!recoveringMemory) { diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index fab59d6c8f08..e3033c9c01a8 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -30,6 +30,7 @@ import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL; import android.os.Debug; import android.os.IBinder; import android.util.Slog; +import android.view.SurfaceControl; import java.io.PrintWriter; @@ -245,6 +246,18 @@ class WindowToken extends WindowContainer<WindowState> { void onDisplayChanged(DisplayContent dc) { dc.reParentWindowToken(this); mDisplayContent = dc; + + // TODO(b/36740756): One day this should perhaps be hooked + // up with goodToGo, so we don't move a window + // to another display before the window behind + // it is ready. + SurfaceControl.openTransaction(); + for (int i = mChildren.size() - 1; i >= 0; --i) { + final WindowState win = mChildren.get(i); + win.mWinAnimator.updateLayerStackInTransaction(); + } + SurfaceControl.closeTransaction(); + super.onDisplayChanged(dc); } diff --git a/services/core/jni/com_android_server_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp index ec36df1d9a12..57bb9fedc135 100644 --- a/services/core/jni/com_android_server_am_BatteryStatsService.cpp +++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp @@ -57,6 +57,8 @@ namespace android static bool wakeup_init = false; static sem_t wakeup_sem; extern sp<IPower> gPowerHal; +extern std::mutex gPowerHalMutex; +extern bool getPowerHal(); static void wakeup_callback(bool success) { @@ -191,41 +193,26 @@ static jint getPlatformLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject o return -1; } - if (gPowerHal == nullptr) { - ALOGE("gPowerHal not loaded"); - return -1; - } + { + std::lock_guard<std::mutex> lock(gPowerHalMutex); + if (!getPowerHal()) { + ALOGE("Power Hal not loaded"); + return -1; + } - gPowerHal->getPlatformLowPowerStats( - [&offset, &remaining, &total_added](hidl_vec<PowerStatePlatformSleepState> states, - Status status) { - if (status != Status::SUCCESS) - return; - for (size_t i = 0; i < states.size(); i++) { - int added; - const PowerStatePlatformSleepState& state = states[i]; - - added = snprintf(offset, remaining, - "state_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ", - i + 1, state.name.c_str(), state.residencyInMsecSinceBoot, - state.totalTransitions); - if (added < 0) { - break; - } - if (added > remaining) { - added = remaining; - } - offset += added; - remaining -= added; - total_added += added; + Return<void> ret = gPowerHal->getPlatformLowPowerStats( + [&offset, &remaining, &total_added](hidl_vec<PowerStatePlatformSleepState> states, + Status status) { + if (status != Status::SUCCESS) + return; + for (size_t i = 0; i < states.size(); i++) { + int added; + const PowerStatePlatformSleepState& state = states[i]; - for (size_t j = 0; j < state.voters.size(); j++) { - const PowerStateVoter& voter = state.voters[j]; added = snprintf(offset, remaining, - "voter_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ", - j + 1, voter.name.c_str(), - voter.totalTimeInMsecVotedForSinceBoot, - voter.totalNumberOfTimesVotedSinceBoot); + "state_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ", + i + 1, state.name.c_str(), state.residencyInMsecSinceBoot, + state.totalTransitions); if (added < 0) { break; } @@ -235,18 +222,42 @@ static jint getPlatformLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject o offset += added; remaining -= added; total_added += added; - } - if (remaining <= 0) { - /* rewrite NULL character*/ - offset--; - total_added--; - ALOGE("PowerHal: buffer not enough"); - break; + for (size_t j = 0; j < state.voters.size(); j++) { + const PowerStateVoter& voter = state.voters[j]; + added = snprintf(offset, remaining, + "voter_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ", + j + 1, voter.name.c_str(), + voter.totalTimeInMsecVotedForSinceBoot, + voter.totalNumberOfTimesVotedSinceBoot); + if (added < 0) { + break; + } + if (added > remaining) { + added = remaining; + } + offset += added; + remaining -= added; + total_added += added; + } + + if (remaining <= 0) { + /* rewrite NULL character*/ + offset--; + total_added--; + ALOGE("PowerHal: buffer not enough"); + break; + } } } + ); + + if (!ret.isOk()) { + ALOGE("getPlatformLowPowerStats() failed: power HAL service not available"); + gPowerHal = nullptr; + return -1; } - ); + } *offset = 0; total_added += 1; return total_added; diff --git a/services/core/jni/com_android_server_power_PowerManagerService.cpp b/services/core/jni/com_android_server_power_PowerManagerService.cpp index fab309bfb148..1bdcd7aa9bd6 100644 --- a/services/core/jni/com_android_server_power_PowerManagerService.cpp +++ b/services/core/jni/com_android_server_power_PowerManagerService.cpp @@ -43,7 +43,7 @@ using android::hardware::Void; using android::hardware::power::V1_0::IPower; using android::hardware::power::V1_0::PowerHint; using android::hardware::power::V1_0::Feature; -using android::hardware::hidl_vec; +using android::String8; namespace android { @@ -56,7 +56,8 @@ static struct { // ---------------------------------------------------------------------------- static jobject gPowerManagerServiceObj; -sp<IPower> gPowerHal; +sp<IPower> gPowerHal = nullptr; +std::mutex gPowerHalMutex; static nsecs_t gLastEventTime[USER_ACTIVITY_EVENT_LAST + 1]; // Throttling interval for user activity calls. @@ -74,11 +75,37 @@ static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodNa return false; } +// Check validity of current handle to the power HAL service, and call getService() if necessary. +// The caller must be holding gPowerHalMutex. +bool getPowerHal() { + if (gPowerHal == nullptr) { + gPowerHal = IPower::getService(); + if (gPowerHal != nullptr) { + ALOGI("Loaded power HAL service"); + } else { + ALOGI("Couldn't load power HAL service"); + } + } + return gPowerHal != nullptr; +} + +// Check if a call to a power HAL function failed; if so, log the failure and invalidate the +// current handle to the power HAL service. The caller must be holding gPowerHalMutex. +static void processReturn(const Return<void> &ret, const char* functionName) { + if (!ret.isOk()) { + ALOGE("%s() failed: power HAL service not available.", functionName); + gPowerHal = nullptr; + } +} + void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t eventType) { // Tell the power HAL when user activity occurs. - if (gPowerHal != nullptr) { - gPowerHal->powerHint(PowerHint::INTERACTION, 0); + gPowerHalMutex.lock(); + if (getPowerHal()) { + Return<void> ret = gPowerHal->powerHint(PowerHint::INTERACTION, 0); + processReturn(ret, "powerHint"); } + gPowerHalMutex.unlock(); if (gPowerManagerServiceObj) { // Throttle calls into user activity by event type. @@ -106,14 +133,13 @@ void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t } // ---------------------------------------------------------------------------- -//TODO(b/31632518) + static void nativeInit(JNIEnv* env, jobject obj) { gPowerManagerServiceObj = env->NewGlobalRef(obj); - gPowerHal = IPower::getService(); - if (gPowerHal == nullptr) { - ALOGE("Couldn't load PowerHAL module"); - } + gPowerHalMutex.lock(); + getPowerHal(); + gPowerHalMutex.unlock(); } static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass /* clazz */, jstring nameStr) { @@ -127,14 +153,12 @@ static void nativeReleaseSuspendBlocker(JNIEnv *env, jclass /* clazz */, jstring } static void nativeSetInteractive(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) { - if (gPowerHal != nullptr) { - if (enable) { - ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(true) while turning screen on"); - gPowerHal->setInteractive(true); - } else { - ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(false) while turning screen off"); - gPowerHal->setInteractive(false); - } + std::lock_guard<std::mutex> lock(gPowerHalMutex); + if (getPowerHal()) { + String8 err("Excessive delay in setInteractive(%s) while turning screen %s"); + ALOGD_IF_SLOW(20, String8::format(err, enable ? "true" : "false", enable ? "on" : "off")); + Return<void> ret = gPowerHal->setInteractive(enable); + processReturn(ret, "setInteractive"); } } @@ -149,20 +173,18 @@ static void nativeSetAutoSuspend(JNIEnv* /* env */, jclass /* clazz */, jboolean } static void nativeSendPowerHint(JNIEnv *env, jclass clazz, jint hintId, jint data) { - if (gPowerHal != nullptr) { - if(data) - gPowerHal->powerHint((PowerHint)hintId, data); - else { - gPowerHal->powerHint((PowerHint)hintId, 0); - } + std::lock_guard<std::mutex> lock(gPowerHalMutex); + if (getPowerHal()) { + Return<void> ret = gPowerHal->powerHint((PowerHint)hintId, data); + processReturn(ret, "powerHint"); } } static void nativeSetFeature(JNIEnv *env, jclass clazz, jint featureId, jint data) { - int data_param = data; - - if (gPowerHal != nullptr) { - gPowerHal->setFeature((Feature)featureId, data_param ? true : false); + std::lock_guard<std::mutex> lock(gPowerHalMutex); + if (getPowerHal()) { + Return<void> ret = gPowerHal->setFeature((Feature)featureId, static_cast<bool>(data)); + processReturn(ret, "setFeature"); } } @@ -217,7 +239,6 @@ int register_android_server_PowerManagerService(JNIEnv* env) { gLastEventTime[i] = LLONG_MIN; } gPowerManagerServiceObj = NULL; - gPowerHal = NULL; return 0; } diff --git a/services/core/jni/com_android_server_tv_TvInputHal.cpp b/services/core/jni/com_android_server_tv_TvInputHal.cpp index b4333508a84a..78c0fa7d334a 100644 --- a/services/core/jni/com_android_server_tv_TvInputHal.cpp +++ b/services/core/jni/com_android_server_tv_TvInputHal.cpp @@ -577,7 +577,6 @@ JTvInputHal::TvInputCallback::TvInputCallback(JTvInputHal* hal) { } Return<void> JTvInputHal::TvInputCallback::notify(const TvInputEvent& event) { - // TODO(b/32200867): Ensure the event type values are in sync with the framework code. mHal->mLooper->sendMessage(new NotifyHandler(mHal, event), static_cast<int>(event.type)); return Void(); } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java index 9b4de043a647..70c7e586d3fe 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java @@ -26,6 +26,7 @@ import android.os.Looper; import android.os.Message; import android.os.SystemClock; import android.util.Log; +import android.util.LongSparseArray; import com.android.internal.annotations.GuardedBy; @@ -44,12 +45,21 @@ final class NetworkLoggingHandler extends Handler { // If this value changes, update DevicePolicyManager#retrieveNetworkLogs() javadoc private static final int MAX_EVENTS_PER_BATCH = 1200; - private static final long BATCH_FINALIZATION_TIMEOUT_MS = TimeUnit.MINUTES.toMillis(90); - private static final long BATCH_FINALIZATION_TIMEOUT_ALARM_INTERVAL_MS = - TimeUnit.MINUTES.toMillis(30); + + /** + * Maximum number of batches to store in memory. If more batches are generated and the DO + * doesn't fetch them, we will discard the oldest one. + */ + private static final int MAX_BATCHES = 5; + + private static final long BATCH_FINALIZATION_TIMEOUT_MS = 90 * 60 * 1000; // 1.5h + private static final long BATCH_FINALIZATION_TIMEOUT_ALARM_INTERVAL_MS = 30 * 60 * 1000; // 30m private static final String NETWORK_LOGGING_TIMEOUT_ALARM_TAG = "NetworkLogging.batchTimeout"; + /** Delay after which older batches get discarded after a retrieval. */ + private static final long RETRIEVED_BATCH_DISCARD_DELAY_MS = 5 * 60 * 1000; // 5m + private final DevicePolicyManagerService mDpm; private final AlarmManager mAlarmManager; @@ -66,22 +76,27 @@ final class NetworkLoggingHandler extends Handler { static final int LOG_NETWORK_EVENT_MSG = 1; - // threadsafe as it's Handler's thread confined + /** Network events accumulated so far to be finalized into a batch at some point. */ @GuardedBy("this") - private ArrayList<NetworkEvent> mNetworkEvents = new ArrayList<NetworkEvent>(); + private ArrayList<NetworkEvent> mNetworkEvents = new ArrayList<>(); + /** + * Up to {@code MAX_BATCHES} finalized batches of logs ready to be retrieved by the DO. Already + * retrieved batches are discarded after {@code RETRIEVED_BATCH_DISCARD_DELAY_MS}. + */ @GuardedBy("this") - private ArrayList<NetworkEvent> mFullBatch; + private final LongSparseArray<ArrayList<NetworkEvent>> mBatches = + new LongSparseArray<>(MAX_BATCHES); @GuardedBy("this") private boolean mPaused = false; // each full batch is represented by its token, which the DPC has to provide back to retrieve it @GuardedBy("this") - private long mCurrentFullBatchToken; + private long mCurrentBatchToken; @GuardedBy("this") - private long mLastRetrievedFullBatchToken; + private long mLastRetrievedBatchToken; NetworkLoggingHandler(Looper looper, DevicePolicyManagerService dpm) { super(looper); @@ -93,7 +108,7 @@ final class NetworkLoggingHandler extends Handler { public void handleMessage(Message msg) { switch (msg.what) { case LOG_NETWORK_EVENT_MSG: { - NetworkEvent networkEvent = msg.getData().getParcelable(NETWORK_EVENT_KEY); + final NetworkEvent networkEvent = msg.getData().getParcelable(NETWORK_EVENT_KEY); if (networkEvent != null) { synchronized (NetworkLoggingHandler.this) { mNetworkEvents.add(networkEvent); @@ -113,6 +128,8 @@ final class NetworkLoggingHandler extends Handler { void scheduleBatchFinalization() { final long when = SystemClock.elapsedRealtime() + BATCH_FINALIZATION_TIMEOUT_MS; + // We use alarm manager and not just postDelayed here to ensure the batch gets finalized + // even if the device goes to sleep. mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, when, BATCH_FINALIZATION_TIMEOUT_ALARM_INTERVAL_MS, NETWORK_LOGGING_TIMEOUT_ALARM_TAG, mBatchTimeoutAlarmListener, this); @@ -131,62 +148,80 @@ final class NetworkLoggingHandler extends Handler { return; } - Log.d(TAG, "Resumed network logging. Current batch=" - + mCurrentFullBatchToken + ", LastRetrievedBatch=" + mLastRetrievedFullBatchToken); + Log.d(TAG, "Resumed network logging. Current batch=" + mCurrentBatchToken + + ", LastRetrievedBatch=" + mLastRetrievedBatchToken); mPaused = false; - // If there is a full batch ready that the device owner hasn't been notified about, do it - // now. - if (mFullBatch != null && mFullBatch.size() > 0 - && mLastRetrievedFullBatchToken != mCurrentFullBatchToken) { + // If there is a batch ready that the device owner hasn't been notified about, do it now. + if (mBatches.size() > 0 && mLastRetrievedBatchToken != mCurrentBatchToken) { scheduleBatchFinalization(); notifyDeviceOwnerLocked(); } } synchronized void discardLogs() { - mFullBatch = null; - mNetworkEvents = new ArrayList<NetworkEvent>(); + mBatches.clear(); + mNetworkEvents = new ArrayList<>(); Log.d(TAG, "Discarded all network logs"); } @GuardedBy("this") private void finalizeBatchAndNotifyDeviceOwnerLocked() { if (mNetworkEvents.size() > 0) { - // finalize the batch and start a new one from scratch - mFullBatch = mNetworkEvents; - mCurrentFullBatchToken++; - mNetworkEvents = new ArrayList<NetworkEvent>(); + // Finalize the batch and start a new one from scratch. + if (mBatches.size() >= MAX_BATCHES) { + // Remove the oldest batch if we hit the limit. + mBatches.removeAt(0); + } + mCurrentBatchToken++; + mBatches.append(mCurrentBatchToken, mNetworkEvents); + mNetworkEvents = new ArrayList<>(); if (!mPaused) { notifyDeviceOwnerLocked(); } } else { - // don't notify the DO, since there are no events; DPC can still retrieve + // Don't notify the DO, since there are no events; DPC can still retrieve // the last full batch if not paused. Log.d(TAG, "Was about to finalize the batch, but there were no events to send to" - + " the DPC, the batchToken of last available batch: " - + mCurrentFullBatchToken); + + " the DPC, the batchToken of last available batch: " + mCurrentBatchToken); } - // regardless of whether the batch was non-empty schedule a new finalization after timeout + // Regardless of whether the batch was non-empty schedule a new finalization after timeout. scheduleBatchFinalization(); } + /** Sends a notification to the DO. Should only be called when there is a batch available. */ @GuardedBy("this") private void notifyDeviceOwnerLocked() { - Bundle extras = new Bundle(); - extras.putLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, mCurrentFullBatchToken); - extras.putInt(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_COUNT, mFullBatch.size()); + final Bundle extras = new Bundle(); + final int lastBatchSize = mBatches.valueAt(mBatches.size() - 1).size(); + extras.putLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, mCurrentBatchToken); + extras.putInt(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_COUNT, lastBatchSize); Log.d(TAG, "Sending network logging batch broadcast to device owner, batchToken: " - + mCurrentFullBatchToken); + + mCurrentBatchToken); mDpm.sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE, extras); } - synchronized List<NetworkEvent> retrieveFullLogBatch(long batchToken) { - if (batchToken != mCurrentFullBatchToken) { + synchronized List<NetworkEvent> retrieveFullLogBatch(final long batchToken) { + final int index = mBatches.indexOfKey(batchToken); + if (index < 0) { + // Invalid token or batch has already been discarded. return null; } - mLastRetrievedFullBatchToken = mCurrentFullBatchToken; - return mFullBatch; + + // Schedule this and older batches to be discarded after a delay to lessen memory load + // without interfering with the admin's ability to collect logs out-of-order. + // It isn't critical and we allow it to be delayed further if the phone sleeps, so we don't + // use the alarm manager here. + postDelayed(() -> { + synchronized(this) { + while (mBatches.size() > 0 && mBatches.keyAt(0) <= batchToken) { + mBatches.removeAt(0); + } + } + }, RETRIEVED_BATCH_DISCARD_DELAY_MS); + + mLastRetrievedBatchToken = batchToken; + return mBatches.valueAt(index); } } diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index f0732dd56f7a..3f197b7f3927 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -317,7 +317,7 @@ public final class SystemServer { // In case the runtime switched since last boot (such as when // the old runtime was removed in an OTA), set the system - // property so that it is in sync. We can't do this in + // property so that it is in sync. We can | xq oqi't do this in // libnativehelper's JniInvocation::Init code where we already // had to fallback to a different runtime because it is // running as root and we need to be the system user to set @@ -665,6 +665,7 @@ public final class SystemServer { VibratorService vibrator = null; IStorageManager storageManager = null; NetworkManagementService networkManagement = null; + IpSecService ipSecService = null; NetworkStatsService networkStats = null; NetworkPolicyManagerService networkPolicy = null; ConnectivityService connectivity = null; @@ -1012,6 +1013,15 @@ public final class SystemServer { reportWtf("starting NetworkManagement Service", e); } traceEnd(); + + traceBeginAndSlog("StartIpSecService"); + try { + ipSecService = IpSecService.create(context); + ServiceManager.addService(Context.IPSEC_SERVICE, ipSecService); + } catch (Throwable e) { + reportWtf("starting IpSec Service", e); + } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } if (!disableNonCoreServices) { @@ -1631,6 +1641,7 @@ public final class SystemServer { final TelephonyRegistry telephonyRegistryF = telephonyRegistry; final MediaRouterService mediaRouterF = mediaRouter; final MmsServiceBroker mmsServiceF = mmsService; + final IpSecService ipSecServiceF = ipSecService; // We now tell the activity manager it is okay to run third party // code. It will call back into us once it has gotten to the state @@ -1688,6 +1699,13 @@ public final class SystemServer { } catch (Throwable e) { reportWtf("making Network Managment Service ready", e); } + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeIpSecServiceReady"); + try { + if (ipSecServiceF != null) ipSecServiceF.systemReady(); + } catch (Throwable e) { + reportWtf("making IpSec Service ready", e); + } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); CountDownLatch networkPolicyInitReadySignal = null; if (networkPolicyF != null) { networkPolicyInitReadySignal = networkPolicyF diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java index 7b4fa8798885..590bce186430 100644 --- a/services/net/java/android/net/ip/IpManager.java +++ b/services/net/java/android/net/ip/IpManager.java @@ -608,7 +608,7 @@ public class IpManager extends StateMachine { } public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { - if (args.length > 0 && DUMP_ARG_CONFIRM.equals(args[0])) { + if (args != null && args.length > 0 && DUMP_ARG_CONFIRM.equals(args[0])) { // Execute confirmConfiguration() and take no further action. confirmConfiguration(); return; diff --git a/services/print/java/com/android/server/print/CompanionDeviceManagerService.java b/services/print/java/com/android/server/print/CompanionDeviceManagerService.java index 9356dacc29f8..7790698d02e9 100644 --- a/services/print/java/com/android/server/print/CompanionDeviceManagerService.java +++ b/services/print/java/com/android/server/print/CompanionDeviceManagerService.java @@ -20,6 +20,7 @@ package com.android.server.print; import static com.android.internal.util.Preconditions.checkNotNull; import android.Manifest; +import android.annotation.CheckResult; import android.annotation.Nullable; import android.companion.AssociationRequest; import android.companion.CompanionDeviceManager; @@ -36,8 +37,11 @@ import android.content.pm.PackageManager; import android.net.NetworkPolicyManager; import android.os.Binder; import android.os.Environment; +import android.os.Handler; import android.os.IBinder; import android.os.IDeviceIdleController; +import android.os.IInterface; +import android.os.Parcel; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; @@ -68,11 +72,13 @@ import java.util.concurrent.ConcurrentMap; import java.util.function.Function; //TODO move to own package! -//TODO un/linkToDeath & onBinderDied - unbind //TODO onStop schedule unbind in 5 seconds -//TODO Prune association on app uninstall +//TODO make sure APIs are only callable from currently focused app +//TODO schedule stopScan on activity destroy(except if configuration change) +//TODO on associate called again after configuration change -> replace old callback with new +//TODO avoid leaking calling activity in IFindDeviceCallback (see PrintManager#print for example) /** @hide */ -public class CompanionDeviceManagerService extends SystemService { +public class CompanionDeviceManagerService extends SystemService implements Binder.DeathRecipient { private static final ComponentName SERVICE_TO_BIND_TO = ComponentName.createRelative( CompanionDeviceManager.COMPANION_DEVICE_DISCOVERY_PACKAGE_NAME, @@ -90,6 +96,8 @@ public class CompanionDeviceManagerService extends SystemService { private final CompanionDeviceManagerImpl mImpl; private final ConcurrentMap<Integer, AtomicFile> mUidToStorage = new ConcurrentHashMap<>(); private IDeviceIdleController mIdleController; + private IFindDeviceCallback mFindDeviceCallback; + private ServiceConnection mServiceConnection; public CompanionDeviceManagerService(Context context) { super(context); @@ -125,7 +133,51 @@ public class CompanionDeviceManagerService extends SystemService { publishBinderService(Context.COMPANION_DEVICE_SERVICE, mImpl); } + @Override + public void binderDied() { + Handler.getMain().post(this::handleBinderDied); + } + + private void handleBinderDied() { + mServiceConnection = unbind(mServiceConnection); + mFindDeviceCallback = unlinkToDeath(mFindDeviceCallback, this, 0); + } + + /** + * Usage: {@code a = unlinkToDeath(a, deathRecipient, flags); } + */ + @Nullable + @CheckResult + private static <T extends IInterface> T unlinkToDeath(T iinterface, + IBinder.DeathRecipient deathRecipient, int flags) { + if (iinterface != null) { + iinterface.asBinder().unlinkToDeath(deathRecipient, flags); + } + return null; + } + + @Nullable + @CheckResult + private ServiceConnection unbind(@Nullable ServiceConnection conn) { + if (conn != null) { + getContext().unbindService(conn); + } + return null; + } + class CompanionDeviceManagerImpl extends ICompanionDeviceManager.Stub { + + @Override + public boolean onTransact(int code, Parcel data, Parcel reply, int flags) + throws RemoteException { + try { + return super.onTransact(code, data, reply, flags); + } catch (Throwable e) { + Slog.e(LOG_TAG, "Error during IPC", e); + throw ExceptionUtils.propagate(e, RemoteException.class); + } + } + @Override public void associate( AssociationRequest request, @@ -135,14 +187,14 @@ public class CompanionDeviceManagerService extends SystemService { Slog.i(LOG_TAG, "associate(request = " + request + ", callback = " + callback + ", callingPackage = " + callingPackage + ")"); } - checkNotNull(request); - checkNotNull(callback); + checkNotNull(request, "Request cannot be null"); + checkNotNull(callback, "Callback cannot be null"); final long callingIdentity = Binder.clearCallingIdentity(); try { //TODO bindServiceAsUser getContext().bindService( new Intent().setComponent(SERVICE_TO_BIND_TO), - getServiceConnection(request, callback, callingPackage), + createServiceConnection(request, callback, callingPackage), Context.BIND_AUTO_CREATE); } finally { Binder.restoreCallingIdentity(callingIdentity); @@ -168,11 +220,11 @@ public class CompanionDeviceManagerService extends SystemService { return UserHandle.getUserId(Binder.getCallingUid()); } - private ServiceConnection getServiceConnection( + private ServiceConnection createServiceConnection( final AssociationRequest request, final IFindDeviceCallback findDeviceCallback, final String callingPackage) { - return new ServiceConnection() { + mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { if (DEBUG) { @@ -180,6 +232,14 @@ public class CompanionDeviceManagerService extends SystemService { "onServiceConnected(name = " + name + ", service = " + service + ")"); } + mFindDeviceCallback = findDeviceCallback; + try { + mFindDeviceCallback.asBinder().linkToDeath( + CompanionDeviceManagerService.this, 0); + } catch (RemoteException e) { + handleBinderDied(); + return; + } try { ICompanionDeviceDiscoveryService.Stub .asInterface(service) @@ -198,6 +258,7 @@ public class CompanionDeviceManagerService extends SystemService { if (DEBUG) Slog.i(LOG_TAG, "onServiceDisconnected(name = " + name + ")"); } }; + return mServiceConnection; } private ICompanionDeviceDiscoveryServiceCallback.Stub getServiceCallback() { diff --git a/services/tests/servicestests/Android.mk b/services/tests/servicestests/Android.mk index 2a8f4a34f158..bb4507d8386a 100644 --- a/services/tests/servicestests/Android.mk +++ b/services/tests/servicestests/Android.mk @@ -52,6 +52,7 @@ LOCAL_JNI_SHARED_LIBRARIES := \ LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk LOCAL_JACK_FLAGS := --multi-dex native +LOCAL_DX_FLAGS := --multi-dex LOCAL_STATIC_JAVA_LIBRARIES += ub-uiautomator diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java index 29c6f89e5fa0..3671e4b86158 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java @@ -19,6 +19,7 @@ package com.android.server; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.TYPE_WIFI; import static android.net.NetworkPolicy.LIMIT_DISABLED; +import static android.net.NetworkPolicy.SNOOZE_NEVER; import static android.net.NetworkPolicy.WARNING_DISABLED; import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND; import static android.net.NetworkPolicyManager.POLICY_NONE; @@ -26,8 +27,15 @@ import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; import static android.net.NetworkPolicyManager.computeLastCycleBoundary; import static android.net.NetworkPolicyManager.computeNextCycleBoundary; import static android.net.NetworkPolicyManager.uidPoliciesToString; +import static android.net.NetworkTemplate.buildTemplateMobileAll; import static android.net.TrafficStats.KB_IN_BYTES; import static android.net.TrafficStats.MB_IN_BYTES; +import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED; +import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT; +import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED; +import static android.telephony.CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG; +import static android.telephony.CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG; +import static android.telephony.CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT; import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.text.format.DateUtils.MINUTE_IN_MILLIS; import static android.text.format.Time.TIMEZONE_UTC; @@ -94,18 +102,24 @@ import android.net.NetworkStats; import android.net.NetworkTemplate; import android.os.Binder; import android.os.INetworkManagementService; +import android.os.PersistableBundle; import android.os.PowerManagerInternal; import android.os.PowerSaveState; +import android.os.RemoteException; import android.os.UserHandle; import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; import android.support.test.runner.AndroidJUnit4; +import android.telephony.CarrierConfigManager; +import android.telephony.SubscriptionManager; +import android.telephony.TelephonyManager; import android.text.TextUtils; import android.text.format.Time; import android.util.Log; import android.util.TrustedTime; import com.android.internal.util.IndentingPrintWriter; +import com.android.internal.telephony.PhoneConstants; import com.android.internal.util.test.BroadcastInterceptingContext; import com.android.internal.util.test.BroadcastInterceptingContext.FutureIntent; import com.android.server.net.NetworkPolicyManagerInternal; @@ -143,6 +157,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.util.Arrays; +import java.util.Calendar; import java.util.LinkedHashSet; import java.util.List; import java.util.concurrent.CountDownLatch; @@ -200,20 +215,34 @@ public class NetworkPolicyManagerServiceTest { private @Mock INotificationManager mNotifManager; private @Mock PackageManager mPackageManager; private @Mock IPackageManager mIpm; + private @Mock SubscriptionManager mSubscriptionManager; + private @Mock CarrierConfigManager mCarrierConfigManager; + private @Mock TelephonyManager mTelephonyManager; private static ActivityManagerInternal mActivityManagerInternal; private IUidObserver mUidObserver; private INetworkManagementEventObserver mNetworkObserver; - private PowerManagerInternal mPowerManagerInternal; private NetworkPolicyListenerAnswer mPolicyListener; private NetworkPolicyManagerService mService; + /** + * In some of the tests while initializing NetworkPolicyManagerService, + * ACTION_RESTRICT_BACKGROUND_CHANGED is broadcasted. This is for capturing that broadcast. + */ + private FutureIntent mFutureIntent; + private long mStartTime; private long mElapsedRealtime; private static final int USER_ID = 0; + private static final int FAKE_SUB_ID = 3737373; + private static final String FAKE_SUBSCRIBER_ID = "FAKE_SUB_ID"; + private static final int DEFAULT_CYCLE_DAY = 1; + private static final int INVALID_CARRIER_CONFIG_VALUE = -9999; + private long mDefaultWarningBytes; // filled in with the actual default before tests are run + private long mDefaultLimitBytes; // filled in with the actual default before tests are run private static final int APP_ID_A = android.os.Process.FIRST_APPLICATION_UID + 4; private static final int APP_ID_B = android.os.Process.FIRST_APPLICATION_UID + 8; @@ -233,12 +262,13 @@ public class NetworkPolicyManagerServiceTest { public final @Rule NetPolicyMethodRule mNetPolicyXmlRule = new NetPolicyMethodRule(); - @BeforeClass - public static void registerLocalServices() { + private void registerLocalServices() { addLocalServiceMock(DeviceIdleController.LocalService.class); + final UsageStatsManagerInternal usageStats = addLocalServiceMock(UsageStatsManagerInternal.class); when(usageStats.getIdleUidsForUser(anyInt())).thenReturn(new int[]{}); + mActivityManagerInternal = addLocalServiceMock(ActivityManagerInternal.class); final PowerSaveState state = new PowerSaveState.Builder() @@ -255,7 +285,9 @@ public class NetworkPolicyManagerServiceTest { setCurrentTimeMillis(TEST_START); - // intercept various broadcasts, and pretend that uids have packages + registerLocalServices(); + // Intercept various broadcasts, and pretend that uids have packages. + // Also return mock service instances for a few critical services. mServiceContext = new BroadcastInterceptingContext(context) { @Override public PackageManager getPackageManager() { @@ -266,6 +298,20 @@ public class NetworkPolicyManagerServiceTest { public void startActivity(Intent intent) { // ignored } + + @Override + public Object getSystemService(String name) { + switch (name) { + case Context.TELEPHONY_SUBSCRIPTION_SERVICE: + return mSubscriptionManager; + case Context.CARRIER_CONFIG_SERVICE: + return mCarrierConfigManager; + case Context.TELEPHONY_SERVICE: + return mTelephonyManager; + default: + return super.getSystemService(name); + } + } }; setNetpolicyXml(context); @@ -281,6 +327,7 @@ public class NetworkPolicyManagerServiceTest { }).when(mActivityManager).registerUidObserver(any(), anyInt(), eq(ActivityManager.PROCESS_STATE_UNKNOWN), isNull(String.class)); + mFutureIntent = newRestrictBackgroundChangedFuture(); mService = new NetworkPolicyManagerService(mServiceContext, mActivityManager, mStatsService, mNetworkManager, mIpm, mTime, mPolicyDir, true); mService.bindConnectivityManager(mConnManager); @@ -321,6 +368,10 @@ public class NetworkPolicyManagerServiceTest { ArgumentCaptor.forClass(INetworkManagementEventObserver.class); verify(mNetworkManager).registerObserver(networkObserver.capture()); mNetworkObserver = networkObserver.getValue(); + + NetworkPolicy defaultPolicy = mService.buildDefaultMobilePolicy(0, ""); + mDefaultWarningBytes = defaultPolicy.warningBytes; + mDefaultLimitBytes = defaultPolicy.limitBytes; } @After @@ -334,6 +385,12 @@ public class NetworkPolicyManagerServiceTest { public void unregisterLocalServices() throws Exception { // Registered by NetworkPolicyManagerService's constructor. LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class); + + // Added in registerLocalServices() + LocalServices.removeServiceForTest(ActivityManagerInternal.class); + LocalServices.removeServiceForTest(PowerManagerInternal.class); + LocalServices.removeServiceForTest(DeviceIdleController.LocalService.class); + LocalServices.removeServiceForTest(UsageStatsManagerInternal.class); } @Test @@ -348,6 +405,7 @@ public class NetworkPolicyManagerServiceTest { @NetPolicyXml("restrict-background-on.xml") public void testTurnRestrictBackgroundOff() throws Exception { assertRestrictBackgroundOn(); // Sanity check. + assertRestrictBackgroundChangedReceived(mFutureIntent, null); final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); setRestrictBackground(false); assertRestrictBackgroundChangedReceived(futureIntent, null); @@ -360,6 +418,7 @@ public class NetworkPolicyManagerServiceTest { @NetPolicyXml("restrict-background-on.xml") public void testAddRestrictBackgroundWhitelist_restrictBackgroundOn() throws Exception { assertRestrictBackgroundOn(); // Sanity check. + assertRestrictBackgroundChangedReceived(mFutureIntent, null); addRestrictBackgroundWhitelist(true); } @@ -400,6 +459,7 @@ public class NetworkPolicyManagerServiceTest { @NetPolicyXml("uidA-whitelisted-restrict-background-on.xml") public void testRemoveRestrictBackgroundWhitelist_restrictBackgroundOn() throws Exception { assertRestrictBackgroundOn(); // Sanity check. + assertRestrictBackgroundChangedReceived(mFutureIntent, null); removeRestrictBackgroundWhitelist(true); } @@ -519,6 +579,7 @@ public class NetworkPolicyManagerServiceTest { @NetPolicyXml("restrict-background-on.xml") public void testAddRestrictBackgroundBlacklist_restrictBackgroundOn() throws Exception { assertRestrictBackgroundOn(); // Sanity check. + assertRestrictBackgroundChangedReceived(mFutureIntent, null); addRestrictBackgroundBlacklist(false); } @@ -555,6 +616,7 @@ public class NetworkPolicyManagerServiceTest { @NetPolicyXml("uidA-blacklisted-restrict-background-on.xml") public void testRemoveRestrictBackgroundBlacklist_restrictBackgroundOn() throws Exception { assertRestrictBackgroundOn(); // Sanity check. + assertRestrictBackgroundChangedReceived(mFutureIntent, null); removeRestrictBackgroundBlacklist(false); } @@ -590,6 +652,7 @@ public class NetworkPolicyManagerServiceTest { public void testBlacklistedAppIsNotNotifiedWhenRestrictBackgroundIsOn() throws Exception { // Sanity checks. assertRestrictBackgroundOn(); + assertRestrictBackgroundChangedReceived(mFutureIntent, null); assertUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); @@ -602,6 +665,7 @@ public class NetworkPolicyManagerServiceTest { public void testWhitelistedAppIsNotNotifiedWhenRestrictBackgroundIsOn() throws Exception { // Sanity checks. assertRestrictBackgroundOn(); + assertRestrictBackgroundChangedReceived(mFutureIntent, null); assertWhitelistUids(UID_A); final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); @@ -614,6 +678,7 @@ public class NetworkPolicyManagerServiceTest { public void testWhitelistedAppIsNotifiedWhenBlacklisted() throws Exception { // Sanity checks. assertRestrictBackgroundOn(); + assertRestrictBackgroundChangedReceived(mFutureIntent, null); assertWhitelistUids(UID_A); final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); @@ -696,19 +761,19 @@ public class NetworkPolicyManagerServiceTest { @Test public void testUidForeground() throws Exception { // push all uids into background - mUidObserver.onUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, 0); - mUidObserver.onUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_SERVICE, 0); + callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, 0); + callOnUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_SERVICE, 0); assertFalse(mService.isUidForeground(UID_A)); assertFalse(mService.isUidForeground(UID_B)); // push one of the uids into foreground - mUidObserver.onUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_TOP, 0); + callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_TOP, 0); assertTrue(mService.isUidForeground(UID_A)); assertFalse(mService.isUidForeground(UID_B)); // and swap another uid into foreground - mUidObserver.onUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, 0); - mUidObserver.onUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_TOP, 0); + callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, 0); + callOnUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_TOP, 0); assertFalse(mService.isUidForeground(UID_A)); assertTrue(mService.isUidForeground(UID_B)); } @@ -1066,8 +1131,7 @@ public class NetworkPolicyManagerServiceTest { @Test public void testOnUidStateChanged_notifyAMS() throws Exception { final long procStateSeq = 222; - mUidObserver.onUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, - procStateSeq); + callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, procStateSeq); verify(mActivityManagerInternal).notifyNetworkPolicyRulesUpdated(UID_A, procStateSeq); final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); @@ -1079,6 +1143,16 @@ public class NetworkPolicyManagerServiceTest { outputStream.toString().trim()); } + private void callOnUidStateChanged(int uid, int procState, long procStateSeq) + throws Exception { + mUidObserver.onUidStateChanged(uid, procState, procStateSeq); + final CountDownLatch latch = new CountDownLatch(1); + mService.mUidEventHandler.post(() -> { + latch.countDown(); + }); + latch.await(2, TimeUnit.SECONDS); + } + @Test public void testProcStateHistory() { // Verify dump works correctly with no elements added. @@ -1132,6 +1206,269 @@ public class NetworkPolicyManagerServiceTest { } } + private void assertCycleDayAsExpected(PersistableBundle config, int carrierCycleDay, + boolean expectValid) { + config.putInt(KEY_MONTHLY_DATA_CYCLE_DAY_INT, carrierCycleDay); + int actualCycleDay = mService.getCycleDayFromCarrierConfig(config, + INVALID_CARRIER_CONFIG_VALUE); + if (expectValid) { + assertEquals(carrierCycleDay, actualCycleDay); + } else { + // INVALID_CARRIER_CONFIG_VALUE is returned for invalid values + assertEquals(INVALID_CARRIER_CONFIG_VALUE, actualCycleDay); + } + } + + @Test + public void testGetCycleDayFromCarrierConfig() { + PersistableBundle config = CarrierConfigManager.getDefaultConfig(); + final Calendar cal = Calendar.getInstance(); + int actualCycleDay; + + config.putInt(KEY_MONTHLY_DATA_CYCLE_DAY_INT, DATA_CYCLE_USE_PLATFORM_DEFAULT); + actualCycleDay = mService.getCycleDayFromCarrierConfig(config, DEFAULT_CYCLE_DAY); + assertEquals(DEFAULT_CYCLE_DAY, actualCycleDay); + + // null config returns a default value + actualCycleDay = mService.getCycleDayFromCarrierConfig(null, DEFAULT_CYCLE_DAY); + assertEquals(DEFAULT_CYCLE_DAY, actualCycleDay); + + // Sane, non-default values + assertCycleDayAsExpected(config, 1, true); + assertCycleDayAsExpected(config, cal.getMaximum(Calendar.DAY_OF_MONTH), true); + assertCycleDayAsExpected(config, cal.getMinimum(Calendar.DAY_OF_MONTH), true); + + // Invalid values + assertCycleDayAsExpected(config, 0, false); + assertCycleDayAsExpected(config, DATA_CYCLE_THRESHOLD_DISABLED, false); + assertCycleDayAsExpected(config, cal.getMaximum(Calendar.DAY_OF_MONTH) + 1, false); + assertCycleDayAsExpected(config, cal.getMinimum(Calendar.DAY_OF_MONTH) - 5, false); + } + + private void assertWarningBytesAsExpected(PersistableBundle config, long carrierWarningBytes, + long expected) { + config.putLong(KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, carrierWarningBytes); + long actualWarning = mService.getWarningBytesFromCarrierConfig(config, + INVALID_CARRIER_CONFIG_VALUE); + assertEquals(expected, actualWarning); + } + + @Test + public void testGetWarningBytesFromCarrierConfig() { + PersistableBundle config = CarrierConfigManager.getDefaultConfig(); + long actualWarningBytes; + + assertWarningBytesAsExpected(config, DATA_CYCLE_USE_PLATFORM_DEFAULT, + mDefaultWarningBytes); + assertWarningBytesAsExpected(config, DATA_CYCLE_THRESHOLD_DISABLED, WARNING_DISABLED); + assertWarningBytesAsExpected(config, 0, 0); + // not a valid value + assertWarningBytesAsExpected(config, -1000, INVALID_CARRIER_CONFIG_VALUE); + + // null config returns a default value + actualWarningBytes = mService.getWarningBytesFromCarrierConfig(null, mDefaultWarningBytes); + assertEquals(mDefaultWarningBytes, actualWarningBytes); + } + + private void assertLimitBytesAsExpected(PersistableBundle config, long carrierWarningBytes, + long expected) { + config.putLong(KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, carrierWarningBytes); + long actualWarning = mService.getLimitBytesFromCarrierConfig(config, + INVALID_CARRIER_CONFIG_VALUE); + assertEquals(expected, actualWarning); + } + + @Test + public void testGetLimitBytesFromCarrierConfig() { + PersistableBundle config = CarrierConfigManager.getDefaultConfig(); + long actualLimitBytes; + + assertLimitBytesAsExpected(config, DATA_CYCLE_USE_PLATFORM_DEFAULT, + mDefaultLimitBytes); + assertLimitBytesAsExpected(config, DATA_CYCLE_THRESHOLD_DISABLED, LIMIT_DISABLED); + assertLimitBytesAsExpected(config, 0, 0); + // not a valid value + assertLimitBytesAsExpected(config, -1000, INVALID_CARRIER_CONFIG_VALUE); + + // null config returns a default value + actualLimitBytes = mService.getWarningBytesFromCarrierConfig(null, mDefaultLimitBytes); + assertEquals(mDefaultLimitBytes, actualLimitBytes); + } + + private PersistableBundle setupUpdateMobilePolicyCycleTests() throws RemoteException { + when(mConnManager.getAllNetworkState()).thenReturn(new NetworkState[0]); + when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[]{FAKE_SUB_ID}); + when(mTelephonyManager.getSubscriberId(FAKE_SUB_ID)).thenReturn(FAKE_SUBSCRIBER_ID); + PersistableBundle bundle = CarrierConfigManager.getDefaultConfig(); + when(mCarrierConfigManager.getConfigForSubId(FAKE_SUB_ID)).thenReturn(bundle); + setNetworkPolicies(buildDefaultFakeMobilePolicy()); + return bundle; + } + + @Test + public void testUpdateMobilePolicyCycleWithNullConfig() throws RemoteException { + when(mConnManager.getAllNetworkState()).thenReturn(new NetworkState[0]); + when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[]{FAKE_SUB_ID}); + when(mTelephonyManager.getSubscriberId(FAKE_SUB_ID)).thenReturn(FAKE_SUBSCRIBER_ID); + when(mCarrierConfigManager.getConfigForSubId(FAKE_SUB_ID)).thenReturn(null); + setNetworkPolicies(buildDefaultFakeMobilePolicy()); + // smoke test to make sure no errors are raised + mServiceContext.sendBroadcast( + new Intent(ACTION_CARRIER_CONFIG_CHANGED) + .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID) + ); + assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes, + true); + } + + @Test + public void testUpdateMobilePolicyCycleWithInvalidConfig() throws RemoteException { + PersistableBundle bundle = setupUpdateMobilePolicyCycleTests(); + // Test with an invalid CarrierConfig, there should be no changes or crashes. + bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, -100); + bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, -100); + bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, -100); + mServiceContext.sendBroadcast( + new Intent(ACTION_CARRIER_CONFIG_CHANGED) + .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID) + ); + + assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes, + true); + } + + @Test + public void testUpdateMobilePolicyCycleWithDefaultConfig() throws RemoteException { + PersistableBundle bundle = setupUpdateMobilePolicyCycleTests(); + // Test that we respect the platform values when told to + bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, + DATA_CYCLE_USE_PLATFORM_DEFAULT); + bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, + DATA_CYCLE_USE_PLATFORM_DEFAULT); + bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, + DATA_CYCLE_USE_PLATFORM_DEFAULT); + mServiceContext.sendBroadcast( + new Intent(ACTION_CARRIER_CONFIG_CHANGED) + .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID) + ); + + assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes, + true); + } + + @Test + public void testUpdateMobilePolicyCycleWithUserOverrides() throws RemoteException { + PersistableBundle bundle = setupUpdateMobilePolicyCycleTests(); + + // inferred = false implies that a user manually modified this policy. + NetworkPolicy policy = buildDefaultFakeMobilePolicy(); + policy.inferred = false; + setNetworkPolicies(policy); + + bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31); + bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, 9999); + bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, + DATA_CYCLE_THRESHOLD_DISABLED); + mServiceContext.sendBroadcast( + new Intent(ACTION_CARRIER_CONFIG_CHANGED) + .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID) + ); + + // The policy still shouldn't change, because we don't want to overwrite user settings. + assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes, + false); + } + + @Test + public void testUpdateMobilePolicyCycleUpdatesDataCycle() throws RemoteException { + PersistableBundle bundle = setupUpdateMobilePolicyCycleTests(); + + bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31); + bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, 9999); + bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, 9999); + mServiceContext.sendBroadcast( + new Intent(ACTION_CARRIER_CONFIG_CHANGED) + .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID) + ); + + assertNetworkPolicyEquals(31, 9999, 9999, true); + } + + @Test + public void testUpdateMobilePolicyCycleDisableThresholds() throws RemoteException { + PersistableBundle bundle = setupUpdateMobilePolicyCycleTests(); + + bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31); + bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, + DATA_CYCLE_THRESHOLD_DISABLED); + bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, + DATA_CYCLE_THRESHOLD_DISABLED); + mServiceContext.sendBroadcast( + new Intent(ACTION_CARRIER_CONFIG_CHANGED) + .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID) + ); + + assertNetworkPolicyEquals(31, WARNING_DISABLED, LIMIT_DISABLED, true); + } + + @Test + public void testUpdateMobilePolicyCycleRevertsToDefault() throws RemoteException { + PersistableBundle bundle = setupUpdateMobilePolicyCycleTests(); + + bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31); + bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, + DATA_CYCLE_THRESHOLD_DISABLED); + bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, + DATA_CYCLE_THRESHOLD_DISABLED); + mServiceContext.sendBroadcast( + new Intent(ACTION_CARRIER_CONFIG_CHANGED) + .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID) + ); + assertNetworkPolicyEquals(31, WARNING_DISABLED, LIMIT_DISABLED, true); + + // If the user switches carriers to one that doesn't use a CarrierConfig, we should revert + // to the default data limit and warning. The cycle date doesn't need to revert as it's + // arbitrary anyways. + bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, + DATA_CYCLE_USE_PLATFORM_DEFAULT); + bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, + DATA_CYCLE_USE_PLATFORM_DEFAULT); + bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, + DATA_CYCLE_USE_PLATFORM_DEFAULT); + mServiceContext.sendBroadcast( + new Intent(ACTION_CARRIER_CONFIG_CHANGED) + .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID) + ); + + assertNetworkPolicyEquals(31, mDefaultWarningBytes, mDefaultLimitBytes, + true); + } + + private NetworkPolicy buildDefaultFakeMobilePolicy() { + NetworkPolicy p = mService.buildDefaultMobilePolicy(FAKE_SUB_ID, FAKE_SUBSCRIBER_ID); + // set a deterministic cycle date + p.cycleDay = DEFAULT_CYCLE_DAY; + return p; + } + + private static NetworkPolicy buildFakeMobilePolicy(int cycleDay, long warningBytes, + long limitBytes, boolean inferred){ + final NetworkTemplate template = buildTemplateMobileAll(FAKE_SUBSCRIBER_ID); + return new NetworkPolicy(template, cycleDay, new Time().timezone, warningBytes, + limitBytes, SNOOZE_NEVER, SNOOZE_NEVER, true, inferred); + } + + private void assertNetworkPolicyEquals(int expectedCycleDay, long expectedWarningBytes, + long expectedLimitBytes, boolean expectedInferred) { + NetworkPolicy[] policies = mService.getNetworkPolicies( + mServiceContext.getOpPackageName()); + assertEquals("Unexpected number of network policies", 1, policies.length); + NetworkPolicy actualPolicy = policies[0]; + NetworkPolicy expectedPolicy = buildFakeMobilePolicy(expectedCycleDay, expectedWarningBytes, + expectedLimitBytes, expectedInferred); + assertEquals(expectedPolicy, actualPolicy); + } + private static long parseTime(String time) { final Time result = new Time(); result.parse3339(time); diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java index a9c69f6bd3d2..e0ac393290ac 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java @@ -128,9 +128,11 @@ public class NetworkScoreServiceTest { private static final ScoredNetwork SCORED_NETWORK_2 = new ScoredNetwork(new NetworkKey(new WifiKey(quote(SSID_2), "00:00:00:00:00:00")), null /* rssiCurve*/); + private static final String NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID = + "networkAvailableNotificationChannelId"; private static final NetworkScorerAppData NEW_SCORER = new NetworkScorerAppData( 1, RECOMMENDATION_SERVICE_COMP, RECOMMENDATION_SERVICE_LABEL, - USE_WIFI_ENABLE_ACTIVITY_COMP); + USE_WIFI_ENABLE_ACTIVITY_COMP, NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID); @Mock private NetworkScorerAppManager mNetworkScorerAppManager; @Mock private Context mContext; @@ -965,7 +967,7 @@ public class NetworkScoreServiceTest { .thenReturn(PackageManager.PERMISSION_GRANTED); NetworkScorerAppData expectedAppData = new NetworkScorerAppData(Binder.getCallingUid(), RECOMMENDATION_SERVICE_COMP, RECOMMENDATION_SERVICE_LABEL, - USE_WIFI_ENABLE_ACTIVITY_COMP); + USE_WIFI_ENABLE_ACTIVITY_COMP, NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID); bindToScorer(expectedAppData); assertEquals(expectedAppData, mNetworkScoreService.getActiveScorer()); } @@ -1007,7 +1009,7 @@ public class NetworkScoreServiceTest { final int callingUid = callerIsScorer ? Binder.getCallingUid() : Binder.getCallingUid() + 1; NetworkScorerAppData appData = new NetworkScorerAppData(callingUid, RECOMMENDATION_SERVICE_COMP, RECOMMENDATION_SERVICE_LABEL, - USE_WIFI_ENABLE_ACTIVITY_COMP); + USE_WIFI_ENABLE_ACTIVITY_COMP, NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID); bindToScorer(appData); } diff --git a/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java b/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java index e8663a2f2a22..9197ccf972c4 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java @@ -62,6 +62,8 @@ import java.util.List; public class NetworkScorerAppManagerTest { private static String MOCK_SERVICE_LABEL = "Mock Service"; private static String MOCK_OVERRIDEN_SERVICE_LABEL = "Mock Service Label Override"; + private static String MOCK_NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID = + "Mock Network Available Notification Channel Id"; @Mock private Context mMockContext; @Mock private PackageManager mMockPm; @@ -168,13 +170,30 @@ public class NetworkScorerAppManagerTest { mockScoreNetworksGranted(recoComponent.getPackageName()); mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, enableUseOpenWifiComponent.getPackageName()); - mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent); final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer(); assertNotNull(activeScorer); assertEquals(recoComponent, activeScorer.getRecommendationServiceComponent()); assertEquals(924, activeScorer.packageUid); assertEquals(enableUseOpenWifiComponent, activeScorer.getEnableUseOpenWifiActivity()); + assertNull(activeScorer.getNetworkAvailableNotificationChannelId()); + } + + @Test + public void testGetActiveScorer_providerAvailable_networkAvailableNotificationChannelIdSet() { + final ComponentName recoComponent = new ComponentName("package1", "class1"); + setNetworkRecoPackageSetting(recoComponent.getPackageName()); + mockScoreNetworksGranted(recoComponent.getPackageName()); + mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, + null /* enableUseOpenWifiActivityPackage */, false /* serviceLabelOverride */, + true /* setNotificationChannelId */); + + final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer(); + assertNotNull(activeScorer); + assertEquals(recoComponent, activeScorer.getRecommendationServiceComponent()); + assertEquals(924, activeScorer.packageUid); + assertEquals(MOCK_NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID, + activeScorer.getNetworkAvailableNotificationChannelId()); } @Test @@ -368,6 +387,13 @@ public class NetworkScorerAppManagerTest { private void mockRecommendationServiceAvailable(final ComponentName compName, int packageUid, String enableUseOpenWifiActivityPackage, boolean serviceLabelOverride) { + mockRecommendationServiceAvailable(compName, packageUid, enableUseOpenWifiActivityPackage, + serviceLabelOverride, false); + } + + private void mockRecommendationServiceAvailable(final ComponentName compName, int packageUid, + String enableUseOpenWifiActivityPackage, boolean serviceLabelOverride, + boolean setNotificationChannel) { final ResolveInfo serviceInfo = new ResolveInfo(); serviceInfo.serviceInfo = new ServiceInfo(); serviceInfo.serviceInfo.name = compName.getClassName(); @@ -390,6 +416,14 @@ public class NetworkScorerAppManagerTest { } else { serviceInfo.serviceInfo.nonLocalizedLabel = MOCK_SERVICE_LABEL; } + if (setNotificationChannel) { + if (serviceInfo.serviceInfo.metaData == null) { + serviceInfo.serviceInfo.metaData = new Bundle(); + } + serviceInfo.serviceInfo.metaData.putString( + NetworkScoreManager.NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID_META_DATA, + MOCK_NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID); + } final int flags = PackageManager.GET_META_DATA; when(mMockPm.resolveService( diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java index 374aee10da45..00f6273d14bf 100644 --- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java @@ -94,7 +94,7 @@ import java.util.concurrent.atomic.AtomicLong; * <p>Run with:<pre> * mmma -j40 frameworks/base/services/tests/servicestests * adb install -r ${OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk - * adb shell am instrument -w -e class package com.android.server.accounts \ + * adb shell am instrument -w -e package com.android.server.accounts \ * com.android.frameworks.servicestests\ * /android.support.test.runner.AndroidJUnitRunner * </pre> diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java index 2cb8af4e97e7..aa374073e4a5 100644 --- a/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java +++ b/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java @@ -385,6 +385,42 @@ public class AccountsDbTest { } @Test + public void testFindAllVisibilityValues() { + long accId = 10; + long accId2 = 11; + String packageName1 = "com.example.one"; + String packageName2 = "com.example.two"; + Account account = new Account("name", "example.com"); + Account account2 = new Account("name2", "example2.com"); + assertNull(mAccountsDb.findAccountVisibility(account, packageName1)); + + mAccountsDb.insertDeAccount(account, accId); + assertNull(mAccountsDb.findAccountVisibility(account, packageName1)); + assertNull(mAccountsDb.findAccountVisibility(accId, packageName1)); + mAccountsDb.insertDeAccount(account2, accId2); + + mAccountsDb.setAccountVisibility(accId, packageName1, 1); + mAccountsDb.setAccountVisibility(accId, packageName2, 2); + mAccountsDb.setAccountVisibility(accId2, packageName1, 1); + + Map<Account, Map<String, Integer>> vis = mAccountsDb.findAllVisibilityValues(); + assertEquals(vis.size(), 2); + Map<String, Integer> accnt1Visibility = vis.get(account); + assertEquals(accnt1Visibility.size(), 2); + assertEquals(accnt1Visibility.get(packageName1), Integer.valueOf(1)); + assertEquals(accnt1Visibility.get(packageName2), Integer.valueOf(2)); + Map<String, Integer> accnt2Visibility = vis.get(account2); + assertEquals(accnt2Visibility.size(), 1); + assertEquals(accnt2Visibility.get(packageName1), Integer.valueOf(1)); + + mAccountsDb.setAccountVisibility(accId2, packageName2, 3); + vis = mAccountsDb.findAllVisibilityValues(); + accnt2Visibility = vis.get(account2); + assertEquals(accnt2Visibility.size(), 2); + assertEquals(accnt2Visibility.get(packageName2), Integer.valueOf(3)); + } + + @Test public void testVisibilityCleanupTrigger() { long accId = 10; String packageName1 = "com.example.one"; diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java index b12da34f4375..1e038dfaf1af 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java @@ -51,7 +51,9 @@ import android.app.ActivityManager; import android.app.AppOpsManager; import android.app.IApplicationThread; import android.app.IUidObserver; +import android.content.Context; import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; @@ -116,7 +118,9 @@ public class ActivityManagerServiceTest { UidRecord.CHANGE_ACTIVE }; + @Mock private Context mContext; @Mock private AppOpsService mAppOpsService; + @Mock private PackageManager mPackageManager; private TestInjector mInjector; private ActivityManagerService mAms; @@ -133,6 +137,8 @@ public class ActivityManagerServiceTest { mInjector = new TestInjector(); mAms = new ActivityManagerService(mInjector); mAms.mWaitForNetworkTimeoutMs = 100; + + when(mContext.getPackageManager()).thenReturn(mPackageManager); } @After @@ -601,10 +607,12 @@ public class ActivityManagerServiceTest { uidRecord.pendingChange = changeItem; uidRecord.curProcStateSeq = TEST_PROC_STATE_SEQ2; verifyLastProcStateSeqUpdated(uidRecord, -1, TEST_PROC_STATE_SEQ2); + } + @Test + public void testEnqueueUidChangeLocked_nullUidRecord() { // Use "null" uidRecord to make sure there is no crash. - // TODO: currently it crashes, uncomment after fixing it. - // mAms.enqueueUidChangeLocked(null, TEST_UID, UidRecord.CHANGE_ACTIVE); + mAms.enqueueUidChangeLocked(null, TEST_UID, UidRecord.CHANGE_ACTIVE); } private void verifyLastProcStateSeqUpdated(UidRecord uidRecord, int uid, long curProcstateSeq) { @@ -770,6 +778,11 @@ public class ActivityManagerServiceTest { private boolean mRestricted = true; @Override + public Context getContext() { + return mContext; + } + + @Override public AppOpsService getAppOpsService(File file, Handler handler) { return mAppOpsService; } diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java index b5826f0c1106..2003b91bcfad 100644 --- a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java +++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java @@ -26,8 +26,10 @@ import android.support.test.runner.AndroidJUnit4; import android.view.Surface; import android.view.WindowManager; +import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; +import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; @@ -160,4 +162,22 @@ public class AppWindowTokenTests extends WindowTestsBase { sWm.mRoot.mOrientationChangeComplete = true; sWm.mRoot.performSurfacePlacement(false /* recoveringMemory */); } + + @Test + public void testGetOrientation() throws Exception { + final TestAppWindowToken token = new TestAppWindowToken(sDisplayContent); + token.setOrientation(SCREEN_ORIENTATION_LANDSCAPE); + + token.setFillsParent(false); + // Can not specify orientation if app doesn't fill parent. + assertEquals(SCREEN_ORIENTATION_UNSET, token.getOrientation()); + + token.setFillsParent(true); + token.hidden = true; + token.sendingToBottom = true; + // Can not specify orientation if app isn't visible even though it fills parent. + assertEquals(SCREEN_ORIENTATION_UNSET, token.getOrientation()); + // Can specify orientation if the current orientation candidate is orientation behind. + assertEquals(SCREEN_ORIENTATION_LANDSCAPE, token.getOrientation(SCREEN_ORIENTATION_BEHIND)); + } } diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java index 3868242616b2..1729ceec0005 100644 --- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java @@ -21,6 +21,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION; +import static com.android.server.wm.WindowContainer.POSITION_TOP; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -233,6 +234,68 @@ public class DisplayContentTests extends WindowTestsBase { assertEquals(currentOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */); } + @Test + public void testFocusedWindowMultipleDisplays() throws Exception { + // Create a focusable window and check that focus is calcualted correctly + final WindowState window1 = + createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "window1"); + assertEquals(window1, sWm.mRoot.computeFocusedWindow()); + + // Check that a new display doesn't affect focus + final DisplayContent dc = createNewDisplay(); + assertEquals(window1, sWm.mRoot.computeFocusedWindow()); + + // Add a window to the second display, and it should be focused + final WindowState window2 = createWindow(null, TYPE_BASE_APPLICATION, dc, "window2"); + assertEquals(window2, sWm.mRoot.computeFocusedWindow()); + + // Move the first window to the to including parents, and make sure focus is updated + window1.getParent().positionChildAt(POSITION_TOP, window1, true); + assertEquals(window1, sWm.mRoot.computeFocusedWindow()); + } + + /** + * This tests setting the maximum ui width on a display. + */ + @Test + public void testMaxUiWidth() throws Exception { + final int baseWidth = 1440; + final int baseHeight = 2560; + final int baseDensity = 300; + + sDisplayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity); + + final int maxWidth = 300; + final int resultingHeight = (maxWidth * baseHeight) / baseWidth; + final int resultingDensity = (maxWidth * baseDensity) / baseWidth; + + sDisplayContent.setMaxUiWidth(maxWidth); + verifySizes(sDisplayContent, maxWidth, resultingHeight, resultingDensity); + + // Assert setting values again does not change; + sDisplayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity); + verifySizes(sDisplayContent, maxWidth, resultingHeight, resultingDensity); + + final int smallerWidth = 200; + final int smallerHeight = 400; + final int smallerDensity = 100; + + // Specify smaller dimension, verify that it is honored + sDisplayContent.updateBaseDisplayMetrics(smallerWidth, smallerHeight, smallerDensity); + verifySizes(sDisplayContent, smallerWidth, smallerHeight, smallerDensity); + + // Verify that setting the max width to a greater value than the base width has no effect + sDisplayContent.setMaxUiWidth(maxWidth); + verifySizes(sDisplayContent, smallerWidth, smallerHeight, smallerDensity); + } + + private static void verifySizes(DisplayContent displayContent, int expectedBaseWidth, + int expectedBaseHeight, int expectedBaseDensity) { + assertEquals(displayContent.mBaseDisplayWidth, expectedBaseWidth); + assertEquals(displayContent.mBaseDisplayHeight, expectedBaseHeight); + assertEquals(displayContent.mBaseDisplayDensity, expectedBaseDensity); + } + private void assertForAllWindowsOrder(List<WindowState> expectedWindows) { final LinkedList<WindowState> actualWindows = new LinkedList(); diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java index 3ce3df1557dd..9dbd8a617eec 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java +++ b/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java @@ -76,9 +76,9 @@ public class TaskStackTests extends WindowTestsBase { task2.addChild(appWindowToken2, 0); appWindowToken2.setOrientation(SCREEN_ORIENTATION_PORTRAIT); - assertEquals(stack.getOrientation(), SCREEN_ORIENTATION_PORTRAIT); + assertEquals(SCREEN_ORIENTATION_PORTRAIT, stack.getOrientation()); sWm.mClosingApps.add(appWindowToken2); - assertEquals(stack.getOrientation(), SCREEN_ORIENTATION_LANDSCAPE); + assertEquals(SCREEN_ORIENTATION_LANDSCAPE, stack.getOrientation()); } @Test @@ -94,9 +94,9 @@ public class TaskStackTests extends WindowTestsBase { task2.addChild(appWindowToken2, 0); appWindowToken2.setOrientation(SCREEN_ORIENTATION_PORTRAIT); - assertEquals(stack.getOrientation(), SCREEN_ORIENTATION_PORTRAIT); + assertEquals(SCREEN_ORIENTATION_PORTRAIT, stack.getOrientation()); task2.setSendingToBottom(true); - assertEquals(stack.getOrientation(), SCREEN_ORIENTATION_LANDSCAPE); + assertEquals(SCREEN_ORIENTATION_LANDSCAPE, stack.getOrientation()); } @Test diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java index 80b2e7d9bc3c..a7d594cbd256 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java +++ b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java @@ -422,7 +422,7 @@ public class WindowContainerTests extends WindowTestsBase { final TestWindowContainer child1 = root.addChildWindow(builder); child1.setFillsParent(true); - assertTrue(root.getOrientation() == expectedOrientation); + assertEquals(expectedOrientation, root.getOrientation()); } @Test @@ -805,8 +805,13 @@ public class WindowContainerTests extends WindowTestsBase { } @Override + int getOrientation(int candidate) { + return mOrientation != null ? mOrientation : super.getOrientation(candidate); + } + + @Override int getOrientation() { - return mOrientation != null ? mOrientation : super.getOrientation(); + return getOrientation(super.mOrientation); } @Override diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java index 48799d23c06e..a9d930f5c893 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java @@ -16,6 +16,8 @@ package com.android.server.wm; +import static android.view.View.VISIBLE; + import android.app.ActivityManager.TaskDescription; import android.content.res.Configuration; import android.graphics.Rect; @@ -233,7 +235,7 @@ class WindowTestsBase { attrs.setTitle(name); final WindowState w = new WindowState(sWm, sMockSession, sIWindow, token, parent, OP_NONE, - 0, attrs, 0, 0, ownerCanAddInternalSystemWindow); + 0, attrs, VISIBLE, 0, ownerCanAddInternalSystemWindow); // TODO: Probably better to make this call in the WindowState ctor to avoid errors with // adding it to the token... token.addWindow(w); diff --git a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java index 1b28db72b9b3..e55e073cf063 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java +++ b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java @@ -20,6 +20,7 @@ import android.app.usage.TimeSparseArray; import android.app.usage.UsageStats; import android.app.usage.UsageStatsManager; import android.os.Build; +import android.os.SystemProperties; import android.util.AtomicFile; import android.util.Slog; import android.util.TimeUtils; @@ -56,6 +57,9 @@ class UsageStatsDatabase { private static final boolean DEBUG = UsageStatsService.DEBUG; private static final String BAK_SUFFIX = ".bak"; private static final String CHECKED_IN_SUFFIX = UsageStatsXml.CHECKED_IN_SUFFIX; + private static final String RETENTION_LEN_KEY = "ro.usagestats.chooser.retention"; + private static final int SELECTION_LOG_RETENTION_LEN = + SystemProperties.getInt(RETENTION_LEN_KEY, 14); private final Object mLock = new Object(); private final File[] mIntervalDirs; @@ -504,7 +508,7 @@ class UsageStatsDatabase { mCal.getTimeInMillis()); mCal.setTimeInMillis(currentTimeMillis); - mCal.addDays(-14); + mCal.addDays(-SELECTION_LOG_RETENTION_LEN); for (int i = 0; i < mIntervalDirs.length; ++i) { pruneChooserCountsOlderThan(mIntervalDirs[i], mCal.getTimeInMillis()); } diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java index f1cf4414de9e..0878e8ba369c 100644 --- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java @@ -554,7 +554,7 @@ public class UsbDeviceManager { boolean usbDataUnlocked) { if (DEBUG) { Slog.d(TAG, "setEnabledFunctions functions=" + functions + ", " - + "forceRestart=" + forceRestart); + + "forceRestart=" + forceRestart + ", usbDataUnlocked=" + usbDataUnlocked); } if (usbDataUnlocked != mUsbDataUnlocked) { @@ -641,8 +641,11 @@ public class UsbDeviceManager { // Set the new USB configuration. setUsbConfig(oemFunctions); - // Start up dependent services. - updateUsbStateBroadcastIfNeeded(true); + if (UsbManager.containsFunction(functions, UsbManager.USB_FUNCTION_MTP) + || UsbManager.containsFunction(functions, UsbManager.USB_FUNCTION_PTP)) { + // Start up dependent services. + updateUsbStateBroadcastIfNeeded(true); + } if (!waitForState(oemFunctions)) { Slog.e(TAG, "Failed to switch USB config to " + functions); @@ -878,7 +881,12 @@ public class UsbDeviceManager { setEnabledFunctions(functions, false, msg.arg1 == 1); break; case MSG_UPDATE_USER_RESTRICTIONS: - setEnabledFunctions(mCurrentFunctions, false, mUsbDataUnlocked); + // Restart the USB stack if USB transfer is enabled but no longer allowed. + final boolean forceRestart = mUsbDataUnlocked + && isUsbDataTransferActive() + && !isUsbTransferAllowed(); + setEnabledFunctions( + mCurrentFunctions, forceRestart, mUsbDataUnlocked && !forceRestart); break; case MSG_SYSTEM_READY: updateUsbNotification(); @@ -902,12 +910,10 @@ public class UsbDeviceManager { case MSG_USER_SWITCHED: { if (mCurrentUser != msg.arg1) { // Restart the USB stack and re-apply user restrictions for MTP or PTP. - final boolean active = UsbManager.containsFunction(mCurrentFunctions, - UsbManager.USB_FUNCTION_MTP) - || UsbManager.containsFunction(mCurrentFunctions, - UsbManager.USB_FUNCTION_PTP); - if (mUsbDataUnlocked && active && mCurrentUser != UserHandle.USER_NULL) { - Slog.v(TAG, "Current user switched to " + mCurrentUser + if (mUsbDataUnlocked + && isUsbDataTransferActive() + && mCurrentUser != UserHandle.USER_NULL) { + Slog.v(TAG, "Current user switched to " + msg.arg1 + "; resetting USB host stack for MTP or PTP"); // avoid leaking sensitive data from previous user setEnabledFunctions(mCurrentFunctions, true, false); @@ -928,6 +934,11 @@ public class UsbDeviceManager { } } + private boolean isUsbDataTransferActive() { + return UsbManager.containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_MTP) + || UsbManager.containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_PTP); + } + public UsbAccessory getCurrentAccessory() { return mCurrentAccessory; } diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java index c79090203c0b..92233b1fed39 100644 --- a/telecomm/java/android/telecom/Call.java +++ b/telecomm/java/android/telecom/Call.java @@ -125,8 +125,9 @@ public final class Call { public static final String AVAILABLE_PHONE_ACCOUNTS = "selectPhoneAccountAccounts"; /** - * Extra key used to indicate the time (in millis) when the last outgoing emergency call was - * made. This is used to identify potential emergency callbacks. + * Extra key used to indicate the time (in milliseconds since midnight, January 1, 1970 UTC) + * when the last outgoing emergency call was made. This is used to identify potential emergency + * callbacks. */ public static final String EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS = "android.telecom.extra.LAST_EMERGENCY_CALLBACK_TIME_MILLIS"; diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 7a226a04d7eb..2b4bce31bbda 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -771,6 +771,13 @@ public class CarrierConfigManager { public static final String KEY_EDITABLE_ENHANCED_4G_LTE_BOOL = "editable_enhanced_4g_lte_bool"; /** + * Determines whether the Enhanced 4G LTE toggle will be shown in the settings. When this + * option is {@code true}, the toggle will be hidden regardless of whether the device and + * carrier supports 4G LTE or not. + */ + public static final String KEY_HIDE_ENHANCED_4G_LTE_BOOL = "hide_enhanced_4g_lte_bool"; + + /** * Determine whether IMS apn can be shown. */ public static final String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool"; @@ -1522,6 +1529,7 @@ public class CarrierConfigManager { sDefaults.putInt(KEY_IMS_CONFERENCE_SIZE_LIMIT_INT, 5); sDefaults.putBoolean(KEY_DISPLAY_HD_AUDIO_PROPERTY_BOOL, true); sDefaults.putBoolean(KEY_EDITABLE_ENHANCED_4G_LTE_BOOL, true); + sDefaults.putBoolean(KEY_HIDE_ENHANCED_4G_LTE_BOOL, false); sDefaults.putBoolean(KEY_HIDE_IMS_APN_BOOL, false); sDefaults.putBoolean(KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL, false); sDefaults.putBoolean(KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL, false); diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index 85904823a731..7d4d90bb75ab 100644 --- a/telephony/java/android/telephony/SmsManager.java +++ b/telephony/java/android/telephony/SmsManager.java @@ -387,8 +387,8 @@ public final class SmsManager { /** * Inject an SMS PDU into the android application framework. * - * The caller should have carrier privileges. - * @see android.telephony.TelephonyManager#hasCarrierPrivileges + * <p>Requires permission: {@link android.Manifest.permission#MODIFY_PHONE_STATE} or carrier + * privileges. @see android.telephony.TelephonyManager#hasCarrierPrivileges * * @param pdu is the byte array of pdu to be injected into android application framework * @param format is the format of SMS pdu (3gpp or 3gpp2) diff --git a/telephony/java/com/android/ims/ImsException.java b/telephony/java/com/android/ims/ImsException.java index 74b20f472641..0e8bad79c59b 100644 --- a/telephony/java/com/android/ims/ImsException.java +++ b/telephony/java/com/android/ims/ImsException.java @@ -32,7 +32,7 @@ public class ImsException extends Exception { } public ImsException(String message, int code) { - super(message + ", code = " + code); + super(message + "(" + code + ")"); mCode = code; } diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java index bcaac6e77bdd..73ee25ad5bcf 100644 --- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java +++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java @@ -261,7 +261,7 @@ public class TelephonyIntents { * by the system. */ public static final String ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS - = "android.intent.action.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS"; + = "com.android.internal.intent.action.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS"; /** * <p>Broadcast Action: Indicates that the action is forbidden by network. diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java index da1d9984eea5..dca74ffdcc8c 100644 --- a/test-runner/src/android/test/mock/MockContext.java +++ b/test-runner/src/android/test/mock/MockContext.java @@ -526,6 +526,12 @@ public class MockContext extends Context { } @Override + public ComponentName startForegroundService(Intent service) { + throw new UnsupportedOperationException(); + } + + /** STOPSHIP remove when trial API is turned down */ + @Override public ComponentName startServiceInForeground(Intent service, int id, Notification notification) { throw new UnsupportedOperationException(); @@ -544,6 +550,12 @@ public class MockContext extends Context { /** @hide */ @Override + public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) { + throw new UnsupportedOperationException(); + } + + /** @hide STOPSHIP removed when trial API is turned down */ + @Override public ComponentName startServiceInForegroundAsUser(Intent service, int id, Notification notification, UserHandle user) { throw new UnsupportedOperationException(); diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java index 506f406c333f..960a2d9fd726 100644 --- a/test-runner/src/android/test/mock/MockPackageManager.java +++ b/test-runner/src/android/test/mock/MockPackageManager.java @@ -1118,4 +1118,12 @@ public class MockPackageManager extends PackageManager { public int getInstallReason(String packageName, UserHandle user) { throw new UnsupportedOperationException(); } + + /** + * @hide + */ + @Override + public ComponentName getInstantAppResolverSettingsComponent() { + throw new UnsupportedOperationException(); + } } diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 04443a53527c..f22ad1d2e795 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -23,7 +23,12 @@ import static android.net.ConnectivityManager.TYPE_WIFI; import static android.net.ConnectivityManager.getNetworkTypeName; import static android.net.NetworkCapabilities.*; +import static org.mockito.Mockito.anyBoolean; +import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; import android.app.NotificationManager; import android.app.PendingIntent; @@ -33,6 +38,7 @@ import android.content.Context; import android.content.ContextWrapper; import android.content.Intent; import android.content.IntentFilter; +import android.content.res.Resources; import android.net.ConnectivityManager; import android.net.ConnectivityManager.NetworkCallback; import android.net.ConnectivityManager.PacketKeepalive; @@ -76,11 +82,16 @@ import android.util.LogPrinter; import com.android.internal.util.WakeupMessage; import com.android.internal.util.test.BroadcastInterceptingContext; import com.android.internal.util.test.FakeSettingsProvider; +import com.android.server.connectivity.MockableSystemProperties; import com.android.server.connectivity.NetworkAgentInfo; import com.android.server.connectivity.NetworkMonitor; import com.android.server.connectivity.NetworkMonitor.CaptivePortalProbeResult; import com.android.server.net.NetworkPinner; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.Spy; + import java.net.InetAddress; import java.util.ArrayList; import java.util.Arrays; @@ -133,8 +144,19 @@ public class ConnectivityServiceTest extends AndroidTestCase { private class MockContext extends BroadcastInterceptingContext { private final MockContentResolver mContentResolver; + @Spy private Resources mResources; + MockContext(Context base) { super(base); + + mResources = spy(base.getResources()); + when(mResources.getStringArray(com.android.internal.R.array.networkAttributes)). + thenReturn(new String[] { + "wifi,1,1,1,-1,true", + "mobile,0,0,0,-1,true", + "mobile_mms,2,0,2,60000,true", + }); + mContentResolver = new MockContentResolver(); mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); } @@ -150,6 +172,11 @@ public class ConnectivityServiceTest extends AndroidTestCase { public ContentResolver getContentResolver() { return mContentResolver; } + + @Override + public Resources getResources() { + return mResources; + } } /** @@ -620,6 +647,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { private class WrappedConnectivityService extends ConnectivityService { public WrappedMultinetworkPolicyTracker wrappedMultinetworkPolicyTracker; private WrappedNetworkMonitor mLastCreatedNetworkMonitor; + private MockableSystemProperties mSystemProperties; public WrappedConnectivityService(Context context, INetworkManagementService netManager, INetworkStatsService statsService, INetworkPolicyManager policyManager, @@ -629,9 +657,13 @@ public class ConnectivityServiceTest extends AndroidTestCase { } @Override - protected int getDefaultTcpRwnd() { - // Prevent wrapped ConnectivityService from trying to write to SystemProperties. - return 0; + protected MockableSystemProperties getSystemProperties() { + // Minimal approach to overriding system properties: let most calls fall through to real + // device values, and only override ones values that are important to this test. + mSystemProperties = spy(new MockableSystemProperties()); + when(mSystemProperties.getInt("net.tcp.default_init_rwnd", 0)).thenReturn(0); + when(mSystemProperties.getBoolean("ro.radio.noril", false)).thenReturn(false); + return mSystemProperties; } @Override @@ -801,6 +833,14 @@ public class ConnectivityServiceTest extends AndroidTestCase { return cv; } + public void testNetworkTypes() { + // Ensure that our mocks for the networkAttributes config variable work as expected. If they + // don't, then tests that depend on CONNECTIVITY_ACTION broadcasts for these network types + // will fail. Failing here is much easier to debug. + assertTrue(mCm.isNetworkSupported(TYPE_WIFI)); + assertTrue(mCm.isNetworkSupported(TYPE_MOBILE)); + } + @SmallTest public void testLingering() throws Exception { verifyNoNetwork(); diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java index b51b2771db16..efe6fec6fc7d 100644 --- a/tests/net/java/com/android/server/connectivity/VpnTest.java +++ b/tests/net/java/com/android/server/connectivity/VpnTest.java @@ -27,10 +27,12 @@ import android.annotation.UserIdInt; import android.app.AppOpsManager; import android.app.NotificationManager; import android.content.Context; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.net.NetworkInfo.DetailedState; import android.net.UidRange; +import android.os.Build; import android.os.INetworkManagementService; import android.os.Looper; import android.os.UserHandle; @@ -45,6 +47,7 @@ import java.util.Arrays; import java.util.Map; import java.util.Set; +import org.mockito.Answers; import org.mockito.ArgumentCaptor; import org.mockito.InOrder; import org.mockito.Mock; @@ -87,12 +90,13 @@ public class VpnTest extends AndroidTestCase { } } - @Mock private Context mContext; + @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext; @Mock private UserManager mUserManager; @Mock private PackageManager mPackageManager; @Mock private INetworkManagementService mNetService; @Mock private AppOpsManager mAppOps; @Mock private NotificationManager mNotificationManager; + @Mock private Vpn.SystemServices mSystemServices; @Override public void setUp() throws Exception { @@ -104,6 +108,12 @@ public class VpnTest extends AndroidTestCase { when(mContext.getSystemService(eq(Context.APP_OPS_SERVICE))).thenReturn(mAppOps); when(mContext.getSystemService(eq(Context.NOTIFICATION_SERVICE))) .thenReturn(mNotificationManager); + + // Used by {@link Notification.Builder} + ApplicationInfo applicationInfo = new ApplicationInfo(); + applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT; + when(mContext.getApplicationInfo()).thenReturn(applicationInfo); + doNothing().when(mNetService).registerObserver(any()); } @@ -111,7 +121,7 @@ public class VpnTest extends AndroidTestCase { public void testRestrictedProfilesAreAddedToVpn() { setMockedUsers(primaryUser, secondaryUser, restrictedProfileA, restrictedProfileB); - final Vpn vpn = spyVpn(primaryUser.id); + final Vpn vpn = createVpn(primaryUser.id); final Set<UidRange> ranges = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id, null, null); @@ -125,7 +135,7 @@ public class VpnTest extends AndroidTestCase { public void testManagedProfilesAreNotAddedToVpn() { setMockedUsers(primaryUser, managedProfileA); - final Vpn vpn = spyVpn(primaryUser.id); + final Vpn vpn = createVpn(primaryUser.id); final Set<UidRange> ranges = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id, null, null); @@ -138,7 +148,7 @@ public class VpnTest extends AndroidTestCase { public void testAddUserToVpnOnlyAddsOneUser() { setMockedUsers(primaryUser, restrictedProfileA, managedProfileA); - final Vpn vpn = spyVpn(primaryUser.id); + final Vpn vpn = createVpn(primaryUser.id); final Set<UidRange> ranges = new ArraySet<>(); vpn.addUserToRanges(ranges, primaryUser.id, null, null); @@ -149,7 +159,7 @@ public class VpnTest extends AndroidTestCase { @SmallTest public void testUidWhiteAndBlacklist() throws Exception { - final Vpn vpn = spyVpn(primaryUser.id); + final Vpn vpn = createVpn(primaryUser.id); final UidRange user = UidRange.createForUser(primaryUser.id); final String[] packages = {PKGS[0], PKGS[1], PKGS[2]}; @@ -174,7 +184,7 @@ public class VpnTest extends AndroidTestCase { @SmallTest public void testLockdownChangingPackage() throws Exception { - final Vpn vpn = spyVpn(primaryUser.id); + final Vpn vpn = createVpn(primaryUser.id); final UidRange user = UidRange.createForUser(primaryUser.id); // Default state. @@ -209,7 +219,7 @@ public class VpnTest extends AndroidTestCase { @SmallTest public void testLockdownAddingAProfile() throws Exception { - final Vpn vpn = spyVpn(primaryUser.id); + final Vpn vpn = createVpn(primaryUser.id); setMockedUsers(primaryUser); // Make a copy of the restricted profile, as we're going to mark it deleted halfway through. @@ -249,40 +259,41 @@ public class VpnTest extends AndroidTestCase { @SmallTest public void testNotificationShownForAlwaysOnApp() { - final Vpn vpn = spyVpn(primaryUser.id); - final InOrder order = inOrder(vpn); + final UserHandle userHandle = UserHandle.of(primaryUser.id); + final Vpn vpn = createVpn(primaryUser.id); setMockedUsers(primaryUser); + final InOrder order = inOrder(mNotificationManager); + // Don't show a notification for regular disconnected states. vpn.updateState(DetailedState.DISCONNECTED, TAG); - order.verify(vpn).updateAlwaysOnNotificationInternal(false); + order.verify(mNotificationManager, atLeastOnce()) + .cancelAsUser(anyString(), anyInt(), eq(userHandle)); // Start showing a notification for disconnected once always-on. vpn.setAlwaysOnPackage(PKGS[0], false); - order.verify(vpn).updateAlwaysOnNotificationInternal(true); + order.verify(mNotificationManager) + .notifyAsUser(anyString(), anyInt(), any(), eq(userHandle)); // Stop showing the notification once connected. vpn.updateState(DetailedState.CONNECTED, TAG); - order.verify(vpn).updateAlwaysOnNotificationInternal(false); + order.verify(mNotificationManager).cancelAsUser(anyString(), anyInt(), eq(userHandle)); // Show the notification if we disconnect again. vpn.updateState(DetailedState.DISCONNECTED, TAG); - order.verify(vpn).updateAlwaysOnNotificationInternal(true); + order.verify(mNotificationManager) + .notifyAsUser(anyString(), anyInt(), any(), eq(userHandle)); // Notification should be cleared after unsetting always-on package. vpn.setAlwaysOnPackage(null, false); - order.verify(vpn).updateAlwaysOnNotificationInternal(false); + order.verify(mNotificationManager).cancelAsUser(anyString(), anyInt(), eq(userHandle)); } /** * Mock some methods of vpn object. */ - private Vpn spyVpn(@UserIdInt int userId) { - final Vpn vpn = spy(new Vpn(Looper.myLooper(), mContext, mNetService, userId)); - - // Block calls to the NotificationManager or PendingIntent#getActivity. - doNothing().when(vpn).updateAlwaysOnNotificationInternal(anyBoolean()); - return vpn; + private Vpn createVpn(@UserIdInt int userId) { + return new Vpn(Looper.myLooper(), mContext, mNetService, userId, mSystemServices); } private static void assertBlocked(Vpn vpn, int... uids) { diff --git a/tests/testables/src/android/testing/BaseFragmentTest.java b/tests/testables/src/android/testing/BaseFragmentTest.java index 53841d597e26..b09bcde897d7 100644 --- a/tests/testables/src/android/testing/BaseFragmentTest.java +++ b/tests/testables/src/android/testing/BaseFragmentTest.java @@ -133,14 +133,7 @@ public abstract class BaseFragmentTest { public void testRecreate() { mFragments.dispatchResume(); processAllMessages(); - mFragments.dispatchPause(); - Parcelable p = mFragments.saveAllState(); - mFragments.dispatchDestroy(); - - mFragments = FragmentController.createController(new HostCallbacks()); - mFragments.attachHost(null); - mFragments.restoreAllState(p, (FragmentManagerNonConfig) null); - mFragments.dispatchResume(); + recreateFragment(); processAllMessages(); } @@ -154,6 +147,18 @@ public abstract class BaseFragmentTest { processAllMessages(); } + protected void recreateFragment() { + mFragments.dispatchPause(); + Parcelable p = mFragments.saveAllState(); + mFragments.dispatchDestroy(); + + mFragments = FragmentController.createController(new HostCallbacks()); + mFragments.attachHost(null); + mFragments.restoreAllState(p, (FragmentManagerNonConfig) null); + mFragments.dispatchResume(); + mFragment = mFragments.getFragmentManager().findFragmentById(VIEW_ID); + } + protected void attachFragmentToWindow() { ViewUtils.attachView(mView); TestableLooper.get(this).processMessages(1); diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp index 3330b1a78c1e..2bf52066b618 100644 --- a/tools/aapt/Resource.cpp +++ b/tools/aapt/Resource.cpp @@ -1403,7 +1403,8 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil String8 src = it.getFile()->getPrintableSource(); err = compileXmlFile(bundle, assets, String16(it.getBaseName()), it.getFile(), &table, xmlFlags); - if (err == NO_ERROR) { + // Only verify IDs if there was no error and the file is non-empty. + if (err == NO_ERROR && it.getFile()->hasData()) { ResXMLTree block; block.setTo(it.getFile()->getData(), it.getFile()->getSize(), true); checkForIds(src, block); @@ -1550,7 +1551,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil String8 src = it.getFile()->getPrintableSource(); err = compileXmlFile(bundle, assets, String16(it.getBaseName()), it.getFile(), &table, xmlFlags); - if (err == NO_ERROR) { + if (err == NO_ERROR && it.getFile()->hasData()) { ResXMLTree block; block.setTo(it.getFile()->getData(), it.getFile()->getSize(), true); checkForIds(src, block); @@ -1598,7 +1599,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil err = compileXmlFile(bundle, assets, workItem.resourceName, workItem.xmlRoot, workItem.file, &table, xmlCompilationFlags); - if (err == NO_ERROR) { + if (err == NO_ERROR && workItem.file->hasData()) { assets->addResource(workItem.resPath.getPathLeaf(), workItem.resPath, workItem.file, diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp index 391aa47469ef..221f3c2cd0c3 100644 --- a/tools/aapt/ResourceTable.cpp +++ b/tools/aapt/ResourceTable.cpp @@ -78,6 +78,17 @@ status_t compileXmlFile(const Bundle* bundle, ResourceTable* table, int options) { + if (table->versionForCompat(bundle, resourceName, target, root)) { + // The file was versioned, so stop processing here. + // The resource entry has already been removed and the new one added. + // Remove the assets entry. + sp<AaptDir> resDir = assets->getDirs().valueFor(String8("res")); + sp<AaptDir> dir = resDir->getDirs().valueFor(target->getGroupEntry().toDirName( + target->getResourceType())); + dir->removeFile(target->getPath().getPathLeaf()); + return NO_ERROR; + } + if ((options&XML_COMPILE_STRIP_WHITESPACE) != 0) { root->removeWhitespace(true, NULL); } else if ((options&XML_COMPILE_COMPACT_WHITESPACE) != 0) { @@ -4758,6 +4769,77 @@ static bool IsTransitionElement(const String16& name) { return false; } +bool ResourceTable::versionForCompat(const Bundle* bundle, const String16& resourceName, + const sp<AaptFile>& target, const sp<XMLNode>& root) { + XMLNode* node = root.get(); + while (node->getType() != XMLNode::TYPE_ELEMENT) { + // We're assuming the root element is what we're looking for, which can only be under a + // bunch of namespace declarations. + if (node->getChildren().size() != 1) { + // Not sure what to do, bail. + return false; + } + node = node->getChildren().itemAt(0).get(); + } + + if (node->getElementNamespace().size() != 0) { + // Not something we care about. + return false; + } + + int versionedSdk = 0; + if (node->getElementName() == String16("adaptive-icon")) { + versionedSdk = SDK_O; + } + + const int minSdkVersion = getMinSdkVersion(bundle); + const ConfigDescription config(target->getGroupEntry().toParams()); + if (versionedSdk <= minSdkVersion || versionedSdk <= config.sdkVersion) { + return false; + } + + sp<ConfigList> cl = getConfigList(String16(mAssets->getPackage()), + String16(target->getResourceType()), resourceName); + if (!shouldGenerateVersionedResource(cl, config, versionedSdk)) { + return false; + } + + // Remove the original entry. + cl->removeEntry(config); + + // We need to wholesale version this file. + ConfigDescription newConfig(config); + newConfig.sdkVersion = versionedSdk; + sp<AaptFile> newFile = new AaptFile(target->getSourceFile(), + AaptGroupEntry(newConfig), target->getResourceType()); + String8 resPath = String8::format("res/%s/%s.xml", + newFile->getGroupEntry().toDirName(target->getResourceType()).string(), + String8(resourceName).string()); + resPath.convertToResPath(); + + // Add a resource table entry. + addEntry(SourcePos(), + String16(mAssets->getPackage()), + String16(target->getResourceType()), + resourceName, + String16(resPath), + NULL, + &newConfig); + + // Schedule this to be compiled. + CompileResourceWorkItem item; + item.resourceName = resourceName; + item.resPath = resPath; + item.file = newFile; + item.xmlRoot = root->clone(); + item.needsCompiling = false; // This step occurs after we parse/assign, so we don't need + // to do it again. + mWorkQueue.push(item); + + // Now mark the old entry as deleted. + return true; +} + status_t ResourceTable::modifyForCompat(const Bundle* bundle, const String16& resourceName, const sp<AaptFile>& target, diff --git a/tools/aapt/ResourceTable.h b/tools/aapt/ResourceTable.h index cf1e992ec330..aff22d4d1364 100644 --- a/tools/aapt/ResourceTable.h +++ b/tools/aapt/ResourceTable.h @@ -203,6 +203,9 @@ public: size_t numLocalResources() const; bool hasResources() const; + bool versionForCompat(const Bundle* bundle, const String16& resourceName, + const sp<AaptFile>& file, const sp<XMLNode>& root); + status_t modifyForCompat(const Bundle* bundle); status_t modifyForCompat(const Bundle* bundle, const String16& resourceName, @@ -431,6 +434,10 @@ public: mEntries.add(config, entry); } + void removeEntry(const ResTable_config& config) { + mEntries.removeItem(config); + } + const DefaultKeyedVector<ConfigDescription, sp<Entry> >& getEntries() const { return mEntries; } private: const String16 mName; diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp index 5e9b81a29af9..36c1de6a4f26 100644 --- a/tools/aapt2/Main.cpp +++ b/tools/aapt2/Main.cpp @@ -25,7 +25,7 @@ namespace aapt { static const char* sMajorVersion = "2"; // Update minor version whenever a feature or flag is added. -static const char* sMinorVersion = "11"; +static const char* sMinorVersion = "12"; int PrintVersion() { std::cerr << "Android Asset Packaging Tool (aapt) " << sMajorVersion << "." diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp index 6e4b450b65e5..1947628e9267 100644 --- a/tools/aapt2/ResourceTable.cpp +++ b/tools/aapt2/ResourceTable.cpp @@ -32,22 +32,19 @@ using android::StringPiece; namespace aapt { -static bool less_than_type(const std::unique_ptr<ResourceTableType>& lhs, - ResourceType rhs) { +static bool less_than_type(const std::unique_ptr<ResourceTableType>& lhs, ResourceType rhs) { return lhs->type < rhs; } template <typename T> -static bool less_than_struct_with_name(const std::unique_ptr<T>& lhs, - const StringPiece& rhs) { +static bool less_than_struct_with_name(const std::unique_ptr<T>& lhs, const StringPiece& rhs) { return lhs->name.compare(0, lhs->name.size(), rhs.data(), rhs.size()) < 0; } ResourceTablePackage* ResourceTable::FindPackage(const StringPiece& name) { const auto last = packages.end(); - auto iter = - std::lower_bound(packages.begin(), last, name, - less_than_struct_with_name<ResourceTablePackage>); + auto iter = std::lower_bound(packages.begin(), last, name, + less_than_struct_with_name<ResourceTablePackage>); if (iter != last && name == (*iter)->name) { return iter->get(); } @@ -63,8 +60,7 @@ ResourceTablePackage* ResourceTable::FindPackageById(uint8_t id) { return nullptr; } -ResourceTablePackage* ResourceTable::CreatePackage(const StringPiece& name, - Maybe<uint8_t> id) { +ResourceTablePackage* ResourceTable::CreatePackage(const StringPiece& name, Maybe<uint8_t> id) { ResourceTablePackage* package = FindOrCreatePackage(name); if (id && !package->id) { package->id = id; @@ -77,18 +73,15 @@ ResourceTablePackage* ResourceTable::CreatePackage(const StringPiece& name, return package; } -ResourceTablePackage* ResourceTable::FindOrCreatePackage( - const StringPiece& name) { +ResourceTablePackage* ResourceTable::FindOrCreatePackage(const StringPiece& name) { const auto last = packages.end(); - auto iter = - std::lower_bound(packages.begin(), last, name, - less_than_struct_with_name<ResourceTablePackage>); + auto iter = std::lower_bound(packages.begin(), last, name, + less_than_struct_with_name<ResourceTablePackage>); if (iter != last && name == (*iter)->name) { return iter->get(); } - std::unique_ptr<ResourceTablePackage> new_package = - util::make_unique<ResourceTablePackage>(); + std::unique_ptr<ResourceTablePackage> new_package = util::make_unique<ResourceTablePackage>(); new_package->name = name.to_string(); return packages.emplace(iter, std::move(new_package))->get(); } @@ -113,8 +106,8 @@ ResourceTableType* ResourceTablePackage::FindOrCreateType(ResourceType type) { ResourceEntry* ResourceTableType::FindEntry(const StringPiece& name) { const auto last = entries.end(); - auto iter = std::lower_bound(entries.begin(), last, name, - less_than_struct_with_name<ResourceEntry>); + auto iter = + std::lower_bound(entries.begin(), last, name, less_than_struct_with_name<ResourceEntry>); if (iter != last && name == (*iter)->name) { return iter->get(); } @@ -123,8 +116,8 @@ ResourceEntry* ResourceTableType::FindEntry(const StringPiece& name) { ResourceEntry* ResourceTableType::FindOrCreateEntry(const StringPiece& name) { auto last = entries.end(); - auto iter = std::lower_bound(entries.begin(), last, name, - less_than_struct_with_name<ResourceEntry>); + auto iter = + std::lower_bound(entries.begin(), last, name, less_than_struct_with_name<ResourceEntry>); if (iter != last && name == (*iter)->name) { return iter->get(); } @@ -140,8 +133,7 @@ struct ConfigKey { const StringPiece& product; }; -bool ltConfigKeyRef(const std::unique_ptr<ResourceConfigValue>& lhs, - const ConfigKey& rhs) { +bool ltConfigKeyRef(const std::unique_ptr<ResourceConfigValue>& lhs, const ConfigKey& rhs) { int cmp = lhs->config.compare(*rhs.config); if (cmp == 0) { cmp = StringPiece(lhs->product).compare(rhs.product); @@ -151,8 +143,8 @@ bool ltConfigKeyRef(const std::unique_ptr<ResourceConfigValue>& lhs, ResourceConfigValue* ResourceEntry::FindValue(const ConfigDescription& config, const StringPiece& product) { - auto iter = std::lower_bound(values.begin(), values.end(), - ConfigKey{&config, product}, ltConfigKeyRef); + auto iter = + std::lower_bound(values.begin(), values.end(), ConfigKey{&config, product}, ltConfigKeyRef); if (iter != values.end()) { ResourceConfigValue* value = iter->get(); if (value->config == config && StringPiece(value->product) == product) { @@ -162,10 +154,10 @@ ResourceConfigValue* ResourceEntry::FindValue(const ConfigDescription& config, return nullptr; } -ResourceConfigValue* ResourceEntry::FindOrCreateValue( - const ConfigDescription& config, const StringPiece& product) { - auto iter = std::lower_bound(values.begin(), values.end(), - ConfigKey{&config, product}, ltConfigKeyRef); +ResourceConfigValue* ResourceEntry::FindOrCreateValue(const ConfigDescription& config, + const StringPiece& product) { + auto iter = + std::lower_bound(values.begin(), values.end(), ConfigKey{&config, product}, ltConfigKeyRef); if (iter != values.end()) { ResourceConfigValue* value = iter->get(); if (value->config == config && StringPiece(value->product) == product) { @@ -173,14 +165,11 @@ ResourceConfigValue* ResourceEntry::FindOrCreateValue( } } ResourceConfigValue* newValue = - values - .insert(iter, util::make_unique<ResourceConfigValue>(config, product)) - ->get(); + values.insert(iter, util::make_unique<ResourceConfigValue>(config, product))->get(); return newValue; } -std::vector<ResourceConfigValue*> ResourceEntry::findAllValues( - const ConfigDescription& config) { +std::vector<ResourceConfigValue*> ResourceEntry::FindAllValues(const ConfigDescription& config) { std::vector<ResourceConfigValue*> results; auto iter = values.begin(); @@ -237,8 +226,8 @@ std::vector<ResourceConfigValue*> ResourceEntry::FindValuesIf( * format for there to be * no error. */ -ResourceTable::CollisionResult ResourceTable::ResolveValueCollision( - Value* existing, Value* incoming) { +ResourceTable::CollisionResult ResourceTable::ResolveValueCollision(Value* existing, + Value* incoming) { Attribute* existing_attr = ValueCast<Attribute>(existing); Attribute* incoming_attr = ValueCast<Attribute>(incoming); if (!incoming_attr) { @@ -278,18 +267,15 @@ ResourceTable::CollisionResult ResourceTable::ResolveValueCollision( // The two attributes are both DECLs, but they are plain attributes // with the same formats. // Keep the strongest one. - return existing_attr->IsWeak() ? CollisionResult::kTakeNew - : CollisionResult::kKeepOriginal; + return existing_attr->IsWeak() ? CollisionResult::kTakeNew : CollisionResult::kKeepOriginal; } - if (existing_attr->IsWeak() && - existing_attr->type_mask == android::ResTable_map::TYPE_ANY) { + if (existing_attr->IsWeak() && existing_attr->type_mask == android::ResTable_map::TYPE_ANY) { // Any incoming attribute is better than this. return CollisionResult::kTakeNew; } - if (incoming_attr->IsWeak() && - incoming_attr->type_mask == android::ResTable_map::TYPE_ANY) { + if (incoming_attr->IsWeak() && incoming_attr->type_mask == android::ResTable_map::TYPE_ANY) { // The incoming attribute may be a USE instead of a DECL. // Keep the existing attribute. return CollisionResult::kKeepOriginal; @@ -298,15 +284,26 @@ ResourceTable::CollisionResult ResourceTable::ResolveValueCollision( } static constexpr const char* kValidNameChars = "._-"; -static constexpr const char* kValidNameMangledChars = "._-$"; + +static StringPiece ValidateName(const StringPiece& name) { + auto iter = util::FindNonAlphaNumericAndNotInSet(name, kValidNameChars); + if (iter != name.end()) { + return StringPiece(iter, 1); + } + return {}; +} + +static StringPiece SkipValidateName(const StringPiece& /*name*/) { + return {}; +} bool ResourceTable::AddResource(const ResourceNameRef& name, const ConfigDescription& config, const StringPiece& product, std::unique_ptr<Value> value, IDiagnostics* diag) { - return AddResourceImpl(name, {}, config, product, std::move(value), - kValidNameChars, ResolveValueCollision, diag); + return AddResourceImpl(name, {}, config, product, std::move(value), ValidateName, + ResolveValueCollision, diag); } bool ResourceTable::AddResource(const ResourceNameRef& name, @@ -315,8 +312,8 @@ bool ResourceTable::AddResource(const ResourceNameRef& name, const StringPiece& product, std::unique_ptr<Value> value, IDiagnostics* diag) { - return AddResourceImpl(name, res_id, config, product, std::move(value), - kValidNameChars, ResolveValueCollision, diag); + return AddResourceImpl(name, res_id, config, product, std::move(value), ValidateName, + ResolveValueCollision, diag); } bool ResourceTable::AddFileReference(const ResourceNameRef& name, @@ -324,29 +321,26 @@ bool ResourceTable::AddFileReference(const ResourceNameRef& name, const Source& source, const StringPiece& path, IDiagnostics* diag) { - return AddFileReferenceImpl(name, config, source, path, nullptr, - kValidNameChars, diag); + return AddFileReferenceImpl(name, config, source, path, nullptr, ValidateName, diag); } bool ResourceTable::AddFileReferenceAllowMangled( const ResourceNameRef& name, const ConfigDescription& config, const Source& source, const StringPiece& path, io::IFile* file, IDiagnostics* diag) { - return AddFileReferenceImpl(name, config, source, path, file, - kValidNameMangledChars, diag); + return AddFileReferenceImpl(name, config, source, path, file, SkipValidateName, diag); } -bool ResourceTable::AddFileReferenceImpl( - const ResourceNameRef& name, const ConfigDescription& config, - const Source& source, const StringPiece& path, io::IFile* file, - const char* valid_chars, IDiagnostics* diag) { +bool ResourceTable::AddFileReferenceImpl(const ResourceNameRef& name, + const ConfigDescription& config, const Source& source, + const StringPiece& path, io::IFile* file, + NameValidator name_validator, IDiagnostics* diag) { std::unique_ptr<FileReference> fileRef = util::make_unique<FileReference>(string_pool.MakeRef(path)); fileRef->SetSource(source); fileRef->file = file; - return AddResourceImpl(name, ResourceId{}, config, StringPiece{}, - std::move(fileRef), valid_chars, ResolveValueCollision, - diag); + return AddResourceImpl(name, ResourceId{}, config, StringPiece{}, std::move(fileRef), + name_validator, ResolveValueCollision, diag); } bool ResourceTable::AddResourceAllowMangled(const ResourceNameRef& name, @@ -354,8 +348,8 @@ bool ResourceTable::AddResourceAllowMangled(const ResourceNameRef& name, const StringPiece& product, std::unique_ptr<Value> value, IDiagnostics* diag) { - return AddResourceImpl(name, ResourceId{}, config, product, std::move(value), - kValidNameMangledChars, ResolveValueCollision, diag); + return AddResourceImpl(name, ResourceId{}, config, product, std::move(value), SkipValidateName, + ResolveValueCollision, diag); } bool ResourceTable::AddResourceAllowMangled(const ResourceNameRef& name, @@ -364,25 +358,24 @@ bool ResourceTable::AddResourceAllowMangled(const ResourceNameRef& name, const StringPiece& product, std::unique_ptr<Value> value, IDiagnostics* diag) { - return AddResourceImpl(name, id, config, product, std::move(value), - kValidNameMangledChars, ResolveValueCollision, diag); + return AddResourceImpl(name, id, config, product, std::move(value), SkipValidateName, + ResolveValueCollision, diag); } -bool ResourceTable::AddResourceImpl( - const ResourceNameRef& name, const ResourceId& res_id, - const ConfigDescription& config, const StringPiece& product, - std::unique_ptr<Value> value, const char* valid_chars, - const CollisionResolverFunc& conflictResolver, IDiagnostics* diag) { +bool ResourceTable::AddResourceImpl(const ResourceNameRef& name, const ResourceId& res_id, + const ConfigDescription& config, const StringPiece& product, + std::unique_ptr<Value> value, NameValidator name_validator, + const CollisionResolverFunc& conflictResolver, + IDiagnostics* diag) { CHECK(value != nullptr); CHECK(diag != nullptr); - auto bad_char_iter = - util::FindNonAlphaNumericAndNotInSet(name.entry, valid_chars); - if (bad_char_iter != name.entry.end()) { - diag->Error(DiagMessage(value->GetSource()) - << "resource '" << name << "' has invalid entry name '" - << name.entry << "'. Invalid character '" - << StringPiece(bad_char_iter, 1) << "'"); + const StringPiece bad_char = name_validator(name.entry); + if (!bad_char.empty()) { + diag->Error(DiagMessage(value->GetSource()) << "resource '" << name + << "' has invalid entry name '" << name.entry + << "'. Invalid character '" << bad_char << "'"); + return false; } @@ -450,30 +443,26 @@ bool ResourceTable::AddResourceImpl( bool ResourceTable::SetSymbolState(const ResourceNameRef& name, const ResourceId& res_id, const Symbol& symbol, IDiagnostics* diag) { - return SetSymbolStateImpl(name, res_id, symbol, kValidNameChars, diag); + return SetSymbolStateImpl(name, res_id, symbol, ValidateName, diag); } bool ResourceTable::SetSymbolStateAllowMangled(const ResourceNameRef& name, const ResourceId& res_id, const Symbol& symbol, IDiagnostics* diag) { - return SetSymbolStateImpl(name, res_id, symbol, kValidNameMangledChars, diag); + return SetSymbolStateImpl(name, res_id, symbol, SkipValidateName, diag); } -bool ResourceTable::SetSymbolStateImpl(const ResourceNameRef& name, - const ResourceId& res_id, - const Symbol& symbol, - const char* valid_chars, +bool ResourceTable::SetSymbolStateImpl(const ResourceNameRef& name, const ResourceId& res_id, + const Symbol& symbol, NameValidator name_validator, IDiagnostics* diag) { CHECK(diag != nullptr); - auto bad_char_iter = - util::FindNonAlphaNumericAndNotInSet(name.entry, valid_chars); - if (bad_char_iter != name.entry.end()) { - diag->Error(DiagMessage(symbol.source) - << "resource '" << name << "' has invalid entry name '" - << name.entry << "'. Invalid character '" - << StringPiece(bad_char_iter, 1) << "'"); + const StringPiece bad_char = name_validator(name.entry); + if (!bad_char.empty()) { + diag->Error(DiagMessage(symbol.source) << "resource '" << name << "' has invalid entry name '" + << name.entry << "'. Invalid character '" << bad_char + << "'"); return false; } @@ -532,8 +521,7 @@ bool ResourceTable::SetSymbolStateImpl(const ResourceNameRef& name, return true; } -Maybe<ResourceTable::SearchResult> ResourceTable::FindResource( - const ResourceNameRef& name) { +Maybe<ResourceTable::SearchResult> ResourceTable::FindResource(const ResourceNameRef& name) { ResourceTablePackage* package = FindPackage(name.package); if (!package) { return {}; diff --git a/tools/aapt2/ResourceTable.h b/tools/aapt2/ResourceTable.h index 6b69aaf02cbe..b0321214c6cc 100644 --- a/tools/aapt2/ResourceTable.h +++ b/tools/aapt2/ResourceTable.h @@ -113,8 +113,7 @@ class ResourceEntry { const android::StringPiece& product); ResourceConfigValue* FindOrCreateValue(const ConfigDescription& config, const android::StringPiece& product); - std::vector<ResourceConfigValue*> findAllValues( - const ConfigDescription& config); + std::vector<ResourceConfigValue*> FindAllValues(const ConfigDescription& config); std::vector<ResourceConfigValue*> FindValuesIf( const std::function<bool(ResourceConfigValue*)>& f); @@ -189,8 +188,7 @@ class ResourceTable { * When a collision of resources occurs, this method decides which value to * keep. */ - static CollisionResult ResolveValueCollision(Value* existing, - Value* incoming); + static CollisionResult ResolveValueCollision(Value* existing, Value* incoming); bool AddResource(const ResourceNameRef& name, const ConfigDescription& config, const android::StringPiece& product, std::unique_ptr<Value> value, @@ -274,20 +272,24 @@ class ResourceTable { std::map<size_t, std::string> included_packages_; private: + // The function type that validates a symbol name. Returns a non-empty StringPiece representing + // the offending character (which may be more than one byte in UTF-8). Returns an empty string + // if the name was valid. + using NameValidator = android::StringPiece(const android::StringPiece&); + ResourceTablePackage* FindOrCreatePackage(const android::StringPiece& name); bool AddResourceImpl(const ResourceNameRef& name, const ResourceId& res_id, const ConfigDescription& config, const android::StringPiece& product, - std::unique_ptr<Value> value, const char* valid_chars, + std::unique_ptr<Value> value, NameValidator name_validator, const CollisionResolverFunc& conflict_resolver, IDiagnostics* diag); bool AddFileReferenceImpl(const ResourceNameRef& name, const ConfigDescription& config, const Source& source, const android::StringPiece& path, io::IFile* file, - const char* valid_chars, IDiagnostics* diag); + NameValidator name_validator, IDiagnostics* diag); bool SetSymbolStateImpl(const ResourceNameRef& name, const ResourceId& res_id, - const Symbol& symbol, const char* valid_chars, - IDiagnostics* diag); + const Symbol& symbol, NameValidator name_validator, IDiagnostics* diag); DISALLOW_COPY_AND_ASSIGN(ResourceTable); }; diff --git a/tools/aapt2/ResourceTable_test.cpp b/tools/aapt2/ResourceTable_test.cpp index cb3699a00f75..e2b37be994ff 100644 --- a/tools/aapt2/ResourceTable_test.cpp +++ b/tools/aapt2/ResourceTable_test.cpp @@ -40,6 +40,14 @@ TEST(ResourceTableTest, FailToAddResourceWithBadName) { test::GetDiagnostics())); } +TEST(ResourceTableTest, AddResourceWithWeirdNameWhenAddingMangledResources) { + ResourceTable table; + + EXPECT_TRUE(table.AddResourceAllowMangled( + test::ParseNameOrDie("android:id/heythere "), ConfigDescription{}, "", + test::ValueBuilder<Id>().SetSource("test.xml", 21u).Build(), test::GetDiagnostics())); +} + TEST(ResourceTableTest, AddOneResource) { ResourceTable table; @@ -130,7 +138,7 @@ TEST(ResourceTableTest, ProductVaryingValues) { table.FindResource(test::ParseNameOrDie("android:string/foo")); AAPT_ASSERT_TRUE(sr); std::vector<ResourceConfigValue*> values = - sr.value().entry->findAllValues(test::ParseConfigOrDie("land")); + sr.value().entry->FindAllValues(test::ParseConfigOrDie("land")); ASSERT_EQ(2u, values.size()); EXPECT_EQ(std::string("phone"), values[0]->product); EXPECT_EQ(std::string("tablet"), values[1]->product); diff --git a/tools/aapt2/readme.md b/tools/aapt2/readme.md index 9899f803b339..2e674bddce7e 100644 --- a/tools/aapt2/readme.md +++ b/tools/aapt2/readme.md @@ -1,5 +1,13 @@ # Android Asset Packaging Tool 2.0 (AAPT2) release notes +## Version 2.12 +### `aapt2 optimize ...` +- aapt2 optimize now understands map (complex) values under the type `id`. It ignores their + contents and interprets them as a sentinel `id` type. This was added to support existing + apps that build with their `id` types as map values. + AAPT and AAPT2 always generate a simple value for the type `ID`, so it is unclear how some + these apps are encoded. + ## Version 2.11 ### `aapt2 link ...` - Adds the ability to specify assets directories with the -A parameter. Assets work just like diff --git a/tools/aapt2/unflatten/BinaryResourceParser.cpp b/tools/aapt2/unflatten/BinaryResourceParser.cpp index 66bcfa034dfb..35bf618c1635 100644 --- a/tools/aapt2/unflatten/BinaryResourceParser.cpp +++ b/tools/aapt2/unflatten/BinaryResourceParser.cpp @@ -168,10 +168,11 @@ bool BinaryResourceParser::ParseTable(const ResChunk_header* chunk) { } bool BinaryResourceParser::ParsePackage(const ResChunk_header* chunk) { - const ResTable_package* package_header = ConvertTo<ResTable_package>(chunk); + constexpr size_t kMinPackageSize = + sizeof(ResTable_package) - sizeof(ResTable_package::typeIdOffset); + const ResTable_package* package_header = ConvertTo<ResTable_package, kMinPackageSize>(chunk); if (!package_header) { - context_->GetDiagnostics()->Error(DiagMessage(source_) - << "corrupt ResTable_package chunk"); + context_->GetDiagnostics()->Error(DiagMessage(source_) << "corrupt ResTable_package chunk"); return false; } @@ -498,8 +499,14 @@ std::unique_ptr<Value> BinaryResourceParser::ParseMapEntry( return ParseArray(name, config, map); case ResourceType::kPlurals: return ParsePlural(name, config, map); + case ResourceType::kId: + // Special case: An ID is not a bag, but some apps have defined the auto-generated + // IDs that come from declaring an enum value in an attribute as an empty map... + // We can ignore the value here. + return util::make_unique<Id>(); default: - LOG(FATAL) << "unknown map type"; + context_->GetDiagnostics()->Error(DiagMessage() << "illegal map type '" << ToString(name.type) + << "' (" << (int)name.type << ")"); break; } return {}; diff --git a/tools/layoutlib/.gitignore b/tools/layoutlib/.gitignore index 819103db9d99..a2b0c3364a3e 100644 --- a/tools/layoutlib/.gitignore +++ b/tools/layoutlib/.gitignore @@ -2,3 +2,4 @@ bin /.idea/workspace.xml /out /bridge/out +/.idea/kotlinc.xml
\ No newline at end of file diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java index 2c7e9363da72..cda8e6aca8df 100644 --- a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java +++ b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java @@ -740,9 +740,11 @@ public final class BridgeTypedArray extends TypedArray { } int id = getResourceId(index, 0); String resIdMessage = id > 0 ? " (resource id 0x" + Integer.toHexString(id) + ')' : ""; - throw new NotFoundException( - String.format("%1$s in %2$s%3$s is not a valid array resource.", - resVal.getValue(), mNames[index], resIdMessage)); + assert false : + String.format("%1$s in %2$s%3$s is not a valid array resource.", resVal.getValue(), + mNames[index], resIdMessage); + + return new CharSequence[0]; } @Override diff --git a/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java index e3bc34b64582..c20ee12ee30c 100644 --- a/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java +++ b/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java @@ -33,7 +33,6 @@ import com.android.layoutlib.bridge.impl.ResourceHelper; import com.android.layoutlib.bridge.util.NinePatchInputStream; import com.android.ninepatch.NinePatch; import com.android.resources.ResourceType; -import com.android.resources.ResourceUrl; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; import com.android.util.Pair; @@ -60,8 +59,6 @@ import java.io.FileNotFoundException; import java.io.InputStream; import java.util.Iterator; -import static com.android.SdkConstants.ANDROID_NS_NAME; - @SuppressWarnings("deprecation") public class Resources_Delegate { @@ -140,8 +137,8 @@ public class Resources_Delegate { if (value == null) { // Unable to resolve the attribute, just leave the unresolved value - value = new ResourceValue(ResourceUrl.create(resourceInfo.getFirst(), attributeName, - platformResFlag_out[0]), attributeName); + value = new ResourceValue(resourceInfo.getFirst(), attributeName, attributeName, + platformResFlag_out[0]); } return Pair.of(attributeName, value); } @@ -681,7 +678,7 @@ public class Resources_Delegate { String packageName; if (resourceInfo != null) { if (platformOut[0]) { - packageName = ANDROID_NS_NAME; + packageName = SdkConstants.ANDROID_NS_NAME; } else { packageName = resources.mContext.getPackageName(); packageName = packageName == null ? SdkConstants.APP_PREFIX : packageName; @@ -699,7 +696,7 @@ public class Resources_Delegate { Pair<ResourceType, String> resourceInfo = getResourceInfo(resources, resid, platformOut); if (resourceInfo != null) { if (platformOut[0]) { - return ANDROID_NS_NAME; + return SdkConstants.ANDROID_NS_NAME; } String packageName = resources.mContext.getPackageName(); return packageName == null ? SdkConstants.APP_PREFIX : packageName; diff --git a/tools/layoutlib/bridge/src/android/graphics/BlendComposite.java b/tools/layoutlib/bridge/src/android/graphics/BlendComposite.java index e4fcf1be32bd..5cc964aee722 100644 --- a/tools/layoutlib/bridge/src/android/graphics/BlendComposite.java +++ b/tools/layoutlib/bridge/src/android/graphics/BlendComposite.java @@ -88,8 +88,9 @@ public final class BlendComposite implements Composite { private void setAlpha(float alpha) { if (alpha < 0.0f || alpha > 1.0f) { - throw new IllegalArgumentException( - "alpha must be comprised between 0.0f and 1.0f"); + assert false : "alpha must be comprised between 0.0f and 1.0f"; + alpha = Math.min(alpha, 1.0f); + alpha = Math.max(alpha, 0.0f); } this.alpha = alpha; @@ -266,9 +267,21 @@ public final class BlendComposite implements Composite { return result; } }; + default: + assert false : "Blender not implement for " + composite.getMode().name(); + + // Ignore the blend + return new Blender() { + @Override + public int[] blend(int[] src, int[] dst, int[] result) { + result[0] = dst[0]; + result[1] = dst[1]; + result[2] = dst[2]; + result[3] = dst[3]; + return result; + } + }; } - throw new IllegalArgumentException("Blender not implement for " + - composite.getMode().name()); } } } diff --git a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java index 3bab4acc3635..7fe464abbf32 100644 --- a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java @@ -252,7 +252,8 @@ public class FontFamily_Delegate { /*package*/ static boolean addFont(FontFamily thisFontFamily, String path, int ttcIndex, FontConfig.Axis[] axes, int weight, int italic) { if (thisFontFamily.mBuilderPtr == 0) { - throw new IllegalStateException("Unable to call addFont after freezing."); + assert false : "Unable to call addFont after freezing."; + return false; } final FontFamily_Delegate delegate = getDelegate(thisFontFamily.mBuilderPtr); return delegate != null && delegate.addFont(path, ttcIndex, weight, italic); diff --git a/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java index 6a89d8ff9342..64410e4c6a05 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java @@ -49,21 +49,19 @@ public abstract class Gradient_Delegate extends Shader_Delegate { */ protected Gradient_Delegate(long nativeMatrix, int colors[], float positions[]) { super(nativeMatrix); - if (colors.length < 2) { - throw new IllegalArgumentException("needs >= 2 number of colors"); - } - if (positions != null && colors.length != positions.length) { - throw new IllegalArgumentException("color and position arrays must be of equal length"); - } + assert colors.length >= 2 : "needs >= 2 number of colors"; if (positions == null) { float spacing = 1.f / (colors.length - 1); positions = new float[colors.length]; positions[0] = 0.f; - positions[colors.length-1] = 1.f; - for (int i = 1; i < colors.length - 1 ; i++) { + positions[colors.length - 1] = 1.f; + for (int i = 1; i < colors.length - 1; i++) { positions[i] = spacing * i; } + } else { + assert colors.length == positions.length : + "color and position " + "arrays must be of equal length"; } mColors = colors; diff --git a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java index 579fce09d094..50b916532319 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java @@ -548,10 +548,11 @@ public final class Path_Delegate { case EVEN_ODD: case INVERSE_EVEN_ODD: return GeneralPath.WIND_EVEN_ODD; - } - assert false; - throw new IllegalArgumentException(); + default: + assert false; + return GeneralPath.WIND_NON_ZERO; + } } @NonNull diff --git a/tools/layoutlib/bridge/src/android/graphics/RoundRectangle.java b/tools/layoutlib/bridge/src/android/graphics/RoundRectangle.java index edd36e54aa77..736f03ec5a8c 100644 --- a/tools/layoutlib/bridge/src/android/graphics/RoundRectangle.java +++ b/tools/layoutlib/bridge/src/android/graphics/RoundRectangle.java @@ -61,10 +61,8 @@ public class RoundRectangle extends RectangularShape { * ellipse that corner is a quarter of. */ public RoundRectangle(float x, float y, float width, float height, float[] cornerDimensions) { - if (cornerDimensions.length != 8) { - throw new IllegalArgumentException("The array of corner dimensions must have eight " + - "elements"); - } + assert cornerDimensions.length == 8 : "The array of corner dimensions must have eight " + + "elements"; this.x = x; this.y = y; diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java index e118889b3714..80e3bada8ca3 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java @@ -233,7 +233,8 @@ public final class Typeface_Delegate { Map<String, ByteBuffer> bufferForPath) { FontFamily fontFamily = new FontFamily(family.getLanguage(), family.getVariant()); for (FontConfig.Font font : family.getFonts()) { - FontFamily_Delegate.addFont(fontFamily.mBuilderPtr, font.getFontName(), + String fullPathName = "/system/fonts/" + font.getFontName(); + FontFamily_Delegate.addFont(fontFamily.mBuilderPtr, fullPathName, font.getWeight(), font.isItalic()); } fontFamily.freeze(); diff --git a/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java index cc7631ac939a..616784c10aae 100644 --- a/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java @@ -585,8 +585,8 @@ public class VectorDrawable_Delegate { return this::setTrimPathOffset; } - throw new IllegalArgumentException("Invalid VFullPath_Delegate property index " - + propertyIdx); + assert false : ("Invalid VFullPath_Delegate property index " + propertyIdx); + return t -> {}; } @NonNull @@ -598,8 +598,8 @@ public class VectorDrawable_Delegate { return this::setFillColor; } - throw new IllegalArgumentException("Invalid VFullPath_Delegate property index " - + propertyIdx); + assert false : ("Invalid VFullPath_Delegate property index " + propertyIdx); + return t -> {}; } ///////////////////////////////////////////////////// @@ -827,8 +827,8 @@ public class VectorDrawable_Delegate { return this::setTranslateY; } - throw new IllegalArgumentException("Invalid VGroup_Delegate property index " - + propertyIdx); + assert false : ("Invalid VGroup_Delegate property index " + propertyIdx); + return t -> {}; } ///////////////////////////////////////////////////// diff --git a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java index 1b9901594f6e..cc031439226b 100644 --- a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java +++ b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java @@ -164,7 +164,9 @@ public class StaticLayout_Delegate { builder.mTabStopCalculator); break; default: - throw new AssertionError("Unknown break strategy: " + builder.mBreakStrategy); + assert false : "Unknown break strategy: " + builder.mBreakStrategy; + builder.mLineBreaker = new GreedyLineBreaker(primitives, builder.mLineWidth, + builder.mTabStopCalculator); } builder.mLineBreaker.computeBreaks(recycle); return recycle.breaks.length; diff --git a/tools/layoutlib/bridge/src/android/util/PathParser_Delegate.java b/tools/layoutlib/bridge/src/android/util/PathParser_Delegate.java index 6d3bb4ca9115..7b69388a0b1e 100644 --- a/tools/layoutlib/bridge/src/android/util/PathParser_Delegate.java +++ b/tools/layoutlib/bridge/src/android/util/PathParser_Delegate.java @@ -361,7 +361,8 @@ public class PathParser_Delegate { } return Arrays.copyOf(results, count); } catch (NumberFormatException e) { - throw new RuntimeException("error in parsing \"" + s + "\"", e); + assert false : "error in parsing \"" + s + "\"" + e; + return new float[0]; } } diff --git a/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java b/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java index 27b406a70ac7..cec6bb3844db 100644 --- a/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java +++ b/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java @@ -16,6 +16,8 @@ package android.view; +import com.android.ide.common.rendering.api.LayoutLog; +import com.android.layoutlib.bridge.Bridge; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; import org.xmlpull.v1.XmlPullParser; @@ -104,8 +106,10 @@ public class LayoutInflater_Delegate { if (layout == 0) { final String value = attrs.getAttributeValue(null, ATTR_LAYOUT); if (value == null || value.length() <= 0) { - throw new InflateException("You must specify a layout in the" - + " include tag: <include layout=\"@layout/layoutID\" />"); + Bridge.getLog().error(LayoutLog.TAG_BROKEN, "You must specify a layout in the" + + " include tag: <include layout=\"@layout/layoutID\" />", null); + LayoutInflater.consumeChildElements(parser); + return; } // Attempt to resolve the "?attr/name" string to an identifier. @@ -125,11 +129,11 @@ public class LayoutInflater_Delegate { if (layout == 0) { final String value = attrs.getAttributeValue(null, ATTR_LAYOUT); if (value == null) { - throw new InflateException("You must specifiy a layout in the" - + " include tag: <include layout=\"@layout/layoutID\" />"); + Bridge.getLog().error(LayoutLog.TAG_BROKEN, "You must specify a layout in the" + + " include tag: <include layout=\"@layout/layoutID\" />", null); } else { - throw new InflateException("You must specifiy a valid layout " - + "reference. The layout ID " + value + " is not valid."); + Bridge.getLog().error(LayoutLog.TAG_BROKEN, "You must specify a valid layout " + + "reference. The layout ID " + value + " is not valid.", null); } } else { final XmlResourceParser childParser = @@ -144,8 +148,11 @@ public class LayoutInflater_Delegate { } if (type != XmlPullParser.START_TAG) { - throw new InflateException(childParser.getPositionDescription() + - ": No start tag found!"); + Bridge.getLog().error(LayoutLog.TAG_BROKEN, + childParser.getPositionDescription() + ": No start tag found!", + null); + LayoutInflater.consumeChildElements(parser); + return; } final String childName = childParser.getName(); @@ -219,7 +226,9 @@ public class LayoutInflater_Delegate { } } } else { - throw new InflateException("<include /> can only be used inside of a ViewGroup"); + Bridge.getLog().error(LayoutLog.TAG_BROKEN, + "<include /> can only be used inside of a ViewGroup", + null); } LayoutInflater.consumeChildElements(parser); diff --git a/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java b/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java index e4b20206ef40..8ae212cd2ebf 100644 --- a/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java +++ b/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java @@ -37,7 +37,8 @@ public class RectShadowPainter { @NonNull Canvas canvas) { Rect outline = new Rect(); if (!viewOutline.getRect(outline)) { - throw new IllegalArgumentException("Outline is not a rect shadow"); + assert false : "Outline is not a rect shadow"; + return; } Rect originCanvasRect = canvas.getClipBounds(); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java index 2e149748636b..93fd005ebc05 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java @@ -52,7 +52,6 @@ import java.lang.ref.SoftReference; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.Arrays; -import java.util.Comparator; import java.util.EnumMap; import java.util.EnumSet; import java.util.HashMap; @@ -62,7 +61,6 @@ import java.util.concurrent.locks.ReentrantLock; import libcore.io.MemoryMappedFile_Delegate; import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN; -import static com.android.ide.common.rendering.api.Result.Status.SUCCESS; /** * Main entry point of the LayoutLib Bridge. @@ -90,19 +88,14 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { /** * Maps from id to resource type/name. This is for com.android.internal.R */ - private final static Map<Integer, Pair<ResourceType, String>> sRMap = - new HashMap<Integer, Pair<ResourceType, String>>(); + @SuppressWarnings("deprecation") + private final static Map<Integer, Pair<ResourceType, String>> sRMap = new HashMap<>(); /** - * Same as sRMap except for int[] instead of int resources. This is for android.R only. - */ - private final static Map<IntArray, String> sRArrayMap = new HashMap<IntArray, String>(384); - /** * Reverse map compared to sRMap, resource type -> (resource name -> id). * This is for com.android.internal.R. */ - private final static Map<ResourceType, Map<String, Integer>> sRevRMap = - new EnumMap<ResourceType, Map<String,Integer>>(ResourceType.class); + private final static Map<ResourceType, Map<String, Integer>> sRevRMap = new EnumMap<>(ResourceType.class); // framework resources are defined as 0x01XX#### where XX is the resource type (layout, // drawable, etc...). Using FF as the type allows for 255 resource types before we get a @@ -111,56 +104,19 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { private final static DynamicIdMap sDynamicIds = new DynamicIdMap(DYNAMIC_ID_SEED_START); private final static Map<Object, Map<String, SoftReference<Bitmap>>> sProjectBitmapCache = - new HashMap<Object, Map<String, SoftReference<Bitmap>>>(); + new HashMap<>(); private final static Map<Object, Map<String, SoftReference<NinePatchChunk>>> sProject9PatchCache = - new HashMap<Object, Map<String, SoftReference<NinePatchChunk>>>(); - private final static Map<String, SoftReference<Bitmap>> sFrameworkBitmapCache = - new HashMap<String, SoftReference<Bitmap>>(); + new HashMap<>(); + + private final static Map<String, SoftReference<Bitmap>> sFrameworkBitmapCache = new HashMap<>(); private final static Map<String, SoftReference<NinePatchChunk>> sFramework9PatchCache = - new HashMap<String, SoftReference<NinePatchChunk>>(); + new HashMap<>(); private static Map<String, Map<String, Integer>> sEnumValueMap; private static Map<String, String> sPlatformProperties; /** - * int[] wrapper to use as keys in maps. - */ - private final static class IntArray { - private int[] mArray; - - private IntArray() { - // do nothing - } - - private IntArray(int[] a) { - mArray = a; - } - - private void set(int[] a) { - mArray = a; - } - - @Override - public int hashCode() { - return Arrays.hashCode(mArray); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - - IntArray other = (IntArray) obj; - return Arrays.equals(mArray, other.mArray); - } - } - - /** Instance of IntArrayWrapper to be reused in {@link #resolveResourceId(int[])}. */ - private final static IntArray sIntArrayWrapper = new IntArray(); - - /** * A default log than prints to stdout/stderr. */ private final static LayoutLog sDefaultLog = new LayoutLog() { @@ -192,6 +148,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { return com.android.ide.common.rendering.api.Bridge.API_CURRENT; } + @SuppressWarnings("deprecation") @Override @Deprecated public EnumSet<Capability> getCapabilities() { @@ -272,11 +229,11 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { case STRING: case STYLE: // Slightly less than thousand entries in each. - fullMap = new HashMap<String, Integer>(1280); + fullMap = new HashMap<>(1280); // no break. default: if (fullMap == null) { - fullMap = new HashMap<String, Integer>(); + fullMap = new HashMap<>(); } sRevRMap.put(resType, fullMap); } @@ -288,13 +245,9 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { continue; } Class<?> type = f.getType(); - if (type.isArray()) { - // if the object is an int[] we put it in sRArrayMap using an IntArray - // wrapper that properly implements equals and hashcode for the array - // objects, as required by the map contract. - sRArrayMap.put(new IntArray((int[]) f.get(null)), f.getName()); - } else { + if (!type.isArray()) { Integer value = (Integer) f.get(null); + //noinspection deprecation sRMap.put(value, Pair.of(resType, f.getName())); fullMap.put(f.getName(), value); } @@ -332,32 +285,29 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { // values, we try and find them from the styleables. // There were 1500 elements in this map at M timeframe. - Map<String, Integer> revRAttrMap = new HashMap<String, Integer>(2048); + Map<String, Integer> revRAttrMap = new HashMap<>(2048); sRevRMap.put(ResourceType.ATTR, revRAttrMap); // There were 2000 elements in this map at M timeframe. - Map<String, Integer> revRStyleableMap = new HashMap<String, Integer>(3072); + Map<String, Integer> revRStyleableMap = new HashMap<>(3072); sRevRMap.put(ResourceType.STYLEABLE, revRStyleableMap); Class<?> c = com.android.internal.R.styleable.class; Field[] fields = c.getDeclaredFields(); // Sort the fields to bring all arrays to the beginning, so that indices into the array are // able to refer back to the arrays (i.e. no forward references). - Arrays.sort(fields, new Comparator<Field>() { - @Override - public int compare(Field o1, Field o2) { - if (o1 == o2) { - return 0; - } - Class<?> t1 = o1.getType(); - Class<?> t2 = o2.getType(); - if (t1.isArray() && !t2.isArray()) { - return -1; - } else if (t2.isArray() && !t1.isArray()) { - return 1; - } - return o1.getName().compareTo(o2.getName()); + Arrays.sort(fields, (o1, o2) -> { + if (o1 == o2) { + return 0; } + Class<?> t1 = o1.getType(); + Class<?> t2 = o2.getType(); + if (t1.isArray() && !t2.isArray()) { + return -1; + } else if (t2.isArray() && !t1.isArray()) { + return 1; + } + return o1.getName().compareTo(o2.getName()); }); - Map<String, int[]> styleables = new HashMap<String, int[]>(); + Map<String, int[]> styleables = new HashMap<>(); for (Field field : fields) { if (!isValidRField(field)) { // Only consider public static fields that are int or int[]. @@ -367,7 +317,6 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { String name = field.getName(); if (field.getType().isArray()) { int[] styleableValue = (int[]) field.get(null); - sRArrayMap.put(new IntArray(styleableValue), name); styleables.put(name, styleableValue); continue; } @@ -389,9 +338,11 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { if (arrayValue != null) { String attrName = name.substring(arrayName.length() + 1); int attrValue = arrayValue[index]; + //noinspection deprecation sRMap.put(attrValue, Pair.of(ResourceType.ATTR, attrName)); revRAttrMap.put(attrName, attrValue); } + //noinspection deprecation sRMap.put(index, Pair.of(ResourceType.STYLEABLE, name)); revRStyleableMap.put(name, index); } @@ -422,7 +373,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { @Override public RenderSession createSession(SessionParams params) { try { - Result lastResult = SUCCESS.createResult(); + Result lastResult; RenderSessionImpl scene = new RenderSessionImpl(params); try { prepareThread(); @@ -456,7 +407,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { @Override public Result renderDrawable(DrawableParams params) { try { - Result lastResult = SUCCESS.createResult(); + Result lastResult; RenderDrawable action = new RenderDrawable(params); try { prepareThread(); @@ -581,26 +532,16 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { * @return a Pair containing the resource type and name, or null if the id * does not match any resource. */ + @SuppressWarnings("deprecation") public static Pair<ResourceType, String> resolveResourceId(int value) { Pair<ResourceType, String> pair = sRMap.get(value); if (pair == null) { pair = sDynamicIds.resolveId(value); - if (pair == null) { - //System.out.println(String.format("Missing id: %1$08X (%1$d)", value)); - } } return pair; } /** - * Returns the name of a framework resource whose value is an int array. - */ - public static String resolveResourceId(int[] array) { - sIntArrayWrapper.set(array); - return sRArrayMap.get(sIntArrayWrapper); - } - - /** * Returns the integer id of a framework resource, from a given resource type and resource name. * <p/> * If no resource is found, it creates a dynamic id for the resource. @@ -674,16 +615,12 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { */ public static void setCachedBitmap(String value, Bitmap bmp, Object projectKey) { if (projectKey != null) { - Map<String, SoftReference<Bitmap>> map = sProjectBitmapCache.get(projectKey); - - if (map == null) { - map = new HashMap<String, SoftReference<Bitmap>>(); - sProjectBitmapCache.put(projectKey, map); - } + Map<String, SoftReference<Bitmap>> map = + sProjectBitmapCache.computeIfAbsent(projectKey, k -> new HashMap<>()); - map.put(value, new SoftReference<Bitmap>(bmp)); + map.put(value, new SoftReference<>(bmp)); } else { - sFrameworkBitmapCache.put(value, new SoftReference<Bitmap>(bmp)); + sFrameworkBitmapCache.put(value, new SoftReference<>(bmp)); } } @@ -722,16 +659,12 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { */ public static void setCached9Patch(String value, NinePatchChunk ninePatch, Object projectKey) { if (projectKey != null) { - Map<String, SoftReference<NinePatchChunk>> map = sProject9PatchCache.get(projectKey); - - if (map == null) { - map = new HashMap<String, SoftReference<NinePatchChunk>>(); - sProject9PatchCache.put(projectKey, map); - } + Map<String, SoftReference<NinePatchChunk>> map = + sProject9PatchCache.computeIfAbsent(projectKey, k -> new HashMap<>()); - map.put(value, new SoftReference<NinePatchChunk>(ninePatch)); + map.put(value, new SoftReference<>(ninePatch)); } else { - sFramework9PatchCache.put(value, new SoftReference<NinePatchChunk>(ninePatch)); + sFramework9PatchCache.put(value, new SoftReference<>(ninePatch)); } } } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java index 4ffb2e2bba9d..fdf6d63b1cb2 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java @@ -26,10 +26,13 @@ import com.android.layoutlib.bridge.impl.RenderSessionImpl; import com.android.tools.layoutlib.java.System_Delegate; import com.android.util.PropertiesMap; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.view.View; import android.view.ViewGroup; import java.awt.image.BufferedImage; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -42,7 +45,9 @@ import java.util.Map; */ public class BridgeRenderSession extends RenderSession { + @Nullable private final RenderSessionImpl mSession; + @NonNull private Result mLastResult; @Override @@ -52,41 +57,44 @@ public class BridgeRenderSession extends RenderSession { @Override public BufferedImage getImage() { - return mSession.getImage(); + return mSession != null ? mSession.getImage() : + new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); } @Override public boolean isAlphaChannelImage() { - return mSession.isAlphaChannelImage(); + return mSession != null && mSession.isAlphaChannelImage(); } @Override public List<ViewInfo> getRootViews() { - return mSession.getViewInfos(); + return mSession != null ? mSession.getViewInfos() : Collections.emptyList(); } @Override public List<ViewInfo> getSystemRootViews() { - return mSession.getSystemViewInfos(); + return mSession != null ? mSession.getSystemViewInfos() : Collections.emptyList(); } @Override public Map<Object, PropertiesMap> getDefaultProperties() { - return mSession.getDefaultProperties(); + return mSession != null ? mSession.getDefaultProperties() : Collections.emptyMap(); } @Override public Result measure(long timeout) { - try { - Bridge.prepareThread(); - mLastResult = mSession.acquire(timeout); - if (mLastResult.isSuccess()) { - mSession.invalidateRenderingSize(); - mLastResult = mSession.measure(); + if (mSession != null) { + try { + Bridge.prepareThread(); + mLastResult = mSession.acquire(timeout); + if (mLastResult.isSuccess()) { + mSession.invalidateRenderingSize(); + mLastResult = mSession.measure(); + } + } finally { + mSession.release(); + Bridge.cleanupThread(); } - } finally { - mSession.release(); - Bridge.cleanupThread(); } return mLastResult; @@ -94,18 +102,20 @@ public class BridgeRenderSession extends RenderSession { @Override public Result render(long timeout, boolean forceMeasure) { - try { - Bridge.prepareThread(); - mLastResult = mSession.acquire(timeout); - if (mLastResult.isSuccess()) { - if (forceMeasure) { - mSession.invalidateRenderingSize(); + if (mSession != null) { + try { + Bridge.prepareThread(); + mLastResult = mSession.acquire(timeout); + if (mLastResult.isSuccess()) { + if (forceMeasure) { + mSession.invalidateRenderingSize(); + } + mLastResult = mSession.render(false /*freshRender*/); } - mLastResult = mSession.render(false /*freshRender*/); + } finally { + mSession.release(); + Bridge.cleanupThread(); } - } finally { - mSession.release(); - Bridge.cleanupThread(); } return mLastResult; @@ -114,16 +124,18 @@ public class BridgeRenderSession extends RenderSession { @Override public Result animate(Object targetObject, String animationName, boolean isFrameworkAnimation, IAnimationListener listener) { - try { - Bridge.prepareThread(); - mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT); - if (mLastResult.isSuccess()) { - mLastResult = mSession.animate(targetObject, animationName, isFrameworkAnimation, - listener); + if (mSession != null) { + try { + Bridge.prepareThread(); + mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT); + if (mLastResult.isSuccess()) { + mLastResult = mSession.animate(targetObject, animationName, isFrameworkAnimation, + listener); + } + } finally { + mSession.release(); + Bridge.cleanupThread(); } - } finally { - mSession.release(); - Bridge.cleanupThread(); } return mLastResult; @@ -136,16 +148,18 @@ public class BridgeRenderSession extends RenderSession { throw new IllegalArgumentException("parentView is not a ViewGroup"); } - try { - Bridge.prepareThread(); - mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT); - if (mLastResult.isSuccess()) { - mLastResult = mSession.insertChild((ViewGroup) parentView, childXml, index, - listener); + if (mSession != null) { + try { + Bridge.prepareThread(); + mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT); + if (mLastResult.isSuccess()) { + mLastResult = + mSession.insertChild((ViewGroup) parentView, childXml, index, listener); + } + } finally { + mSession.release(); + Bridge.cleanupThread(); } - } finally { - mSession.release(); - Bridge.cleanupThread(); } return mLastResult; @@ -162,16 +176,18 @@ public class BridgeRenderSession extends RenderSession { throw new IllegalArgumentException("childView is not a View"); } - try { - Bridge.prepareThread(); - mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT); - if (mLastResult.isSuccess()) { - mLastResult = mSession.moveChild((ViewGroup) parentView, (View) childView, index, - layoutParams, listener); + if (mSession != null) { + try { + Bridge.prepareThread(); + mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT); + if (mLastResult.isSuccess()) { + mLastResult = mSession.moveChild((ViewGroup) parentView, (View) childView, index, + layoutParams, listener); + } + } finally { + mSession.release(); + Bridge.cleanupThread(); } - } finally { - mSession.release(); - Bridge.cleanupThread(); } return mLastResult; @@ -183,15 +199,17 @@ public class BridgeRenderSession extends RenderSession { throw new IllegalArgumentException("childView is not a View"); } - try { - Bridge.prepareThread(); - mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT); - if (mLastResult.isSuccess()) { - mLastResult = mSession.removeChild((View) childView, listener); + if (mSession != null) { + try { + Bridge.prepareThread(); + mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT); + if (mLastResult.isSuccess()) { + mLastResult = mSession.removeChild((View) childView, listener); + } + } finally { + mSession.release(); + Bridge.cleanupThread(); } - } finally { - mSession.release(); - Bridge.cleanupThread(); } return mLastResult; @@ -221,7 +239,7 @@ public class BridgeRenderSession extends RenderSession { } } - /*package*/ BridgeRenderSession(RenderSessionImpl scene, Result lastResult) { + /*package*/ BridgeRenderSession(@Nullable RenderSessionImpl scene, @NonNull Result lastResult) { mSession = scene; if (scene != null) { mSession.setScene(this); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java index 432fddaad3a4..23e049881a03 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java @@ -31,7 +31,6 @@ import com.android.layoutlib.bridge.android.view.WindowManagerImpl; import com.android.layoutlib.bridge.impl.ParserFactory; import com.android.layoutlib.bridge.impl.Stack; import com.android.resources.ResourceType; -import com.android.resources.ResourceUrl; import com.android.util.Pair; import com.android.util.PropertiesMap; import com.android.util.PropertiesMap.Property; @@ -87,6 +86,7 @@ import android.util.TypedValue; import android.view.BridgeInflater; import android.view.Display; import android.view.DisplayAdjustments; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; @@ -107,7 +107,6 @@ import java.util.List; import java.util.Map; import static android.os._Original_Build.VERSION_CODES.JELLY_BEAN_MR1; -import static com.android.SdkConstants.ANDROID_NS_NAME; import static com.android.layoutlib.bridge.android.RenderParamsFlags.FLAG_KEY_APPLICATION_PACKAGE; /** @@ -122,23 +121,20 @@ public class BridgeContext extends Context { static { FRAMEWORK_PATCHED_VALUES.put("animateFirstView", new ResourceValue( - ResourceUrl.create(ANDROID_NS_NAME, ResourceType.BOOL, "animateFirstView"), - "false")); - FRAMEWORK_PATCHED_VALUES.put("animateLayoutChanges", new ResourceValue( - ResourceUrl.create(ANDROID_NS_NAME, ResourceType.BOOL, "animateLayoutChanges"), - "false")); + ResourceType.BOOL, "animateFirstView", "false", false)); + FRAMEWORK_PATCHED_VALUES.put("animateLayoutChanges", + new ResourceValue(ResourceType.BOOL, "animateLayoutChanges", "false", false)); - FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionItemLayout", new ResourceValue( - ResourceUrl.create(ANDROID_NS_NAME, ResourceType.LAYOUT, - "textEditSuggestionItemLayout"), "text_edit_suggestion_item")); - FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionContainerLayout", new ResourceValue( - ResourceUrl.create(ANDROID_NS_NAME, ResourceType.LAYOUT, - "textEditSuggestionContainerLayout"), "text_edit_suggestion_container")); - FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionHighlightStyle", new ResourceValue( - ResourceUrl.create(ANDROID_NS_NAME, ResourceType.STYLE, - "textEditSuggestionHighlightStyle"), - "TextAppearance.Holo.SuggestionHighlight")); + FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionItemLayout", + new ResourceValue(ResourceType.LAYOUT, "textEditSuggestionItemLayout", + "text_edit_suggestion_item", true)); + FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionContainerLayout", + new ResourceValue(ResourceType.LAYOUT, "textEditSuggestionContainerLayout", + "text_edit_suggestion_container", true)); + FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionHighlightStyle", + new ResourceValue(ResourceType.STYLE, "textEditSuggestionHighlightStyle", + "TextAppearance.Holo.SuggestionHighlight", true)); } @@ -648,7 +644,12 @@ public class BridgeContext extends Context { return null; } - throw new UnsupportedOperationException("Unsupported Service: " + service); + if (AUDIO_SERVICE.equals(service)) { + return null; + } + + assert false : "Unsupported Service: " + service; + return null; } @Override @@ -678,7 +679,9 @@ public class BridgeContext extends Context { } if (style == null) { - throw new Resources.NotFoundException(); + Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE, + "Failed to find style with " + resId, null); + return null; } } @@ -967,9 +970,7 @@ public class BridgeContext extends Context { // there is a value in the XML, but we need to resolve it in case it's // referencing another resource or a theme value. ta.bridgeSetValue(index, attrName, frameworkAttr, - mRenderResources.resolveResValue(new ResourceValue( - ResourceUrl.create(ResourceType.STRING, attrName, - isPlatformFile), value))); + mRenderResources.resolveValue(null, attrName, value, isPlatformFile)); } } } @@ -1846,6 +1847,18 @@ public class BridgeContext extends Context { } @Override + public ComponentName startForegroundService(Intent service) { + // pass + return null; + } + + @Override + public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) { + // pass + return null; + } + + @Override public ComponentName startServiceInForeground(Intent service, int id, Notification notification) { // pass diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java index 906ebb1fe39e..5a239e1f3f38 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java @@ -49,6 +49,7 @@ import android.content.pm.VersionedPackage; import android.content.res.Resources; import android.content.res.XmlResourceParser; import android.graphics.Rect; +import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Handler; @@ -307,7 +308,8 @@ public class BridgePackageManager extends PackageManager { @Override public Drawable getInstantAppIcon(String packageName) { - throw new UnsupportedOperationException(); + assert false : "Unsupported operation"; + return new ColorDrawable(); } @Override @@ -916,4 +918,9 @@ public class BridgePackageManager extends PackageManager { public boolean canRequestPackageInstalls() { return false; } + + @Override + public ComponentName getInstantAppResolverSettingsComponent() { + return null; + } } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java index f900b451fa6e..a439e7d034df 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java @@ -21,6 +21,7 @@ import com.android.ide.common.rendering.api.ActionBarCallback.HomeButtonStyle; import com.android.ide.common.rendering.api.RenderResources; import com.android.ide.common.rendering.api.ResourceValue; import com.android.ide.common.rendering.api.SessionParams; +import com.android.layoutlib.bridge.MockView; import com.android.layoutlib.bridge.android.BridgeContext; import android.annotation.NonNull; @@ -53,35 +54,41 @@ public abstract class BridgeActionBar { mParams = params; mCallback = params.getLayoutlibCallback().getActionBarCallback(); ResourceValue layoutName = getLayoutResource(context); + + int layoutId = 0; if (layoutName == null) { - throw new RuntimeException("Unable to find the layout for Action Bar."); + assert false : "Unable to find the layout for Action Bar."; } - int layoutId; - if (layoutName.isFramework()) { - layoutId = context.getFrameworkResourceValue(layoutName.getResourceType(), - layoutName.getName(), 0); - } else { - layoutId = context.getProjectResourceValue(layoutName.getResourceType(), - layoutName.getName(), 0); - + else { + if (layoutName.isFramework()) { + layoutId = context.getFrameworkResourceValue(layoutName.getResourceType(), + layoutName.getName(), 0); + } else { + layoutId = context.getProjectResourceValue(layoutName.getResourceType(), + layoutName.getName(), 0); + + } } if (layoutId == 0) { - throw new RuntimeException( - String.format("Unable to resolve attribute \"%1$s\" of type \"%2$s\"", - layoutName.getName(), layoutName.getResourceType())); - } - if (mCallback.isOverflowPopupNeeded()) { - // Create a RelativeLayout around the action bar, to which the overflow popup may be - // added. - mEnclosingLayout = new RelativeLayout(mBridgeContext); - setMatchParent(mEnclosingLayout); - } else { + assert false : String.format("Unable to resolve attribute \"%1$s\" of type \"%2$s\"", + layoutName.getName(), layoutName.getResourceType()); + mDecorContent = new MockView(context); mEnclosingLayout = null; } - - // Inflate action bar layout. - mDecorContent = - getInflater(context).inflate(layoutId, mEnclosingLayout, mEnclosingLayout != null); + else { + if (mCallback.isOverflowPopupNeeded()) { + // Create a RelativeLayout around the action bar, to which the overflow popup may be + // added. + mEnclosingLayout = new RelativeLayout(mBridgeContext); + setMatchParent(mEnclosingLayout); + } else { + mEnclosingLayout = null; + } + + // Inflate action bar layout. + mDecorContent = getInflater(context).inflate(layoutId, mEnclosingLayout, + mEnclosingLayout != null); + } } /** diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java index 8bb2c593f7a1..2984fc0e5abb 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java @@ -83,18 +83,18 @@ abstract class CustomBar extends LinearLayout { XmlPullParser parser; try { parser = ParserFactory.create(getClass().getResourceAsStream(layoutPath), name); + + BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(parser, context, false); + + try { + inflater.inflate(bridgeParser, this, true); + } finally { + bridgeParser.ensurePopped(); + } } catch (XmlPullParserException e) { // Should not happen as the resource is bundled with the jar, and ParserFactory should // have been initialized. - throw new AssertionError(e); - } - - BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(parser, context, false); - - try { - inflater.inflate(bridgeParser, this, true); - } finally { - bridgeParser.ensurePopped(); + assert false; } } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java index d2a5117cf866..fd49c7700ea9 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java @@ -176,7 +176,8 @@ public class FrameworkActionBar extends BridgeActionBar { ArrayList<MenuItemImpl> menus = mActionBar.getMenuBuilder().getNonActionItems(); ActionMenuPresenter presenter = mActionBar.getActionMenuPresenter(); if (presenter == null) { - throw new RuntimeException("Failed to create a Presenter for Action Bar Menus."); + assert false : "Failed to create a Presenter for Action Bar Menus."; + return false; } if (presenter.isOverflowReserved() && menus != null) { diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java index 45337742998f..75f9ec527e63 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java @@ -43,6 +43,7 @@ import android.content.res.GradientColor; import android.content.res.Resources.Theme; import android.graphics.Bitmap; import android.graphics.Bitmap_Delegate; +import android.graphics.Color; import android.graphics.NinePatch_Delegate; import android.graphics.Rect; import android.graphics.Typeface; @@ -184,7 +185,8 @@ public final class ResourceHelper { } if (type != XmlPullParser.START_TAG) { - throw new XmlPullParserException("No start tag found"); + assert false : "No start tag found"; + return null; } final String name = blockParser.getName(); diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/BridgeRenderSessionTest.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/BridgeRenderSessionTest.java new file mode 100644 index 000000000000..63b9b436cffd --- /dev/null +++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/BridgeRenderSessionTest.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2017 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.layoutlib.bridge; + +import com.android.ide.common.rendering.api.Result; +import com.android.ide.common.rendering.api.Result.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class BridgeRenderSessionTest { + @Test + public void testNullSession() { + BridgeRenderSession renderSession = new BridgeRenderSession(null, Status.ERROR_UNKNOWN + .createResult("Test result")); + + assertNotNull(renderSession.getImage()); + assertNotNull(renderSession.getRootViews()); + assertNotNull(renderSession.getSystemRootViews()); + assertNotNull(renderSession.getDefaultProperties()); + } +}
\ No newline at end of file diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java index c83d2e4ecea3..eb264d655a9c 100644 --- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java +++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java @@ -16,6 +16,7 @@ package com.android.layoutlib.bridge.intensive; +import com.android.layoutlib.bridge.BridgeRenderSessionTest; import com.android.layoutlib.bridge.TestDelegates; import com.android.layoutlib.bridge.android.BridgeXmlBlockParserTest; import com.android.layoutlib.bridge.impl.LayoutParserWrapperTest; @@ -34,7 +35,8 @@ import android.util.BridgeXmlPullAttributesTest; @SuiteClasses({ RenderTests.class, LayoutParserWrapperTest.class, BridgeXmlBlockParserTest.class, BridgeXmlPullAttributesTest.class, - Matrix_DelegateTest.class, TestDelegates.class, PerformanceTests.class + Matrix_DelegateTest.class, TestDelegates.class, PerformanceTests.class, + BridgeRenderSessionTest.class }) public class Main { } diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java index 00dddeed3e8c..8739b7fade9a 100644 --- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java +++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java @@ -311,7 +311,6 @@ public class RenderTestBase { sFrameworkRepo = null; sProjectResources = null; sLogger = null; - sBridge.dispose(); sBridge = null; TestUtils.gc(); @@ -329,7 +328,6 @@ public class RenderTestBase { RenderSession session = sBridge.createSession(params); try { - if (frameTimeNanos != -1) { session.setElapsedFrameTimeNanos(frameTimeNanos); } @@ -338,11 +336,13 @@ public class RenderTestBase { getLogger().error(session.getResult().getException(), session.getResult().getErrorMessage()); } - // Render the session with a timeout of 50s. - Result renderResult = session.render(50000); - if (!renderResult.isSuccess()) { - getLogger().error(session.getResult().getException(), - session.getResult().getErrorMessage()); + else { + // Render the session with a timeout of 50s. + Result renderResult = session.render(50000); + if (!renderResult.isSuccess()) { + getLogger().error(session.getResult().getException(), + session.getResult().getErrorMessage()); + } } return RenderResult.getFromSession(session); diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 10ffd8ae1f7d..1852feb8afc9 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -81,8 +81,6 @@ interface IWifiManager boolean disableNetwork(int netId); - boolean pingSupplicant(); - void startScan(in ScanSettings requested, in WorkSource ws); List<ScanResult> getScanResults(String callingPackage); diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java index da9aa06918c1..afee290cbd5b 100644 --- a/wifi/java/android/net/wifi/ScanResult.java +++ b/wifi/java/android/net/wifi/ScanResult.java @@ -336,12 +336,12 @@ public class ScanResult implements Parcelable { /** * Indicates venue name (such as 'San Francisco Airport') published by access point; only - * available on passpoint network and if published by access point. + * available on Passpoint network and if published by access point. */ public CharSequence venueName; /** - * Indicates passpoint operator name published by access point. + * Indicates Passpoint operator name published by access point. */ public CharSequence operatorFriendlyName; diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 04f9059fb544..7defa7c17d95 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -367,12 +367,12 @@ public class WifiConfiguration implements Parcelable { public WifiEnterpriseConfig enterpriseConfig; /** - * Fully qualified domain name of a passpoint configuration + * Fully qualified domain name of a Passpoint configuration */ public String FQDN; /** - * Name of passpoint credential provider + * Name of Passpoint credential provider */ public String providerFriendlyName; @@ -385,8 +385,8 @@ public class WifiConfiguration implements Parcelable { public boolean isHomeProviderNetwork; /** - * Roaming Consortium Id list for passpoint credential; identifies a set of networks where - * passpoint credential will be considered valid + * Roaming Consortium Id list for Passpoint credential; identifies a set of networks where + * Passpoint credential will be considered valid */ public long[] roamingConsortiumIds; @@ -1425,7 +1425,7 @@ public class WifiConfiguration implements Parcelable { } /** - * Identify if this configuration represents a passpoint network + * Identify if this configuration represents a Passpoint network */ public boolean isPasspoint() { return !TextUtils.isEmpty(FQDN) diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java index 4268f24a0999..18f30f834bc1 100644 --- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java +++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java @@ -940,8 +940,8 @@ public class WifiEnterpriseConfig implements Parcelable { } /** - * Set realm for passpoint credential; realm identifies a set of networks where your - * passpoint credential can be used + * Set realm for Passpoint credential; realm identifies a set of networks where your + * Passpoint credential can be used * @param realm the realm */ public void setRealm(String realm) { @@ -949,7 +949,7 @@ public class WifiEnterpriseConfig implements Parcelable { } /** - * Get realm for passpoint credential; see {@link #setRealm(String)} for more information + * Get realm for Passpoint credential; see {@link #setRealm(String)} for more information * @return the realm */ public String getRealm() { @@ -957,7 +957,7 @@ public class WifiEnterpriseConfig implements Parcelable { } /** - * Set plmn (Public Land Mobile Network) of the provider of passpoint credential + * Set plmn (Public Land Mobile Network) of the provider of Passpoint credential * @param plmn the plmn value derived from mcc (mobile country code) & mnc (mobile network code) */ public void setPlmn(String plmn) { @@ -965,7 +965,7 @@ public class WifiEnterpriseConfig implements Parcelable { } /** - * Get plmn (Public Land Mobile Network) for passpoint credential; see {@link #setPlmn + * Get plmn (Public Land Mobile Network) for Passpoint credential; see {@link #setPlmn * (String)} for more information * @return the plmn */ diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index ae6a6793dc9d..9ee772a61ed5 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -858,6 +858,10 @@ public class WifiManager { /** * Returns a WifiConfiguration matching this ScanResult + * + * An {@link UnsupportedOperationException} will be thrown if Passpoint is not enabled + * on the device. + * * @param scanResult scanResult that represents the BSSID * @return {@link WifiConfiguration} that matches this BSSID or null * @hide @@ -944,6 +948,8 @@ public class WifiManager { * FQDN, the new configuration will replace the existing configuration. * * An {@link IllegalArgumentException} will be thrown on failure. + * An {@link UnsupportedOperationException} will be thrown if Passpoint is not enabled + * on the device. * * @param config The Passpoint configuration to be added */ @@ -961,8 +967,10 @@ public class WifiManager { * Remove the Passpoint configuration identified by its FQDN (Fully Qualified Domain Name). * * An {@link IllegalArgumentException} will be thrown on failure. + * An {@link UnsupportedOperationException} will be thrown if Passpoint is not enabled + * on the device. * - * @param fqdn The FQDN of the passpoint configuration to be removed + * @param fqdn The FQDN of the Passpoint configuration to be removed */ public void removePasspointConfiguration(String fqdn) { try { @@ -979,6 +987,9 @@ public class WifiManager { * * An empty list will be returned when no configurations are installed. * + * An {@link UnsupportedOperationException} will be thrown if Passpoint is not enabled + * on the device. + * * @return A list of {@link PasspointConfiguration} */ public List<PasspointConfiguration> getPasspointConfigurations() { @@ -995,6 +1006,9 @@ public class WifiManager { * {@link #EXTRA_ICON} will indicate the result of the request. * A missing intent extra {@link #EXTRA_ICON} will indicate a failure. * + * An {@link UnsupportedOperationException} will be thrown if Passpoint is not enabled + * on the device. + * * @param bssid The BSSID of the AP * @param fileName Name of the icon file (remote file) to query from the AP */ @@ -1254,7 +1268,7 @@ public class WifiManager { } /** - * @return true if this adapter supports passpoint + * @return true if this adapter supports Passpoint * @hide */ public boolean isPasspointSupported() { diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 5847f798712d..40e34b1f3001 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -934,46 +934,13 @@ public class WifiScanner { /** Implement the Parcelable interface {@hide} */ public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(rssiSampleSize); - dest.writeInt(lostApSampleSize); - dest.writeInt(unchangedSampleSize); - dest.writeInt(minApsBreachingThreshold); - dest.writeInt(periodInMs); - if (bssidInfos != null) { - dest.writeInt(bssidInfos.length); - for (int i = 0; i < bssidInfos.length; i++) { - BssidInfo info = bssidInfos[i]; - dest.writeString(info.bssid); - dest.writeInt(info.low); - dest.writeInt(info.high); - dest.writeInt(info.frequencyHint); - } - } else { - dest.writeInt(0); - } } /** Implement the Parcelable interface {@hide} */ public static final Creator<WifiChangeSettings> CREATOR = new Creator<WifiChangeSettings>() { public WifiChangeSettings createFromParcel(Parcel in) { - WifiChangeSettings settings = new WifiChangeSettings(); - settings.rssiSampleSize = in.readInt(); - settings.lostApSampleSize = in.readInt(); - settings.unchangedSampleSize = in.readInt(); - settings.minApsBreachingThreshold = in.readInt(); - settings.periodInMs = in.readInt(); - int len = in.readInt(); - settings.bssidInfos = new BssidInfo[len]; - for (int i = 0; i < len; i++) { - BssidInfo info = new BssidInfo(); - info.bssid = in.readString(); - info.low = in.readInt(); - info.high = in.readInt(); - info.frequencyHint = in.readInt(); - settings.bssidInfos[i] = info; - } - return settings; + return new WifiChangeSettings(); } public WifiChangeSettings[] newArray(int size) { @@ -998,20 +965,10 @@ public class WifiScanner { int unchangedSampleSize, /* samples to confirm no change */ int minApsBreachingThreshold, /* change threshold to trigger event */ int periodInMs, /* period of scan */ - BssidInfo[] bssidInfos /* signal thresholds to crosss */ + BssidInfo[] bssidInfos /* signal thresholds to cross */ ) { - validateChannel(); - - WifiChangeSettings settings = new WifiChangeSettings(); - settings.rssiSampleSize = rssiSampleSize; - settings.lostApSampleSize = lostApSampleSize; - settings.unchangedSampleSize = unchangedSampleSize; - settings.minApsBreachingThreshold = minApsBreachingThreshold; - settings.periodInMs = periodInMs; - settings.bssidInfos = bssidInfos; - - configureWifiChange(settings); + throw new UnsupportedOperationException(); } /** @@ -1034,11 +991,7 @@ public class WifiScanner { * provided on {@link #stopTrackingWifiChange} */ public void startTrackingWifiChange(WifiChangeListener listener) { - Preconditions.checkNotNull(listener, "listener cannot be null"); - int key = addListener(listener); - if (key == INVALID_KEY) return; - validateChannel(); - mAsyncChannel.sendMessage(CMD_START_TRACKING_CHANGE, 0, key); + throw new UnsupportedOperationException(); } /** @@ -1047,17 +1000,13 @@ public class WifiScanner { * #stopTrackingWifiChange} */ public void stopTrackingWifiChange(WifiChangeListener listener) { - int key = removeListener(listener); - if (key == INVALID_KEY) return; - validateChannel(); - mAsyncChannel.sendMessage(CMD_STOP_TRACKING_CHANGE, 0, key); + throw new UnsupportedOperationException(); } /** @hide */ @SystemApi public void configureWifiChange(WifiChangeSettings settings) { - validateChannel(); - mAsyncChannel.sendMessage(CMD_CONFIGURE_WIFI_CHANGE, 0, 0, settings); + throw new UnsupportedOperationException(); } /** interface to receive hotlist events on; use this on {@link #setHotlist} */ @@ -1085,20 +1034,6 @@ public class WifiScanner { /** Implement the Parcelable interface {@hide} */ public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(apLostThreshold); - - if (bssidInfos != null) { - dest.writeInt(bssidInfos.length); - for (int i = 0; i < bssidInfos.length; i++) { - BssidInfo info = bssidInfos[i]; - dest.writeString(info.bssid); - dest.writeInt(info.low); - dest.writeInt(info.high); - dest.writeInt(info.frequencyHint); - } - } else { - dest.writeInt(0); - } } /** Implement the Parcelable interface {@hide} */ @@ -1106,17 +1041,6 @@ public class WifiScanner { new Creator<HotlistSettings>() { public HotlistSettings createFromParcel(Parcel in) { HotlistSettings settings = new HotlistSettings(); - settings.apLostThreshold = in.readInt(); - int n = in.readInt(); - settings.bssidInfos = new BssidInfo[n]; - for (int i = 0; i < n; i++) { - BssidInfo info = new BssidInfo(); - info.bssid = in.readString(); - info.low = in.readInt(); - info.high = in.readInt(); - info.frequencyHint = in.readInt(); - settings.bssidInfos[i] = info; - } return settings; } @@ -1135,14 +1059,7 @@ public class WifiScanner { */ public void startTrackingBssids(BssidInfo[] bssidInfos, int apLostThreshold, BssidListener listener) { - Preconditions.checkNotNull(listener, "listener cannot be null"); - int key = addListener(listener); - if (key == INVALID_KEY) return; - validateChannel(); - HotlistSettings settings = new HotlistSettings(); - settings.bssidInfos = bssidInfos; - settings.apLostThreshold = apLostThreshold; - mAsyncChannel.sendMessage(CMD_SET_HOTLIST, 0, key, settings); + throw new UnsupportedOperationException(); } /** @@ -1150,11 +1067,7 @@ public class WifiScanner { * @param listener same object provided in {@link #startTrackingBssids} */ public void stopTrackingBssids(BssidListener listener) { - Preconditions.checkNotNull(listener, "listener cannot be null"); - int key = removeListener(listener); - if (key == INVALID_KEY) return; - validateChannel(); - mAsyncChannel.sendMessage(CMD_RESET_HOTLIST, 0, key); + throw new UnsupportedOperationException(); } @@ -1177,20 +1090,10 @@ public class WifiScanner { /** @hide */ public static final int CMD_SCAN_RESULT = BASE + 5; /** @hide */ - public static final int CMD_SET_HOTLIST = BASE + 6; - /** @hide */ - public static final int CMD_RESET_HOTLIST = BASE + 7; - /** @hide */ public static final int CMD_AP_FOUND = BASE + 9; /** @hide */ public static final int CMD_AP_LOST = BASE + 10; /** @hide */ - public static final int CMD_START_TRACKING_CHANGE = BASE + 11; - /** @hide */ - public static final int CMD_STOP_TRACKING_CHANGE = BASE + 12; - /** @hide */ - public static final int CMD_CONFIGURE_WIFI_CHANGE = BASE + 13; - /** @hide */ public static final int CMD_WIFI_CHANGE_DETECTED = BASE + 15; /** @hide */ public static final int CMD_WIFI_CHANGES_STABILIZED = BASE + 16; diff --git a/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java b/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java index 9645b1d32a34..334205b13bba 100644 --- a/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java +++ b/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java @@ -85,7 +85,7 @@ public class DiscoverySessionCallback { /** * Called when a discovery session (publish or subscribe) terminates. Termination may be due * to user-request (either directly through {@link DiscoverySession#destroy()} or - * application-specified expiration, e.g. {@link PublishConfig.Builder#setPublishCount(int)} + * application-specified expiration, e.g. {@link PublishConfig.Builder#setTtlSec(int)} * or {@link SubscribeConfig.Builder#setTtlSec(int)}). */ public void onSessionTerminated() { diff --git a/wifi/java/android/net/wifi/aware/PublishConfig.java b/wifi/java/android/net/wifi/aware/PublishConfig.java index a996844883b0..1ce12f30a25e 100644 --- a/wifi/java/android/net/wifi/aware/PublishConfig.java +++ b/wifi/java/android/net/wifi/aware/PublishConfig.java @@ -75,9 +75,6 @@ public final class PublishConfig implements Parcelable { public final int mPublishType; /** @hide */ - public final int mPublishCount; - - /** @hide */ public final int mTtlSec; /** @hide */ @@ -85,12 +82,11 @@ public final class PublishConfig implements Parcelable { /** @hide */ public PublishConfig(byte[] serviceName, byte[] serviceSpecificInfo, byte[] matchFilter, - int publishType, int publichCount, int ttlSec, boolean enableTerminateNotification) { + int publishType, int ttlSec, boolean enableTerminateNotification) { mServiceName = serviceName; mServiceSpecificInfo = serviceSpecificInfo; mMatchFilter = matchFilter; mPublishType = publishType; - mPublishCount = publichCount; mTtlSec = ttlSec; mEnableTerminateNotification = enableTerminateNotification; } @@ -100,8 +96,8 @@ public final class PublishConfig implements Parcelable { return "PublishConfig [mServiceName='" + mServiceName + ", mServiceSpecificInfo='" + ( (mServiceSpecificInfo == null) ? "null" : HexEncoding.encode(mServiceSpecificInfo)) + ", mMatchFilter=" + (new TlvBufferUtils.TlvIterable(0, 1, - mMatchFilter)).toString() + ", mPublishType=" + mPublishType + ", mPublishCount=" - + mPublishCount + ", mTtlSec=" + mTtlSec + ", mEnableTerminateNotification=" + mMatchFilter)).toString() + ", mPublishType=" + mPublishType + + ", mTtlSec=" + mTtlSec + ", mEnableTerminateNotification=" + mEnableTerminateNotification + "]"; } @@ -116,7 +112,6 @@ public final class PublishConfig implements Parcelable { dest.writeByteArray(mServiceSpecificInfo); dest.writeByteArray(mMatchFilter); dest.writeInt(mPublishType); - dest.writeInt(mPublishCount); dest.writeInt(mTtlSec); dest.writeInt(mEnableTerminateNotification ? 1 : 0); } @@ -133,11 +128,10 @@ public final class PublishConfig implements Parcelable { byte[] ssi = in.createByteArray(); byte[] matchFilter = in.createByteArray(); int publishType = in.readInt(); - int publishCount = in.readInt(); int ttlSec = in.readInt(); boolean enableTerminateNotification = in.readInt() != 0; - return new PublishConfig(serviceName, ssi, matchFilter, publishType, publishCount, + return new PublishConfig(serviceName, ssi, matchFilter, publishType, ttlSec, enableTerminateNotification); } }; @@ -156,7 +150,7 @@ public final class PublishConfig implements Parcelable { return Arrays.equals(mServiceName, lhs.mServiceName) && Arrays.equals(mServiceSpecificInfo, lhs.mServiceSpecificInfo) && Arrays.equals(mMatchFilter, lhs.mMatchFilter) - && mPublishType == lhs.mPublishType && mPublishCount == lhs.mPublishCount + && mPublishType == lhs.mPublishType && mTtlSec == lhs.mTtlSec && mEnableTerminateNotification == lhs.mEnableTerminateNotification; } @@ -169,7 +163,6 @@ public final class PublishConfig implements Parcelable { result = 31 * result + Arrays.hashCode(mServiceSpecificInfo); result = 31 * result + Arrays.hashCode(mMatchFilter); result = 31 * result + mPublishType; - result = 31 * result + mPublishCount; result = 31 * result + mTtlSec; result = 31 * result + (mEnableTerminateNotification ? 1 : 0); @@ -193,9 +186,6 @@ public final class PublishConfig implements Parcelable { if (mPublishType < PUBLISH_TYPE_UNSOLICITED || mPublishType > PUBLISH_TYPE_SOLICITED) { throw new IllegalArgumentException("Invalid publishType - " + mPublishType); } - if (mPublishCount < 0) { - throw new IllegalArgumentException("Invalid publishCount - must be non-negative"); - } if (mTtlSec < 0) { throw new IllegalArgumentException("Invalid ttlSec - must be non-negative"); } @@ -229,7 +219,6 @@ public final class PublishConfig implements Parcelable { private byte[] mServiceSpecificInfo; private byte[] mMatchFilter; private int mPublishType = PUBLISH_TYPE_UNSOLICITED; - private int mPublishCount = 0; private int mTtlSec = 0; private boolean mEnableTerminateNotification = true; @@ -317,30 +306,6 @@ public final class PublishConfig implements Parcelable { } /** - * Sets the number of times an unsolicited (configured using - * {@link PublishConfig.Builder#setPublishType(int)}) publish session - * will be broadcast. When the count is reached an event will be - * generated for {@link DiscoverySessionCallback#onSessionTerminated()} - * [unless {@link #setTerminateNotificationEnabled(boolean)} disables the callback]. - * <p> - * Optional. 0 by default - indicating the session doesn't terminate on its own. - * Session will be terminated when {@link DiscoverySession#destroy()} is - * called. - * - * @param publishCount Number of publish packets to broadcast. - * - * @return The builder to facilitate chaining - * {@code builder.setXXX(..).setXXX(..)}. - */ - public Builder setPublishCount(int publishCount) { - if (publishCount < 0) { - throw new IllegalArgumentException("Invalid publishCount - must be non-negative"); - } - mPublishCount = publishCount; - return this; - } - - /** * Sets the time interval (in seconds) an unsolicited ( * {@link PublishConfig.Builder#setPublishType(int)}) publish session * will be alive - broadcasting a packet. When the TTL is reached @@ -387,7 +352,7 @@ public final class PublishConfig implements Parcelable { */ public PublishConfig build() { return new PublishConfig(mServiceName, mServiceSpecificInfo, mMatchFilter, mPublishType, - mPublishCount, mTtlSec, mEnableTerminateNotification); + mTtlSec, mEnableTerminateNotification); } } } diff --git a/wifi/java/android/net/wifi/aware/SubscribeConfig.java b/wifi/java/android/net/wifi/aware/SubscribeConfig.java index 3397c4bc2ac3..97a6a3f91e86 100644 --- a/wifi/java/android/net/wifi/aware/SubscribeConfig.java +++ b/wifi/java/android/net/wifi/aware/SubscribeConfig.java @@ -94,9 +94,6 @@ public final class SubscribeConfig implements Parcelable { public final int mSubscribeType; /** @hide */ - public final int mSubscribeCount; - - /** @hide */ public final int mTtlSec; /** @hide */ @@ -107,13 +104,12 @@ public final class SubscribeConfig implements Parcelable { /** @hide */ public SubscribeConfig(byte[] serviceName, byte[] serviceSpecificInfo, byte[] matchFilter, - int subscribeType, int publichCount, int ttlSec, int matchStyle, + int subscribeType, int ttlSec, int matchStyle, boolean enableTerminateNotification) { mServiceName = serviceName; mServiceSpecificInfo = serviceSpecificInfo; mMatchFilter = matchFilter; mSubscribeType = subscribeType; - mSubscribeCount = publichCount; mTtlSec = ttlSec; mMatchStyle = matchStyle; mEnableTerminateNotification = enableTerminateNotification; @@ -125,7 +121,7 @@ public final class SubscribeConfig implements Parcelable { (mServiceSpecificInfo == null) ? "null" : HexEncoding.encode(mServiceSpecificInfo)) + ", mMatchFilter=" + (new TlvBufferUtils.TlvIterable(0, 1, mMatchFilter)).toString() + ", mSubscribeType=" + mSubscribeType - + ", mSubscribeCount=" + mSubscribeCount + ", mTtlSec=" + mTtlSec + ", mMatchType=" + + ", mTtlSec=" + mTtlSec + ", mMatchType=" + mMatchStyle + ", mEnableTerminateNotification=" + mEnableTerminateNotification + "]"; } @@ -141,7 +137,6 @@ public final class SubscribeConfig implements Parcelable { dest.writeByteArray(mServiceSpecificInfo); dest.writeByteArray(mMatchFilter); dest.writeInt(mSubscribeType); - dest.writeInt(mSubscribeCount); dest.writeInt(mTtlSec); dest.writeInt(mMatchStyle); dest.writeInt(mEnableTerminateNotification ? 1 : 0); @@ -159,12 +154,11 @@ public final class SubscribeConfig implements Parcelable { byte[] ssi = in.createByteArray(); byte[] matchFilter = in.createByteArray(); int subscribeType = in.readInt(); - int subscribeCount = in.readInt(); int ttlSec = in.readInt(); int matchStyle = in.readInt(); boolean enableTerminateNotification = in.readInt() != 0; - return new SubscribeConfig(serviceName, ssi, matchFilter, subscribeType, subscribeCount, + return new SubscribeConfig(serviceName, ssi, matchFilter, subscribeType, ttlSec, matchStyle, enableTerminateNotification); } }; @@ -183,7 +177,7 @@ public final class SubscribeConfig implements Parcelable { return Arrays.equals(mServiceName, lhs.mServiceName) && Arrays.equals(mServiceSpecificInfo, lhs.mServiceSpecificInfo) && Arrays.equals(mMatchFilter, lhs.mMatchFilter) - && mSubscribeType == lhs.mSubscribeType && mSubscribeCount == lhs.mSubscribeCount + && mSubscribeType == lhs.mSubscribeType && mTtlSec == lhs.mTtlSec && mMatchStyle == lhs.mMatchStyle && mEnableTerminateNotification == lhs.mEnableTerminateNotification; } @@ -196,7 +190,6 @@ public final class SubscribeConfig implements Parcelable { result = 31 * result + Arrays.hashCode(mServiceSpecificInfo); result = 31 * result + Arrays.hashCode(mMatchFilter); result = 31 * result + mSubscribeType; - result = 31 * result + mSubscribeCount; result = 31 * result + mTtlSec; result = 31 * result + mMatchStyle; result = 31 * result + (mEnableTerminateNotification ? 1 : 0); @@ -221,9 +214,6 @@ public final class SubscribeConfig implements Parcelable { if (mSubscribeType < SUBSCRIBE_TYPE_PASSIVE || mSubscribeType > SUBSCRIBE_TYPE_ACTIVE) { throw new IllegalArgumentException("Invalid subscribeType - " + mSubscribeType); } - if (mSubscribeCount < 0) { - throw new IllegalArgumentException("Invalid subscribeCount - must be non-negative"); - } if (mTtlSec < 0) { throw new IllegalArgumentException("Invalid ttlSec - must be non-negative"); } @@ -261,7 +251,6 @@ public final class SubscribeConfig implements Parcelable { private byte[] mServiceSpecificInfo; private byte[] mMatchFilter; private int mSubscribeType = SUBSCRIBE_TYPE_PASSIVE; - private int mSubscribeCount = 0; private int mTtlSec = 0; private int mMatchStyle = MATCH_STYLE_ALL; private boolean mEnableTerminateNotification = true; @@ -350,29 +339,6 @@ public final class SubscribeConfig implements Parcelable { } /** - * Sets the number of times an active ( - * {@link SubscribeConfig.Builder#setSubscribeType(int)}) subscribe session - * will broadcast. When the count is reached an event will be - * generated for {@link DiscoverySessionCallback#onSessionTerminated()}. - * <p> - * Optional. 0 by default - indicating the session doesn't terminate on its own. - * Session will be terminated when {@link DiscoverySession#destroy()} is - * called. - * - * @param subscribeCount Number of subscribe packets to broadcast. - * - * @return The builder to facilitate chaining - * {@code builder.setXXX(..).setXXX(..)}. - */ - public Builder setSubscribeCount(int subscribeCount) { - if (subscribeCount < 0) { - throw new IllegalArgumentException("Invalid subscribeCount - must be non-negative"); - } - mSubscribeCount = subscribeCount; - return this; - } - - /** * Sets the time interval (in seconds) an active ( * {@link SubscribeConfig.Builder#setSubscribeType(int)}) subscribe session * will be alive - i.e. broadcasting a packet. When the TTL is reached @@ -440,7 +406,7 @@ public final class SubscribeConfig implements Parcelable { */ public SubscribeConfig build() { return new SubscribeConfig(mServiceName, mServiceSpecificInfo, mMatchFilter, - mSubscribeType, mSubscribeCount, mTtlSec, mMatchStyle, + mSubscribeType, mTtlSec, mMatchStyle, mEnableTerminateNotification); } } diff --git a/wifi/tests/src/android/net/wifi/WifiScannerTest.java b/wifi/tests/src/android/net/wifi/WifiScannerTest.java index a829eb933b59..e542789e01e3 100644 --- a/wifi/tests/src/android/net/wifi/WifiScannerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiScannerTest.java @@ -16,20 +16,12 @@ package android.net.wifi; -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.validateMockitoUsage; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; -import android.net.wifi.WifiScanner.BssidInfo; -import android.net.wifi.WifiScanner.BssidListener; import android.os.Handler; -import android.os.Message; import android.os.test.TestLooper; import android.test.suitebuilder.annotation.SmallTest; @@ -37,11 +29,10 @@ import com.android.internal.util.test.BidirectionalAsyncChannelServer; import org.junit.After; import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; + /** * Unit tests for {@link android.net.wifi.WifiScanner}. */ @@ -51,8 +42,6 @@ public class WifiScannerTest { private Context mContext; @Mock private IWifiScanner mService; - @Mock - private BssidListener mBssidListener; private WifiScanner mWifiScanner; private TestLooper mLooper; @@ -81,31 +70,4 @@ public class WifiScannerTest { validateMockitoUsage(); } - private void verifySetHotlistMessage(Handler handler) { - ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); - verify(handler, atLeastOnce()).handleMessage(messageCaptor.capture()); - assertEquals("message.what is not CMD_SET_HOTLIST", - WifiScanner.CMD_SET_HOTLIST, - messageCaptor.getValue().what); - } - - /** - * Test duplicate listeners for bssid tracking. - */ - @Test - public void testStartTrackingBssidsDuplicateListeners() throws Exception { - BssidInfo[] bssids = new BssidInfo[] { - new BssidInfo() - }; - - // First start tracking succeeds. - mWifiScanner.startTrackingBssids(bssids, -100, mBssidListener); - mLooper.dispatchAll(); - verifySetHotlistMessage(mHandler); - - // Second start tracking should fail. - mWifiScanner.startTrackingBssids(bssids, -100, mBssidListener); - mLooper.dispatchAll(); - verify(mBssidListener).onFailure(eq(WifiScanner.REASON_DUPLICATE_REQEUST), anyString()); - } } diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java index eceb3658d1d6..830db22929e8 100644 --- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java +++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java @@ -18,11 +18,10 @@ package android.net.wifi.aware; import static org.hamcrest.core.IsEqual.equalTo; import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; -import static org.mockito.Matchers.isNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; @@ -140,8 +139,8 @@ public class WifiAwareManagerTest { // (1) connect + success mDut.attach(mockCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).connect(binder.capture(), anyString(), - clientProxyCallback.capture(), (ConfigRequest) isNull(), eq(false)); + inOrder.verify(mockAwareService).connect(binder.capture(), any(), + clientProxyCallback.capture(), isNull(), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); inOrder.verify(mockCallback).onAttached(sessionCaptor.capture()); @@ -150,8 +149,7 @@ public class WifiAwareManagerTest { // (2) publish - should succeed PublishConfig publishConfig = new PublishConfig.Builder().build(); session.publish(publishConfig, mockSessionCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).publish(eq(clientId), eq(publishConfig), - any(IWifiAwareDiscoverySessionCallback.class)); + inOrder.verify(mockAwareService).publish(eq(clientId), eq(publishConfig), any()); // (3) disconnect session.destroy(); @@ -163,8 +161,8 @@ public class WifiAwareManagerTest { // (5) connect mDut.attach(mockCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).connect(binder.capture(), anyString(), - any(IWifiAwareEventCallback.class), (ConfigRequest) isNull(), eq(false)); + inOrder.verify(mockAwareService).connect(binder.capture(), any(), any(), isNull(), + eq(false)); verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService); } @@ -185,16 +183,16 @@ public class WifiAwareManagerTest { // (1) connect + failure mDut.attach(mockCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).connect(any(IBinder.class), anyString(), - clientProxyCallback.capture(), (ConfigRequest) isNull(), eq(false)); + inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + isNull(), eq(false)); clientProxyCallback.getValue().onConnectFail(reason); mMockLooper.dispatchAll(); inOrder.verify(mockCallback).onAttachFailed(); // (2) connect + success mDut.attach(mockCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).connect(any(IBinder.class), anyString(), - clientProxyCallback.capture(), (ConfigRequest) isNull(), eq(false)); + inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + isNull(), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); inOrder.verify(mockCallback).onAttached(sessionCaptor.capture()); @@ -203,8 +201,7 @@ public class WifiAwareManagerTest { // (4) subscribe: should succeed SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build(); session.subscribe(subscribeConfig, mockSessionCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).subscribe(eq(clientId), eq(subscribeConfig), - any(IWifiAwareDiscoverySessionCallback.class)); + inOrder.verify(mockAwareService).subscribe(eq(clientId), eq(subscribeConfig), any()); verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService); } @@ -223,19 +220,19 @@ public class WifiAwareManagerTest { // (1) connect + success mDut.attach(mockCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).connect(any(IBinder.class), anyString(), - clientProxyCallback.capture(), (ConfigRequest) isNull(), eq(false)); + inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + isNull(), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); - inOrder.verify(mockCallback).onAttached(any(WifiAwareSession.class)); + inOrder.verify(mockCallback).onAttached(any()); // (2) connect + success mDut.attach(mockCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).connect(any(IBinder.class), anyString(), - clientProxyCallback.capture(), (ConfigRequest) isNull(), eq(false)); + inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + isNull(), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId + 1); mMockLooper.dispatchAll(); - inOrder.verify(mockCallback).onAttached(any(WifiAwareSession.class)); + inOrder.verify(mockCallback).onAttached(any()); verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService); } @@ -278,8 +275,8 @@ public class WifiAwareManagerTest { // (0) connect + success mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); - inOrder.verify(mockAwareService).connect(any(IBinder.class), anyString(), - clientProxyCallback.capture(), eq(configRequest), eq(false)); + inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + eq(configRequest), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); inOrder.verify(mockCallback).onAttached(sessionCaptor.capture()); @@ -370,8 +367,8 @@ public class WifiAwareManagerTest { // (1) connect successfully mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); - inOrder.verify(mockAwareService).connect(any(IBinder.class), anyString(), - clientProxyCallback.capture(), eq(configRequest), eq(false)); + inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + eq(configRequest), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); inOrder.verify(mockCallback).onAttached(sessionCaptor.capture()); @@ -426,8 +423,8 @@ public class WifiAwareManagerTest { // (0) connect + success mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); - inOrder.verify(mockAwareService).connect(any(IBinder.class), anyString(), - clientProxyCallback.capture(), eq(configRequest), eq(false)); + inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + eq(configRequest), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); inOrder.verify(mockCallback).onAttached(sessionCaptor.capture()); @@ -507,8 +504,8 @@ public class WifiAwareManagerTest { // (1) connect successfully mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); - inOrder.verify(mockAwareService).connect(any(IBinder.class), anyString(), - clientProxyCallback.capture(), eq(configRequest), eq(false)); + inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + eq(configRequest), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); inOrder.verify(mockCallback).onAttached(sessionCaptor.capture()); @@ -691,7 +688,6 @@ public class WifiAwareManagerTest { collector.checkThat("mServiceName", subscribeConfig.mServiceName, equalTo(null)); collector.checkThat("mSubscribeType", subscribeConfig.mSubscribeType, equalTo(SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE)); - collector.checkThat("mSubscribeCount", subscribeConfig.mSubscribeCount, equalTo(0)); collector.checkThat("mTtlSec", subscribeConfig.mTtlSec, equalTo(0)); collector.checkThat("mMatchStyle", subscribeConfig.mMatchStyle, equalTo(SubscribeConfig.MATCH_STYLE_ALL)); @@ -714,7 +710,7 @@ public class WifiAwareManagerTest { .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter( new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList()) .setSubscribeType(subscribeType) - .setSubscribeCount(subscribeCount).setTtlSec(subscribeTtl).setMatchStyle(matchStyle) + .setTtlSec(subscribeTtl).setMatchStyle(matchStyle) .setTerminateNotificationEnabled(enableTerminateNotification).build(); collector.checkThat("mServiceName", serviceName.getBytes(), @@ -724,8 +720,6 @@ public class WifiAwareManagerTest { collector.checkThat("mMatchFilter", matchFilter, equalTo(subscribeConfig.mMatchFilter)); collector.checkThat("mSubscribeType", subscribeType, equalTo(subscribeConfig.mSubscribeType)); - collector.checkThat("mSubscribeCount", subscribeCount, - equalTo(subscribeConfig.mSubscribeCount)); collector.checkThat("mTtlSec", subscribeTtl, equalTo(subscribeConfig.mTtlSec)); collector.checkThat("mMatchStyle", matchStyle, equalTo(subscribeConfig.mMatchStyle)); collector.checkThat("mEnableTerminateNotification", enableTerminateNotification, @@ -747,7 +741,7 @@ public class WifiAwareManagerTest { .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter( new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList()) .setSubscribeType(subscribeType) - .setSubscribeCount(subscribeCount).setTtlSec(subscribeTtl).setMatchStyle(matchStyle) + .setTtlSec(subscribeTtl).setMatchStyle(matchStyle) .setTerminateNotificationEnabled(enableTerminateNotification).build(); Parcel parcelW = Parcel.obtain(); @@ -769,11 +763,6 @@ public class WifiAwareManagerTest { } @Test(expected = IllegalArgumentException.class) - public void testSubscribeConfigBuilderNegativeCount() { - new SubscribeConfig.Builder().setSubscribeCount(-1); - } - - @Test(expected = IllegalArgumentException.class) public void testSubscribeConfigBuilderNegativeTtl() { new SubscribeConfig.Builder().setTtlSec(-100); } @@ -797,7 +786,6 @@ public class WifiAwareManagerTest { collector.checkThat("mServiceName", publishConfig.mServiceName, equalTo(null)); collector.checkThat("mPublishType", publishConfig.mPublishType, equalTo(PublishConfig.PUBLISH_TYPE_UNSOLICITED)); - collector.checkThat("mPublishCount", publishConfig.mPublishCount, equalTo(0)); collector.checkThat("mTtlSec", publishConfig.mTtlSec, equalTo(0)); collector.checkThat("mEnableTerminateNotification", publishConfig.mEnableTerminateNotification, equalTo(true)); @@ -817,7 +805,7 @@ public class WifiAwareManagerTest { .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter( new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList()) .setPublishType(publishType) - .setPublishCount(publishCount).setTtlSec(publishTtl) + .setTtlSec(publishTtl) .setTerminateNotificationEnabled(enableTerminateNotification).build(); collector.checkThat("mServiceName", serviceName.getBytes(), @@ -826,7 +814,6 @@ public class WifiAwareManagerTest { serviceSpecificInfo.getBytes(), equalTo(publishConfig.mServiceSpecificInfo)); collector.checkThat("mMatchFilter", matchFilter, equalTo(publishConfig.mMatchFilter)); collector.checkThat("mPublishType", publishType, equalTo(publishConfig.mPublishType)); - collector.checkThat("mPublishCount", publishCount, equalTo(publishConfig.mPublishCount)); collector.checkThat("mTtlSec", publishTtl, equalTo(publishConfig.mTtlSec)); collector.checkThat("mEnableTerminateNotification", enableTerminateNotification, equalTo(publishConfig.mEnableTerminateNotification)); @@ -846,7 +833,7 @@ public class WifiAwareManagerTest { .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter( new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList()) .setPublishType(publishType) - .setPublishCount(publishCount).setTtlSec(publishTtl) + .setTtlSec(publishTtl) .setTerminateNotificationEnabled(enableTerminateNotification).build(); Parcel parcelW = Parcel.obtain(); @@ -868,11 +855,6 @@ public class WifiAwareManagerTest { } @Test(expected = IllegalArgumentException.class) - public void testPublishConfigBuilderNegativeCount() { - new PublishConfig.Builder().setPublishCount(-4); - } - - @Test(expected = IllegalArgumentException.class) public void testPublishConfigBuilderNegativeTtl() { new PublishConfig.Builder().setTtlSec(-10); } @@ -899,8 +881,7 @@ public class WifiAwareManagerTest { final RttManager.RttResult rttResults = new RttManager.RttResult(); rttResults.distance = 10; - when(mockAwareService.startRanging(anyInt(), anyInt(), - any(RttManager.ParcelableRttParams.class))).thenReturn(rangingId); + when(mockAwareService.startRanging(anyInt(), anyInt(), any())).thenReturn(rangingId); InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService, mockPublishSession, mockRttListener); @@ -919,8 +900,8 @@ public class WifiAwareManagerTest { // (1) connect successfully mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); - inOrder.verify(mockAwareService).connect(any(IBinder.class), anyString(), - clientProxyCallback.capture(), eq(configRequest), eq(false)); + inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + eq(configRequest), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); inOrder.verify(mockCallback).onAttached(sessionCaptor.capture()); @@ -994,8 +975,8 @@ public class WifiAwareManagerTest { // (1) connect successfully mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); - inOrder.verify(mockAwareService).connect(any(IBinder.class), anyString(), - clientProxyCallback.capture(), eq(configRequest), eq(false)); + inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + eq(configRequest), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); inOrder.verify(mockCallback).onAttached(sessionCaptor.capture()); @@ -1085,8 +1066,8 @@ public class WifiAwareManagerTest { // (1) connect successfully mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); - inOrder.verify(mockAwareService).connect(any(IBinder.class), anyString(), - clientProxyCallback.capture(), eq(configRequest), eq(false)); + inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + eq(configRequest), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); inOrder.verify(mockCallback).onAttached(sessionCaptor.capture()); |