diff options
698 files changed, 14646 insertions, 9522 deletions
diff --git a/Android.bp b/Android.bp index 035420f9ff50..d2d8a3657bcf 100644 --- a/Android.bp +++ b/Android.bp @@ -248,7 +248,6 @@ java_defaults { "core/java/android/os/ICancellationSignal.aidl", "core/java/android/os/IDeviceIdentifiersPolicyService.aidl", "core/java/android/os/IDeviceIdleController.aidl", - "core/java/android/os/IDynamicAndroidService.aidl", "core/java/android/os/IHardwarePropertiesManager.aidl", ":libincident_aidl", "core/java/android/os/IMaintenanceActivityListener.aidl", @@ -272,6 +271,7 @@ java_defaults { "core/java/android/os/IUserManager.aidl", ":libvibrator_aidl", "core/java/android/os/IVibratorService.aidl", + "core/java/android/os/image/IDynamicSystemService.aidl", "core/java/android/os/storage/IStorageManager.aidl", "core/java/android/os/storage/IStorageEventListener.aidl", "core/java/android/os/storage/IStorageShutdownObserver.aidl", @@ -318,6 +318,7 @@ java_defaults { "core/java/android/service/vr/IVrListener.aidl", "core/java/android/service/vr/IVrManager.aidl", "core/java/android/service/vr/IVrStateCallbacks.aidl", + "core/java/android/service/watchdog/IExplicitHealthCheckService.aidl", "core/java/android/print/ILayoutResultCallback.aidl", "core/java/android/print/IPrinterDiscoveryObserver.aidl", "core/java/android/print/IPrintDocumentAdapter.aidl", @@ -886,66 +887,6 @@ gensrcs { output_extension: "srcjar", } -// AIDL interfaces between the core system and the networking mainline module. -aidl_interface { - name: "networkstack-aidl-interfaces", - local_include_dir: "core/java", - srcs: [ - "core/java/android/net/ApfCapabilitiesParcelable.aidl", - "core/java/android/net/DhcpResultsParcelable.aidl", - "core/java/android/net/INetworkMonitor.aidl", - "core/java/android/net/INetworkMonitorCallbacks.aidl", - "core/java/android/net/INetworkStackConnector.aidl", - "core/java/android/net/INetworkStackStatusCallback.aidl", - "core/java/android/net/InitialConfigurationParcelable.aidl", - "core/java/android/net/PrivateDnsConfigParcel.aidl", - "core/java/android/net/ProvisioningConfigurationParcelable.aidl", - "core/java/android/net/StaticIpConfigurationParcelable.aidl", - "core/java/android/net/TcpKeepalivePacketDataParcelable.aidl", - "core/java/android/net/dhcp/DhcpServingParamsParcel.aidl", - "core/java/android/net/dhcp/IDhcpServer.aidl", - "core/java/android/net/dhcp/IDhcpServerCallbacks.aidl", - "core/java/android/net/ip/IIpClient.aidl", - "core/java/android/net/ip/IIpClientCallbacks.aidl", - "core/java/android/net/IIpMemoryStore.aidl", - "core/java/android/net/IIpMemoryStoreCallbacks.aidl", - "core/java/android/net/ipmemorystore/**/*.aidl", - ], - backend: { - ndk: { - enabled: false, - }, - cpp: { - enabled: false, - }, - }, - api_dir: "aidl/networkstack", -} - -aidl_interface { - name: "ipmemorystore-aidl-interfaces", - local_include_dir: "core/java", - srcs: [ - "core/java/android/net/IIpMemoryStore.aidl", - "core/java/android/net/IIpMemoryStoreCallbacks.aidl", - "core/java/android/net/ipmemorystore/**/*.aidl", - ], -} - -aidl_interface { - name: "networkstack-aidl-framework", - local_include_dir: "core/java", - srcs: [ - "core/java/android/net/TcpKeepalivePacketDataParcelable.aidl", - ], - api_dir: "aidl/networkstack", - backend: { - java: { - sdk_version: "28", - }, - }, -} - filegroup { name: "framework-annotations", srcs: [ @@ -1686,6 +1627,7 @@ droidstubs { ":openjdk_java_files", ":non_openjdk_java_files", ":opt-telephony-common-srcs", + "core/java/**/*.java", ], arg_files: [ "core/res/AndroidManifest.xml", diff --git a/CleanSpec.mk b/CleanSpec.mk index 30c2c69e8572..6160acbcf130 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk @@ -253,6 +253,7 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/vendor/overlay/ExperimentNav $(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/overlay/ExperimentNavigationBarSlim) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app/SystemUI) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app/DynamicAndroidInstallationService) # ****************************************************************** # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER # ****************************************************************** diff --git a/api/current.txt b/api/current.txt index 859e54a77897..8192762c4d63 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5481,10 +5481,10 @@ package android.app { method public boolean getAutoExpandBubble(); method @Nullable public android.app.PendingIntent getDeleteIntent(); method public int getDesiredHeight(); + method @DimenRes public int getDesiredHeightResId(); method @NonNull public android.graphics.drawable.Icon getIcon(); method @NonNull public android.app.PendingIntent getIntent(); method public boolean getSuppressInitialNotification(); - method @Deprecated public CharSequence getTitle(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.app.Notification.BubbleMetadata> CREATOR; } @@ -5495,10 +5495,10 @@ package android.app { method @NonNull public android.app.Notification.BubbleMetadata.Builder setAutoExpandBubble(boolean); method @NonNull public android.app.Notification.BubbleMetadata.Builder setDeleteIntent(@Nullable android.app.PendingIntent); method @NonNull public android.app.Notification.BubbleMetadata.Builder setDesiredHeight(int); + method @NonNull public android.app.Notification.BubbleMetadata.Builder setDesiredHeightResId(@DimenRes int); method @NonNull public android.app.Notification.BubbleMetadata.Builder setIcon(@NonNull android.graphics.drawable.Icon); method @NonNull public android.app.Notification.BubbleMetadata.Builder setIntent(@NonNull android.app.PendingIntent); method @NonNull public android.app.Notification.BubbleMetadata.Builder setSuppressInitialNotification(boolean); - method @Deprecated public android.app.Notification.BubbleMetadata.Builder setTitle(CharSequence); } public static class Notification.Builder { @@ -5848,8 +5848,8 @@ package android.app { field public static final int INTERRUPTION_FILTER_NONE = 3; // 0x3 field public static final int INTERRUPTION_FILTER_PRIORITY = 2; // 0x2 field public static final int INTERRUPTION_FILTER_UNKNOWN = 0; // 0x0 - field public static final String META_DATA_AUTOMATIC_RULE_TYPE = "android.app.automatic.ruleType"; - field public static final String META_DATA_RULE_INSTANCE_LIMIT = "android.app.zen.automatic.ruleInstanceLimit"; + field public static final String META_DATA_AUTOMATIC_RULE_TYPE = "android.service.zen.automatic.ruleType"; + field public static final String META_DATA_RULE_INSTANCE_LIMIT = "android.service.zen.automatic.ruleInstanceLimit"; } public static class NotificationManager.Policy implements android.os.Parcelable { @@ -6952,7 +6952,6 @@ package android.app.admin { field public static final int PRIVATE_DNS_SET_NO_ERROR = 0; // 0x0 field public static final int PROVISIONING_MODE_FULLY_MANAGED_DEVICE = 1; // 0x1 field public static final int PROVISIONING_MODE_MANAGED_PROFILE = 2; // 0x2 - field public static final int PROVISIONING_MODE_MANAGED_PROFILE_ON_FULLY_MANAGED_DEVICE = 3; // 0x3 field public static final int RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT = 2; // 0x2 field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1 field public static final int SKIP_SETUP_WIZARD = 1; // 0x1 @@ -9794,6 +9793,7 @@ package android.content { field public static final int BIND_DEBUG_UNBIND = 2; // 0x2 field public static final int BIND_EXTERNAL_SERVICE = -2147483648; // 0x80000000 field public static final int BIND_IMPORTANT = 64; // 0x40 + field public static final int BIND_INCLUDE_CAPABILITIES = 4096; // 0x1000 field public static final int BIND_NOT_FOREGROUND = 4; // 0x4 field public static final int BIND_WAIVE_PRIORITY = 32; // 0x20 field public static final String BIOMETRIC_SERVICE = "biometric"; @@ -12356,6 +12356,7 @@ package android.content.res { method @NonNull public android.content.res.TypedArray obtainStyledAttributes(@NonNull @StyleableRes int[]); method @NonNull public android.content.res.TypedArray obtainStyledAttributes(@StyleRes int, @NonNull @StyleableRes int[]) throws android.content.res.Resources.NotFoundException; method @NonNull public android.content.res.TypedArray obtainStyledAttributes(@Nullable android.util.AttributeSet, @NonNull @StyleableRes int[], @AttrRes int, @StyleRes int); + method public void rebase(); method public boolean resolveAttribute(int, android.util.TypedValue, boolean); method public void setTo(android.content.res.Resources.Theme); } @@ -22664,18 +22665,22 @@ package android.location { public final class GnssClock implements android.os.Parcelable { method public int describeContents(); method public double getBiasNanos(); - method public double getBiasUncertaintyNanos(); + method @FloatRange(from=0.0f) public double getBiasUncertaintyNanos(); method public double getDriftNanosPerSecond(); - method public double getDriftUncertaintyNanosPerSecond(); + method @FloatRange(from=0.0f) public double getDriftUncertaintyNanosPerSecond(); + method public long getElapsedRealtimeNanos(); + method @IntRange(from=0) public long getElapsedRealtimeUncertaintyNanos(); method public long getFullBiasNanos(); method public int getHardwareClockDiscontinuityCount(); method public int getLeapSecond(); method public long getTimeNanos(); - method public double getTimeUncertaintyNanos(); + method @FloatRange(from=0.0f) public double getTimeUncertaintyNanos(); method public boolean hasBiasNanos(); method public boolean hasBiasUncertaintyNanos(); method public boolean hasDriftNanosPerSecond(); method public boolean hasDriftUncertaintyNanosPerSecond(); + method public boolean hasElapsedRealtimeNanos(); + method public boolean hasElapsedRealtimeUncertaintyNanos(); method public boolean hasFullBiasNanos(); method public boolean hasLeapSecond(); method public boolean hasTimeUncertaintyNanos(); @@ -23249,7 +23254,7 @@ package android.media { method public static boolean isHapticPlaybackSupported(); method public boolean isMicrophoneMute(); method public boolean isMusicActive(); - method public static boolean isOffloadedPlaybackSupported(@NonNull android.media.AudioFormat); + method public static boolean isOffloadedPlaybackSupported(@NonNull android.media.AudioFormat, @NonNull android.media.AudioAttributes); method public boolean isSpeakerphoneOn(); method public boolean isStreamMute(int); method public boolean isVolumeFixed(); @@ -23484,11 +23489,11 @@ package android.media { method public void release(); method public void removeOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener); method @Deprecated public void removeOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener); - method public boolean setMicrophoneDirection(int); - method public boolean setMicrophoneFieldDimension(@FloatRange(from=-1.0, to=1.0) float); method public int setNotificationMarkerPosition(int); method public int setPositionNotificationPeriod(int); method public boolean setPreferredDevice(android.media.AudioDeviceInfo); + method public boolean setPreferredMicrophoneDirection(int); + method public boolean setPreferredMicrophoneFieldDimension(@FloatRange(from=-1.0, to=1.0) float); method public void setRecordPositionUpdateListener(android.media.AudioRecord.OnRecordPositionUpdateListener); method public void setRecordPositionUpdateListener(android.media.AudioRecord.OnRecordPositionUpdateListener, android.os.Handler); method public void startRecording() throws java.lang.IllegalStateException; @@ -23760,12 +23765,6 @@ package android.media { field public static final int QUALITY_MEDIUM = 1; // 0x1 } - public abstract class DataSourceCallback implements java.io.Closeable { - ctor public DataSourceCallback(); - method public abstract long getSize() throws java.io.IOException; - method public abstract int readAt(long, @NonNull byte[], int, int) throws java.io.IOException; - } - public class DataSourceDesc { method public long getEndPosition(); method @Nullable public String getMediaId(); @@ -23782,7 +23781,6 @@ package android.media { method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.net.Uri, @Nullable java.util.Map<java.lang.String,java.lang.String>, @Nullable java.util.List<java.net.HttpCookie>); method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.os.ParcelFileDescriptor); method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.os.ParcelFileDescriptor, long, long); - method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.media.DataSourceCallback); method @NonNull public android.media.DataSourceDesc.Builder setEndPosition(long); method @NonNull public android.media.DataSourceDesc.Builder setMediaId(@Nullable String); method @NonNull public android.media.DataSourceDesc.Builder setStartPosition(long); @@ -24853,6 +24851,7 @@ package android.media { field public static final int STATUS_OUTPUT_NOT_ALLOWED = 2; // 0x2 field public static final int STATUS_PENDING = 3; // 0x3 field public static final int STATUS_USABLE = 0; // 0x0 + field public static final int STATUS_USABLE_IN_FUTURE = 5; // 0x5 } public static final class MediaDrm.MediaDrmStateException extends java.lang.IllegalStateException { @@ -24925,6 +24924,7 @@ package android.media { ctor public MediaDrm.SessionException(int, @Nullable String); method public int getErrorCode(); field public static final int ERROR_RESOURCE_CONTENTION = 1; // 0x1 + field public static final int ERROR_UNKNOWN = 0; // 0x0 } public class MediaDrmException extends java.lang.Exception { @@ -25054,6 +25054,7 @@ package android.media { field public static final String KEY_FRAME_RATE = "frame-rate"; field public static final String KEY_GRID_COLUMNS = "grid-cols"; field public static final String KEY_GRID_ROWS = "grid-rows"; + field public static final String KEY_HAPTIC_CHANNEL_COUNT = "haptic-channel-count"; field public static final String KEY_HDR10_PLUS_INFO = "hdr10-plus-info"; field public static final String KEY_HDR_STATIC_INFO = "hdr-static-info"; field public static final String KEY_HEIGHT = "height"; @@ -25552,8 +25553,8 @@ package android.media { method @NonNull public Object clearNextDataSources(); method public void clearPendingCommands(); method public void close(); - method @NonNull public Object deselectTrack(int); - method @NonNull public Object deselectTrack(@NonNull android.media.DataSourceDesc, int); + method @NonNull public Object deselectTrack(@NonNull android.media.MediaPlayer2.TrackInfo); + method @NonNull public Object deselectTrack(@NonNull android.media.DataSourceDesc, @NonNull android.media.MediaPlayer2.TrackInfo); method @NonNull public android.media.AudioAttributes getAudioAttributes(); method public int getAudioSessionId(); method public long getBufferedPosition(); @@ -25568,8 +25569,8 @@ package android.media { method public float getPlayerVolume(); method @Nullable public android.media.AudioDeviceInfo getPreferredDevice(); method @Nullable public android.media.AudioDeviceInfo getRoutedDevice(); - method public int getSelectedTrack(int); - method public int getSelectedTrack(@NonNull android.media.DataSourceDesc, int); + method @Nullable public android.media.MediaPlayer2.TrackInfo getSelectedTrack(int); + method @Nullable public android.media.MediaPlayer2.TrackInfo getSelectedTrack(@NonNull android.media.DataSourceDesc, int); method public int getState(); method @NonNull public android.media.SyncParams getSyncParams(); method @Nullable public android.media.MediaTimestamp getTimestamp(); @@ -25587,8 +25588,8 @@ package android.media { method public void reset(); method @NonNull public Object seekTo(long); method @NonNull public Object seekTo(long, int); - method @NonNull public Object selectTrack(int); - method @NonNull public Object selectTrack(@NonNull android.media.DataSourceDesc, int); + method @NonNull public Object selectTrack(@NonNull android.media.MediaPlayer2.TrackInfo); + method @NonNull public Object selectTrack(@NonNull android.media.DataSourceDesc, @NonNull android.media.MediaPlayer2.TrackInfo); method @NonNull public Object setAudioAttributes(@NonNull android.media.AudioAttributes); method @NonNull public Object setAudioSessionId(int); method @NonNull public Object setAuxEffectSendLevel(float); @@ -25681,11 +25682,11 @@ package android.media { field public static final int SEEK_PREVIOUS_SYNC = 0; // 0x0 } - public static class MediaPlayer2.DrmEventCallback { + public abstract static class MediaPlayer2.DrmEventCallback { ctor public MediaPlayer2.DrmEventCallback(); method public void onDrmConfig(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaDrm); - method @Nullable public android.media.MediaPlayer2.DrmPreparationInfo onDrmInfo(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaPlayer2.DrmInfo); - method @NonNull public byte[] onDrmKeyRequest(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaDrm.KeyRequest); + method @Nullable public abstract android.media.MediaPlayer2.DrmPreparationInfo onDrmInfo(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaPlayer2.DrmInfo); + method @NonNull public abstract byte[] onDrmKeyRequest(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaDrm.KeyRequest); method public void onDrmPrepared(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, int, @Nullable byte[]); } @@ -25695,17 +25696,22 @@ package android.media { } public static final class MediaPlayer2.DrmPreparationInfo { + method @Nullable public byte[] getInitData(); + method @Nullable public byte[] getKeySetId(); + method public int getKeyType(); + method @Nullable public String getMimeType(); + method @Nullable public java.util.Map<java.lang.String,java.lang.String> getOptionalParameters(); + method @NonNull public java.util.UUID getUuid(); } public static final class MediaPlayer2.DrmPreparationInfo.Builder { - ctor public MediaPlayer2.DrmPreparationInfo.Builder(); + ctor public MediaPlayer2.DrmPreparationInfo.Builder(@NonNull java.util.UUID); method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo build(); method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setInitData(@Nullable byte[]); method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setKeySetId(@Nullable byte[]); method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setKeyType(int); method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setMimeType(@Nullable String); method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setOptionalParameters(@Nullable java.util.Map<java.lang.String,java.lang.String>); - method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setUuid(@NonNull java.util.UUID); } public static class MediaPlayer2.EventCallback { @@ -25715,7 +25721,7 @@ package android.media { method public void onError(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, int, int); method public void onInfo(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, int, int); method public void onMediaTimeDiscontinuity(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaTimestamp); - method public void onSubtitleData(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.SubtitleData); + method public void onSubtitleData(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaPlayer2.SubtitleData); method public void onTimedMetaDataAvailable(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.TimedMetaData); method public void onVideoSizeChanged(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.util.Size); } @@ -25739,6 +25745,13 @@ package android.media { ctor public MediaPlayer2.NoDrmSchemeException(@Nullable String); } + public static final class MediaPlayer2.SubtitleData { + method @NonNull public byte[] getData(); + method public long getDurationUs(); + method public long getStartTimeUs(); + method @NonNull public android.media.MediaPlayer2.TrackInfo getTrackInfo(); + } + public static class MediaPlayer2.TrackInfo { method @Nullable public android.media.MediaFormat getFormat(); method @NonNull public String getLanguage(); @@ -25780,8 +25793,6 @@ package android.media { method public void setLocation(float, float); method public void setMaxDuration(int) throws java.lang.IllegalArgumentException; method public void setMaxFileSize(long) throws java.lang.IllegalArgumentException; - method public boolean setMicrophoneDirection(int); - method public boolean setMicrophoneFieldDimension(@FloatRange(from=-1.0, to=1.0) float); method public void setNextOutputFile(java.io.FileDescriptor) throws java.io.IOException; method public void setNextOutputFile(java.io.File) throws java.io.IOException; method public void setOnErrorListener(android.media.MediaRecorder.OnErrorListener); @@ -25792,6 +25803,8 @@ package android.media { method public void setOutputFile(String) throws java.lang.IllegalStateException; method public void setOutputFormat(int) throws java.lang.IllegalStateException; method public boolean setPreferredDevice(android.media.AudioDeviceInfo); + method public boolean setPreferredMicrophoneDirection(int); + method public boolean setPreferredMicrophoneFieldDimension(@FloatRange(from=-1.0, to=1.0) float); method public void setPreviewDisplay(android.view.Surface); method public void setProfile(android.media.CamcorderProfile); method public void setVideoEncoder(int) throws java.lang.IllegalStateException; @@ -26135,11 +26148,11 @@ package android.media { } public interface MicrophoneDirection { - method public boolean setMicrophoneDirection(int); - method public boolean setMicrophoneFieldDimension(@FloatRange(from=-1.0, to=1.0) float); - field public static final int MIC_DIRECTION_BACK = 2; // 0x2 + method public boolean setPreferredMicrophoneDirection(int); + method public boolean setPreferredMicrophoneFieldDimension(@FloatRange(from=-1.0, to=1.0) float); + field public static final int MIC_DIRECTION_AWAY_FROM_USER = 2; // 0x2 field public static final int MIC_DIRECTION_EXTERNAL = 3; // 0x3 - field public static final int MIC_DIRECTION_FRONT = 1; // 0x1 + field public static final int MIC_DIRECTION_TOWARDS_USER = 1; // 0x1 field public static final int MIC_DIRECTION_UNSPECIFIED = 0; // 0x0 } @@ -26344,6 +26357,8 @@ package android.media { method public android.net.Uri getRingtoneUri(int); method public boolean getStopPreviousRingtone(); method public static android.net.Uri getValidRingtoneUri(android.content.Context); + method public boolean hasHapticChannels(int); + method public static boolean hasHapticChannels(@NonNull android.net.Uri); method public int inferStreamType(); method public static boolean isDefault(android.net.Uri); method @Nullable public static android.content.res.AssetFileDescriptor openDefaultRingtoneUri(@NonNull android.content.Context, @NonNull android.net.Uri) throws java.io.FileNotFoundException; @@ -26380,15 +26395,15 @@ package android.media { method public void writeToParcel(@NonNull android.os.Parcel, int); field public static final int COMMAND_CODE_CUSTOM = 0; // 0x0 field @NonNull public static final android.os.Parcelable.Creator<android.media.Session2Command> CREATOR; - field public static final int RESULT_ERROR_UNKNOWN_ERROR = -1; // 0xffffffff - field public static final int RESULT_INFO_SKIPPED = 1; // 0x1 - field public static final int RESULT_SUCCESS = 0; // 0x0 } public static final class Session2Command.Result { ctor public Session2Command.Result(int, @Nullable android.os.Bundle); method public int getResultCode(); method @Nullable public android.os.Bundle getResultData(); + field public static final int RESULT_ERROR_UNKNOWN_ERROR = -1; // 0xffffffff + field public static final int RESULT_INFO_SKIPPED = 1; // 0x1 + field public static final int RESULT_SUCCESS = 0; // 0x0 } public final class Session2CommandGroup implements android.os.Parcelable { @@ -28618,7 +28633,7 @@ package android.net { public class ConnectivityManager { method public void addDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener); method public boolean bindProcessToNetwork(@Nullable android.net.Network); - method public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull android.net.IpSecManager.UdpEncapsulationSocket, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback); + method @NonNull public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull android.net.IpSecManager.UdpEncapsulationSocket, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback); method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) @Nullable public android.net.Network getActiveNetwork(); method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo getActiveNetworkInfo(); method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo[] getAllNetworkInfo(); @@ -28696,7 +28711,7 @@ package android.net { public static class ConnectivityManager.NetworkCallback { ctor public ConnectivityManager.NetworkCallback(); method public void onAvailable(android.net.Network); - method public void onBlockedStatusChanged(android.net.Network, boolean); + method public void onBlockedStatusChanged(@NonNull android.net.Network, boolean); method public void onCapabilitiesChanged(android.net.Network, android.net.NetworkCapabilities); method public void onLinkPropertiesChanged(android.net.Network, android.net.LinkProperties); method public void onLosing(android.net.Network, int); @@ -28730,8 +28745,8 @@ package android.net { public final class DnsResolver { method @NonNull public static android.net.DnsResolver getInstance(); - method public <T> void query(@Nullable android.net.Network, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @NonNull android.net.DnsResolver.AnswerCallback<T>); - method public <T> void query(@Nullable android.net.Network, @NonNull String, int, int, int, @NonNull java.util.concurrent.Executor, @NonNull android.net.DnsResolver.AnswerCallback<T>); + method public <T> void query(@Nullable android.net.Network, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.AnswerCallback<T>); + method public <T> void query(@Nullable android.net.Network, @NonNull String, int, int, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.AnswerCallback<T>); field public static final int CLASS_IN = 1; // 0x1 field public static final int FLAG_EMPTY = 0; // 0x0 field public static final int FLAG_NO_CACHE_LOOKUP = 4; // 0x4 @@ -29153,7 +29168,7 @@ package android.net { method public final void start(@IntRange(from=0xa, to=0xe10) int); method public final void stop(); field public static final int ERROR_HARDWARE_ERROR = -31; // 0xffffffe1 - field public static final int ERROR_HARDWARE_UNSUPPORTED = -30; // 0xffffffe2 + field public static final int ERROR_INSUFFICIENT_RESOURCES = -32; // 0xffffffe0 field public static final int ERROR_INVALID_INTERVAL = -24; // 0xffffffe8 field public static final int ERROR_INVALID_IP_ADDRESS = -21; // 0xffffffeb field public static final int ERROR_INVALID_LENGTH = -23; // 0xffffffe9 @@ -29161,6 +29176,7 @@ package android.net { field public static final int ERROR_INVALID_PORT = -22; // 0xffffffea field public static final int ERROR_INVALID_SOCKET = -25; // 0xffffffe7 field public static final int ERROR_SOCKET_NOT_IDLE = -26; // 0xffffffe6 + field public static final int ERROR_UNSUPPORTED = -30; // 0xffffffe2 } public static class SocketKeepalive.Callback { @@ -30743,7 +30759,6 @@ package android.net.wifi.rtt { method public double getAltitudeUncertainty(); method public java.util.List<android.net.MacAddress> getColocatedBssids(); method public int getDatum(); - method public boolean getDependentStationIndication(); method public int getExpectedToMove(); method public double getFloorNumber(); method public double getHeightAboveFloorMeters(); @@ -30756,7 +30771,6 @@ package android.net.wifi.rtt { method @Nullable public String getMapImageMimeType(); method @Nullable public android.net.Uri getMapImageUri(); method public boolean getRegisteredLocationAgreementIndication(); - method public boolean getRegisteredLocationDseIndication(); method public boolean isLciSubelementValid(); method public boolean isZaxisSubelementValid(); method @Nullable public android.location.Address toCivicLocationAddress(); @@ -34600,6 +34614,7 @@ package android.os { method @RequiresPermission(allOf={android.Manifest.permission.READ_LOGS, android.Manifest.permission.PACKAGE_USAGE_STATS}) @Nullable public android.os.DropBoxManager.Entry getNextEntry(String, long); method public boolean isTagEnabled(String); field public static final String ACTION_DROPBOX_ENTRY_ADDED = "android.intent.action.DROPBOX_ENTRY_ADDED"; + field public static final String EXTRA_DROPPED_COUNT = "android.os.extra.DROPPED_COUNT"; field public static final String EXTRA_TAG = "tag"; field public static final String EXTRA_TIME = "time"; field public static final int IS_EMPTY = 1; // 0x1 @@ -38746,8 +38761,7 @@ package android.provider { field public static final String MIME_TYPE = "mime_type"; field public static final String ORIGINAL_DOCUMENT_ID = "original_document_id"; field public static final String OWNER_PACKAGE_NAME = "owner_package_name"; - field public static final String PRIMARY_DIRECTORY = "primary_directory"; - field public static final String SECONDARY_DIRECTORY = "secondary_directory"; + field public static final String RELATIVE_PATH = "relative_path"; field public static final String SIZE = "_size"; field public static final String TITLE = "title"; field public static final String WIDTH = "width"; @@ -41714,7 +41728,7 @@ package android.service.notification { method public void onNotificationRemoved(android.service.notification.StatusBarNotification); method public void onNotificationRemoved(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap); method public void onNotificationRemoved(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap, int); - method public void onStatusBarIconsBehaviorChanged(boolean); + method public void onSilentStatusBarIconsVisibilityChanged(boolean); method public final void requestInterruptionFilter(int); method public final void requestListenerHints(int); method public static void requestRebind(android.content.ComponentName); @@ -45016,7 +45030,7 @@ package android.telephony { method public String getCountryIso(); method public int getDataRoaming(); method public CharSequence getDisplayName(); - method @Nullable public String getGroupUuid(); + method @Nullable public android.os.ParcelUuid getGroupUuid(); method public String getIccId(); method public int getIconTint(); method @Deprecated public int getMcc(); @@ -45036,7 +45050,9 @@ package android.telephony { public class SubscriptionManager { method public void addOnOpportunisticSubscriptionsChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener); method public void addOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void addSubscriptionsIntoGroup(@NonNull java.util.List<java.lang.Integer>, @NonNull android.os.ParcelUuid); method public boolean canManageSubscription(android.telephony.SubscriptionInfo); + method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.os.ParcelUuid createSubscriptionGroup(@NonNull java.util.List<java.lang.Integer>); method @Deprecated public static android.telephony.SubscriptionManager from(android.content.Context); method public java.util.List<android.telephony.SubscriptionInfo> getAccessibleSubscriptionInfoList(); method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public android.telephony.SubscriptionInfo getActiveSubscriptionInfo(int); @@ -45052,16 +45068,15 @@ package android.telephony { method public static int getSlotIndex(int); method @Nullable public int[] getSubscriptionIds(int); method @NonNull public java.util.List<android.telephony.SubscriptionPlan> getSubscriptionPlans(int); - method @Nullable @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List<android.telephony.SubscriptionInfo> getSubscriptionsInGroup(int); + method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List<android.telephony.SubscriptionInfo> getSubscriptionsInGroup(@NonNull android.os.ParcelUuid); method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isActiveSubscriptionId(int); method public boolean isNetworkRoaming(int); method public static boolean isUsableSubscriptionId(int); method public static boolean isValidSubscriptionId(int); method public void removeOnOpportunisticSubscriptionsChangedListener(@NonNull android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener); method public void removeOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean removeSubscriptionsFromGroup(@NonNull int[]); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void removeSubscriptionsFromGroup(@NonNull java.util.List<java.lang.Integer>, @NonNull android.os.ParcelUuid); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setOpportunistic(boolean, int); - method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String setSubscriptionGroup(@NonNull int[]); method public void setSubscriptionOverrideCongested(int, boolean, long); method public void setSubscriptionOverrideUnmetered(int, boolean, long); method public void setSubscriptionPlans(int, @NonNull java.util.List<android.telephony.SubscriptionPlan>); @@ -45485,26 +45500,26 @@ package android.telephony.data { public static class ApnSetting.Builder { ctor public ApnSetting.Builder(); method public android.telephony.data.ApnSetting build(); - method @NonNull public android.telephony.data.ApnSetting.Builder setApnName(String); + method @NonNull public android.telephony.data.ApnSetting.Builder setApnName(@Nullable String); method @NonNull public android.telephony.data.ApnSetting.Builder setApnTypeBitmask(int); method @NonNull public android.telephony.data.ApnSetting.Builder setAuthType(int); method @NonNull public android.telephony.data.ApnSetting.Builder setCarrierEnabled(boolean); method @NonNull public android.telephony.data.ApnSetting.Builder setCarrierId(int); - method @NonNull public android.telephony.data.ApnSetting.Builder setEntryName(String); + method @NonNull public android.telephony.data.ApnSetting.Builder setEntryName(@Nullable String); method @Deprecated public android.telephony.data.ApnSetting.Builder setMmsProxyAddress(java.net.InetAddress); - method @NonNull public android.telephony.data.ApnSetting.Builder setMmsProxyAddress(String); + method @NonNull public android.telephony.data.ApnSetting.Builder setMmsProxyAddress(@Nullable String); method @NonNull public android.telephony.data.ApnSetting.Builder setMmsProxyPort(int); - method @NonNull public android.telephony.data.ApnSetting.Builder setMmsc(android.net.Uri); + method @NonNull public android.telephony.data.ApnSetting.Builder setMmsc(@Nullable android.net.Uri); method @NonNull public android.telephony.data.ApnSetting.Builder setMvnoType(int); method @NonNull public android.telephony.data.ApnSetting.Builder setNetworkTypeBitmask(int); - method @NonNull public android.telephony.data.ApnSetting.Builder setOperatorNumeric(String); - method @NonNull public android.telephony.data.ApnSetting.Builder setPassword(String); + method @NonNull public android.telephony.data.ApnSetting.Builder setOperatorNumeric(@Nullable String); + method @NonNull public android.telephony.data.ApnSetting.Builder setPassword(@Nullable String); method @NonNull public android.telephony.data.ApnSetting.Builder setProtocol(int); method @Deprecated public android.telephony.data.ApnSetting.Builder setProxyAddress(java.net.InetAddress); - method @NonNull public android.telephony.data.ApnSetting.Builder setProxyAddress(String); + method @NonNull public android.telephony.data.ApnSetting.Builder setProxyAddress(@Nullable String); method @NonNull public android.telephony.data.ApnSetting.Builder setProxyPort(int); method @NonNull public android.telephony.data.ApnSetting.Builder setRoamingProtocol(int); - method @NonNull public android.telephony.data.ApnSetting.Builder setUser(String); + method @NonNull public android.telephony.data.ApnSetting.Builder setUser(@Nullable String); } } diff --git a/api/removed.txt b/api/removed.txt index fa07094e6b84..fe3e866de682 100644 --- a/api/removed.txt +++ b/api/removed.txt @@ -524,6 +524,8 @@ package android.provider { public static interface MediaStore.MediaColumns extends android.provider.BaseColumns { field @Deprecated public static final String HASH = "_hash"; field @Deprecated public static final String IS_TRASHED = "is_trashed"; + field @Deprecated public static final String PRIMARY_DIRECTORY = "primary_directory"; + field @Deprecated public static final String SECONDARY_DIRECTORY = "secondary_directory"; } @Deprecated public static class MediaStore.PendingParams { diff --git a/api/system-current.txt b/api/system-current.txt index bdc0e9cb8729..21b0bbb93321 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -12,6 +12,7 @@ package android { field public static final String ACCESS_MTP = "android.permission.ACCESS_MTP"; field public static final String ACCESS_NETWORK_CONDITIONS = "android.permission.ACCESS_NETWORK_CONDITIONS"; field public static final String ACCESS_NOTIFICATIONS = "android.permission.ACCESS_NOTIFICATIONS"; + field public static final String ACCESS_SHARED_LIBRARIES = "android.permission.ACCESS_SHARED_LIBRARIES"; field public static final String ACCESS_SHORTCUTS = "android.permission.ACCESS_SHORTCUTS"; field public static final String ACCESS_SURFACE_FLINGER = "android.permission.ACCESS_SURFACE_FLINGER"; field public static final String ACTIVITY_EMBEDDING = "android.permission.ACTIVITY_EMBEDDING"; @@ -117,6 +118,7 @@ package android { field public static final String MODIFY_QUIET_MODE = "android.permission.MODIFY_QUIET_MODE"; field public static final String MOVE_PACKAGE = "android.permission.MOVE_PACKAGE"; field public static final String NETWORK_MANAGED_PROVISIONING = "android.permission.NETWORK_MANAGED_PROVISIONING"; + field public static final String NETWORK_SCAN = "android.permission.NETWORK_SCAN"; field public static final String NETWORK_SETUP_WIZARD = "android.permission.NETWORK_SETUP_WIZARD"; field public static final String NOTIFICATION_DURING_SETUP = "android.permission.NOTIFICATION_DURING_SETUP"; field public static final String NOTIFY_TV_INPUTS = "android.permission.NOTIFY_TV_INPUTS"; @@ -186,7 +188,6 @@ package android { field public static final String SUBSTITUTE_NOTIFICATION_APP_NAME = "android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME"; field public static final String SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON = "android.permission.SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON"; field public static final String SUSPEND_APPS = "android.permission.SUSPEND_APPS"; - field public static final String TEST_MANAGE_ROLLBACKS = "android.permission.TEST_MANAGE_ROLLBACKS"; field public static final String TETHER_PRIVILEGED = "android.permission.TETHER_PRIVILEGED"; field public static final String TV_INPUT_HARDWARE = "android.permission.TV_INPUT_HARDWARE"; field public static final String TV_VIRTUAL_REMOTE_CONTROLLER = "android.permission.TV_VIRTUAL_REMOTE_CONTROLLER"; @@ -1063,7 +1064,7 @@ package android.app.prediction { public final class AppPredictor { method public void destroy(); method public void notifyAppTargetEvent(@NonNull android.app.prediction.AppTargetEvent); - method public void notifyLocationShown(@NonNull String, @NonNull java.util.List<android.app.prediction.AppTargetId>); + method public void notifyLaunchLocationShown(@NonNull String, @NonNull java.util.List<android.app.prediction.AppTargetId>); method public void registerPredictionUpdates(@NonNull java.util.concurrent.Executor, @NonNull android.app.prediction.AppPredictor.Callback); method public void requestPredictionUpdate(); method @Nullable public void sortTargets(@NonNull java.util.List<android.app.prediction.AppTarget>, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.util.List<android.app.prediction.AppTarget>>); @@ -1075,8 +1076,6 @@ package android.app.prediction { } public final class AppTarget implements android.os.Parcelable { - ctor public AppTarget(@NonNull android.app.prediction.AppTargetId, @NonNull String, @Nullable String, @NonNull android.os.UserHandle); - ctor public AppTarget(@NonNull android.app.prediction.AppTargetId, @NonNull android.content.pm.ShortcutInfo, @Nullable String); method public int describeContents(); method @Nullable public String getClassName(); method @NonNull public android.app.prediction.AppTargetId getId(); @@ -1088,6 +1087,15 @@ package android.app.prediction { field @NonNull public static final android.os.Parcelable.Creator<android.app.prediction.AppTarget> CREATOR; } + public static final class AppTarget.Builder { + ctor public AppTarget.Builder(@NonNull android.app.prediction.AppTargetId); + method @NonNull public android.app.prediction.AppTarget build(); + method @NonNull public android.app.prediction.AppTarget.Builder setClassName(@NonNull String); + method @NonNull public android.app.prediction.AppTarget.Builder setRank(@IntRange(from=0) int); + method @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull String, @NonNull android.os.UserHandle); + method @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull android.content.pm.ShortcutInfo); + } + public final class AppTargetEvent implements android.os.Parcelable { method public int describeContents(); method public int getAction(); @@ -1353,7 +1361,6 @@ package android.content { field public static final String BACKUP_SERVICE = "backup"; field public static final String CONTENT_SUGGESTIONS_SERVICE = "content_suggestions"; field public static final String CONTEXTHUB_SERVICE = "contexthub"; - field public static final String DYNAMIC_ANDROID_SERVICE = "dynamic_android"; field public static final String EUICC_CARD_SERVICE = "euicc_card"; field public static final String HDMI_CONTROL_SERVICE = "hdmi_control"; field public static final String NETD_SERVICE = "netd"; @@ -1380,32 +1387,6 @@ package android.content { method public void sendOrderedBroadcast(android.content.Intent, String, android.os.Bundle, android.content.BroadcastReceiver, android.os.Handler, int, String, android.os.Bundle); } - public class DynamicAndroidClient { - ctor public DynamicAndroidClient(@NonNull android.content.Context); - method public void bind(); - method public void setOnStatusChangedListener(@NonNull android.content.DynamicAndroidClient.OnStatusChangedListener, @NonNull java.util.concurrent.Executor); - method public void setOnStatusChangedListener(@NonNull android.content.DynamicAndroidClient.OnStatusChangedListener); - method public void start(String, long); - method public void start(String, long, long); - method public void unbind(); - field public static final int CAUSE_ERROR_EXCEPTION = 6; // 0x6 - field public static final int CAUSE_ERROR_INVALID_URL = 4; // 0x4 - field public static final int CAUSE_ERROR_IO = 3; // 0x3 - field public static final int CAUSE_ERROR_IPC = 5; // 0x5 - field public static final int CAUSE_INSTALL_CANCELLED = 2; // 0x2 - field public static final int CAUSE_INSTALL_COMPLETED = 1; // 0x1 - field public static final int CAUSE_NOT_SPECIFIED = 0; // 0x0 - field public static final int STATUS_IN_PROGRESS = 2; // 0x2 - field public static final int STATUS_IN_USE = 4; // 0x4 - field public static final int STATUS_NOT_STARTED = 1; // 0x1 - field public static final int STATUS_READY = 3; // 0x3 - field public static final int STATUS_UNKNOWN = 0; // 0x0 - } - - public static interface DynamicAndroidClient.OnStatusChangedListener { - method public void onStatusChanged(int, int, long); - } - public class Intent implements java.lang.Cloneable android.os.Parcelable { field public static final String ACTION_BATTERY_LEVEL_CHANGED = "android.intent.action.BATTERY_LEVEL_CHANGED"; field public static final String ACTION_CALL_EMERGENCY = "android.intent.action.CALL_EMERGENCY"; @@ -1429,7 +1410,6 @@ package android.content { field public static final String ACTION_QUERY_PACKAGE_RESTART = "android.intent.action.QUERY_PACKAGE_RESTART"; field public static final String ACTION_RESOLVE_INSTANT_APP_PACKAGE = "android.intent.action.RESOLVE_INSTANT_APP_PACKAGE"; field @RequiresPermission(android.Manifest.permission.REVIEW_ACCESSIBILITY_SERVICES) public static final String ACTION_REVIEW_ACCESSIBILITY_SERVICES = "android.intent.action.REVIEW_ACCESSIBILITY_SERVICES"; - field @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) public static final String ACTION_REVIEW_APP_PERMISSION_USAGE = "android.intent.action.REVIEW_APP_PERMISSION_USAGE"; field @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) public static final String ACTION_REVIEW_ONGOING_PERMISSION_USAGE = "android.intent.action.REVIEW_ONGOING_PERMISSION_USAGE"; field public static final String ACTION_REVIEW_PERMISSIONS = "android.intent.action.REVIEW_PERMISSIONS"; field @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) public static final String ACTION_REVIEW_PERMISSION_USAGE = "android.intent.action.REVIEW_PERMISSION_USAGE"; @@ -1438,6 +1418,7 @@ package android.content { field @Deprecated public static final String ACTION_SIM_STATE_CHANGED = "android.intent.action.SIM_STATE_CHANGED"; field public static final String ACTION_SPLIT_CONFIGURATION_CHANGED = "android.intent.action.SPLIT_CONFIGURATION_CHANGED"; field public static final String ACTION_UPGRADE_SETUP = "android.intent.action.UPGRADE_SETUP"; + field public static final String ACTION_USER_ADDED = "android.intent.action.USER_ADDED"; field public static final String ACTION_USER_REMOVED = "android.intent.action.USER_REMOVED"; field public static final String ACTION_VOICE_ASSIST = "android.intent.action.VOICE_ASSIST"; field public static final String CATEGORY_LEANBACK_SETTINGS = "android.intent.category.LEANBACK_SETTINGS"; @@ -1480,15 +1461,16 @@ package android.content.om { field @NonNull public static final android.os.Parcelable.Creator<android.content.om.OverlayInfo> CREATOR; field public final String category; field public final String packageName; + field public final String targetOverlayableName; field public final String targetPackageName; field public final int userId; } public class OverlayManager { method @Nullable public android.content.om.OverlayInfo getOverlayInfo(@NonNull String, @NonNull android.os.UserHandle); - method public java.util.List<android.content.om.OverlayInfo> getOverlayInfosForTarget(@Nullable String, int); - method public boolean setEnabled(@Nullable String, boolean, int); - method public boolean setEnabledExclusiveInCategory(@Nullable String, int); + method @NonNull @RequiresPermission(anyOf={"android.permission.INTERACT_ACROSS_USERS", "android.permission.INTERACT_ACROSS_USERS_FULL"}) public java.util.List<android.content.om.OverlayInfo> getOverlayInfosForTarget(@NonNull String, @NonNull android.os.UserHandle); + method @RequiresPermission(anyOf={"android.permission.INTERACT_ACROSS_USERS", "android.permission.INTERACT_ACROSS_USERS_FULL"}) public void setEnabled(@NonNull String, boolean, @NonNull android.os.UserHandle); + method @RequiresPermission(anyOf={"android.permission.INTERACT_ACROSS_USERS", "android.permission.INTERACT_ACROSS_USERS_FULL"}) public void setEnabledExclusiveInCategory(@NonNull String, @NonNull android.os.UserHandle); } } @@ -1614,6 +1596,7 @@ package android.content.pm { method public abstract java.util.List<android.content.IntentFilter> getAllIntentFilters(String); method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.pm.ApplicationInfo getApplicationInfoAsUser(@NonNull String, int, @NonNull android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException; method @NonNull public android.content.pm.dex.ArtManager getArtManager(); + method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_SHARED_LIBRARIES) public java.util.List<android.content.pm.SharedLibraryInfo> getDeclaredSharedLibraries(@NonNull String, int); method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract String getDefaultBrowserPackageNameAsUser(int); method @Nullable @RequiresPermission(android.Manifest.permission.SET_HARMFUL_APP_WARNINGS) public CharSequence getHarmfulAppWarning(@NonNull String); method public String getIncidentReportApproverPackageName(); @@ -1844,9 +1827,9 @@ package android.content.rollback { } public final class RollbackManager { - method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, android.Manifest.permission.TEST_MANAGE_ROLLBACKS}) public void commitRollback(int, @NonNull java.util.List<android.content.pm.VersionedPackage>, @NonNull android.content.IntentSender); - method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, android.Manifest.permission.TEST_MANAGE_ROLLBACKS}) @NonNull public java.util.List<android.content.rollback.RollbackInfo> getAvailableRollbacks(); - method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, android.Manifest.permission.TEST_MANAGE_ROLLBACKS}) @NonNull public java.util.List<android.content.rollback.RollbackInfo> getRecentlyCommittedRollbacks(); + method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, "android.permission.TEST_MANAGE_ROLLBACKS"}) public void commitRollback(int, @NonNull java.util.List<android.content.pm.VersionedPackage>, @NonNull android.content.IntentSender); + method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, "android.permission.TEST_MANAGE_ROLLBACKS"}) @NonNull public java.util.List<android.content.rollback.RollbackInfo> getAvailableRollbacks(); + method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, "android.permission.TEST_MANAGE_ROLLBACKS"}) @NonNull public java.util.List<android.content.rollback.RollbackInfo> getRecentlyCommittedRollbacks(); field public static final String EXTRA_STATUS = "android.content.rollback.extra.STATUS"; field public static final String EXTRA_STATUS_MESSAGE = "android.content.rollback.extra.STATUS_MESSAGE"; field public static final int STATUS_FAILURE = 1; // 0x1 @@ -3663,13 +3646,14 @@ package android.media.audiopolicy { public static class AudioPolicy.Builder { ctor public AudioPolicy.Builder(android.content.Context); - method public android.media.audiopolicy.AudioPolicy.Builder addMix(@NonNull android.media.audiopolicy.AudioMix) throws java.lang.IllegalArgumentException; - method public android.media.audiopolicy.AudioPolicy build(); + method @NonNull public android.media.audiopolicy.AudioPolicy.Builder addMix(@NonNull android.media.audiopolicy.AudioMix) throws java.lang.IllegalArgumentException; + method @NonNull public android.media.audiopolicy.AudioPolicy build(); method public void setAudioPolicyFocusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener); method public void setAudioPolicyStatusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener); - method public android.media.audiopolicy.AudioPolicy.Builder setAudioPolicyVolumeCallback(@NonNull android.media.audiopolicy.AudioPolicy.AudioPolicyVolumeCallback); - method public android.media.audiopolicy.AudioPolicy.Builder setIsAudioFocusPolicy(boolean); - method public android.media.audiopolicy.AudioPolicy.Builder setLooper(@NonNull android.os.Looper) throws java.lang.IllegalArgumentException; + method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setAudioPolicyVolumeCallback(@NonNull android.media.audiopolicy.AudioPolicy.AudioPolicyVolumeCallback); + method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setIsAudioFocusPolicy(boolean); + method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setIsTestFocusPolicy(boolean); + method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setLooper(@NonNull android.os.Looper) throws java.lang.IllegalArgumentException; } public final class AudioProductStrategies implements java.lang.Iterable<android.media.audiopolicy.AudioProductStrategy> android.os.Parcelable { @@ -4027,7 +4011,6 @@ package android.metrics { package android.net { public class CaptivePortal implements android.os.Parcelable { - ctor public CaptivePortal(@NonNull android.os.IBinder); method public void logEvent(int, @NonNull String); method public void useNetwork(); field public static final int APP_RETURN_DISMISSED = 0; // 0x0 @@ -4036,14 +4019,14 @@ package android.net { } public class ConnectivityManager { - method @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createNattKeepalive(@NonNull android.net.Network, @NonNull java.io.FileDescriptor, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback); - method @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull java.net.Socket, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback); - method public boolean getAvoidBadWifi(); + method @NonNull @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createNattKeepalive(@NonNull android.net.Network, @NonNull android.os.ParcelFileDescriptor, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback); + method @NonNull @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull java.net.Socket, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback); method @RequiresPermission(android.Manifest.permission.LOCAL_MAC_ADDRESS) public String getCaptivePortalServerUrl(); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void getLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEntitlementResultListener); method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public boolean isTetheringSupported(); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEventCallback); method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void setAirplaneMode(boolean); + method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, "android.permission.NETWORK_STACK"}) public boolean shouldAvoidBadWifi(); method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(@NonNull android.net.Network, @NonNull android.os.Bundle); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback, android.os.Handler); @@ -4233,7 +4216,7 @@ package android.net { method @Nullable public String getDomains(); method @Nullable public java.net.InetAddress getGateway(); method @Nullable public android.net.LinkAddress getIpAddress(); - method @NonNull public java.util.List<android.net.RouteInfo> getRoutes(String); + method @NonNull public java.util.List<android.net.RouteInfo> getRoutes(@Nullable String); method public void setDomains(@Nullable String); method public void setGateway(@Nullable java.net.InetAddress); method public void setIpAddress(@Nullable android.net.LinkAddress); @@ -4453,7 +4436,7 @@ package android.net.metrics { } public final class ValidationProbeEvent implements android.net.metrics.IpConnectivityLog.Event { - method public static String getProbeName(int); + method @NonNull public static String getProbeName(int); field public static final int DNS_FAILURE = 0; // 0x0 field public static final int DNS_SUCCESS = 1; // 0x1 field public static final int PROBE_DNS = 0; // 0x0 @@ -4929,7 +4912,6 @@ package android.net.wifi { method public int getCellularDataNetworkType(); method public int getCellularSignalStrengthDb(); method public int getCellularSignalStrengthDbm(); - method public boolean getIsSameRegisteredCell(); method public int getLinkSpeedMbps(); method public int getProbeElapsedTimeSinceLastUpdateMillis(); method public int getProbeMcsRateSinceLastUpdate(); @@ -4953,6 +4935,7 @@ package android.net.wifi { method public long getTotalTxBad(); method public long getTotalTxRetries(); method public long getTotalTxSuccess(); + method public boolean isSameRegisteredCell(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiUsabilityStatsEntry> CREATOR; field public static final int PROBE_STATUS_FAILURE = 3; // 0x3 @@ -5442,14 +5425,14 @@ package android.os { public final class PowerManager { method @RequiresPermission(allOf={android.Manifest.permission.READ_DREAM_STATE, android.Manifest.permission.WRITE_DREAM_STATE}) public void dream(long); method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public boolean forceSuspend(); - method @RequiresPermission(android.Manifest.permission.POWER_SAVER) public int getPowerSaveMode(); + method @RequiresPermission(android.Manifest.permission.POWER_SAVER) public int getPowerSaveModeTrigger(); method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER}) public boolean setAdaptivePowerSaveEnabled(boolean); method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER}) public boolean setAdaptivePowerSavePolicy(@NonNull android.os.BatterySaverPolicyConfig); - method @RequiresPermission(android.Manifest.permission.POWER_SAVER) public boolean setDynamicPowerSavings(boolean, int); + method @RequiresPermission(android.Manifest.permission.POWER_SAVER) public boolean setDynamicPowerSaveHint(boolean, int); method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER}) public boolean setPowerSaveModeEnabled(boolean); method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.USER_ACTIVITY}) public void userActivity(long, int, int); - field public static final int POWER_SAVER_MODE_DYNAMIC = 1; // 0x1 - field public static final int POWER_SAVER_MODE_PERCENTAGE = 0; // 0x0 + field public static final int POWER_SAVE_MODE_TRIGGER_DYNAMIC = 1; // 0x1 + field public static final int POWER_SAVE_MODE_TRIGGER_PERCENTAGE = 0; // 0x0 field public static final int USER_ACTIVITY_EVENT_ACCESSIBILITY = 3; // 0x3 field public static final int USER_ACTIVITY_EVENT_BUTTON = 1; // 0x1 field public static final int USER_ACTIVITY_EVENT_OTHER = 0; // 0x0 @@ -5656,6 +5639,36 @@ package android.os { } +package android.os.image { + + public class DynamicSystemClient { + ctor public DynamicSystemClient(@NonNull android.content.Context); + method @RequiresPermission("android.permission.MANAGE_DYNAMIC_SYSTEM") public void bind(); + method public void setOnStatusChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.os.image.DynamicSystemClient.OnStatusChangedListener); + method public void setOnStatusChangedListener(@NonNull android.os.image.DynamicSystemClient.OnStatusChangedListener); + method @RequiresPermission("android.permission.MANAGE_DYNAMIC_SYSTEM") public void start(@NonNull String, long); + method @RequiresPermission("android.permission.MANAGE_DYNAMIC_SYSTEM") public void start(@NonNull String, long, long); + method @RequiresPermission("android.permission.MANAGE_DYNAMIC_SYSTEM") public void unbind(); + field public static final int CAUSE_ERROR_EXCEPTION = 6; // 0x6 + field public static final int CAUSE_ERROR_INVALID_URL = 4; // 0x4 + field public static final int CAUSE_ERROR_IO = 3; // 0x3 + field public static final int CAUSE_ERROR_IPC = 5; // 0x5 + field public static final int CAUSE_INSTALL_CANCELLED = 2; // 0x2 + field public static final int CAUSE_INSTALL_COMPLETED = 1; // 0x1 + field public static final int CAUSE_NOT_SPECIFIED = 0; // 0x0 + field public static final int STATUS_IN_PROGRESS = 2; // 0x2 + field public static final int STATUS_IN_USE = 4; // 0x4 + field public static final int STATUS_NOT_STARTED = 1; // 0x1 + field public static final int STATUS_READY = 3; // 0x3 + field public static final int STATUS_UNKNOWN = 0; // 0x0 + } + + public static interface DynamicSystemClient.OnStatusChangedListener { + method public void onStatusChanged(int, int, long); + } + +} + package android.os.storage { public class StorageManager { @@ -6035,6 +6048,7 @@ package android.provider { field public static final String ACTION_ENTERPRISE_PRIVACY_SETTINGS = "android.settings.ENTERPRISE_PRIVACY_SETTINGS"; field public static final String ACTION_LOCATION_CONTROLLER_EXTRA_PACKAGE_SETTINGS = "android.settings.LOCATION_CONTROLLER_EXTRA_PACKAGE_SETTINGS"; field public static final String ACTION_MANAGE_DOMAIN_URLS = "android.settings.MANAGE_DOMAIN_URLS"; + field public static final String ACTION_NOTIFICATION_POLICY_ACCESS_DETAIL_SETTINGS = "android.settings.NOTIFICATION_POLICY_ACCESS_DETAIL_SETTINGS"; field public static final String ACTION_REQUEST_ENABLE_CONTENT_CAPTURE = "android.settings.REQUEST_ENABLE_CONTENT_CAPTURE"; field public static final String ACTION_SHOW_ADMIN_SUPPORT_DETAILS = "android.settings.SHOW_ADMIN_SUPPORT_DETAILS"; } @@ -6292,7 +6306,7 @@ package android.service.appprediction { method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent); method public void onCreatePredictionSession(@NonNull android.app.prediction.AppPredictionContext, @NonNull android.app.prediction.AppPredictionSessionId); method @MainThread public void onDestroyPredictionSession(@NonNull android.app.prediction.AppPredictionSessionId); - method @MainThread public abstract void onLocationShown(@NonNull android.app.prediction.AppPredictionSessionId, @NonNull String, @NonNull java.util.List<android.app.prediction.AppTargetId>); + method @MainThread public abstract void onLaunchLocationShown(@NonNull android.app.prediction.AppPredictionSessionId, @NonNull String, @NonNull java.util.List<android.app.prediction.AppTargetId>); method @MainThread public abstract void onRequestPredictionUpdate(@NonNull android.app.prediction.AppPredictionSessionId); method @MainThread public abstract void onSortAppTargets(@NonNull android.app.prediction.AppPredictionSessionId, @NonNull java.util.List<android.app.prediction.AppTarget>, @NonNull android.os.CancellationSignal, @NonNull java.util.function.Consumer<java.util.List<android.app.prediction.AppTarget>>); method @MainThread public void onStartPredictionUpdates(); @@ -6306,20 +6320,23 @@ package android.service.attention { public abstract class AttentionService extends android.app.Service { ctor public AttentionService(); + method public final void disableSelf(); method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent); - method public abstract void onCancelAttentionCheck(int); - method public abstract void onCheckAttention(int, @NonNull android.service.attention.AttentionService.AttentionCallback); - field public static final int ATTENTION_FAILURE_PREEMPTED = 2; // 0x2 - field public static final int ATTENTION_FAILURE_TIMED_OUT = 3; // 0x3 - field public static final int ATTENTION_FAILURE_UNKNOWN = 4; // 0x4 + method public abstract void onCancelAttentionCheck(@NonNull android.service.attention.AttentionService.AttentionCallback); + method public abstract void onCheckAttention(@NonNull android.service.attention.AttentionService.AttentionCallback); + field public static final int ATTENTION_FAILURE_CAMERA_PERMISSION_ABSENT = 6; // 0x6 + field public static final int ATTENTION_FAILURE_CANCELLED = 3; // 0x3 + field public static final int ATTENTION_FAILURE_PREEMPTED = 4; // 0x4 + field public static final int ATTENTION_FAILURE_TIMED_OUT = 5; // 0x5 + field public static final int ATTENTION_FAILURE_UNKNOWN = 2; // 0x2 field public static final int ATTENTION_SUCCESS_ABSENT = 0; // 0x0 field public static final int ATTENTION_SUCCESS_PRESENT = 1; // 0x1 field public static final String SERVICE_INTERFACE = "android.service.attention.AttentionService"; } public static final class AttentionService.AttentionCallback { - method public void onFailure(int, int); - method public void onSuccess(int, int, long); + method public void onFailure(int); + method public void onSuccess(int, long); } } @@ -6418,7 +6435,7 @@ package android.service.contentcapture { public abstract class ContentCaptureService extends android.app.Service { ctor public ContentCaptureService(); - method public final void disableContentCaptureServices(); + method public final void disableSelf(); method public void onActivityEvent(@NonNull android.service.contentcapture.ActivityEvent); method public void onActivitySnapshot(@NonNull android.view.contentcapture.ContentCaptureSessionId, @NonNull android.service.contentcapture.SnapshotData); method public void onConnected(); @@ -6878,6 +6895,22 @@ package android.service.wallpaper { } +package android.service.watchdog { + + public abstract class ExplicitHealthCheckService extends android.app.Service { + ctor public ExplicitHealthCheckService(); + method public final void notifyHealthCheckPassed(@NonNull String); + method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent); + method public abstract void onCancelHealthCheck(@NonNull String); + method @NonNull public abstract java.util.List<java.lang.String> onGetRequestedPackages(); + method @NonNull public abstract java.util.List<java.lang.String> onGetSupportedPackages(); + method public abstract void onRequestHealthCheck(@NonNull String); + field public static final String BIND_PERMISSION = "android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE"; + field public static final String SERVICE_INTERFACE = "android.service.watchdog.ExplicitHealthCheckService"; + } + +} + package android.telecom { @Deprecated public class AudioState implements android.os.Parcelable { @@ -7558,11 +7591,11 @@ package android.telephony { field public static final int VSNCP_TIMEOUT = 2236; // 0x8bc } - public final class DataSpecificRegistrationStates implements android.os.Parcelable { + public final class DataSpecificRegistrationInfo implements android.os.Parcelable { method public int describeContents(); method @NonNull public android.telephony.LteVopsSupportInfo getLteVopsSupportInfo(); method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.DataSpecificRegistrationStates> CREATOR; + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.DataSpecificRegistrationInfo> CREATOR; } public final class DisconnectCause { @@ -7671,7 +7704,7 @@ package android.telephony { method public int getAccessNetworkTechnology(); method @NonNull public java.util.List<java.lang.Integer> getAvailableServices(); method @Nullable public android.telephony.CellIdentity getCellIdentity(); - method @Nullable public android.telephony.DataSpecificRegistrationStates getDataSpecificStates(); + method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo(); method public int getDomain(); method public int getRegistrationState(); method public int getRejectCause(); @@ -8033,6 +8066,7 @@ package android.telephony { method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduBasicChannelBySlot(int, int, int, int, int, int, @Nullable String); method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduLogicalChannelBySlot(int, int, int, int, int, int, int, @Nullable String); method public boolean isDataConnectivityPossible(); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isEmergencyAssistanceEnabled(); method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isIdle(); method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isOffhook(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isPotentialEmergencyNumber(@NonNull String); @@ -9477,6 +9511,10 @@ package android.util { method public int getUid(); } + public final class StatsLog { + method public static void writeRaw(@NonNull byte[], int); + } + public class StatsLogAtoms { field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED = 170; // 0xaa field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_DENIED = 8; // 0x8 diff --git a/api/test-current.txt b/api/test-current.txt index 417a9edf3720..d3ec216fc333 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -352,6 +352,10 @@ package android.app { method public boolean isUiModeLocked(); } + public class WallpaperManager { + method @RequiresPermission("android.permission.SET_WALLPAPER_COMPONENT") public boolean setWallpaperComponent(android.content.ComponentName); + } + public class WindowConfiguration implements java.lang.Comparable<android.app.WindowConfiguration> android.os.Parcelable { ctor public WindowConfiguration(); method public int compareTo(android.app.WindowConfiguration); @@ -461,7 +465,7 @@ package android.app.prediction { method public void destroy(); method public android.app.prediction.AppPredictionSessionId getSessionId(); method public void notifyAppTargetEvent(@NonNull android.app.prediction.AppTargetEvent); - method public void notifyLocationShown(@NonNull String, @NonNull java.util.List<android.app.prediction.AppTargetId>); + method public void notifyLaunchLocationShown(@NonNull String, @NonNull java.util.List<android.app.prediction.AppTargetId>); method public void registerPredictionUpdates(@NonNull java.util.concurrent.Executor, @NonNull android.app.prediction.AppPredictor.Callback); method public void requestPredictionUpdate(); method @Nullable public void sortTargets(@NonNull java.util.List<android.app.prediction.AppTarget>, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.util.List<android.app.prediction.AppTarget>>); @@ -473,7 +477,6 @@ package android.app.prediction { } public final class AppTarget implements android.os.Parcelable { - ctor public AppTarget(@NonNull android.app.prediction.AppTargetId, @NonNull String, @Nullable String, @NonNull android.os.UserHandle); method public int describeContents(); method @Nullable public String getClassName(); method @NonNull public android.app.prediction.AppTargetId getId(); @@ -485,6 +488,15 @@ package android.app.prediction { field @NonNull public static final android.os.Parcelable.Creator<android.app.prediction.AppTarget> CREATOR; } + public static final class AppTarget.Builder { + ctor public AppTarget.Builder(@NonNull android.app.prediction.AppTargetId); + method @NonNull public android.app.prediction.AppTarget build(); + method @NonNull public android.app.prediction.AppTarget.Builder setClassName(@NonNull String); + method @NonNull public android.app.prediction.AppTarget.Builder setRank(@IntRange(from=0) int); + method @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull String, @NonNull android.os.UserHandle); + method @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull android.content.pm.ShortcutInfo); + } + public final class AppTargetEvent implements android.os.Parcelable { method public int describeContents(); method public int getAction(); @@ -576,12 +588,14 @@ package android.content { } public final class ContentCaptureOptions implements android.os.Parcelable { + ctor public ContentCaptureOptions(int); ctor public ContentCaptureOptions(int, int, int, int, int, @Nullable android.util.ArraySet<android.content.ComponentName>); method public int describeContents(); method public static android.content.ContentCaptureOptions forWhitelistingItself(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.content.ContentCaptureOptions> CREATOR; field public final int idleFlushingFrequencyMs; + field public final boolean lite; field public final int logHistorySize; field public final int loggingLevel; field public final int maxBufferSize; @@ -600,6 +614,7 @@ package android.content { public abstract class Context { method public android.content.Context createPackageContextAsUser(String, int, android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException; method public abstract android.view.Display getDisplay(); + method public abstract int getDisplayId(); method public android.os.UserHandle getUser(); method public int getUserId(); method public void setAutofillOptions(@Nullable android.content.AutofillOptions); @@ -610,6 +625,7 @@ package android.content { public class ContextWrapper extends android.content.Context { method public android.view.Display getDisplay(); + method public int getDisplayId(); } public class Intent implements java.lang.Cloneable android.os.Parcelable { @@ -919,19 +935,23 @@ package android.location { method public void resetBiasUncertaintyNanos(); method public void resetDriftNanosPerSecond(); method public void resetDriftUncertaintyNanosPerSecond(); + method public void resetElapsedRealtimeNanos(); + method public void resetElapsedRealtimeUncertaintyNanos(); method public void resetFullBiasNanos(); method public void resetLeapSecond(); method public void resetTimeUncertaintyNanos(); method public void set(android.location.GnssClock); method public void setBiasNanos(double); - method public void setBiasUncertaintyNanos(double); + method public void setBiasUncertaintyNanos(@FloatRange(from=0.0f) double); method public void setDriftNanosPerSecond(double); - method public void setDriftUncertaintyNanosPerSecond(double); + method public void setDriftUncertaintyNanosPerSecond(@FloatRange(from=0.0f) double); + method public void setElapsedRealtimeNanos(long); + method public void setElapsedRealtimeUncertaintyNanos(@IntRange(from=0) long); method public void setFullBiasNanos(long); method public void setHardwareClockDiscontinuityCount(int); method public void setLeapSecond(int); method public void setTimeNanos(long); - method public void setTimeUncertaintyNanos(double); + method public void setTimeUncertaintyNanos(@FloatRange(from=0.0f) double); } public final class GnssMeasurement implements android.os.Parcelable { @@ -1078,10 +1098,6 @@ package android.media { method public android.media.BufferingParams.Builder setResumePlaybackMarkMs(int); } - public class CallbackDataSourceDesc extends android.media.DataSourceDesc { - method @NonNull public android.media.DataSourceCallback getDataSourceCallback(); - } - public class FileDataSourceDesc extends android.media.DataSourceDesc { method public long getLength(); method public long getOffset(); @@ -1207,7 +1223,6 @@ package android.metrics { package android.net { public class CaptivePortal implements android.os.Parcelable { - ctor public CaptivePortal(@NonNull android.os.IBinder); method public void logEvent(int, @NonNull String); method public void useNetwork(); field public static final int APP_RETURN_DISMISSED = 0; // 0x0 @@ -1301,7 +1316,7 @@ package android.net { method @Nullable public String getDomains(); method @Nullable public java.net.InetAddress getGateway(); method @Nullable public android.net.LinkAddress getIpAddress(); - method @NonNull public java.util.List<android.net.RouteInfo> getRoutes(String); + method @NonNull public java.util.List<android.net.RouteInfo> getRoutes(@Nullable String); method public void setDomains(@Nullable String); method public void setGateway(@Nullable java.net.InetAddress); method public void setIpAddress(@Nullable android.net.LinkAddress); @@ -1520,7 +1535,7 @@ package android.net.metrics { } public final class ValidationProbeEvent implements android.net.metrics.IpConnectivityLog.Event { - method public static String getProbeName(int); + method @NonNull public static String getProbeName(int); field public static final int DNS_FAILURE = 0; // 0x0 field public static final int DNS_SUCCESS = 1; // 0x1 field public static final int PROBE_DNS = 0; // 0x0 @@ -1796,11 +1811,11 @@ package android.os { } public final class PowerManager { - method @RequiresPermission("android.permission.POWER_SAVER") public int getPowerSaveMode(); - method @RequiresPermission("android.permission.POWER_SAVER") public boolean setDynamicPowerSavings(boolean, int); + method @RequiresPermission("android.permission.POWER_SAVER") public int getPowerSaveModeTrigger(); + method @RequiresPermission("android.permission.POWER_SAVER") public boolean setDynamicPowerSaveHint(boolean, int); method @RequiresPermission(anyOf={"android.permission.DEVICE_POWER", "android.permission.POWER_SAVER"}) public boolean setPowerSaveModeEnabled(boolean); - field public static final int POWER_SAVER_MODE_DYNAMIC = 1; // 0x1 - field public static final int POWER_SAVER_MODE_PERCENTAGE = 0; // 0x0 + field public static final int POWER_SAVE_MODE_TRIGGER_DYNAMIC = 1; // 0x1 + field public static final int POWER_SAVE_MODE_TRIGGER_PERCENTAGE = 0; // 0x0 } public class Process { @@ -2148,7 +2163,7 @@ package android.provider { public static final class Settings.Global extends android.provider.Settings.NameValueTable { field public static final String AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES = "autofill_compat_mode_allowed_packages"; - field public static final String AUTOMATIC_POWER_SAVER_MODE = "automatic_power_saver_mode"; + field public static final String AUTOMATIC_POWER_SAVE_MODE = "automatic_power_save_mode"; field public static final String BATTERY_SAVER_CONSTANTS = "battery_saver_constants"; field public static final String CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS = "captive_portal_fallback_probe_specs"; field public static final String CAPTIVE_PORTAL_FALLBACK_URL = "captive_portal_fallback_url"; @@ -2258,7 +2273,7 @@ package android.service.appprediction { method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent); method public void onCreatePredictionSession(@NonNull android.app.prediction.AppPredictionContext, @NonNull android.app.prediction.AppPredictionSessionId); method @MainThread public void onDestroyPredictionSession(@NonNull android.app.prediction.AppPredictionSessionId); - method @MainThread public abstract void onLocationShown(@NonNull android.app.prediction.AppPredictionSessionId, @NonNull String, @NonNull java.util.List<android.app.prediction.AppTargetId>); + method @MainThread public abstract void onLaunchLocationShown(@NonNull android.app.prediction.AppPredictionSessionId, @NonNull String, @NonNull java.util.List<android.app.prediction.AppTargetId>); method @MainThread public abstract void onRequestPredictionUpdate(@NonNull android.app.prediction.AppPredictionSessionId); method @MainThread public abstract void onSortAppTargets(@NonNull android.app.prediction.AppPredictionSessionId, @NonNull java.util.List<android.app.prediction.AppTarget>, @NonNull android.os.CancellationSignal, @NonNull java.util.function.Consumer<java.util.List<android.app.prediction.AppTarget>>); method @MainThread public void onStartPredictionUpdates(); @@ -2433,7 +2448,7 @@ package android.service.contentcapture { public abstract class ContentCaptureService extends android.app.Service { ctor public ContentCaptureService(); - method public final void disableContentCaptureServices(); + method public final void disableSelf(); method public void onActivityEvent(@NonNull android.service.contentcapture.ActivityEvent); method public void onActivitySnapshot(@NonNull android.view.contentcapture.ContentCaptureSessionId, @NonNull android.service.contentcapture.SnapshotData); method public void onConnected(); @@ -2552,10 +2567,34 @@ package android.telecom { package android.telephony { + public final class AccessNetworkConstants { + field public static final int TRANSPORT_TYPE_WLAN = 2; // 0x2 + field public static final int TRANSPORT_TYPE_WWAN = 1; // 0x1 + } + public class CarrierConfigManager { method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void overrideConfig(int, @Nullable android.os.PersistableBundle); } + public final class DataSpecificRegistrationInfo implements android.os.Parcelable { + method public int describeContents(); + method @NonNull public android.telephony.LteVopsSupportInfo getLteVopsSupportInfo(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.DataSpecificRegistrationInfo> CREATOR; + } + + public final class LteVopsSupportInfo implements android.os.Parcelable { + ctor public LteVopsSupportInfo(int, int); + method public int describeContents(); + method public int getEmcBearerSupport(); + method public int getVopsSupport(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.LteVopsSupportInfo> CREATOR; + field public static final int LTE_STATUS_NOT_AVAILABLE = 1; // 0x1 + field public static final int LTE_STATUS_NOT_SUPPORTED = 3; // 0x3 + field public static final int LTE_STATUS_SUPPORTED = 2; // 0x2 + } + public class MbmsDownloadSession implements java.lang.AutoCloseable { field public static final String MBMS_DOWNLOAD_SERVICE_OVERRIDE_METADATA = "mbms-download-service-override"; } @@ -2568,12 +2607,59 @@ package android.telephony { field public static final String MBMS_STREAMING_SERVICE_OVERRIDE_METADATA = "mbms-streaming-service-override"; } + public final class NetworkRegistrationInfo implements android.os.Parcelable { + method public int describeContents(); + method public int getAccessNetworkTechnology(); + method @NonNull public java.util.List<java.lang.Integer> getAvailableServices(); + method @Nullable public android.telephony.CellIdentity getCellIdentity(); + method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo(); + method public int getDomain(); + method public int getRegistrationState(); + method public int getRejectCause(); + method public int getRoamingType(); + method public int getTransportType(); + method public boolean isEmergencyEnabled(); + method public boolean isRoaming(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.NetworkRegistrationInfo> CREATOR; + field public static final int DOMAIN_CS = 1; // 0x1 + field public static final int DOMAIN_PS = 2; // 0x2 + field public static final int REGISTRATION_STATE_DENIED = 3; // 0x3 + field public static final int REGISTRATION_STATE_HOME = 1; // 0x1 + field public static final int REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING = 0; // 0x0 + field public static final int REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 2; // 0x2 + field public static final int REGISTRATION_STATE_ROAMING = 5; // 0x5 + field public static final int REGISTRATION_STATE_UNKNOWN = 4; // 0x4 + field public static final int SERVICE_TYPE_DATA = 2; // 0x2 + field public static final int SERVICE_TYPE_EMERGENCY = 5; // 0x5 + field public static final int SERVICE_TYPE_SMS = 3; // 0x3 + field public static final int SERVICE_TYPE_UNKNOWN = 0; // 0x0 + field public static final int SERVICE_TYPE_VIDEO = 4; // 0x4 + field public static final int SERVICE_TYPE_VOICE = 1; // 0x1 + } + + public static final class NetworkRegistrationInfo.Builder { + ctor public NetworkRegistrationInfo.Builder(); + method @NonNull public android.telephony.NetworkRegistrationInfo build(); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setAccessNetworkTechnology(int); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setAvailableServices(@NonNull java.util.List<java.lang.Integer>); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setCellIdentity(@Nullable android.telephony.CellIdentity); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setDomain(int); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setEmergencyOnly(boolean); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegistrationState(int); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRejectCause(int); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setTransportType(int); + } + public class ServiceState implements android.os.Parcelable { + method public void addNetworkRegistrationInfo(android.telephony.NetworkRegistrationInfo); method public void setCdmaSystemAndNetworkId(int, int); method public void setCellBandwidths(int[]); method public void setChannelNumber(int); + method public void setDataRoamingType(int); method public void setRilDataRadioTechnology(int); method public void setRilVoiceRadioTechnology(int); + method public void setVoiceRoamingType(int); } public class TelephonyManager { diff --git a/cmds/idmap2/idmap2/Scan.cpp b/cmds/idmap2/idmap2/Scan.cpp index 24331af9fd6d..55b1003c38af 100644 --- a/cmds/idmap2/idmap2/Scan.cpp +++ b/cmds/idmap2/idmap2/Scan.cpp @@ -196,13 +196,7 @@ Result<Unit> Scan(const std::vector<std::string>& args) { std::stringstream stream; for (const auto& overlay : interesting_apks) { - std::vector<std::string> verify_args = {"--idmap-path", overlay.idmap_path}; - for (const std::string& policy : overlay.policies) { - verify_args.emplace_back("--policy"); - verify_args.emplace_back(policy); - } - - if (!Verify(std::vector<std::string>(verify_args))) { + if (!Verify(std::vector<std::string>({"--idmap-path", overlay.idmap_path}))) { std::vector<std::string> create_args = {"--target-apk-path", target_apk_path, "--overlay-apk-path", overlay.apk_path, "--idmap-path", overlay.idmap_path}; diff --git a/cmds/statsd/src/atom_field_options.proto b/cmds/statsd/src/atom_field_options.proto index 2a3eee2a7e18..16c936c41559 100644 --- a/cmds/statsd/src/atom_field_options.proto +++ b/cmds/statsd/src/atom_field_options.proto @@ -84,4 +84,6 @@ extend google.protobuf.FieldOptions { optional LogMode log_mode = 50002 [default = MODE_AUTOMATIC]; optional bool allow_from_any_uid = 50003 [default = false]; + + optional string log_from_module = 50004; }
\ No newline at end of file diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 1735b05148fa..c2b81e44e5d9 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -40,6 +40,7 @@ import "frameworks/base/core/proto/android/server/job/enums.proto"; import "frameworks/base/core/proto/android/server/location/enums.proto"; import "frameworks/base/core/proto/android/service/procstats_enum.proto"; import "frameworks/base/core/proto/android/service/usb.proto"; +import "frameworks/base/core/proto/android/stats/connectivity/network_stack.proto"; import "frameworks/base/core/proto/android/stats/enums.proto"; import "frameworks/base/core/proto/android/stats/docsui/docsui_enums.proto"; import "frameworks/base/core/proto/android/stats/devicepolicy/device_policy.proto"; @@ -252,6 +253,7 @@ message Atom { StyleUIChanged style_ui_changed = 179; PrivacyIndicatorsInteracted privacy_indicators_interacted = 180; AppInstallOnExternalStorageReported app_install_on_external_storage_reported = 181; + NetworkStackReported network_stack_reported = 182; } // Pulled events will start at field 10000. @@ -2431,6 +2433,8 @@ message TouchEventReported { optional float latency_mean_micros = 3; // Standard deviation optional float latency_stdev_micros = 4; + // Number of touch events (input_event) in this report + optional int32 count = 5; } /** @@ -5851,3 +5855,14 @@ message SystemIonHeapSize { // Size of the system ion heap in bytes. optional int64 size_in_bytes = 1; } + +/** + * Push network stack events. + * + * Log from: + * frameworks/base/packages/NetworkStack/ + */ +message NetworkStackReported { + optional int32 eventId = 1; + optional android.stats.connectivity.NetworkStackEventData network_stack_event = 2 [(log_mode) = MODE_BYTES]; +} diff --git a/config/boot-image-profile.txt b/config/boot-image-profile.txt index d740961cac2a..a3776c4b4d32 100644 --- a/config/boot-image-profile.txt +++ b/config/boot-image-profile.txt @@ -4759,7 +4759,6 @@ HPLandroid/os/IDeviceIdleController$Stub$Proxy;->addPowerSaveTempWhitelistAppFor HPLandroid/os/IDeviceIdleController$Stub$Proxy;->addPowerSaveTempWhitelistAppForSms(Ljava/lang/String;ILjava/lang/String;)J HPLandroid/os/IDeviceIdleController$Stub;->getDefaultTransactionName(I)Ljava/lang/String; HPLandroid/os/IDeviceIdleController$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z -HPLandroid/os/IDynamicAndroidService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z HPLandroid/os/IHardwarePropertiesManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String; HPLandroid/os/IHardwarePropertiesManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z HPLandroid/os/IInstalld$Stub$Proxy;->clearAppData(Ljava/lang/String;Ljava/lang/String;IIJ)V @@ -5081,6 +5080,7 @@ HPLandroid/os/health/HealthStatsWriter;->writeLongsMap(Landroid/os/Parcel;Landro HPLandroid/os/health/HealthStatsWriter;->writeParcelableMap(Landroid/os/Parcel;Landroid/util/ArrayMap;)V HPLandroid/os/health/TimerStat;-><init>(IJ)V HPLandroid/os/health/TimerStat;->writeToParcel(Landroid/os/Parcel;I)V +HPLandroid/os/image/IDynamicSystemService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z HPLandroid/os/storage/IStorageEventListener$Stub$Proxy;->onStorageStateChanged(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V HPLandroid/os/storage/IStorageManager$Stub$Proxy;->allocateBytes(Ljava/lang/String;JILjava/lang/String;)V HPLandroid/os/storage/IStorageManager$Stub$Proxy;->changeEncryptionPassword(ILjava/lang/String;)I @@ -24027,7 +24027,6 @@ HSPLandroid/os/IDeviceIdleController$Stub$Proxy;->isPowerSaveWhitelistApp(Ljava/ HSPLandroid/os/IDeviceIdleController$Stub;-><init>()V HSPLandroid/os/IDeviceIdleController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IDeviceIdleController; HSPLandroid/os/IDumpstate$Stub;-><init>()V -HSPLandroid/os/IDynamicAndroidService$Stub;-><init>()V HSPLandroid/os/IExternalVibratorService$Stub;-><init>()V HSPLandroid/os/IHardwarePropertiesManager$Stub;-><init>()V HSPLandroid/os/IIncidentCompanion$Stub;-><init>()V @@ -24837,6 +24836,7 @@ HSPLandroid/os/ZygoteProcess;->waitForConnectionToZygote(Ljava/lang/String;)V HSPLandroid/os/ZygoteProcess;->zygoteSendArgsAndGetResult(Landroid/os/ZygoteProcess$ZygoteState;ZLjava/util/ArrayList;)Landroid/os/Process$ProcessStartResult; HSPLandroid/os/health/HealthStatsParceler$1;-><init>()V HSPLandroid/os/health/TimerStat$1;-><init>()V +HSPLandroid/os/image/IDynamicSystemService$Stub;-><init>()V HSPLandroid/os/storage/IStorageEventListener$Stub$Proxy;->asBinder()Landroid/os/IBinder; HSPLandroid/os/storage/IStorageEventListener$Stub;->asBinder()Landroid/os/IBinder; HSPLandroid/os/storage/IStorageManager$Stub$Proxy;->getVolumeList(ILjava/lang/String;I)[Landroid/os/storage/StorageVolume; @@ -47386,7 +47386,6 @@ Landroid/os/DeviceIdleManager; Landroid/os/DropBoxManager$Entry$1; Landroid/os/DropBoxManager$Entry; Landroid/os/DropBoxManager; -Landroid/os/DynamicAndroidManager; Landroid/os/Environment$UserEnvironment; Landroid/os/Environment; Landroid/os/EventLogTags; @@ -47428,8 +47427,6 @@ Landroid/os/IDeviceIdleController$Stub; Landroid/os/IDeviceIdleController; Landroid/os/IDumpstate$Stub; Landroid/os/IDumpstate; -Landroid/os/IDynamicAndroidService$Stub; -Landroid/os/IDynamicAndroidService; Landroid/os/IExternalVibratorService$Stub; Landroid/os/IExternalVibratorService; Landroid/os/IHardwarePropertiesManager$Stub; @@ -47689,6 +47686,10 @@ Landroid/os/health/HealthStatsWriter; Landroid/os/health/SystemHealthManager; Landroid/os/health/TimerStat$1; Landroid/os/health/TimerStat; +Landroid/os/image/DynamicSystemClient; +Landroid/os/image/DynamicSystemManager; +Landroid/os/image/IDynamicSystemService$Stub; +Landroid/os/image/IDynamicSystemService; Landroid/os/storage/DiskInfo; Landroid/os/storage/IObbActionListener$Stub; Landroid/os/storage/IObbActionListener; diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt index 76d69cdce5cf..95bdc364998f 100644 --- a/config/hiddenapi-greylist.txt +++ b/config/hiddenapi-greylist.txt @@ -678,11 +678,6 @@ Lcom/android/ims/internal/uce/presence/IPresenceService$Stub;-><init>()V Lcom/android/ims/internal/uce/uceservice/IUceListener$Stub;-><init>()V Lcom/android/ims/internal/uce/uceservice/IUceService$Stub;-><init>()V Lcom/android/internal/app/AlertActivity;-><init>()V -Lcom/android/internal/app/AlertActivity;->mAlert:Lcom/android/internal/app/AlertController; -Lcom/android/internal/app/AlertActivity;->mAlertParams:Lcom/android/internal/app/AlertController$AlertParams; -Lcom/android/internal/app/AlertActivity;->setupAlert()V -Lcom/android/internal/app/AssistUtils;-><init>(Landroid/content/Context;)V -Lcom/android/internal/app/AssistUtils;->getAssistComponentForUser(I)Landroid/content/ComponentName; Lcom/android/internal/app/ChooserActivity;-><init>()V Lcom/android/internal/app/IAppOpsCallback$Stub;-><init>()V Lcom/android/internal/app/IAppOpsService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V @@ -710,42 +705,13 @@ Lcom/android/internal/app/IAppOpsService$Stub;->TRANSACTION_stopWatchingMode:I Lcom/android/internal/app/IBatteryStats$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Lcom/android/internal/app/IBatteryStats$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IBatteryStats; Lcom/android/internal/app/IMediaContainerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IMediaContainerService; -Lcom/android/internal/app/IntentForwarderActivity;->TAG:Ljava/lang/String; Lcom/android/internal/app/IVoiceInteractionManagerService$Stub$Proxy;->showSessionFromSession(Landroid/os/IBinder;Landroid/os/Bundle;I)Z Lcom/android/internal/app/IVoiceInteractionManagerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IVoiceInteractionManagerService; -Lcom/android/internal/app/LocaleHelper$LocaleInfoComparator;-><init>(Ljava/util/Locale;Z)V -Lcom/android/internal/app/LocaleHelper$LocaleInfoComparator;->compare(Lcom/android/internal/app/LocaleStore$LocaleInfo;Lcom/android/internal/app/LocaleStore$LocaleInfo;)I -Lcom/android/internal/app/LocaleHelper;->getDisplayCountry(Ljava/util/Locale;Ljava/util/Locale;)Ljava/lang/String; -Lcom/android/internal/app/LocaleHelper;->getDisplayName(Ljava/util/Locale;Ljava/util/Locale;Z)Ljava/lang/String; -Lcom/android/internal/app/LocaleHelper;->normalizeForSearch(Ljava/lang/String;Ljava/util/Locale;)Ljava/lang/String; -Lcom/android/internal/app/LocalePicker$LocaleInfo;->getLocale()Ljava/util/Locale; -Lcom/android/internal/app/LocalePicker;->getLocales()Landroid/os/LocaleList; -Lcom/android/internal/app/LocalePicker;->updateLocale(Ljava/util/Locale;)V -Lcom/android/internal/app/LocalePicker;->updateLocales(Landroid/os/LocaleList;)V -Lcom/android/internal/app/LocaleStore$LocaleInfo;->getFullNameInUiLanguage()Ljava/lang/String; -Lcom/android/internal/app/LocaleStore$LocaleInfo;->getFullNameNative()Ljava/lang/String; -Lcom/android/internal/app/LocaleStore$LocaleInfo;->getId()Ljava/lang/String; -Lcom/android/internal/app/LocaleStore$LocaleInfo;->getLocale()Ljava/util/Locale; -Lcom/android/internal/app/LocaleStore$LocaleInfo;->getParent()Ljava/util/Locale; -Lcom/android/internal/app/LocaleStore;->fillCache(Landroid/content/Context;)V -Lcom/android/internal/app/LocaleStore;->getLevelLocales(Landroid/content/Context;Ljava/util/Set;Lcom/android/internal/app/LocaleStore$LocaleInfo;Z)Ljava/util/Set; -Lcom/android/internal/app/LocaleStore;->getLocaleInfo(Ljava/util/Locale;)Lcom/android/internal/app/LocaleStore$LocaleInfo; -Lcom/android/internal/app/NetInitiatedActivity;->handleNIVerify(Landroid/content/Intent;)V Lcom/android/internal/app/ResolverActivity;-><init>()V -Lcom/android/internal/app/ResolverActivity;->mAdapter:Lcom/android/internal/app/ResolverActivity$ResolveListAdapter; -Lcom/android/internal/app/ResolverActivity;->mPm:Landroid/content/pm/PackageManager; -Lcom/android/internal/app/ResolverActivity;->onCreate(Landroid/os/Bundle;Landroid/content/Intent;Ljava/lang/CharSequence;[Landroid/content/Intent;Ljava/util/List;Z)V -Lcom/android/internal/app/WindowDecorActionBar$TabImpl;->mCallback:Landroid/app/ActionBar$TabListener; -Lcom/android/internal/app/WindowDecorActionBar;->mTabScrollView:Lcom/android/internal/widget/ScrollingTabContainerView; -Lcom/android/internal/app/WindowDecorActionBar;->setShowHideAnimationEnabled(Z)V Lcom/android/internal/appwidget/IAppWidgetService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/appwidget/IAppWidgetService; Lcom/android/internal/appwidget/IAppWidgetService$Stub;->TRANSACTION_bindAppWidgetId:I Lcom/android/internal/backup/IBackupTransport$Stub;-><init>()V Lcom/android/internal/content/PackageMonitor;-><init>()V -Lcom/android/internal/database/SortCursor;-><init>([Landroid/database/Cursor;Ljava/lang/String;)V -Lcom/android/internal/database/SortCursor;->mCursor:Landroid/database/Cursor; -Lcom/android/internal/database/SortCursor;->mCursors:[Landroid/database/Cursor; -Lcom/android/internal/http/HttpDateTime;->parse(Ljava/lang/String;)J Lcom/android/internal/location/GpsNetInitiatedHandler$GpsNiNotification;-><init>()V Lcom/android/internal/location/GpsNetInitiatedHandler$GpsNiNotification;->requestorId:Ljava/lang/String; Lcom/android/internal/location/GpsNetInitiatedHandler$GpsNiNotification;->requestorIdEncoding:I @@ -764,48 +730,11 @@ Lcom/android/internal/location/ILocationProviderManager$Stub;->asInterface(Landr Lcom/android/internal/logging/MetricsLogger;-><init>()V Lcom/android/internal/net/LegacyVpnInfo;-><init>()V Lcom/android/internal/net/VpnConfig;-><init>()V -Lcom/android/internal/os/AndroidPrintStream;-><init>(ILjava/lang/String;)V Lcom/android/internal/os/BaseCommand;-><init>()V -Lcom/android/internal/os/BaseCommand;->mArgs:Landroid/os/ShellCommand; Lcom/android/internal/os/BatterySipper$DrainType;->values()[Lcom/android/internal/os/BatterySipper$DrainType; -Lcom/android/internal/os/BinderInternal;->getContextObject()Landroid/os/IBinder; -Lcom/android/internal/os/BinderInternal;->handleGc()V -Lcom/android/internal/os/ClassLoaderFactory;->createClassloaderNamespace(Ljava/lang/ClassLoader;ILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;)Ljava/lang/String; Lcom/android/internal/os/IDropBoxManagerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/os/IDropBoxManagerService; -Lcom/android/internal/os/ProcessCpuTracker$Stats;->name:Ljava/lang/String; -Lcom/android/internal/os/ProcessCpuTracker$Stats;->rel_stime:I -Lcom/android/internal/os/ProcessCpuTracker$Stats;->rel_uptime:J -Lcom/android/internal/os/ProcessCpuTracker$Stats;->rel_utime:I -Lcom/android/internal/os/ProcessCpuTracker;-><init>(Z)V -Lcom/android/internal/os/ProcessCpuTracker;->countWorkingStats()I -Lcom/android/internal/os/ProcessCpuTracker;->getWorkingStats(I)Lcom/android/internal/os/ProcessCpuTracker$Stats; -Lcom/android/internal/os/ProcessCpuTracker;->update()V -Lcom/android/internal/os/RuntimeInit;->commonInit()V -Lcom/android/internal/os/RuntimeInit;->getApplicationObject()Landroid/os/IBinder; -Lcom/android/internal/os/RuntimeInit;->initialized:Z -Lcom/android/internal/os/RuntimeInit;->main([Ljava/lang/String;)V -Lcom/android/internal/os/RuntimeInit;->mApplicationObject:Landroid/os/IBinder; -Lcom/android/internal/os/ZygoteConnection;->closeSocket()V -Lcom/android/internal/os/ZygoteConnection;->mSocket:Landroid/net/LocalSocket; -Lcom/android/internal/os/ZygoteConnection;->mSocketOutStream:Ljava/io/DataOutputStream; -Lcom/android/internal/os/ZygoteConnection;->peer:Landroid/net/Credentials; -Lcom/android/internal/os/ZygoteInit;->main([Ljava/lang/String;)V -Lcom/android/internal/os/ZygoteInit;->mResources:Landroid/content/res/Resources; -Lcom/android/internal/os/ZygoteSecurityException;-><init>(Ljava/lang/String;)V -Lcom/android/internal/policy/DecorView;->mLastBottomInset:I -Lcom/android/internal/policy/DecorView;->mLastLeftInset:I -Lcom/android/internal/policy/DecorView;->mLastRightInset:I -Lcom/android/internal/policy/DecorView;->mWindow:Lcom/android/internal/policy/PhoneWindow; Lcom/android/internal/policy/IKeyguardService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/policy/IKeyguardService; Lcom/android/internal/policy/IKeyguardStateCallback$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/policy/IKeyguardStateCallback; -Lcom/android/internal/policy/PhoneFallbackEventHandler;-><init>(Landroid/content/Context;)V -Lcom/android/internal/policy/PhoneFallbackEventHandler;->mContext:Landroid/content/Context; -Lcom/android/internal/policy/PhoneFallbackEventHandler;->mView:Landroid/view/View; -Lcom/android/internal/policy/PhoneFallbackEventHandler;->onKeyDown(ILandroid/view/KeyEvent;)Z -Lcom/android/internal/policy/PhoneFallbackEventHandler;->onKeyUp(ILandroid/view/KeyEvent;)Z -Lcom/android/internal/policy/PhoneFallbackEventHandler;->startCallActivity()V -Lcom/android/internal/policy/PhoneWindow;-><init>(Landroid/content/Context;)V -Lcom/android/internal/policy/PhoneWindow;->mTitle:Ljava/lang/CharSequence; Lcom/android/internal/preference/YesNoPreference;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V Lcom/android/internal/R$anim;->fade_in:I Lcom/android/internal/R$array;->config_autoBrightnessLcdBacklightValues:I @@ -1556,203 +1485,15 @@ Lcom/android/internal/telephony/uicc/IccUtils;->parseToBnW([BI)Landroid/graphics Lcom/android/internal/telephony/uicc/IccUtils;->parseToRGB([BIZ)Landroid/graphics/Bitmap; Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;->values()[Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState; Lcom/android/internal/textservice/ITextServicesManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V -Lcom/android/internal/util/ArrayUtils;->appendElement(Ljava/lang/Class;[Ljava/lang/Object;Ljava/lang/Object;)[Ljava/lang/Object; -Lcom/android/internal/util/ArrayUtils;->appendInt([II)[I -Lcom/android/internal/util/ArrayUtils;->contains([II)Z -Lcom/android/internal/util/ArrayUtils;->contains([Ljava/lang/Object;Ljava/lang/Object;)Z -Lcom/android/internal/util/ArrayUtils;->emptyArray(Ljava/lang/Class;)[Ljava/lang/Object; -Lcom/android/internal/util/ArrayUtils;->indexOf([Ljava/lang/Object;Ljava/lang/Object;)I -Lcom/android/internal/util/ArrayUtils;->isEmpty([Ljava/lang/Object;)Z -Lcom/android/internal/util/ArrayUtils;->newUnpaddedArray(Ljava/lang/Class;I)[Ljava/lang/Object; -Lcom/android/internal/util/ArrayUtils;->newUnpaddedIntArray(I)[I -Lcom/android/internal/util/ArrayUtils;->removeElement(Ljava/lang/Class;[Ljava/lang/Object;Ljava/lang/Object;)[Ljava/lang/Object; -Lcom/android/internal/util/BitwiseInputStream;-><init>([B)V -Lcom/android/internal/util/BitwiseInputStream;->available()I -Lcom/android/internal/util/BitwiseInputStream;->read(I)I -Lcom/android/internal/util/BitwiseInputStream;->readByteArray(I)[B -Lcom/android/internal/util/BitwiseInputStream;->skip(I)V -Lcom/android/internal/util/BitwiseOutputStream;-><init>(I)V -Lcom/android/internal/util/BitwiseOutputStream;->toByteArray()[B -Lcom/android/internal/util/BitwiseOutputStream;->write(II)V -Lcom/android/internal/util/BitwiseOutputStream;->writeByteArray(I[B)V -Lcom/android/internal/util/CharSequences;->compareToIgnoreCase(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)I -Lcom/android/internal/util/CharSequences;->equals(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Z -Lcom/android/internal/util/FastMath;->round(F)I -Lcom/android/internal/util/FastXmlSerializer;-><init>()V -Lcom/android/internal/util/GrowingArrayUtils;->append([III)[I -Lcom/android/internal/util/GrowingArrayUtils;->append([Ljava/lang/Object;ILjava/lang/Object;)[Ljava/lang/Object; -Lcom/android/internal/util/HexDump;->hexStringToByteArray(Ljava/lang/String;)[B -Lcom/android/internal/util/HexDump;->toHexString(I)Ljava/lang/String; -Lcom/android/internal/util/HexDump;->toHexString([B)Ljava/lang/String; -Lcom/android/internal/util/HexDump;->toHexString([BII)Ljava/lang/String; -Lcom/android/internal/util/HexDump;->toHexString([BZ)Ljava/lang/String; -Lcom/android/internal/util/IState;->getName()Ljava/lang/String; Lcom/android/internal/util/MemInfoReader;-><init>()V -Lcom/android/internal/util/MemInfoReader;->getCachedSize()J -Lcom/android/internal/util/MemInfoReader;->getFreeSize()J -Lcom/android/internal/util/MemInfoReader;->getRawInfo()[J -Lcom/android/internal/util/MemInfoReader;->getTotalSize()J -Lcom/android/internal/util/MemInfoReader;->readMemInfo()V -Lcom/android/internal/util/Preconditions;->checkArgument(Z)V -Lcom/android/internal/util/Preconditions;->checkArgument(ZLjava/lang/Object;)V -Lcom/android/internal/util/Preconditions;->checkArgumentInRange(IIILjava/lang/String;)I -Lcom/android/internal/util/Preconditions;->checkNotNull(Ljava/lang/Object;)Ljava/lang/Object; -Lcom/android/internal/util/Preconditions;->checkNotNull(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; -Lcom/android/internal/util/Preconditions;->checkState(Z)V -Lcom/android/internal/util/Preconditions;->checkState(ZLjava/lang/String;)V -Lcom/android/internal/util/State;-><init>()V -Lcom/android/internal/util/State;->enter()V -Lcom/android/internal/util/State;->exit()V -Lcom/android/internal/util/State;->getName()Ljava/lang/String; -Lcom/android/internal/util/State;->processMessage(Landroid/os/Message;)Z -Lcom/android/internal/util/StateMachine;-><init>(Ljava/lang/String;)V -Lcom/android/internal/util/StateMachine;-><init>(Ljava/lang/String;Landroid/os/Handler;)V -Lcom/android/internal/util/StateMachine;-><init>(Ljava/lang/String;Landroid/os/Looper;)V -Lcom/android/internal/util/StateMachine;->dump(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;)V -Lcom/android/internal/util/StateMachine;->obtainMessage(III)Landroid/os/Message; -Lcom/android/internal/util/StateMachine;->obtainMessage(IIILjava/lang/Object;)Landroid/os/Message; -Lcom/android/internal/util/StateMachine;->sendMessage(I)V -Lcom/android/internal/util/StateMachine;->sendMessage(II)V -Lcom/android/internal/util/StateMachine;->sendMessage(IIILjava/lang/Object;)V -Lcom/android/internal/util/StateMachine;->sendMessage(ILjava/lang/Object;)V -Lcom/android/internal/util/StateMachine;->sendMessage(Landroid/os/Message;)V -Lcom/android/internal/view/ActionBarPolicy;-><init>(Landroid/content/Context;)V -Lcom/android/internal/view/ActionBarPolicy;->get(Landroid/content/Context;)Lcom/android/internal/view/ActionBarPolicy; -Lcom/android/internal/view/ActionBarPolicy;->getEmbeddedMenuWidthLimit()I -Lcom/android/internal/view/ActionBarPolicy;->getMaxActionButtons()I -Lcom/android/internal/view/ActionBarPolicy;->getStackedTabMaxWidth()I -Lcom/android/internal/view/ActionBarPolicy;->getTabContainerHeight()I -Lcom/android/internal/view/ActionBarPolicy;->hasEmbeddedTabs()Z -Lcom/android/internal/view/ActionBarPolicy;->mContext:Landroid/content/Context; -Lcom/android/internal/view/ActionBarPolicy;->showsOverflowMenuButton()Z Lcom/android/internal/view/IInputMethodManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Lcom/android/internal/view/IInputMethodManager$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/view/IInputMethodManager; Lcom/android/internal/view/IInputMethodSession$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/view/IInputMethodSession; -Lcom/android/internal/view/InputConnectionWrapper$InputContextCallback;->dispose()V -Lcom/android/internal/view/InputConnectionWrapper$InputContextCallback;->getInstance()Lcom/android/internal/view/InputConnectionWrapper$InputContextCallback; -Lcom/android/internal/view/menu/ActionMenu;-><init>(Landroid/content/Context;)V -Lcom/android/internal/view/menu/ActionMenuItem;-><init>(Landroid/content/Context;IIIILjava/lang/CharSequence;)V -Lcom/android/internal/view/menu/ContextMenuBuilder;-><init>(Landroid/content/Context;)V -Lcom/android/internal/view/menu/IconMenuItemView;->getTextAppropriateLayoutParams()Lcom/android/internal/view/menu/IconMenuView$LayoutParams; -Lcom/android/internal/view/menu/IconMenuItemView;->setIconMenuView(Lcom/android/internal/view/menu/IconMenuView;)V -Lcom/android/internal/view/menu/IconMenuItemView;->setItemInvoker(Lcom/android/internal/view/menu/MenuBuilder$ItemInvoker;)V -Lcom/android/internal/view/menu/IconMenuView$SavedState;-><init>(Landroid/os/Parcel;)V -Lcom/android/internal/view/menu/IconMenuView;->createMoreItemView()Lcom/android/internal/view/menu/IconMenuItemView; -Lcom/android/internal/view/menu/IconMenuView;->getNumActualItemsShown()I -Lcom/android/internal/view/menu/IconMenuView;->mItemBackground:Landroid/graphics/drawable/Drawable; -Lcom/android/internal/view/menu/IconMenuView;->mMaxItems:I -Lcom/android/internal/view/menu/IconMenuView;->mMenu:Lcom/android/internal/view/menu/MenuBuilder; -Lcom/android/internal/view/menu/MenuDialogHelper;-><init>(Lcom/android/internal/view/menu/MenuBuilder;)V -Lcom/android/internal/view/menu/MenuDialogHelper;->dismiss()V -Lcom/android/internal/view/menu/MenuDialogHelper;->show(Landroid/os/IBinder;)V -Lcom/android/internal/view/WindowManagerPolicyThread;->getLooper()Landroid/os/Looper; -Lcom/android/internal/widget/AbsActionBarView;->dismissPopupMenus()V -Lcom/android/internal/widget/ActionBarContextView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V -Lcom/android/internal/widget/ActionBarOverlayLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V -Lcom/android/internal/widget/ActionBarOverlayLayout;->setWindowCallback(Landroid/view/Window$Callback;)V -Lcom/android/internal/widget/EditableInputConnection;-><init>(Landroid/widget/TextView;)V Lcom/android/internal/widget/ILockSettings$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/widget/ILockSettings; Lcom/android/internal/widget/IRemoteViewsFactory$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/widget/IRemoteViewsFactory; -Lcom/android/internal/widget/LinearLayoutWithDefaultTouchRecepient;-><init>(Landroid/content/Context;)V -Lcom/android/internal/widget/LinearLayoutWithDefaultTouchRecepient;->setDefaultTouchRecepient(Landroid/view/View;)V -Lcom/android/internal/widget/LockPatternChecker;->checkPassword(Lcom/android/internal/widget/LockPatternUtils;Ljava/lang/String;ILcom/android/internal/widget/LockPatternChecker$OnCheckCallback;)Landroid/os/AsyncTask; -Lcom/android/internal/widget/LockPatternUtils$RequestThrottledException;-><init>(I)V -Lcom/android/internal/widget/LockPatternUtils$RequestThrottledException;->getTimeoutMs()I -Lcom/android/internal/widget/LockPatternUtils;-><init>(Landroid/content/Context;)V -Lcom/android/internal/widget/LockPatternUtils;->checkPassword(Ljava/lang/String;I)Z -Lcom/android/internal/widget/LockPatternUtils;->getActivePasswordQuality(I)I -Lcom/android/internal/widget/LockPatternUtils;->getDevicePolicyManager()Landroid/app/admin/DevicePolicyManager; -Lcom/android/internal/widget/LockPatternUtils;->getKeyguardStoredPasswordQuality(I)I -Lcom/android/internal/widget/LockPatternUtils;->getLockSettings()Lcom/android/internal/widget/ILockSettings; -Lcom/android/internal/widget/LockPatternUtils;->getOwnerInfo(I)Ljava/lang/String; -Lcom/android/internal/widget/LockPatternUtils;->getPowerButtonInstantlyLocks(I)Z -Lcom/android/internal/widget/LockPatternUtils;->getString(Ljava/lang/String;I)Ljava/lang/String; -Lcom/android/internal/widget/LockPatternUtils;->isDeviceEncryptionEnabled()Z -Lcom/android/internal/widget/LockPatternUtils;->isLockPasswordEnabled(I)Z -Lcom/android/internal/widget/LockPatternUtils;->isLockPatternEnabled(I)Z -Lcom/android/internal/widget/LockPatternUtils;->isLockScreenDisabled(I)Z -Lcom/android/internal/widget/LockPatternUtils;->isSecure(I)Z -Lcom/android/internal/widget/LockPatternUtils;->isTactileFeedbackEnabled()Z -Lcom/android/internal/widget/LockPatternUtils;->isVisiblePatternEnabled(I)Z -Lcom/android/internal/widget/LockPatternUtils;->mContentResolver:Landroid/content/ContentResolver; -Lcom/android/internal/widget/LockPatternUtils;->mContext:Landroid/content/Context; -Lcom/android/internal/widget/LockPatternUtils;->patternToHash(Ljava/util/List;)[B -Lcom/android/internal/widget/LockPatternUtils;->patternToString(Ljava/util/List;)Ljava/lang/String; -Lcom/android/internal/widget/LockPatternUtils;->reportFailedPasswordAttempt(I)V -Lcom/android/internal/widget/LockPatternUtils;->reportSuccessfulPasswordAttempt(I)V -Lcom/android/internal/widget/LockPatternUtils;->saveLockPassword(Ljava/lang/String;Ljava/lang/String;II)V -Lcom/android/internal/widget/LockPatternUtils;->setLockoutAttemptDeadline(II)J -Lcom/android/internal/widget/LockPatternUtils;->setLong(Ljava/lang/String;JI)V -Lcom/android/internal/widget/LockPatternUtils;->setOwnerInfo(Ljava/lang/String;I)V -Lcom/android/internal/widget/LockPatternUtils;->setOwnerInfoEnabled(ZI)V -Lcom/android/internal/widget/LockPatternUtils;->setString(Ljava/lang/String;Ljava/lang/String;I)V -Lcom/android/internal/widget/LockPatternView$Cell;->column:I -Lcom/android/internal/widget/LockPatternView$Cell;->row:I -Lcom/android/internal/widget/LockPatternView$DisplayMode;->Animate:Lcom/android/internal/widget/LockPatternView$DisplayMode; -Lcom/android/internal/widget/LockPatternView$DisplayMode;->Correct:Lcom/android/internal/widget/LockPatternView$DisplayMode; -Lcom/android/internal/widget/LockPatternView$DisplayMode;->Wrong:Lcom/android/internal/widget/LockPatternView$DisplayMode; -Lcom/android/internal/widget/LockPatternView$SavedState;-><init>(Landroid/os/Parcel;)V -Lcom/android/internal/widget/LockPatternView$SavedState;-><init>(Landroid/os/Parcelable;Ljava/lang/String;IZZZ)V -Lcom/android/internal/widget/LockPatternView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V -Lcom/android/internal/widget/LockPatternView;->clearPattern()V -Lcom/android/internal/widget/LockPatternView;->disableInput()V -Lcom/android/internal/widget/LockPatternView;->enableInput()V -Lcom/android/internal/widget/LockPatternView;->getCellStates()[[Lcom/android/internal/widget/LockPatternView$CellState; -Lcom/android/internal/widget/LockPatternView;->mInStealthMode:Z -Lcom/android/internal/widget/LockPatternView;->mPaint:Landroid/graphics/Paint; -Lcom/android/internal/widget/LockPatternView;->mPathPaint:Landroid/graphics/Paint; -Lcom/android/internal/widget/LockPatternView;->mPattern:Ljava/util/ArrayList; -Lcom/android/internal/widget/LockPatternView;->mPatternDisplayMode:Lcom/android/internal/widget/LockPatternView$DisplayMode; -Lcom/android/internal/widget/LockPatternView;->mPatternInProgress:Z -Lcom/android/internal/widget/LockPatternView;->mSquareHeight:F -Lcom/android/internal/widget/LockPatternView;->mSquareWidth:F -Lcom/android/internal/widget/LockPatternView;->notifyPatternDetected()V -Lcom/android/internal/widget/LockPatternView;->setDisplayMode(Lcom/android/internal/widget/LockPatternView$DisplayMode;)V -Lcom/android/internal/widget/LockPatternView;->setInStealthMode(Z)V -Lcom/android/internal/widget/LockPatternView;->setOnPatternListener(Lcom/android/internal/widget/LockPatternView$OnPatternListener;)V -Lcom/android/internal/widget/LockPatternView;->setTactileFeedbackEnabled(Z)V Lcom/android/internal/widget/PointerLocationView$PointerState;-><init>()V -Lcom/android/internal/widget/PointerLocationView$PointerState;->mCurDown:Z -Lcom/android/internal/widget/PointerLocationView;->mCurDown:Z -Lcom/android/internal/widget/PointerLocationView;->mCurNumPointers:I -Lcom/android/internal/widget/PointerLocationView;->mMaxNumPointers:I -Lcom/android/internal/widget/PointerLocationView;->mPointers:Ljava/util/ArrayList; -Lcom/android/internal/widget/PointerLocationView;->mPrintCoords:Z -Lcom/android/internal/widget/PreferenceImageView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V -Lcom/android/internal/widget/RecyclerView$RecycledViewPool$ScrapData;->mScrapHeap:Ljava/util/ArrayList; -Lcom/android/internal/widget/ScrollBarUtils;->getThumbLength(IIII)I -Lcom/android/internal/widget/SlidingTab$Slider;->tab:Landroid/widget/ImageView; -Lcom/android/internal/widget/SlidingTab$Slider;->text:Landroid/widget/TextView; -Lcom/android/internal/widget/SlidingTab;->mAnimationDoneListener:Landroid/view/animation/Animation$AnimationListener; -Lcom/android/internal/widget/SlidingTab;->mLeftSlider:Lcom/android/internal/widget/SlidingTab$Slider; -Lcom/android/internal/widget/SlidingTab;->mRightSlider:Lcom/android/internal/widget/SlidingTab$Slider; -Lcom/android/internal/widget/SlidingTab;->onAnimationDone()V -Lcom/android/internal/widget/SlidingTab;->resetView()V -Lcom/android/internal/widget/SlidingTab;->setHoldAfterTrigger(ZZ)V -Lcom/android/internal/widget/SlidingTab;->setLeftHintText(I)V -Lcom/android/internal/widget/SlidingTab;->setLeftTabResources(IIII)V -Lcom/android/internal/widget/SlidingTab;->setOnTriggerListener(Lcom/android/internal/widget/SlidingTab$OnTriggerListener;)V -Lcom/android/internal/widget/SlidingTab;->setRightHintText(I)V -Lcom/android/internal/widget/SlidingTab;->setRightTabResources(IIII)V -Lcom/android/internal/widget/TextViewInputDisabler;-><init>(Landroid/widget/TextView;)V -Lcom/android/internal/widget/TextViewInputDisabler;->setInputEnabled(Z)V -Lcom/android/internal/widget/ViewPager$OnPageChangeListener;->onPageScrolled(IFI)V -Lcom/android/internal/widget/ViewPager$OnPageChangeListener;->onPageScrollStateChanged(I)V -Lcom/android/internal/widget/ViewPager$OnPageChangeListener;->onPageSelected(I)V -Lcom/android/internal/widget/ViewPager;->getCurrentItem()I Lcom/android/server/net/BaseNetworkObserver;-><init>()V -Lcom/android/server/net/NetlinkTracker;-><init>(Ljava/lang/String;Lcom/android/server/net/NetlinkTracker$Callback;)V -Lcom/android/server/net/NetlinkTracker;->clearLinkProperties()V -Lcom/android/server/net/NetlinkTracker;->getLinkProperties()Landroid/net/LinkProperties; Lcom/android/server/ResettableTimeout$T;-><init>(Lcom/android/server/ResettableTimeout;)V -Lcom/android/server/ResettableTimeout;->mLock:Landroid/os/ConditionVariable; -Lcom/android/server/ResettableTimeout;->mOffAt:J -Lcom/google/android/collect/Lists;->newArrayList([Ljava/lang/Object;)Ljava/util/ArrayList; -Lcom/google/android/collect/Sets;->newArraySet()Landroid/util/ArraySet; -Lcom/google/android/collect/Sets;->newArraySet([Ljava/lang/Object;)Landroid/util/ArraySet; -Lcom/google/android/collect/Sets;->newHashSet()Ljava/util/HashSet; -Lcom/google/android/collect/Sets;->newHashSet([Ljava/lang/Object;)Ljava/util/HashSet; -Lcom/google/android/collect/Sets;->newSortedSet()Ljava/util/SortedSet; Lcom/google/android/gles_jni/EGLImpl;-><init>()V Lcom/google/android/gles_jni/GLImpl;-><init>()V Lcom/google/android/mms/ContentType;->getAudioTypes()Ljava/util/ArrayList; @@ -2034,17 +1775,7 @@ Lcom/google/android/mms/util/SqliteWrapper;->insert(Landroid/content/Context;Lan Lcom/google/android/mms/util/SqliteWrapper;->query(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor; Lcom/google/android/mms/util/SqliteWrapper;->requery(Landroid/content/Context;Landroid/database/Cursor;)Z Lcom/google/android/mms/util/SqliteWrapper;->update(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;Landroid/content/ContentValues;Ljava/lang/String;[Ljava/lang/String;)I -Lcom/google/android/util/AbstractMessageParser$Token$Type;->ACRONYM:Lcom/google/android/util/AbstractMessageParser$Token$Type; -Lcom/google/android/util/AbstractMessageParser$Token$Type;->FLICKR:Lcom/google/android/util/AbstractMessageParser$Token$Type; -Lcom/google/android/util/AbstractMessageParser$Token$Type;->FORMAT:Lcom/google/android/util/AbstractMessageParser$Token$Type; -Lcom/google/android/util/AbstractMessageParser$Token$Type;->GOOGLE_VIDEO:Lcom/google/android/util/AbstractMessageParser$Token$Type; -Lcom/google/android/util/AbstractMessageParser$Token$Type;->HTML:Lcom/google/android/util/AbstractMessageParser$Token$Type; -Lcom/google/android/util/AbstractMessageParser$Token$Type;->LINK:Lcom/google/android/util/AbstractMessageParser$Token$Type; -Lcom/google/android/util/AbstractMessageParser$Token$Type;->MUSIC:Lcom/google/android/util/AbstractMessageParser$Token$Type; -Lcom/google/android/util/AbstractMessageParser$Token$Type;->PHOTO:Lcom/google/android/util/AbstractMessageParser$Token$Type; -Lcom/google/android/util/AbstractMessageParser$Token$Type;->SMILEY:Lcom/google/android/util/AbstractMessageParser$Token$Type; Lcom/google/android/util/AbstractMessageParser$Token$Type;->values()[Lcom/google/android/util/AbstractMessageParser$Token$Type; -Lcom/google/android/util/AbstractMessageParser$Token$Type;->YOUTUBE_VIDEO:Lcom/google/android/util/AbstractMessageParser$Token$Type; Lgov/nist/core/Debug;->printStackTrace(Ljava/lang/Exception;)V Lgov/nist/core/GenericObject;-><init>()V Lgov/nist/core/GenericObject;->dbgPrint()V diff --git a/config/preloaded-classes b/config/preloaded-classes index fda028de33f3..abdbab2a29eb 100644 --- a/config/preloaded-classes +++ b/config/preloaded-classes @@ -2724,7 +2724,6 @@ android.os.DeviceIdleManager android.os.DropBoxManager$Entry$1 android.os.DropBoxManager$Entry android.os.DropBoxManager -android.os.DynamicAndroidManager android.os.Environment$UserEnvironment android.os.Environment android.os.EventLogTags @@ -2909,6 +2908,8 @@ android.os.health.HealthStatsParceler android.os.health.SystemHealthManager android.os.health.TimerStat$1 android.os.health.TimerStat +android.os.image.DynamicSystemClient +android.os.image.DynamicSystemManager android.os.storage.IObbActionListener$Stub android.os.storage.IObbActionListener android.os.storage.IStorageManager$Stub$Proxy diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 7a0639eef8cc..404e52011c39 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -536,6 +536,19 @@ public class ApplicationPackageManager extends PackageManager { } } + @NonNull + @Override + public List<SharedLibraryInfo> getDeclaredSharedLibraries(@NonNull String packageName, + @InstallFlags int flags) { + try { + ParceledListSlice<SharedLibraryInfo> sharedLibraries = mPM.getDeclaredSharedLibraries( + packageName, flags, mContext.getUserId()); + return sharedLibraries != null ? sharedLibraries.getList() : Collections.emptyList(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** @hide */ @Override public @NonNull String getServicesSystemSharedLibraryPackageName() { diff --git a/core/java/android/app/AutomaticZenRule.java b/core/java/android/app/AutomaticZenRule.java index ec2825edebe6..7180c01143a5 100644 --- a/core/java/android/app/AutomaticZenRule.java +++ b/core/java/android/app/AutomaticZenRule.java @@ -231,7 +231,7 @@ public final class AutomaticZenRule implements Parcelable { * Sets the zen policy. */ public void setZenPolicy(ZenPolicy zenPolicy) { - this.mZenPolicy = zenPolicy; + this.mZenPolicy = (zenPolicy == null ? null : zenPolicy.copy()); } /** diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 5945eef52b2c..11000df5b993 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -1090,7 +1090,6 @@ class ContextImpl extends Context { @Override public void sendBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user, String[] receiverPermissions) { - warnIfCallingFromSystemProcess(); String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); try { intent.prepareToLeaveProcess(this); diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 7ba614685ad8..d634aa578429 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -21,6 +21,7 @@ import static android.graphics.drawable.Icon.TYPE_BITMAP; import static com.android.internal.util.ContrastColorUtil.satisfiesTextContrast; import android.annotation.ColorInt; +import android.annotation.DimenRes; import android.annotation.DrawableRes; import android.annotation.IdRes; import android.annotation.IntDef; @@ -8521,6 +8522,7 @@ public class Notification implements Parcelable private PendingIntent mDeleteIntent; private Icon mIcon; private int mDesiredHeight; + @DimenRes private int mDesiredHeightResId; private int mFlags; /** @@ -8547,10 +8549,11 @@ public class Notification implements Parcelable private static final int FLAG_SUPPRESS_INITIAL_NOTIFICATION = 0x00000002; private BubbleMetadata(PendingIntent expandIntent, PendingIntent deleteIntent, - Icon icon, int height) { + Icon icon, int height, @DimenRes int heightResId) { mPendingIntent = expandIntent; mIcon = icon; mDesiredHeight = height; + mDesiredHeightResId = heightResId; mDeleteIntent = deleteIntent; } @@ -8562,6 +8565,7 @@ public class Notification implements Parcelable if (in.readInt() != 0) { mDeleteIntent = PendingIntent.CREATOR.createFromParcel(in); } + mDesiredHeightResId = in.readInt(); } /** @@ -8581,17 +8585,6 @@ public class Notification implements Parcelable } /** - * @return the title that will appear along with the app content defined by - * {@link #getIntent()} for this bubble. - * - * @deprecated titles are no longer required or shown. - */ - @Deprecated - public CharSequence getTitle() { - return ""; - } - - /** * @return the icon that will be displayed for this bubble when it is collapsed. */ @NonNull @@ -8600,7 +8593,7 @@ public class Notification implements Parcelable } /** - * @return the ideal height for the floating window that app content defined by + * @return the ideal height, in DPs, for the floating window that app content defined by * {@link #getIntent()} for this bubble. */ public int getDesiredHeight() { @@ -8608,6 +8601,15 @@ public class Notification implements Parcelable } /** + * @return the resId of ideal height for the floating window that app content defined by + * {@link #getIntent()} for this bubble. + */ + @DimenRes + public int getDesiredHeightResId() { + return mDesiredHeightResId; + } + + /** * @return whether this bubble should auto expand when it is posted. * * @see BubbleMetadata.Builder#setAutoExpandBubble(boolean) @@ -8654,6 +8656,7 @@ public class Notification implements Parcelable if (mDeleteIntent != null) { mDeleteIntent.writeToParcel(out, 0); } + out.writeInt(mDesiredHeightResId); } private void setFlags(int flags) { @@ -8668,6 +8671,7 @@ public class Notification implements Parcelable private PendingIntent mPendingIntent; private Icon mIcon; private int mDesiredHeight; + @DimenRes private int mDesiredHeightResId; private int mFlags; private PendingIntent mDeleteIntent; @@ -8691,19 +8695,6 @@ public class Notification implements Parcelable } /** - * Sets the title that will appear along with the app content for this bubble. - * - * <p>A title is required and should expect to fit on a single line and make sense when - * shown with the content defined by {@link #setIntent(PendingIntent)}.</p> - * - * @deprecated titles are no longer required or shown. - */ - @Deprecated - public BubbleMetadata.Builder setTitle(CharSequence title) { - return this; - } - - /** * Sets the icon that will represent the bubble when it is collapsed. * * <p>An icon is required and should be representative of the content within the bubble. @@ -8733,13 +8724,35 @@ public class Notification implements Parcelable } /** - * Sets the desired height for the app content defined by + * Sets the desired height in DPs for the app content defined by * {@link #setIntent(PendingIntent)}, this height may not be respected if there is not * enough space on the screen or if the provided height is too small to be useful. + * <p> + * If {@link #setDesiredHeightResId(int)} was previously called on this builder, the + * previous value set will be cleared after calling this method, and this value will + * be used instead. */ @NonNull public BubbleMetadata.Builder setDesiredHeight(int height) { mDesiredHeight = Math.max(height, 0); + mDesiredHeightResId = 0; + return this; + } + + + /** + * Sets the desired height via resId for the app content defined by + * {@link #setIntent(PendingIntent)}, this height may not be respected if there is not + * enough space on the screen or if the provided height is too small to be useful. + * <p> + * If {@link #setDesiredHeight(int)} was previously called on this builder, the + * previous value set will be cleared after calling this method, and this value will + * be used instead. + */ + @NonNull + public BubbleMetadata.Builder setDesiredHeightResId(@DimenRes int heightResId) { + mDesiredHeightResId = heightResId; + mDesiredHeight = 0; return this; } @@ -8801,7 +8814,7 @@ public class Notification implements Parcelable throw new IllegalStateException("Must supply an icon for the bubble"); } BubbleMetadata data = new BubbleMetadata(mPendingIntent, mDeleteIntent, - mIcon, mDesiredHeight); + mIcon, mDesiredHeight, mDesiredHeightResId); data.setFlags(mFlags); return data; } diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index 1aacf966fc14..0bec21fcda90 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -315,7 +315,8 @@ public class NotificationManager { * This tag should contain a localized name of the type of the zen rule provided by the * activity. */ - public static final String META_DATA_AUTOMATIC_RULE_TYPE = "android.app.automatic.ruleType"; + public static final String META_DATA_AUTOMATIC_RULE_TYPE = + "android.service.zen.automatic.ruleType"; /** * An optional {@code meta-data} tag for activities that handle @@ -325,7 +326,7 @@ public class NotificationManager { * can be created for this rule type. Omit or enter a value <= 0 to allow unlimited instances. */ public static final String META_DATA_RULE_INSTANCE_LIMIT = - "android.app.zen.automatic.ruleInstanceLimit"; + "android.service.zen.automatic.ruleInstanceLimit"; /** Value signifying that the user has not expressed a per-app visibility override value. * @hide */ diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 4d280b76b3fa..d67bfb6c9c84 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -131,13 +131,11 @@ import android.os.BugreportManager; import android.os.Build; import android.os.DeviceIdleManager; import android.os.DropBoxManager; -import android.os.DynamicAndroidManager; import android.os.HardwarePropertiesManager; import android.os.IBatteryPropertiesRegistrar; import android.os.IBinder; import android.os.IDeviceIdleController; import android.os.IDumpstate; -import android.os.IDynamicAndroidService; import android.os.IHardwarePropertiesManager; import android.os.IPowerManager; import android.os.IRecoverySystem; @@ -155,6 +153,8 @@ import android.os.UserHandle; import android.os.UserManager; import android.os.Vibrator; import android.os.health.SystemHealthManager; +import android.os.image.DynamicSystemManager; +import android.os.image.IDynamicSystemService; import android.os.storage.StorageManager; import android.permission.PermissionControllerManager; import android.permission.PermissionManager; @@ -1275,15 +1275,15 @@ final class SystemServiceRegistry { IRollbackManager.Stub.asInterface(b)); }}); - registerService(Context.DYNAMIC_ANDROID_SERVICE, DynamicAndroidManager.class, - new CachedServiceFetcher<DynamicAndroidManager>() { + registerService(Context.DYNAMIC_SYSTEM_SERVICE, DynamicSystemManager.class, + new CachedServiceFetcher<DynamicSystemManager>() { @Override - public DynamicAndroidManager createService(ContextImpl ctx) + public DynamicSystemManager createService(ContextImpl ctx) throws ServiceNotFoundException { IBinder b = ServiceManager.getServiceOrThrow( - Context.DYNAMIC_ANDROID_SERVICE); - return new DynamicAndroidManager( - IDynamicAndroidService.Stub.asInterface(b)); + Context.DYNAMIC_SYSTEM_SERVICE); + return new DynamicSystemManager( + IDynamicSystemService.Stub.asInterface(b)); }}); //CHECKSTYLE:ON IndentationCheck } diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index a929fe0f688e..325a54bffbfb 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -25,6 +25,7 @@ import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.annotation.SystemService; +import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.ContentResolver; @@ -1666,6 +1667,7 @@ public class WallpaperManager { * * @hide */ + @TestApi @SystemApi @RequiresPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT) public boolean setWallpaperComponent(ComponentName name) { diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 20e85e6793f1..4c05497479c0 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -2226,7 +2226,6 @@ public class DevicePolicyManager { * <ul> * <li>{@link #PROVISIONING_MODE_FULLY_MANAGED_DEVICE}</li> * <li>{@link #PROVISIONING_MODE_MANAGED_PROFILE}</li> - * <li>{@link #PROVISIONING_MODE_MANAGED_PROFILE_ON_FULLY_MANAGED_DEVICE}</li> * </ul> * * <p>The target activity may also return the account that needs to be migrated from primary @@ -2253,7 +2252,6 @@ public class DevicePolicyManager { * <ul> * <li>{@link #PROVISIONING_MODE_FULLY_MANAGED_DEVICE}</li> * <li>{@link #PROVISIONING_MODE_MANAGED_PROFILE}</li> - * <li>{@link #PROVISIONING_MODE_MANAGED_PROFILE_ON_FULLY_MANAGED_DEVICE}</li> * </ul> */ public static final String EXTRA_PROVISIONING_MODE = @@ -2270,11 +2268,6 @@ public class DevicePolicyManager { public static final int PROVISIONING_MODE_MANAGED_PROFILE = 2; /** - * The provisioning mode for managed profile on a fully managed device. - */ - public static final int PROVISIONING_MODE_MANAGED_PROFILE_ON_FULLY_MANAGED_DEVICE = 3; - - /** * Activity action: Starts the administrator to show policy compliance for the provisioning. */ public static final String ACTION_ADMIN_POLICY_COMPLIANCE = @@ -4358,6 +4351,7 @@ public class DevicePolicyManager { /** * Disable text entry into notifications on secure keyguard screens (e.g. PIN/Pattern/Password). + * This flag has no effect starting from version {@link android.os.Build.VERSION_CODES#N} */ public static final int KEYGUARD_DISABLE_REMOTE_INPUT = 1 << 6; diff --git a/core/java/android/app/admin/PasswordMetrics.java b/core/java/android/app/admin/PasswordMetrics.java index d71d3553db7e..992985528fca 100644 --- a/core/java/android/app/admin/PasswordMetrics.java +++ b/core/java/android/app/admin/PasswordMetrics.java @@ -24,8 +24,12 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; +import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; +import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD; +import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN; + import android.annotation.IntDef; import android.annotation.NonNull; import android.app.admin.DevicePolicyManager.PasswordComplexity; @@ -33,13 +37,15 @@ import android.os.Parcel; import android.os.Parcelable; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.Preconditions; +import com.android.internal.widget.LockPatternUtils.CredentialType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** - * A class that represents the metrics of a password that are used to decide whether or not a - * password meets the requirements. + * A class that represents the metrics of a credential that are used to decide whether or not a + * credential meets the requirements. If the credential is a pattern, only quality matters. * * {@hide} */ @@ -48,8 +54,6 @@ public class PasswordMetrics implements Parcelable { // consider it a complex PIN/password. public static final int MAX_ALLOWED_SEQUENCE = 3; - // TODO(b/120536847): refactor isActivePasswordSufficient logic so that the actual password - // quality is not overwritten public int quality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; public int length = 0; public int letters = 0; @@ -222,6 +226,25 @@ public class PasswordMetrics implements Parcelable { }; /** + * Returnsthe {@code PasswordMetrics} for a given credential. + * + * If the credential is a pin or a password, equivalent to {@link #computeForPassword(byte[])}. + * {@code credential} cannot be null when {@code type} is + * {@link com.android.internal.widget.LockPatternUtils#CREDENTIAL_TYPE_PASSWORD}. + */ + public static PasswordMetrics computeForCredential( + @CredentialType int type, byte[] credential) { + if (type == CREDENTIAL_TYPE_PASSWORD) { + Preconditions.checkNotNull(credential, "credential cannot be null"); + return PasswordMetrics.computeForPassword(credential); + } else if (type == CREDENTIAL_TYPE_PATTERN) { + return new PasswordMetrics(PASSWORD_QUALITY_SOMETHING); + } else /* if (type == CREDENTIAL_TYPE_NONE) */ { + return new PasswordMetrics(PASSWORD_QUALITY_UNSPECIFIED); + } + } + + /** * Returns the {@code PasswordMetrics} for a given password */ public static PasswordMetrics computeForPassword(@NonNull byte[] password) { @@ -233,8 +256,8 @@ public class PasswordMetrics implements Parcelable { int symbols = 0; int nonLetter = 0; final int length = password.length; - for (int i = 0; i < length; i++) { - switch (categoryChar((char) password[i])) { + for (byte b : password) { + switch (categoryChar((char) b)) { case CHAR_LOWER_CASE: letters++; lowerCase++; diff --git a/core/java/android/app/admin/SecurityLog.java b/core/java/android/app/admin/SecurityLog.java index 638657342066..19f4335893cb 100644 --- a/core/java/android/app/admin/SecurityLog.java +++ b/core/java/android/app/admin/SecurityLog.java @@ -136,8 +136,11 @@ public class SecurityLog { public static final int TAG_APP_PROCESS_START = SecurityLogTags.SECURITY_APP_PROCESS_START; /** - * Indicates that keyguard has been dismissed. + * Indicates that keyguard has been dismissed. This event is only logged if the device + * has a secure keyguard. It is logged regardless of how keyguard is dismissed, including + * via PIN/pattern/password, biometrics or via a trust agent. * There is no extra payload in the log event. + * @see #TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT */ public static final int TAG_KEYGUARD_DISMISSED = SecurityLogTags.SECURITY_KEYGUARD_DISMISSED; diff --git a/core/java/android/app/prediction/AppPredictor.java b/core/java/android/app/prediction/AppPredictor.java index 3e4e8dc2db72..3f2f2090bf33 100644 --- a/core/java/android/app/prediction/AppPredictor.java +++ b/core/java/android/app/prediction/AppPredictor.java @@ -131,14 +131,14 @@ public final class AppPredictor { * @param launchLocation The launch location where the targets are shown to the user. * @param targetIds List of {@link AppTargetId}s that are shown to the user. */ - public void notifyLocationShown(@NonNull String launchLocation, + public void notifyLaunchLocationShown(@NonNull String launchLocation, @NonNull List<AppTargetId> targetIds) { if (mIsClosed.get()) { throw new IllegalStateException("This client has already been destroyed."); } try { - mPredictionManager.notifyLocationShown(mSessionId, launchLocation, + mPredictionManager.notifyLaunchLocationShown(mSessionId, launchLocation, new ParceledListSlice<>(targetIds)); } catch (RemoteException e) { Log.e(TAG, "Failed to notify location shown event", e); diff --git a/core/java/android/app/prediction/AppTarget.java b/core/java/android/app/prediction/AppTarget.java index bb1b96ce5f00..826c149b2e05 100644 --- a/core/java/android/app/prediction/AppTarget.java +++ b/core/java/android/app/prediction/AppTarget.java @@ -43,20 +43,13 @@ public final class AppTarget implements Parcelable { private final ShortcutInfo mShortcutInfo; - private int mRank; + private final int mRank; /** - * Creates an instance of AppTarget that represent a launchable component. - * - * @param id A unique id for this launchable target. - * @param packageName Package name of the target. - * @param className Class name of the target. - * @param user The UserHandle of the user which this target belongs to. - * + * @deprecated use the Builder class * @hide */ - @SystemApi - @TestApi + @Deprecated public AppTarget(@NonNull AppTargetId id, @NonNull String packageName, @Nullable String className, @NonNull UserHandle user) { mId = id; @@ -65,18 +58,14 @@ public final class AppTarget implements Parcelable { mPackageName = Preconditions.checkNotNull(packageName); mClassName = className; mUser = Preconditions.checkNotNull(user); + mRank = 0; } /** - * Creates an instance of AppTarget that represent a launchable shortcut. - * - * @param id A unique id for this launchable target. - * @param shortcutInfo The {@link ShortcutInfo} that is represented with this target. - * @param className Class name fo the target. - * + * @deprecated use the Builder class * @hide */ - @SystemApi + @Deprecated public AppTarget(@NonNull AppTargetId id, @NonNull ShortcutInfo shortcutInfo, @Nullable String className) { mId = id; @@ -85,6 +74,17 @@ public final class AppTarget implements Parcelable { mPackageName = mShortcutInfo.getPackage(); mUser = mShortcutInfo.getUserHandle(); mClassName = className; + mRank = 0; + } + + private AppTarget(AppTargetId id, String packageName, UserHandle user, + ShortcutInfo shortcutInfo, String className, int rank) { + mId = id; + mShortcutInfo = shortcutInfo; + mPackageName = packageName; + mClassName = className; + mUser = user; + mRank = rank; } private AppTarget(Parcel parcel) { @@ -142,17 +142,6 @@ public final class AppTarget implements Parcelable { } /** - * Sets the rank of the for the target. - * @hide - */ - public void setRank(@IntRange(from = 0) int rank) { - if (rank < 0) { - throw new IllegalArgumentException("rank cannot be a negative value"); - } - mRank = rank; - } - - /** * Returns the rank for the target. Rank of an AppTarget is a non-negative integer that * represents the importance of this target compared to other candidate targets. A smaller value * means higher importance in the list. @@ -196,6 +185,101 @@ public final class AppTarget implements Parcelable { dest.writeInt(mRank); } + /** + * A builder for app targets. + * @hide + */ + @SystemApi + @TestApi + public static final class Builder { + + @NonNull + private final AppTargetId mId; + + private String mPackageName; + private UserHandle mUser; + private ShortcutInfo mShortcutInfo; + + private String mClassName; + private int mRank; + + /** + * @param id A unique id for this launchable target. + * @hide + */ + @SystemApi + @TestApi + public Builder(@NonNull AppTargetId id) { + mId = id; + } + + /** + * Sets the target to be an app. + * + * @param packageName PackageName of the app + * @param user The UserHandle of the user which this target belongs to. + * + * @throws IllegalArgumentException is the target is already set + */ + @NonNull + public Builder setTarget(@NonNull String packageName, @NonNull UserHandle user) { + if (mPackageName == null) { + throw new IllegalArgumentException("Target is already set"); + } + mPackageName = Preconditions.checkNotNull(packageName); + mUser = Preconditions.checkNotNull(user); + return this; + } + + /** + * Sets the target to be a ShortcutInfo. + * + * @throws IllegalArgumentException is the target is already set + */ + @NonNull + public Builder setTarget(@NonNull ShortcutInfo info) { + setTarget(info.getPackage(), info.getUserHandle()); + mShortcutInfo = Preconditions.checkNotNull(info); + return this; + } + + /** + * Sets the className for the target + */ + @NonNull + public Builder setClassName(@NonNull String className) { + mClassName = Preconditions.checkNotNull(className); + return this; + } + + /** + * Sets the rank of the for the target. + */ + @NonNull + public Builder setRank(@IntRange(from = 0) int rank) { + if (rank < 0) { + throw new IllegalArgumentException("rank cannot be a negative value"); + } + mRank = rank; + return this; + } + + /** + * Builds a new AppTarget instance. + * + * @throws IllegalStateException if no target is set + * @see #setTarget(ShortcutInfo) + * @see #setTarget(String, UserHandle) + */ + @NonNull + public AppTarget build() { + if (mPackageName == null) { + throw new IllegalStateException("No target set"); + } + return new AppTarget(mId, mPackageName, mUser, mShortcutInfo, mClassName, mRank); + } + } + public static final @android.annotation.NonNull Parcelable.Creator<AppTarget> CREATOR = new Parcelable.Creator<AppTarget>() { public AppTarget createFromParcel(Parcel parcel) { diff --git a/core/java/android/app/prediction/IPredictionManager.aidl b/core/java/android/app/prediction/IPredictionManager.aidl index 114a1ffb0eb2..587e3fd52377 100644 --- a/core/java/android/app/prediction/IPredictionManager.aidl +++ b/core/java/android/app/prediction/IPredictionManager.aidl @@ -33,7 +33,7 @@ interface IPredictionManager { void notifyAppTargetEvent(in AppPredictionSessionId sessionId, in AppTargetEvent event); - void notifyLocationShown(in AppPredictionSessionId sessionId, in String launchLocation, + void notifyLaunchLocationShown(in AppPredictionSessionId sessionId, in String launchLocation, in ParceledListSlice targetIds); void sortAppTargets(in AppPredictionSessionId sessionId, in ParceledListSlice targets, diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java index a6ceeb1c5233..26c8218a71ba 100644 --- a/core/java/android/app/usage/UsageStatsManager.java +++ b/core/java/android/app/usage/UsageStatsManager.java @@ -758,23 +758,6 @@ public final class UsageStatsManager { } /** - * @deprecated use - * {@link #registerAppUsageLimitObserver(int, String[], Duration, Duration, PendingIntent)}. - * - * @removed - * @hide - */ - @Deprecated - @UnsupportedAppUsage - // STOPSHIP b/126917290: remove this method once b/126926550 is fixed. - public void registerAppUsageLimitObserver(int observerId, @NonNull String[] observedEntities, - long timeLimit, @NonNull TimeUnit timeUnit, @Nullable PendingIntent callbackIntent) { - final Duration timeLimitDuration = Duration.ofMillis(timeUnit.toMillis(timeLimit)); - registerAppUsageLimitObserver(observerId, observedEntities, - timeLimitDuration, timeLimitDuration, callbackIntent); - } - - /** * Register a usage limit observer that receives a callback on the provided intent when the * sum of usages of apps and tokens in the provided {@code observedEntities} array exceeds the * {@code timeLimit} specified. The structure of a token is a {@link String} with the reporting diff --git a/core/java/android/attention/AttentionManagerInternal.java b/core/java/android/attention/AttentionManagerInternal.java index 6b7f10e8d426..fa3d3b8dea0c 100644 --- a/core/java/android/attention/AttentionManagerInternal.java +++ b/core/java/android/attention/AttentionManagerInternal.java @@ -30,44 +30,45 @@ public abstract class AttentionManagerInternal { /** * Checks whether user attention is at the screen and calls in the provided callback. * - * @param requestCode a code associated with the attention check request; this code would be - * used to call back in {@link AttentionCallbackInternal#onSuccess} and - * {@link AttentionCallbackInternal#onFailure} * @param timeoutMillis a budget for the attention check; if it takes longer - {@link * AttentionCallbackInternal#onFailure} would be called with the {@link * android.service.attention.AttentionService#ATTENTION_FAILURE_TIMED_OUT} * code * @param callback a callback for when the attention check has completed - * @return {@code true} if the attention check should succeed; {@false} otherwise. + * @return {@code true} if the attention check should succeed. */ - public abstract boolean checkAttention(int requestCode, - long timeoutMillis, AttentionCallbackInternal callback); + public abstract boolean checkAttention(long timeoutMillis, AttentionCallbackInternal callback); /** * Cancels the specified attention check in case it's no longer needed. * - * @param requestCode a code provided during {@link #checkAttention} + * @param callback a callback that was used in {@link #checkAttention} */ - public abstract void cancelAttentionCheck(int requestCode); + public abstract void cancelAttentionCheck(AttentionCallbackInternal callback); + + /** + * Disables the dependants. + * + * Example: called if the service does not have sufficient permissions to perform the task. + */ + public abstract void disableSelf(); /** Internal interface for attention callback. */ public abstract static class AttentionCallbackInternal { /** * Provides the result of the attention check, if the check was successful. * - * @param requestCode a code provided in {@link #checkAttention} * @param result an int with the result of the check * @param timestamp a {@code SystemClock.uptimeMillis()} timestamp associated with the * attention check */ - public abstract void onSuccess(int requestCode, int result, long timestamp); + public abstract void onSuccess(int result, long timestamp); /** * Provides the explanation for why the attention check had failed. * - * @param requestCode a code provided in {@link #checkAttention} * @param error an int with the reason for failure */ - public abstract void onFailure(int requestCode, int error); + public abstract void onFailure(int error); } } diff --git a/core/java/android/content/ContentCaptureOptions.java b/core/java/android/content/ContentCaptureOptions.java index 6be0bea4c9f2..1727d341bd82 100644 --- a/core/java/android/content/ContentCaptureOptions.java +++ b/core/java/android/content/ContentCaptureOptions.java @@ -72,9 +72,29 @@ public final class ContentCaptureOptions implements Parcelable { @Nullable public final ArraySet<ComponentName> whitelistedComponents; + /** + * Used to enable just a small set of APIs so it can used by activities belonging to the + * content capture service APK. + */ + public final boolean lite; + + public ContentCaptureOptions(int loggingLevel) { + this(/* lite= */ true, loggingLevel, /* maxBufferSize= */ 0, + /* idleFlushingFrequencyMs= */ 0, /* textChangeFlushingFrequencyMs= */ 0, + /* logHistorySize= */ 0, /* whitelistedComponents= */ null); + } + public ContentCaptureOptions(int loggingLevel, int maxBufferSize, int idleFlushingFrequencyMs, int textChangeFlushingFrequencyMs, int logHistorySize, @Nullable ArraySet<ComponentName> whitelistedComponents) { + this(/* lite= */ false, loggingLevel, maxBufferSize, idleFlushingFrequencyMs, + textChangeFlushingFrequencyMs, logHistorySize, whitelistedComponents); + } + + private ContentCaptureOptions(boolean lite, int loggingLevel, int maxBufferSize, + int idleFlushingFrequencyMs, int textChangeFlushingFrequencyMs, int logHistorySize, + @Nullable ArraySet<ComponentName> whitelistedComponents) { + this.lite = lite; this.loggingLevel = loggingLevel; this.maxBufferSize = maxBufferSize; this.idleFlushingFrequencyMs = idleFlushingFrequencyMs; @@ -115,6 +135,9 @@ public final class ContentCaptureOptions implements Parcelable { @Override public String toString() { + if (lite) { + return "ContentCaptureOptions [(lite) loggingLevel=" + loggingLevel + "]"; + } return "ContentCaptureOptions [loggingLevel=" + loggingLevel + ", maxBufferSize=" + maxBufferSize + ", idleFlushingFrequencyMs=" + idleFlushingFrequencyMs + ", textChangeFlushingFrequencyMs=" + textChangeFlushingFrequencyMs @@ -125,6 +148,10 @@ public final class ContentCaptureOptions implements Parcelable { /** @hide */ public void dumpShort(@NonNull PrintWriter pw) { pw.print("logLvl="); pw.print(loggingLevel); + if (lite) { + pw.print(", lite"); + return; + } pw.print(", bufferSize="); pw.print(maxBufferSize); pw.print(", idle="); pw.print(idleFlushingFrequencyMs); pw.print(", textIdle="); pw.print(textChangeFlushingFrequencyMs); @@ -141,7 +168,10 @@ public final class ContentCaptureOptions implements Parcelable { @Override public void writeToParcel(Parcel parcel, int flags) { + parcel.writeBoolean(lite); parcel.writeInt(loggingLevel); + if (lite) return; + parcel.writeInt(maxBufferSize); parcel.writeInt(idleFlushingFrequencyMs); parcel.writeInt(textChangeFlushingFrequencyMs); @@ -154,7 +184,11 @@ public final class ContentCaptureOptions implements Parcelable { @Override public ContentCaptureOptions createFromParcel(Parcel parcel) { + final boolean lite = parcel.readBoolean(); final int loggingLevel = parcel.readInt(); + if (lite) { + return new ContentCaptureOptions(loggingLevel); + } final int maxBufferSize = parcel.readInt(); final int idleFlushingFrequencyMs = parcel.readInt(); final int textChangeFlushingFrequencyMs = parcel.readInt(); @@ -171,6 +205,5 @@ public final class ContentCaptureOptions implements Parcelable { public ContentCaptureOptions[] newArray(int size) { return new ContentCaptureOptions[size]; } - }; } diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index fb933b1a7163..d7a2e1b80f84 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -338,6 +338,14 @@ public abstract class Context { public static final int BIND_ADJUST_BELOW_PERCEPTIBLE = 0x0100; /** + * Flag for {@link #bindService}: If binding from an app that has specific capabilities + * due to its foreground state such as an activity or foreground service, then this flag will + * allow the bound app to get the same capabilities, as long as it has the required permissions + * as well. + */ + public static final int BIND_INCLUDE_CAPABILITIES = 0x00001000; + + /** * Flag for {@link #bindService}: This flag is intended to be used only by the system to adjust * the scheduling policy for IMEs (and any other out-of-process user-visible components that * work closely with the top app) so that UI hosted in such services can have the same @@ -4644,11 +4652,10 @@ public abstract class Context { /** * Use with {@link #getSystemService(String)} to retrieve an - * {@link android.os.DynamicAndroidManager}. + * {@link android.os.image.DynamicSystemManager}. * @hide */ - @SystemApi - public static final String DYNAMIC_ANDROID_SERVICE = "dynamic_android"; + public static final String DYNAMIC_SYSTEM_SERVICE = "dynamic_system"; /** * Determine whether the given permission is allowed for a particular @@ -5322,6 +5329,7 @@ public abstract class Context { * @return display ID associated with this {@link Context}. * @hide */ + @TestApi public abstract int getDisplayId(); /** diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 6bb949804390..032e5acf12ed 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -29,6 +29,7 @@ import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; +import android.app.AppGlobals; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.ComponentInfo; @@ -43,6 +44,7 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.IBinder; +import android.os.IncidentManager; import android.os.Parcel; import android.os.Parcelable; import android.os.PersistableBundle; @@ -51,6 +53,7 @@ import android.os.ResultReceiver; import android.os.ShellCommand; import android.os.StrictMode; import android.os.UserHandle; +import android.os.storage.StorageManager; import android.provider.ContactsContract.QuickContact; import android.provider.DocumentsContract; import android.provider.DocumentsProvider; @@ -68,6 +71,7 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; +import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.io.Serializable; @@ -632,6 +636,8 @@ import java.util.Set; * of all possible flags. */ public class Intent implements Parcelable, Cloneable { + private static final String TAG = "Intent"; + private static final String ATTR_ACTION = "action"; private static final String TAG_CATEGORIES = "categories"; private static final String ATTR_CATEGORY = "category"; @@ -2118,29 +2124,6 @@ public class Intent implements Parcelable, Cloneable { "android.intent.action.REVIEW_ONGOING_PERMISSION_USAGE"; /** - * Activity action: Launch UI to review uses of permissions for a single app. - * <p> - * Input: {@link #EXTRA_PACKAGE_NAME} specifies the package whose - * permissions will be reviewed (mandatory). - * </p> - * <p> - * Output: Nothing. - * </p> - * <p class="note"> - * This requires {@link android.Manifest.permission#GRANT_RUNTIME_PERMISSIONS} permission. - * </p> - * - * @see #EXTRA_PACKAGE_NAME - * - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) - @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) - public static final String ACTION_REVIEW_APP_PERMISSION_USAGE = - "android.intent.action.REVIEW_APP_PERMISSION_USAGE"; - - /** * Activity action: Launch UI to review running accessibility services. * <p> * Input: Nothing. @@ -3500,6 +3483,7 @@ public class Intent implements Parcelable, Cloneable { * {@link android.Manifest.permission#MANAGE_USERS} to receive this broadcast. * @hide */ + @SystemApi public static final String ACTION_USER_ADDED = "android.intent.action.USER_ADDED"; @@ -9829,7 +9813,7 @@ public class Intent implements Parcelable, Cloneable { // may fail. We really should handle this (i.e., the Bundle // impl shouldn't be on top of a plain map), but for now just // ignore it and keep the original contents. :( - Log.w("Intent", "Failure filling in extras", e); + Log.w(TAG, "Failure filling in extras", e); } } if (mayHaveCopiedUris && mContentUserHint == UserHandle.USER_CURRENT @@ -10545,7 +10529,7 @@ public class Intent implements Parcelable, Cloneable { } else if (ATTR_FLAGS.equals(attrName)) { intent.setFlags(Integer.parseInt(attrValue, 16)); } else { - Log.e("Intent", "restoreFromXml: unknown attribute=" + attrName); + Log.e(TAG, "restoreFromXml: unknown attribute=" + attrName); } } @@ -10561,7 +10545,7 @@ public class Intent implements Parcelable, Cloneable { intent.addCategory(in.getAttributeValue(attrNdx)); } } else { - Log.w("Intent", "restoreFromXml: unknown name=" + name); + Log.w(TAG, "restoreFromXml: unknown name=" + name); XmlUtils.skipCurrentTag(in); } } @@ -10675,6 +10659,20 @@ public class Intent implements Parcelable, Cloneable { mData.checkContentUriWithoutPermission("Intent.getData()", getFlags()); } } + + // Translate raw filesystem paths out of storage sandbox + if (ACTION_MEDIA_SCANNER_SCAN_FILE.equals(mAction) && mData != null + && ContentResolver.SCHEME_FILE.equals(mData.getScheme()) && leavingPackage) { + final StorageManager sm = AppGlobals.getInitialApplication() + .getSystemService(StorageManager.class); + final File before = new File(mData.getPath()); + final File after = sm.translateAppToSystem(before, + android.os.Process.myPid(), android.os.Process.myUid()); + if (!Objects.equals(before, after)) { + Log.v(TAG, "Translated " + before + " to " + after); + mData = Uri.fromFile(after); + } + } } /** diff --git a/core/java/android/content/om/OverlayInfo.java b/core/java/android/content/om/OverlayInfo.java index 999d98662828..aabe59d18383 100644 --- a/core/java/android/content/om/OverlayInfo.java +++ b/core/java/android/content/om/OverlayInfo.java @@ -18,12 +18,14 @@ package android.content.om; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.Objects; /** * Immutable overlay information about a package. All PackageInfos that @@ -138,6 +140,14 @@ public final class OverlayInfo implements Parcelable { public final String targetPackageName; /** + * Name of the target overlayable declaration. + * + * @hide + */ + @SystemApi + public final String targetOverlayableName; + + /** * Category of the overlay package * * @hide @@ -190,16 +200,19 @@ public final class OverlayInfo implements Parcelable { * @hide */ public OverlayInfo(@NonNull OverlayInfo source, @State int state) { - this(source.packageName, source.targetPackageName, source.category, source.baseCodePath, - state, source.userId, source.priority, source.isStatic); + this(source.packageName, source.targetPackageName, source.targetOverlayableName, + source.category, source.baseCodePath, state, source.userId, source.priority, + source.isStatic); } /** @hide */ public OverlayInfo(@NonNull String packageName, @NonNull String targetPackageName, - @NonNull String category, @NonNull String baseCodePath, int state, int userId, + @Nullable String targetOverlayableName, @Nullable String category, + @NonNull String baseCodePath, int state, int userId, int priority, boolean isStatic) { this.packageName = packageName; this.targetPackageName = targetPackageName; + this.targetOverlayableName = targetOverlayableName; this.category = category; this.baseCodePath = baseCodePath; this.state = state; @@ -213,6 +226,7 @@ public final class OverlayInfo implements Parcelable { public OverlayInfo(Parcel source) { packageName = source.readString(); targetPackageName = source.readString(); + targetOverlayableName = source.readString(); category = source.readString(); baseCodePath = source.readString(); state = source.readInt(); @@ -256,6 +270,7 @@ public final class OverlayInfo implements Parcelable { public void writeToParcel(Parcel dest, int flags) { dest.writeString(packageName); dest.writeString(targetPackageName); + dest.writeString(targetOverlayableName); dest.writeString(category); dest.writeString(baseCodePath); dest.writeInt(state); @@ -335,6 +350,8 @@ public final class OverlayInfo implements Parcelable { result = prime * result + state; result = prime * result + ((packageName == null) ? 0 : packageName.hashCode()); result = prime * result + ((targetPackageName == null) ? 0 : targetPackageName.hashCode()); + result = prime * result + ((targetOverlayableName == null) ? 0 + : targetOverlayableName.hashCode()); result = prime * result + ((category == null) ? 0 : category.hashCode()); result = prime * result + ((baseCodePath == null) ? 0 : baseCodePath.hashCode()); return result; @@ -364,7 +381,10 @@ public final class OverlayInfo implements Parcelable { if (!targetPackageName.equals(other.targetPackageName)) { return false; } - if (!category.equals(other.category)) { + if (!Objects.equals(targetOverlayableName, other.targetOverlayableName)) { + return false; + } + if (!Objects.equals(category, other.category)) { return false; } if (!baseCodePath.equals(other.baseCodePath)) { @@ -375,7 +395,9 @@ public final class OverlayInfo implements Parcelable { @Override public String toString() { - return "OverlayInfo { overlay=" + packageName + ", target=" + targetPackageName + ", state=" - + state + " (" + stateToString(state) + "), userId=" + userId + " }"; + return "OverlayInfo { overlay=" + packageName + ", targetPackage=" + targetPackageName + + ((targetOverlayableName == null) ? "" + : ", targetOverlyabale=" + targetOverlayableName) + + ", state=" + state + " (" + stateToString(state) + "), userId=" + userId + " }"; } } diff --git a/core/java/android/content/om/OverlayManager.java b/core/java/android/content/om/OverlayManager.java index ceea0435a254..f2716fedc186 100644 --- a/core/java/android/content/om/OverlayManager.java +++ b/core/java/android/content/om/OverlayManager.java @@ -18,6 +18,7 @@ package android.content.om; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; import android.content.Context; @@ -61,40 +62,57 @@ public class OverlayManager { * Request that an overlay package is enabled and any other overlay packages with the same * target package and category are disabled. * + * If a set of overlay packages share the same category, single call to this method is + * equivalent to multiple calls to {@link #setEnabled(String, boolean, UserHandle)}. + * * @param packageName the name of the overlay package to enable. - * @param userId The user for which to change the overlay. - * @return true if the system successfully registered the request, false otherwise. + * @param user The user for which to change the overlay. * * @hide */ @SystemApi - public boolean setEnabledExclusiveInCategory(@Nullable final String packageName, - int userId) { + @RequiresPermission(anyOf = { + "android.permission.INTERACT_ACROSS_USERS", + "android.permission.INTERACT_ACROSS_USERS_FULL" + }) + public void setEnabledExclusiveInCategory(@NonNull final String packageName, + @NonNull UserHandle user) { try { - return mService.setEnabledExclusiveInCategory(packageName, userId); + if (!mService.setEnabledExclusiveInCategory(packageName, user.getIdentifier())) { + throw new IllegalStateException("setEnabledExclusiveInCategory failed"); + } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** - * Request that an overlay package is enabled. + * Request that an overlay package is enabled or disabled. + * + * While {@link #setEnabledExclusiveInCategory(String, UserHandle)} doesn't support disabling + * every overlay in a category, this method allows you to disable everything. * * @param packageName the name of the overlay package to enable. * @param enable {@code false} if the overlay should be turned off. - * @param userId The user for which to change the overlay. - * @return true if the system successfully registered the request, false otherwise. + * @param user The user for which to change the overlay. * * @hide */ @SystemApi - public boolean setEnabled(@Nullable final String packageName, final boolean enable, - int userId) { + @RequiresPermission(anyOf = { + "android.permission.INTERACT_ACROSS_USERS", + "android.permission.INTERACT_ACROSS_USERS_FULL" + }) + public void setEnabled(@NonNull final String packageName, final boolean enable, + @NonNull UserHandle user) { try { - return mService.setEnabled(packageName, enable, userId); + if (!mService.setEnabled(packageName, enable, user.getIdentifier())) { + throw new IllegalStateException("setEnabled failed"); + } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } + return; } /** @@ -113,7 +131,7 @@ public class OverlayManager { public OverlayInfo getOverlayInfo(@NonNull final String packageName, @NonNull final UserHandle userHandle) { try { - return mService.getOverlayInfo(packageName, userHandle.myUserId()); + return mService.getOverlayInfo(packageName, userHandle.getIdentifier()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -125,17 +143,22 @@ public class OverlayManager { * overlay priority with the highest priority at the end of the list. * * @param targetPackageName The name of the target package. - * @param userId The user to get the OverlayInfos for. + * @param user The user to get the OverlayInfos for. * @return A list of OverlayInfo objects; if no overlays exist for the * requested package, an empty list is returned. * * @hide */ @SystemApi - public List<OverlayInfo> getOverlayInfosForTarget(@Nullable final String targetPackageName, - int userId) { + @RequiresPermission(anyOf = { + "android.permission.INTERACT_ACROSS_USERS", + "android.permission.INTERACT_ACROSS_USERS_FULL" + }) + @NonNull + public List<OverlayInfo> getOverlayInfosForTarget(@NonNull final String targetPackageName, + @NonNull UserHandle user) { try { - return mService.getOverlayInfosForTarget(targetPackageName, userId); + return mService.getOverlayInfosForTarget(targetPackageName, user.getIdentifier()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 464e866e0b31..c798270d1fdc 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -714,6 +714,8 @@ interface IPackageManager { ParceledListSlice getSharedLibraries(in String packageName, int flags, int userId); + ParceledListSlice getDeclaredSharedLibraries(in String packageName, int flags, int userId); + boolean canRequestPackageInstalls(String packageName, int userId); void deletePreloadsFileCache(); diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java index 725d60117780..d6fb28f694fd 100644 --- a/core/java/android/content/pm/PackageInfo.java +++ b/core/java/android/content/pm/PackageInfo.java @@ -354,12 +354,12 @@ public class PackageInfo implements Parcelable { public String overlayTarget; /** - * What overlayable set of elements package, if any, this package will overlay. + * The name of the overlayable set of elements package, if any, this package will overlay. * * Overlayable name defined within the target package, or null. * @hide */ - public String overlayTargetName; + public String targetOverlayableName; /** * The overlay category, if any, of this package diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 461045ed4d0f..961faa0c19b6 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -4239,6 +4239,24 @@ public abstract class PackageManager { @InstallFlags int flags, @UserIdInt int userId); /** + * Get the list of shared libraries declared by a package. + * + * @param packageName the package name to query + * @param flags the flags to filter packages + * @return the shared library list + * + * @hide + */ + @NonNull + @RequiresPermission(Manifest.permission.ACCESS_SHARED_LIBRARIES) + @SystemApi + public List<SharedLibraryInfo> getDeclaredSharedLibraries(@NonNull String packageName, + @InstallFlags int flags) { + throw new UnsupportedOperationException( + "getDeclaredSharedLibraries() not implemented in subclass"); + } + + /** * Get the name of the package hosting the services shared library. * * @return The library host package. @@ -5653,7 +5671,9 @@ public abstract class PackageManager { * @deprecated This function no longer does anything. It is the platform's * responsibility to assign preferred activities and this cannot be modified * directly. To determine the activities resolved by the platform, use - * {@link #resolveActivity} or {@link #queryIntentActivities}. + * {@link #resolveActivity} or {@link #queryIntentActivities}. To configure + * an app to be responsible for a particular role and to check current role + * holders, see {@link android.app.role.RoleManager}. */ @Deprecated public abstract void addPackageToPreferred(String packageName); @@ -5662,7 +5682,9 @@ public abstract class PackageManager { * @deprecated This function no longer does anything. It is the platform's * responsibility to assign preferred activities and this cannot be modified * directly. To determine the activities resolved by the platform, use - * {@link #resolveActivity} or {@link #queryIntentActivities}. + * {@link #resolveActivity} or {@link #queryIntentActivities}. To configure + * an app to be responsible for a particular role and to check current role + * holders, see {@link android.app.role.RoleManager}. */ @Deprecated public abstract void removePackageFromPreferred(String packageName); @@ -5679,7 +5701,9 @@ public abstract class PackageManager { * @deprecated This function no longer does anything. It is the platform's * responsibility to assign preferred activities and this cannot be modified * directly. To determine the activities resolved by the platform, use - * {@link #resolveActivity} or {@link #queryIntentActivities}. + * {@link #resolveActivity} or {@link #queryIntentActivities}. To configure + * an app to be responsible for a particular role and to check current role + * holders, see {@link android.app.role.RoleManager}. */ @Deprecated public abstract List<PackageInfo> getPreferredPackages(@PackageInfoFlags int flags); @@ -5702,7 +5726,9 @@ public abstract class PackageManager { * @deprecated This function no longer does anything. It is the platform's * responsibility to assign preferred activities and this cannot be modified * directly. To determine the activities resolved by the platform, use - * {@link #resolveActivity} or {@link #queryIntentActivities}. + * {@link #resolveActivity} or {@link #queryIntentActivities}. To configure + * an app to be responsible for a particular role and to check current role + * holders, see {@link android.app.role.RoleManager}. */ @Deprecated public abstract void addPreferredActivity(IntentFilter filter, int match, @@ -5717,7 +5743,9 @@ public abstract class PackageManager { * @deprecated This function no longer does anything. It is the platform's * responsibility to assign preferred activities and this cannot be modified * directly. To determine the activities resolved by the platform, use - * {@link #resolveActivity} or {@link #queryIntentActivities}. + * {@link #resolveActivity} or {@link #queryIntentActivities}. To configure + * an app to be responsible for a particular role and to check current role + * holders, see {@link android.app.role.RoleManager}. */ @Deprecated @UnsupportedAppUsage @@ -5747,7 +5775,9 @@ public abstract class PackageManager { * @deprecated This function no longer does anything. It is the platform's * responsibility to assign preferred activities and this cannot be modified * directly. To determine the activities resolved by the platform, use - * {@link #resolveActivity} or {@link #queryIntentActivities}. + * {@link #resolveActivity} or {@link #queryIntentActivities}. To configure + * an app to be responsible for a particular role and to check current role + * holders, see {@link android.app.role.RoleManager}. */ @Deprecated @UnsupportedAppUsage @@ -5773,7 +5803,9 @@ public abstract class PackageManager { * @deprecated This function no longer does anything. It is the platform's * responsibility to assign preferred activities and this cannot be modified * directly. To determine the activities resolved by the platform, use - * {@link #resolveActivity} or {@link #queryIntentActivities}. + * {@link #resolveActivity} or {@link #queryIntentActivities}. To configure + * an app to be responsible for a particular role and to check current role + * holders, see {@link android.app.role.RoleManager}. */ @Deprecated @SystemApi @@ -5788,7 +5820,9 @@ public abstract class PackageManager { * @deprecated This function no longer does anything. It is the platform's * responsibility to assign preferred activities and this cannot be modified * directly. To determine the activities resolved by the platform, use - * {@link #resolveActivity} or {@link #queryIntentActivities}. + * {@link #resolveActivity} or {@link #queryIntentActivities}. To configure + * an app to be responsible for a particular role and to check current role + * holders, see {@link android.app.role.RoleManager}. */ @Deprecated @UnsupportedAppUsage @@ -5809,7 +5843,9 @@ public abstract class PackageManager { * @deprecated This function no longer does anything. It is the platform's * responsibility to assign preferred activities and this cannot be modified * directly. To determine the activities resolved by the platform, use - * {@link #resolveActivity} or {@link #queryIntentActivities}. + * {@link #resolveActivity} or {@link #queryIntentActivities}. To configure + * an app to be responsible for a particular role and to check current role + * holders, see {@link android.app.role.RoleManager}. */ @Deprecated public abstract void clearPackagePreferredActivities(String packageName); @@ -5834,7 +5870,9 @@ public abstract class PackageManager { * @deprecated This function no longer does anything. It is the platform's * responsibility to assign preferred activities and this cannot be modified * directly. To determine the activities resolved by the platform, use - * {@link #resolveActivity} or {@link #queryIntentActivities}. + * {@link #resolveActivity} or {@link #queryIntentActivities}. To configure + * an app to be responsible for a particular role and to check current role + * holders, see {@link android.app.role.RoleManager}. */ @Deprecated public abstract int getPreferredActivities(@NonNull List<IntentFilter> outFilters, diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 743a302cc543..b480939ae450 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -689,7 +689,7 @@ public class PackageParser { pi.restrictedAccountType = p.mRestrictedAccountType; pi.requiredAccountType = p.mRequiredAccountType; pi.overlayTarget = p.mOverlayTarget; - pi.overlayTargetName = p.mOverlayTargetName; + pi.targetOverlayableName = p.mOverlayTargetName; pi.overlayCategory = p.mOverlayCategory; pi.overlayPriority = p.mOverlayPriority; pi.mOverlayIsStatic = p.mOverlayIsStatic; diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index 6b8416d46601..d7e4e1452cfe 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -1721,8 +1721,6 @@ public class Resources { * Rebases the theme against the parent Resource object's current * configuration by re-applying the styles passed to * {@link #applyStyle(int, boolean)}. - * - * @hide */ public void rebase() { mThemeImpl.rebase(); diff --git a/core/java/android/hardware/display/NightDisplayListener.java b/core/java/android/hardware/display/NightDisplayListener.java index 468f8332dc2b..3638572a01a9 100644 --- a/core/java/android/hardware/display/NightDisplayListener.java +++ b/core/java/android/hardware/display/NightDisplayListener.java @@ -35,119 +35,137 @@ import java.time.LocalTime; public class NightDisplayListener { private final Context mContext; - private final int mUserId; private final ColorDisplayManager mManager; + private final Handler mHandler; + private final ContentObserver mContentObserver; + private final int mUserId; - private ContentObserver mContentObserver; private Callback mCallback; public NightDisplayListener(@NonNull Context context) { - this(context, ActivityManager.getCurrentUser()); + this(context, ActivityManager.getCurrentUser(), new Handler(Looper.getMainLooper())); + } + + public NightDisplayListener(@NonNull Context context, @NonNull Handler handler) { + this(context, ActivityManager.getCurrentUser(), handler); } - public NightDisplayListener(@NonNull Context context, @UserIdInt int userId) { + public NightDisplayListener(@NonNull Context context, @UserIdInt int userId, + @NonNull Handler handler) { mContext = context.getApplicationContext(); - mUserId = userId; mManager = mContext.getSystemService(ColorDisplayManager.class); + mUserId = userId; + + mHandler = handler; + mContentObserver = new ContentObserver(mHandler) { + @Override + public void onChange(boolean selfChange, Uri uri) { + super.onChange(selfChange, uri); + final String setting = uri == null ? null : uri.getLastPathSegment(); + if (setting != null && mCallback != null) { + switch (setting) { + case Secure.NIGHT_DISPLAY_ACTIVATED: + mCallback.onActivated(mManager.isNightDisplayActivated()); + break; + case Secure.NIGHT_DISPLAY_AUTO_MODE: + mCallback.onAutoModeChanged(mManager.getNightDisplayAutoMode()); + break; + case Secure.NIGHT_DISPLAY_CUSTOM_START_TIME: + mCallback.onCustomStartTimeChanged( + mManager.getNightDisplayCustomStartTime()); + break; + case Secure.NIGHT_DISPLAY_CUSTOM_END_TIME: + mCallback.onCustomEndTimeChanged( + mManager.getNightDisplayCustomEndTime()); + break; + case Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE: + mCallback.onColorTemperatureChanged( + mManager.getNightDisplayColorTemperature()); + break; + } + } + } + }; } /** * Register a callback to be invoked whenever the Night display settings are changed. */ public void setCallback(Callback callback) { - final Callback oldCallback = mCallback; - if (oldCallback != callback) { - mCallback = callback; - - if (mContentObserver == null) { - mContentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) { - @Override - public void onChange(boolean selfChange, Uri uri) { - super.onChange(selfChange, uri); - onSettingChanged(uri); - } - }; - } + if (Looper.myLooper() != mHandler.getLooper()) { + mHandler.post(() -> setCallbackInternal(callback)); + } + setCallbackInternal(callback); + } - if (callback == null) { - // Stop listening for changes now that there IS NOT a callback. + private void setCallbackInternal(Callback newCallback) { + final Callback oldCallback = mCallback; + if (oldCallback != newCallback) { + mCallback = newCallback; + if (mCallback == null) { mContext.getContentResolver().unregisterContentObserver(mContentObserver); } else if (oldCallback == null) { - // Start listening for changes now that there IS a callback. final ContentResolver cr = mContext.getContentResolver(); cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_ACTIVATED), false /* notifyForDescendants */, mContentObserver, mUserId); cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_AUTO_MODE), false /* notifyForDescendants */, mContentObserver, mUserId); - cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_CUSTOM_START_TIME), + cr.registerContentObserver( + Secure.getUriFor(Secure.NIGHT_DISPLAY_CUSTOM_START_TIME), false /* notifyForDescendants */, mContentObserver, mUserId); - cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_CUSTOM_END_TIME), + cr.registerContentObserver( + Secure.getUriFor(Secure.NIGHT_DISPLAY_CUSTOM_END_TIME), false /* notifyForDescendants */, mContentObserver, mUserId); - cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE), + cr.registerContentObserver( + Secure.getUriFor(Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE), false /* notifyForDescendants */, mContentObserver, mUserId); } } } - private void onSettingChanged(Uri uri) { - final String setting = uri == null ? null : uri.getLastPathSegment(); - if (setting == null || mCallback == null) { - return; - } - - switch (setting) { - case Secure.NIGHT_DISPLAY_ACTIVATED: - mCallback.onActivated(mManager.isNightDisplayActivated()); - break; - case Secure.NIGHT_DISPLAY_AUTO_MODE: - mCallback.onAutoModeChanged(mManager.getNightDisplayAutoMode()); - break; - case Secure.NIGHT_DISPLAY_CUSTOM_START_TIME: - mCallback.onCustomStartTimeChanged(mManager.getNightDisplayCustomStartTime()); - break; - case Secure.NIGHT_DISPLAY_CUSTOM_END_TIME: - mCallback.onCustomEndTimeChanged(mManager.getNightDisplayCustomEndTime()); - break; - case Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE: - mCallback.onColorTemperatureChanged(mManager.getNightDisplayColorTemperature()); - break; - } - } - /** * Callback invoked whenever the Night display settings are changed. */ public interface Callback { + /** * Callback invoked when the activated state changes. * * @param activated {@code true} if Night display is activated */ - default void onActivated(boolean activated) {} + default void onActivated(boolean activated) { + } + /** * Callback invoked when the auto mode changes. * * @param autoMode the auto mode to use */ - default void onAutoModeChanged(int autoMode) {} + default void onAutoModeChanged(int autoMode) { + } + /** * Callback invoked when the time to automatically activate Night display changes. * * @param startTime the local time to automatically activate Night display */ - default void onCustomStartTimeChanged(LocalTime startTime) {} + default void onCustomStartTimeChanged(LocalTime startTime) { + } + /** * Callback invoked when the time to automatically deactivate Night display changes. * * @param endTime the local time to automatically deactivate Night display */ - default void onCustomEndTimeChanged(LocalTime endTime) {} + default void onCustomEndTimeChanged(LocalTime endTime) { + } /** * Callback invoked when the color temperature changes. * * @param colorTemperature the color temperature to tint the screen */ - default void onColorTemperatureChanged(int colorTemperature) {} + default void onColorTemperatureChanged(int colorTemperature) { + } } } diff --git a/core/java/android/net/CaptivePortal.java b/core/java/android/net/CaptivePortal.java index 3e4e35a8f16d..133943226c0d 100644 --- a/core/java/android/net/CaptivePortal.java +++ b/core/java/android/net/CaptivePortal.java @@ -64,8 +64,6 @@ public class CaptivePortal implements Parcelable { private final IBinder mBinder; /** @hide */ - @SystemApi - @TestApi public CaptivePortal(@NonNull IBinder binder) { mBinder = binder; } diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 16322353add2..ae93cf019776 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -44,6 +44,7 @@ import android.os.INetworkManagementService; import android.os.Looper; import android.os.Message; import android.os.Messenger; +import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.RemoteException; import android.os.ResultReceiver; @@ -64,6 +65,8 @@ import com.android.internal.util.Protocol; import libcore.net.event.NetworkEventDispatcher; import java.io.FileDescriptor; +import java.io.IOException; +import java.io.UncheckedIOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.net.InetAddress; @@ -1345,12 +1348,15 @@ public class ConnectivityManager { } /** - * Gets the URL that should be used for resolving whether a captive portal is present. + * Gets a URL that can be used for resolving whether a captive portal is present. * 1. This URL should respond with a 204 response to a GET request to indicate no captive * portal is present. * 2. This URL must be HTTP as redirect responses are used to find captive portal * sign-in pages. Captive portals cannot respond to HTTPS requests with redirects. * + * The system network validation may be using different strategies to detect captive portals, + * so this method does not necessarily return a URL used by the system. It only returns a URL + * that may be relevant for other components trying to detect captive portals. * @hide */ @SystemApi @@ -1920,14 +1926,22 @@ public class ConnectivityManager { * @return A {@link SocketKeepalive} object that can be used to control the keepalive on the * given socket. **/ - public SocketKeepalive createSocketKeepalive(@NonNull Network network, + public @NonNull SocketKeepalive createSocketKeepalive(@NonNull Network network, @NonNull UdpEncapsulationSocket socket, @NonNull InetAddress source, @NonNull InetAddress destination, @NonNull @CallbackExecutor Executor executor, @NonNull Callback callback) { - return new NattSocketKeepalive(mService, network, socket.getFileDescriptor(), - socket.getResourceId(), source, destination, executor, callback); + ParcelFileDescriptor dup; + try { + dup = ParcelFileDescriptor.dup(socket.getFileDescriptor()); + } catch (IOException ignored) { + // Construct an invalid fd, so that if the user later calls start(), it will fail with + // ERROR_INVALID_SOCKET. + dup = new ParcelFileDescriptor(new FileDescriptor()); + } + return new NattSocketKeepalive(mService, network, dup, socket.getResourceId(), source, + destination, executor, callback); } /** @@ -1935,9 +1949,9 @@ public class ConnectivityManager { * by system apps which don't use IpSecService to create {@link UdpEncapsulationSocket}. * * @param network The {@link Network} the socket is on. - * @param fd The {@link FileDescriptor} that needs to be kept alive. The provided - * {@link FileDescriptor} must be bound to a port and the keepalives will be sent from - * that port. + * @param pfd The {@link ParcelFileDescriptor} that needs to be kept alive. The provided + * {@link ParcelFileDescriptor} must be bound to a port and the keepalives will be sent + * from that port. * @param source The source address of the {@link UdpEncapsulationSocket}. * @param destination The destination address of the {@link UdpEncapsulationSocket}. The * keepalive packets will always be sent to port 4500 of the given {@code destination}. @@ -1953,14 +1967,22 @@ public class ConnectivityManager { */ @SystemApi @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) - public SocketKeepalive createNattKeepalive(@NonNull Network network, - @NonNull FileDescriptor fd, + public @NonNull SocketKeepalive createNattKeepalive(@NonNull Network network, + @NonNull ParcelFileDescriptor pfd, @NonNull InetAddress source, @NonNull InetAddress destination, @NonNull @CallbackExecutor Executor executor, @NonNull Callback callback) { - return new NattSocketKeepalive(mService, network, fd, INVALID_RESOURCE_ID /* Unused */, - source, destination, executor, callback); + ParcelFileDescriptor dup; + try { + dup = pfd.dup(); + } catch (IOException ignored) { + // Construct an invalid fd, so that if the user later calls start(), it will fail with + // ERROR_INVALID_SOCKET. + dup = new ParcelFileDescriptor(new FileDescriptor()); + } + return new NattSocketKeepalive(mService, network, dup, + INVALID_RESOURCE_ID /* Unused */, source, destination, executor, callback); } /** @@ -1984,11 +2006,19 @@ public class ConnectivityManager { */ @SystemApi @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) - public SocketKeepalive createSocketKeepalive(@NonNull Network network, + public @NonNull SocketKeepalive createSocketKeepalive(@NonNull Network network, @NonNull Socket socket, @NonNull Executor executor, @NonNull Callback callback) { - return new TcpSocketKeepalive(mService, network, socket, executor, callback); + ParcelFileDescriptor dup; + try { + dup = ParcelFileDescriptor.fromSocket(socket); + } catch (UncheckedIOException ignored) { + // Construct an invalid fd, so that if the user later calls start(), it will fail with + // ERROR_INVALID_SOCKET. + dup = new ParcelFileDescriptor(new FileDescriptor()); + } + return new TcpSocketKeepalive(mService, network, dup, executor, callback); } /** @@ -3320,7 +3350,7 @@ public class ConnectivityManager { * @param network The {@link Network} whose blocked status has changed. * @param blocked The blocked status of this {@link Network}. */ - public void onBlockedStatusChanged(Network network, boolean blocked) {} + public void onBlockedStatusChanged(@NonNull Network network, boolean blocked) {} private NetworkRequest networkRequest; } @@ -4101,9 +4131,12 @@ public class ConnectivityManager { * @hide */ @SystemApi - public boolean getAvoidBadWifi() { + @RequiresPermission(anyOf = { + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, + android.Manifest.permission.NETWORK_STACK}) + public boolean shouldAvoidBadWifi() { try { - return mService.getAvoidBadWifi(); + return mService.shouldAvoidBadWifi(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/net/DnsResolver.java b/core/java/android/net/DnsResolver.java index 93b8cf801d45..59802514c7a3 100644 --- a/core/java/android/net/DnsResolver.java +++ b/core/java/android/net/DnsResolver.java @@ -16,6 +16,7 @@ package android.net; +import static android.net.NetworkUtils.resNetworkCancel; import static android.net.NetworkUtils.resNetworkQuery; import static android.net.NetworkUtils.resNetworkResult; import static android.net.NetworkUtils.resNetworkSend; @@ -26,6 +27,7 @@ import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.os.CancellationSignal; import android.os.Looper; import android.system.ErrnoException; import android.util.Log; @@ -191,11 +193,18 @@ public final class DnsResolver { * @param query blob message * @param flags flags as a combination of the FLAGS_* constants * @param executor The {@link Executor} that the callback should be executed on. + * @param cancellationSignal used by the caller to signal if the query should be + * cancelled. May be {@code null}. * @param callback an {@link AnswerCallback} which will be called to notify the caller - * of the result of dns query. + * of the result of dns query. */ public <T> void query(@Nullable Network network, @NonNull byte[] query, @QueryFlag int flags, - @NonNull @CallbackExecutor Executor executor, @NonNull AnswerCallback<T> callback) { + @NonNull @CallbackExecutor Executor executor, + @Nullable CancellationSignal cancellationSignal, + @NonNull AnswerCallback<T> callback) { + if (cancellationSignal != null && cancellationSignal.isCanceled()) { + return; + } final FileDescriptor queryfd; try { queryfd = resNetworkSend((network != null @@ -205,6 +214,7 @@ public final class DnsResolver { return; } + maybeAddCancellationSignal(cancellationSignal, queryfd); registerFDListener(executor, queryfd, callback); } @@ -219,12 +229,19 @@ public final class DnsResolver { * @param nsType dns resource record (RR) type as one of the TYPE_* constants * @param flags flags as a combination of the FLAGS_* constants * @param executor The {@link Executor} that the callback should be executed on. + * @param cancellationSignal used by the caller to signal if the query should be + * cancelled. May be {@code null}. * @param callback an {@link AnswerCallback} which will be called to notify the caller - * of the result of dns query. + * of the result of dns query. */ public <T> void query(@Nullable Network network, @NonNull String domain, @QueryClass int nsClass, @QueryType int nsType, @QueryFlag int flags, - @NonNull @CallbackExecutor Executor executor, @NonNull AnswerCallback<T> callback) { + @NonNull @CallbackExecutor Executor executor, + @Nullable CancellationSignal cancellationSignal, + @NonNull AnswerCallback<T> callback) { + if (cancellationSignal != null && cancellationSignal.isCanceled()) { + return; + } final FileDescriptor queryfd; try { queryfd = resNetworkQuery((network != null @@ -233,6 +250,8 @@ public final class DnsResolver { callback.onQueryException(e); return; } + + maybeAddCancellationSignal(cancellationSignal, queryfd); registerFDListener(executor, queryfd, callback); } @@ -264,6 +283,17 @@ public final class DnsResolver { }); } + private void maybeAddCancellationSignal(@Nullable CancellationSignal cancellationSignal, + @NonNull FileDescriptor queryfd) { + if (cancellationSignal == null) return; + cancellationSignal.setOnCancelListener( + () -> { + Looper.getMainLooper().getQueue() + .removeOnFileDescriptorEventListener(queryfd); + resNetworkCancel(queryfd); + }); + } + private static class DnsAddressAnswer extends DnsPacket { private static final String TAG = "DnsResolver.DnsAddressAnswer"; private static final boolean DBG = false; diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index 24e6a855ffe8..61648dc7f1d8 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -182,7 +182,7 @@ interface IConnectivityManager void startCaptivePortalApp(in Network network); void startCaptivePortalAppInternal(in Network network, in Bundle appExtras); - boolean getAvoidBadWifi(); + boolean shouldAvoidBadWifi(); int getMultipathPreference(in Network Network); NetworkRequest getDefaultRequest(); diff --git a/core/java/android/net/NattSocketKeepalive.java b/core/java/android/net/NattSocketKeepalive.java index 84da294f8940..b0ce0c71fbeb 100644 --- a/core/java/android/net/NattSocketKeepalive.java +++ b/core/java/android/net/NattSocketKeepalive.java @@ -17,10 +17,10 @@ package android.net; import android.annotation.NonNull; +import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.util.Log; -import java.io.FileDescriptor; import java.net.InetAddress; import java.util.concurrent.Executor; @@ -31,21 +31,19 @@ public final class NattSocketKeepalive extends SocketKeepalive { @NonNull private final InetAddress mSource; @NonNull private final InetAddress mDestination; - @NonNull private final FileDescriptor mFd; private final int mResourceId; NattSocketKeepalive(@NonNull IConnectivityManager service, @NonNull Network network, - @NonNull FileDescriptor fd, + @NonNull ParcelFileDescriptor pfd, int resourceId, @NonNull InetAddress source, @NonNull InetAddress destination, @NonNull Executor executor, @NonNull Callback callback) { - super(service, network, executor, callback); + super(service, network, pfd, executor, callback); mSource = source; mDestination = destination; - mFd = fd; mResourceId = resourceId; } @@ -53,8 +51,8 @@ public final class NattSocketKeepalive extends SocketKeepalive { void startImpl(int intervalSec) { mExecutor.execute(() -> { try { - mService.startNattKeepaliveWithFd(mNetwork, mFd, mResourceId, intervalSec, - mCallback, + mService.startNattKeepaliveWithFd(mNetwork, mPfd.getFileDescriptor(), mResourceId, + intervalSec, mCallback, mSource.getHostAddress(), mDestination.getHostAddress()); } catch (RemoteException e) { Log.e(TAG, "Error starting socket keepalive: ", e); @@ -75,6 +73,5 @@ public final class NattSocketKeepalive extends SocketKeepalive { throw e.rethrowFromSystemServer(); } }); - } } diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java index 273f8cd4f21d..419fa7a61de5 100644 --- a/core/java/android/net/NetworkAgent.java +++ b/core/java/android/net/NetworkAgent.java @@ -488,14 +488,14 @@ public abstract class NetworkAgent extends Handler { * Requests that the network hardware send the specified packet at the specified interval. */ protected void startSocketKeepalive(Message msg) { - onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED); + onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED); } /** * Requests that the network hardware send the specified packet at the specified interval. */ protected void stopSocketKeepalive(Message msg) { - onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED); + onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED); } /** @@ -511,7 +511,7 @@ public abstract class NetworkAgent extends Handler { * override this method. */ protected void addKeepalivePacketFilter(Message msg) { - onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED); + onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED); } /** @@ -520,7 +520,7 @@ public abstract class NetworkAgent extends Handler { * must override this method. */ protected void removeKeepalivePacketFilter(Message msg) { - onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED); + onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED); } /** diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java index ed410e277a42..5188866fe49d 100644 --- a/core/java/android/net/NetworkUtils.java +++ b/core/java/android/net/NetworkUtils.java @@ -177,6 +177,12 @@ public class NetworkUtils { public static native byte[] resNetworkResult(FileDescriptor fd) throws ErrnoException; /** + * DNS resolver series jni method. + * Attempts to cancel the in-progress query associated with the {@code fd}. + */ + public static native void resNetworkCancel(FileDescriptor fd); + + /** * Add an entry into the ARP cache. */ public static void addArpEntry(Inet4Address ipv4Addr, MacAddress ethAddr, String ifname, diff --git a/core/java/android/net/SocketKeepalive.java b/core/java/android/net/SocketKeepalive.java index 0e768dfc8eb9..9d91620bdf96 100644 --- a/core/java/android/net/SocketKeepalive.java +++ b/core/java/android/net/SocketKeepalive.java @@ -21,8 +21,10 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Binder; +import android.os.ParcelFileDescriptor; import android.os.RemoteException; +import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.concurrent.Executor; @@ -73,10 +75,15 @@ public abstract class SocketKeepalive implements AutoCloseable { /** The target socket is not idle. */ public static final int ERROR_SOCKET_NOT_IDLE = -26; - /** The hardware does not support this request. */ - public static final int ERROR_HARDWARE_UNSUPPORTED = -30; + /** The device does not support this request. */ + public static final int ERROR_UNSUPPORTED = -30; + /** @hide TODO: delete when telephony code has been updated. */ + public static final int ERROR_HARDWARE_UNSUPPORTED = ERROR_UNSUPPORTED; /** The hardware returned an error. */ public static final int ERROR_HARDWARE_ERROR = -31; + /** The limitation of resource is reached. */ + public static final int ERROR_INSUFFICIENT_RESOURCES = -32; + /** @hide */ @Retention(RetentionPolicy.SOURCE) @@ -147,15 +154,18 @@ public abstract class SocketKeepalive implements AutoCloseable { @NonNull final IConnectivityManager mService; @NonNull final Network mNetwork; + @NonNull final ParcelFileDescriptor mPfd; @NonNull final Executor mExecutor; @NonNull final ISocketKeepaliveCallback mCallback; // TODO: remove slot since mCallback could be used to identify which keepalive to stop. @Nullable Integer mSlot; SocketKeepalive(@NonNull IConnectivityManager service, @NonNull Network network, + @NonNull ParcelFileDescriptor pfd, @NonNull Executor executor, @NonNull Callback callback) { mService = service; mNetwork = network; + mPfd = pfd; mExecutor = executor; mCallback = new ISocketKeepaliveCallback.Stub() { @Override @@ -233,6 +243,11 @@ public abstract class SocketKeepalive implements AutoCloseable { @Override public final void close() { stop(); + try { + mPfd.close(); + } catch (IOException e) { + // Nothing much can be done. + } } /** diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java index e2531059ac61..565f36f14208 100644 --- a/core/java/android/net/StaticIpConfiguration.java +++ b/core/java/android/net/StaticIpConfiguration.java @@ -134,7 +134,7 @@ public final class StaticIpConfiguration implements Parcelable { * route to the gateway as well. This configuration is arguably invalid, but it used to work * in K and earlier, and other OSes appear to accept it. */ - public @NonNull List<RouteInfo> getRoutes(String iface) { + public @NonNull List<RouteInfo> getRoutes(@Nullable String iface) { List<RouteInfo> routes = new ArrayList<RouteInfo>(3); if (ipAddress != null) { RouteInfo connectedRoute = new RouteInfo(ipAddress, null, iface); diff --git a/core/java/android/net/TcpSocketKeepalive.java b/core/java/android/net/TcpSocketKeepalive.java index 26cc8ff181b2..436397ea7754 100644 --- a/core/java/android/net/TcpSocketKeepalive.java +++ b/core/java/android/net/TcpSocketKeepalive.java @@ -17,25 +17,22 @@ package android.net; import android.annotation.NonNull; +import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.util.Log; import java.io.FileDescriptor; -import java.net.Socket; import java.util.concurrent.Executor; /** @hide */ final class TcpSocketKeepalive extends SocketKeepalive { - private final Socket mSocket; - TcpSocketKeepalive(@NonNull IConnectivityManager service, @NonNull Network network, - @NonNull Socket socket, + @NonNull ParcelFileDescriptor pfd, @NonNull Executor executor, @NonNull Callback callback) { - super(service, network, executor, callback); - mSocket = socket; + super(service, network, pfd, executor, callback); } /** @@ -57,7 +54,7 @@ final class TcpSocketKeepalive extends SocketKeepalive { void startImpl(int intervalSec) { mExecutor.execute(() -> { try { - final FileDescriptor fd = mSocket.getFileDescriptor$(); + final FileDescriptor fd = mPfd.getFileDescriptor(); mService.startTcpKeepalive(mNetwork, fd, intervalSec, mCallback); } catch (RemoteException e) { Log.e(TAG, "Error starting packet keepalive: ", e); diff --git a/core/java/android/net/metrics/DhcpErrorEvent.java b/core/java/android/net/metrics/DhcpErrorEvent.java index 652ce5dd19a3..876000463cb1 100644 --- a/core/java/android/net/metrics/DhcpErrorEvent.java +++ b/core/java/android/net/metrics/DhcpErrorEvent.java @@ -37,27 +37,6 @@ public final class DhcpErrorEvent implements IpConnectivityLog.Event { public static final int DHCP_ERROR = 4; public static final int MISC_ERROR = 5; - public static final int L2_TOO_SHORT = (L2_ERROR << 24) | (1 << 16); - public static final int L2_WRONG_ETH_TYPE = (L2_ERROR << 24) | (2 << 16); - - public static final int L3_TOO_SHORT = (L3_ERROR << 24) | (1 << 16); - public static final int L3_NOT_IPV4 = (L3_ERROR << 24) | (2 << 16); - public static final int L3_INVALID_IP = (L3_ERROR << 24) | (3 << 16); - - public static final int L4_NOT_UDP = (L4_ERROR << 24) | (1 << 16); - public static final int L4_WRONG_PORT = (L4_ERROR << 24) | (2 << 16); - - public static final int BOOTP_TOO_SHORT = (DHCP_ERROR << 24) | (1 << 16); - public static final int DHCP_BAD_MAGIC_COOKIE = (DHCP_ERROR << 24) | (2 << 16); - public static final int DHCP_INVALID_OPTION_LENGTH = (DHCP_ERROR << 24) | (3 << 16); - public static final int DHCP_NO_MSG_TYPE = (DHCP_ERROR << 24) | (4 << 16); - public static final int DHCP_UNKNOWN_MSG_TYPE = (DHCP_ERROR << 24) | (5 << 16); - public static final int DHCP_NO_COOKIE = (DHCP_ERROR << 24) | (6 << 16); - - public static final int BUFFER_UNDERFLOW = (MISC_ERROR << 24) | (1 << 16); - public static final int RECEIVE_ERROR = (MISC_ERROR << 24) | (2 << 16); - public static final int PARSING_ERROR = (MISC_ERROR << 24) | (3 << 16); - // error code byte format (MSB to LSB): // byte 0: error type // byte 1: error subtype @@ -66,6 +45,33 @@ public final class DhcpErrorEvent implements IpConnectivityLog.Event { /** @hide */ public final int errorCode; + private static final int L2_ERROR_TYPE = L2_ERROR << 8; + private static final int L3_ERROR_TYPE = L3_ERROR << 8; + private static final int L4_ERROR_TYPE = L4_ERROR << 8; + private static final int DHCP_ERROR_TYPE = DHCP_ERROR << 8; + private static final int MISC_ERROR_TYPE = MISC_ERROR << 8; + + public static final int L2_TOO_SHORT = (L2_ERROR_TYPE | 0x1) << 16; + public static final int L2_WRONG_ETH_TYPE = (L2_ERROR_TYPE | 0x2) << 16; + + public static final int L3_TOO_SHORT = (L3_ERROR_TYPE | 0x1) << 16; + public static final int L3_NOT_IPV4 = (L3_ERROR_TYPE | 0x2) << 16; + public static final int L3_INVALID_IP = (L3_ERROR_TYPE | 0x3) << 16; + + public static final int L4_NOT_UDP = (L4_ERROR_TYPE | 0x1) << 16; + public static final int L4_WRONG_PORT = (L4_ERROR_TYPE | 0x2) << 16; + + public static final int BOOTP_TOO_SHORT = (DHCP_ERROR_TYPE | 0x1) << 16; + public static final int DHCP_BAD_MAGIC_COOKIE = (DHCP_ERROR_TYPE | 0x2) << 16; + public static final int DHCP_INVALID_OPTION_LENGTH = (DHCP_ERROR_TYPE | 0x3) << 16; + public static final int DHCP_NO_MSG_TYPE = (DHCP_ERROR_TYPE | 0x4) << 16; + public static final int DHCP_UNKNOWN_MSG_TYPE = (DHCP_ERROR_TYPE | 0x5) << 16; + public static final int DHCP_NO_COOKIE = (DHCP_ERROR_TYPE | 0x6) << 16; + + public static final int BUFFER_UNDERFLOW = (MISC_ERROR_TYPE | 0x1) << 16; + public static final int RECEIVE_ERROR = (MISC_ERROR_TYPE | 0x2) << 16; + public static final int PARSING_ERROR = (MISC_ERROR_TYPE | 0x3) << 16; + public DhcpErrorEvent(int errorCode) { this.errorCode = errorCode; } diff --git a/core/java/android/net/metrics/ValidationProbeEvent.java b/core/java/android/net/metrics/ValidationProbeEvent.java index 45b665d45cc5..c9d7b1b8f7d9 100644 --- a/core/java/android/net/metrics/ValidationProbeEvent.java +++ b/core/java/android/net/metrics/ValidationProbeEvent.java @@ -153,11 +153,14 @@ public final class ValidationProbeEvent implements IpConnectivityLog.Event { return (probeType & 0xff) | (firstValidation ? FIRST_VALIDATION : REVALIDATION); } - public static String getProbeName(int probeType) { + /** + * Get the name of a probe specified by its probe type. + */ + public static @NonNull String getProbeName(int probeType) { return Decoder.constants.get(probeType & 0xff, "PROBE_???"); } - private static String getValidationStage(int probeType) { + private static @NonNull String getValidationStage(int probeType) { return Decoder.constants.get(probeType & 0xff00, "UNKNOWN"); } diff --git a/core/java/android/os/DropBoxManager.java b/core/java/android/os/DropBoxManager.java index 320f471e4b3f..b92e71357503 100644 --- a/core/java/android/os/DropBoxManager.java +++ b/core/java/android/os/DropBoxManager.java @@ -92,6 +92,13 @@ public class DropBoxManager { public static final String EXTRA_TIME = "time"; /** + * Extra for {@link android.os.DropBoxManager#ACTION_DROPBOX_ENTRY_ADDED}: + * integer value containing number of broadcasts dropped due to rate limiting on + * this {@link android.os.DropBoxManager#EXTRA_TAG} + */ + public static final String EXTRA_DROPPED_COUNT = "android.os.extra.DROPPED_COUNT"; + + /** * A single entry retrieved from the drop box. * This may include a reference to a stream, so you must call * {@link #close()} when you are done using it. diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java index 707a404da4ed..41691d763673 100644 --- a/core/java/android/os/GraphicsEnvironment.java +++ b/core/java/android/os/GraphicsEnvironment.java @@ -63,7 +63,7 @@ public class GraphicsEnvironment { private static final long SYSTEM_DRIVER_VERSION_CODE = 0; private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0"; private static final String PROPERTY_GFX_DRIVER_BUILD_TIME = "ro.gfx.driver_build_time"; - private static final String METADATA_DRIVER_BUILD_TIME = "driver_build_time"; + private static final String METADATA_DRIVER_BUILD_TIME = "com.android.gamedriver.build_time"; private static final String ANGLE_RULES_FILE = "a4a_rules.json"; private static final String ANGLE_TEMP_RULES = "debug.angle.rules"; private static final String ACTION_ANGLE_FOR_ANDROID = "android.app.action.ANGLE_FOR_ANDROID"; @@ -702,7 +702,7 @@ public class GraphicsEnvironment { final String driverBuildTime = driverAppInfo.metaData.getString(METADATA_DRIVER_BUILD_TIME); if (driverBuildTime == null || driverBuildTime.isEmpty()) { - throw new IllegalArgumentException("driver_build_time meta-data is not set"); + throw new IllegalArgumentException("com.android.gamedriver.build_time is not set"); } // driver_build_time in the meta-data is in "L<Unix epoch timestamp>" format. e.g. L123456. // Long.parseLong will throw if the meta-data "driver_build_time" is not set properly. diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl index b5c6604c8b99..e1d605e1c99d 100644 --- a/core/java/android/os/IPowerManager.aidl +++ b/core/java/android/os/IPowerManager.aidl @@ -53,10 +53,10 @@ interface IPowerManager boolean isPowerSaveMode(); PowerSaveState getPowerSaveState(int serviceType); boolean setPowerSaveModeEnabled(boolean mode); - boolean setDynamicPowerSavings(boolean dynamicPowerSavingsEnabled, int disableThreshold); + boolean setDynamicPowerSaveHint(boolean powerSaveHint, int disableThreshold); boolean setAdaptivePowerSavePolicy(in BatterySaverPolicyConfig config); boolean setAdaptivePowerSaveEnabled(boolean enabled); - int getPowerSaveMode(); + int getPowerSaveModeTrigger(); boolean isDeviceIdleMode(); boolean isLightDeviceIdleMode(); diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 36bae2daf9bd..64e2f890ee47 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -1460,7 +1460,7 @@ public final class PowerManager { * an on/off switch for a subset of features. * @hide * - * @param dynamicPowerSavingsEnabled A signal indicating to the system if it believes the + * @param powerSaveHint A signal indicating to the system if it believes the * dynamic power savings behaviors should be activated. * @param disableThreshold When the suggesting app believes it would be safe to disable dynamic * power savings behaviors. @@ -1471,10 +1471,9 @@ public final class PowerManager { @SystemApi @TestApi @RequiresPermission(permission.POWER_SAVER) - public boolean setDynamicPowerSavings(boolean dynamicPowerSavingsEnabled, - int disableThreshold) { + public boolean setDynamicPowerSaveHint(boolean powerSaveHint, int disableThreshold) { try { - return mService.setDynamicPowerSavings(dynamicPowerSavingsEnabled, disableThreshold); + return mService.setDynamicPowerSaveHint(powerSaveHint, disableThreshold); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1525,54 +1524,54 @@ public final class PowerManager { /** * Indicates automatic battery saver toggling by the system will be based on percentage. * - * @see PowerManager#getPowerSaveMode() + * @see PowerManager#getPowerSaveModeTrigger() * * @hide */ @SystemApi @TestApi - public static final int POWER_SAVER_MODE_PERCENTAGE = 0; + public static final int POWER_SAVE_MODE_TRIGGER_PERCENTAGE = 0; /** * Indicates automatic battery saver toggling by the system will be based on the state * of the dynamic power savings signal. * - * @see PowerManager#setDynamicPowerSavings(boolean, int) - * @see PowerManager#getPowerSaveMode() + * @see PowerManager#setDynamicPowerSaveHint(boolean, int) + * @see PowerManager#getPowerSaveModeTrigger() * * @hide */ @SystemApi @TestApi - public static final int POWER_SAVER_MODE_DYNAMIC = 1; + public static final int POWER_SAVE_MODE_TRIGGER_DYNAMIC = 1; /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(value = { - POWER_SAVER_MODE_PERCENTAGE, - POWER_SAVER_MODE_DYNAMIC + POWER_SAVE_MODE_TRIGGER_PERCENTAGE, + POWER_SAVE_MODE_TRIGGER_DYNAMIC }) - public @interface AutoPowerSaverMode{} + public @interface AutoPowerSaveModeTriggers {} /** * Returns the current battery saver control mode. Values it may return are defined in - * AutoPowerSaverMode. Note that this is a global device state, not a per user setting. + * AutoPowerSaveModeTriggers. Note that this is a global device state, not a per user setting. * * @return The current value power saver mode for the system. * - * @see AutoPowerSaverMode - * @see PowerManager#getPowerSaveMode() + * @see AutoPowerSaveModeTriggers + * @see PowerManager#getPowerSaveModeTrigger() * @hide */ - @AutoPowerSaverMode + @AutoPowerSaveModeTriggers @SystemApi @TestApi @RequiresPermission(android.Manifest.permission.POWER_SAVER) - public int getPowerSaveMode() { + public int getPowerSaveModeTrigger() { try { - return mService.getPowerSaveMode(); + return mService.getPowerSaveModeTrigger(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java index c74cbff567c5..7958ddd29c70 100644 --- a/core/java/android/os/VibrationEffect.java +++ b/core/java/android/os/VibrationEffect.java @@ -23,7 +23,7 @@ import android.annotation.TestApi; import android.content.ContentResolver; import android.content.Context; import android.hardware.vibrator.V1_0.EffectStrength; -import android.hardware.vibrator.V1_2.Effect; +import android.hardware.vibrator.V1_3.Effect; import android.net.Uri; import android.util.MathUtils; @@ -94,6 +94,18 @@ public abstract class VibrationEffect implements Parcelable { */ public static final int EFFECT_HEAVY_CLICK = Effect.HEAVY_CLICK; + /** + * A texture effect meant to replicate soft ticks. + * + * Unlike normal effects, texture effects are meant to be called repeatedly, generally in + * response to some motion, in order to replicate the feeling of some texture underneath the + * user's fingers. + * + * @see #get(int) + * @hide + */ + public static final int EFFECT_TEXTURE_TICK = Effect.TEXTURE_TICK; + /** {@hide} */ @TestApi public static final int EFFECT_STRENGTH_LIGHT = EffectStrength.LIGHT; @@ -746,6 +758,7 @@ public abstract class VibrationEffect implements Parcelable { case EFFECT_CLICK: case EFFECT_DOUBLE_CLICK: case EFFECT_TICK: + case EFFECT_TEXTURE_TICK: case EFFECT_THUD: case EFFECT_POP: case EFFECT_HEAVY_CLICK: @@ -798,7 +811,7 @@ public abstract class VibrationEffect implements Parcelable { out.writeInt(mEffectStrength); } - public static final @android.annotation.NonNull Parcelable.Creator<Prebaked> CREATOR = + public static final @NonNull Parcelable.Creator<Prebaked> CREATOR = new Parcelable.Creator<Prebaked>() { @Override public Prebaked createFromParcel(Parcel in) { @@ -813,7 +826,7 @@ public abstract class VibrationEffect implements Parcelable { }; } - public static final @android.annotation.NonNull Parcelable.Creator<VibrationEffect> CREATOR = + public static final @NonNull Parcelable.Creator<VibrationEffect> CREATOR = new Parcelable.Creator<VibrationEffect>() { @Override public VibrationEffect createFromParcel(Parcel in) { diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java index 40238d2a9f27..34200077044d 100644 --- a/core/java/android/os/ZygoteProcess.java +++ b/core/java/android/os/ZygoteProcess.java @@ -66,22 +66,14 @@ import java.util.UUID; */ public class ZygoteProcess { - /** - * @hide for internal use only. - */ - public static final int ZYGOTE_CONNECT_TIMEOUT_MS = 20000; + private static final int ZYGOTE_CONNECT_TIMEOUT_MS = 20000; /** - * @hide for internal use only. - * * Use a relatively short delay, because for app zygote, this is in the critical path of * service launch. */ - public static final int ZYGOTE_CONNECT_RETRY_DELAY_MS = 50; + private static final int ZYGOTE_CONNECT_RETRY_DELAY_MS = 50; - /** - * @hide for internal use only - */ private static final String LOG_TAG = "ZygoteProcess"; /** @@ -141,7 +133,7 @@ public class ZygoteProcess { /** * State for communicating with the zygote process. */ - public static class ZygoteState { + private static class ZygoteState implements AutoCloseable { final LocalSocketAddress mZygoteSocketAddress; final LocalSocketAddress mUsapSocketAddress; @@ -178,12 +170,12 @@ public class ZygoteProcess { * address * @throws IOException */ - public static ZygoteState connect(@NonNull LocalSocketAddress zygoteSocketAddress, - @Nullable LocalSocketAddress usapSocketAddress) + static ZygoteState connect(@NonNull LocalSocketAddress zygoteSocketAddress, + @Nullable LocalSocketAddress usapSocketAddress) throws IOException { - DataInputStream zygoteInputStream = null; - BufferedWriter zygoteOutputWriter = null; + DataInputStream zygoteInputStream; + BufferedWriter zygoteOutputWriter; final LocalSocket zygoteSessionSocket = new LocalSocket(); if (zygoteSocketAddress == null) { @@ -357,8 +349,6 @@ public class ZygoteProcess { /** * Queries the zygote for the list of ABIS it supports. - * - * @throws ZygoteStartFailedEx if the query failed. */ @GuardedBy("mLock") private static List<String> getAbiList(BufferedWriter writer, DataInputStream inputStream) @@ -411,52 +401,24 @@ public class ZygoteProcess { * the child or -1 on failure, followed by boolean to * indicate whether a wrapper process was used. */ - String msgStr = Integer.toString(args.size()) + "\n" - + String.join("\n", args) + "\n"; - - // Should there be a timeout on this? - Process.ProcessStartResult result = new Process.ProcessStartResult(); + String msgStr = args.size() + "\n" + String.join("\n", args) + "\n"; - // TODO (chriswailes): Move branch body into separate function. if (useUsapPool && mUsapPoolEnabled && isValidUsapCommand(args)) { - LocalSocket usapSessionSocket = null; - try { - usapSessionSocket = zygoteState.getUsapSessionSocket(); - - final BufferedWriter usapWriter = - new BufferedWriter( - new OutputStreamWriter(usapSessionSocket.getOutputStream()), - Zygote.SOCKET_BUFFER_SIZE); - final DataInputStream usapReader = - new DataInputStream(usapSessionSocket.getInputStream()); - - usapWriter.write(msgStr); - usapWriter.flush(); - - result.pid = usapReader.readInt(); - // USAPs can't be used to spawn processes that need wrappers. - result.usingWrapper = false; - - if (result.pid < 0) { - throw new ZygoteStartFailedEx("USAP specialization failed"); - } - - return result; + return attemptUsapSendArgsAndGetResult(zygoteState, msgStr); } catch (IOException ex) { // If there was an IOException using the USAP pool we will log the error and // attempt to start the process through the Zygote. Log.e(LOG_TAG, "IO Exception while communicating with USAP pool - " - + ex.getMessage()); - } finally { - try { - usapSessionSocket.close(); - } catch (IOException ex) { - Log.e(LOG_TAG, "Failed to close USAP session socket: " + ex.getMessage()); - } + + ex.getMessage()); } } + return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr); + } + + private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult( + ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx { try { final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter; final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream; @@ -467,20 +429,48 @@ public class ZygoteProcess { // Always read the entire result from the input stream to avoid leaving // bytes in the stream for future process starts to accidentally stumble // upon. + Process.ProcessStartResult result = new Process.ProcessStartResult(); result.pid = zygoteInputStream.readInt(); result.usingWrapper = zygoteInputStream.readBoolean(); + + if (result.pid < 0) { + throw new ZygoteStartFailedEx("fork() failed"); + } + + return result; } catch (IOException ex) { zygoteState.close(); Log.e(LOG_TAG, "IO Exception while communicating with Zygote - " + ex.toString()); throw new ZygoteStartFailedEx(ex); } + } - if (result.pid < 0) { - throw new ZygoteStartFailedEx("fork() failed"); + private Process.ProcessStartResult attemptUsapSendArgsAndGetResult( + ZygoteState zygoteState, String msgStr) + throws ZygoteStartFailedEx, IOException { + try (LocalSocket usapSessionSocket = zygoteState.getUsapSessionSocket()) { + final BufferedWriter usapWriter = + new BufferedWriter( + new OutputStreamWriter(usapSessionSocket.getOutputStream()), + Zygote.SOCKET_BUFFER_SIZE); + final DataInputStream usapReader = + new DataInputStream(usapSessionSocket.getInputStream()); + + usapWriter.write(msgStr); + usapWriter.flush(); + + Process.ProcessStartResult result = new Process.ProcessStartResult(); + result.pid = usapReader.readInt(); + // USAPs can't be used to spawn processes that need wrappers. + result.usingWrapper = false; + + if (result.pid >= 0) { + return result; + } else { + throw new ZygoteStartFailedEx("USAP specialization failed"); + } } - - return result; } /** @@ -557,7 +547,7 @@ public class ZygoteProcess { boolean useUnspecializedAppProcessPool, @Nullable String[] extraArgs) throws ZygoteStartFailedEx { - ArrayList<String> argsForZygote = new ArrayList<String>(); + ArrayList<String> argsForZygote = new ArrayList<>(); // --runtime-args, --setuid=, --setgid=, // and --setgroups= must go first @@ -627,17 +617,7 @@ public class ZygoteProcess { } if (packagesForUid != null && packagesForUid.length > 0) { - final StringBuilder sb = new StringBuilder(); - sb.append("--packages-for-uid="); - - // TODO (chriswailes): Replace with String.join - for (int i = 0; i < packagesForUid.length; ++i) { - if (i != 0) { - sb.append(','); - } - sb.append(packagesForUid[i]); - } - argsForZygote.add(sb.toString()); + argsForZygote.add("--packages-for-uid=" + String.join(",", packagesForUid)); } if (sandboxId != null) { @@ -647,9 +627,7 @@ public class ZygoteProcess { argsForZygote.add(processClass); if (extraArgs != null) { - for (String arg : extraArgs) { - argsForZygote.add(arg); - } + Collections.addAll(argsForZygote, extraArgs); } synchronized(mLock) { @@ -671,11 +649,13 @@ public class ZygoteProcess { Boolean.parseBoolean(USAP_POOL_ENABLED_DEFAULT)); } - if (origVal != mUsapPoolEnabled) { + boolean valueChanged = origVal != mUsapPoolEnabled; + + if (valueChanged) { Log.i(LOG_TAG, "usapPoolEnabled = " + mUsapPoolEnabled); } - return origVal != mUsapPoolEnabled; + return valueChanged; } private boolean mIsFirstPropCheck = true; @@ -805,10 +785,10 @@ public class ZygoteProcess { if (state == null || state.isClosed()) { Slog.e(LOG_TAG, "Can't set API blacklist exemptions: no zygote connection"); return false; - } - if (!sendIfEmpty && mApiBlacklistExemptions.isEmpty()) { + } else if (!sendIfEmpty && mApiBlacklistExemptions.isEmpty()) { return true; } + try { state.mZygoteOutputWriter.write(Integer.toString(mApiBlacklistExemptions.size() + 1)); state.mZygoteOutputWriter.newLine(); @@ -832,17 +812,15 @@ public class ZygoteProcess { } private void maybeSetHiddenApiAccessLogSampleRate(ZygoteState state) { - if (state == null || state.isClosed()) { - return; - } - if (mHiddenApiAccessLogSampleRate == -1) { + if (state == null || state.isClosed() || mHiddenApiAccessLogSampleRate == -1) { return; } + try { state.mZygoteOutputWriter.write(Integer.toString(1)); state.mZygoteOutputWriter.newLine(); state.mZygoteOutputWriter.write("--hidden-api-log-sampling-rate=" - + Integer.toString(mHiddenApiAccessLogSampleRate)); + + mHiddenApiAccessLogSampleRate); state.mZygoteOutputWriter.newLine(); state.mZygoteOutputWriter.flush(); int status = state.mZygoteInputStream.readInt(); @@ -855,17 +833,15 @@ public class ZygoteProcess { } private void maybeSetHiddenApiAccessStatslogSampleRate(ZygoteState state) { - if (state == null || state.isClosed()) { - return; - } - if (mHiddenApiAccessStatslogSampleRate == -1) { + if (state == null || state.isClosed() || mHiddenApiAccessStatslogSampleRate == -1) { return; } + try { state.mZygoteOutputWriter.write(Integer.toString(1)); state.mZygoteOutputWriter.newLine(); state.mZygoteOutputWriter.write("--hidden-api-statslog-sampling-rate=" - + Integer.toString(mHiddenApiAccessStatslogSampleRate)); + + mHiddenApiAccessStatslogSampleRate); state.mZygoteOutputWriter.newLine(); state.mZygoteOutputWriter.flush(); int status = state.mZygoteInputStream.readInt(); @@ -942,8 +918,8 @@ public class ZygoteProcess { * Only the app zygote supports this function. * TODO preloadPackageForAbi() can probably be removed and the callers an use this instead. */ - public boolean preloadApp(ApplicationInfo appInfo, String abi) throws ZygoteStartFailedEx, - IOException { + public boolean preloadApp(ApplicationInfo appInfo, String abi) + throws ZygoteStartFailedEx, IOException { synchronized (mLock) { ZygoteState state = openZygoteSocketIfNeeded(abi); state.mZygoteOutputWriter.write("2"); @@ -971,10 +947,10 @@ 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 boolean preloadPackageForAbi(String packagePath, String libsPath, String libFileName, - String cacheKey, String abi) throws ZygoteStartFailedEx, - IOException { - synchronized(mLock) { + public boolean preloadPackageForAbi( + String packagePath, String libsPath, String libFileName, String cacheKey, String abi) + throws ZygoteStartFailedEx, IOException { + synchronized (mLock) { ZygoteState state = openZygoteSocketIfNeeded(abi); state.mZygoteOutputWriter.write("5"); state.mZygoteOutputWriter.newLine(); @@ -1049,8 +1025,7 @@ public class ZygoteProcess { try { Thread.sleep(ZYGOTE_CONNECT_RETRY_DELAY_MS); - } catch (InterruptedException ie) { - } + } catch (InterruptedException ignored) { } } Slog.wtf(LOG_TAG, "Failed to connect to Zygote through socket " + zygoteSocketAddress.getName()); diff --git a/core/java/android/content/DynamicAndroidClient.java b/core/java/android/os/image/DynamicSystemClient.java index 571cba429ea9..33a6ee888d0a 100644 --- a/core/java/android/content/DynamicAndroidClient.java +++ b/core/java/android/os/image/DynamicSystemClient.java @@ -13,12 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.content; +package android.os.image; +import android.annotation.BytesLong; import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.RequiresPermission; import android.annotation.SystemApi; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -34,12 +40,28 @@ import java.lang.ref.WeakReference; import java.util.concurrent.Executor; /** - * This class contains methods and constants used to start DynamicAndroid - * installation, and a listener for progress update. + * <p>This class contains methods and constants used to start a {@code DynamicSystem} installation, + * and a listener for status updates.</p> + * + * <p>{@code DynamicSystem} allows user to run certified system images in a non destructive manner + * without needing to prior OEM unlock. While running in {@code DynamicSystem}, persitent storage + * for factory reset protection (FRP) remains unchanged. The new system is installed in a + * temporarily allocated partition. After the installation is completed, the device will be running + * in the new system on next reboot. Then, when the user reboots the device again, it will leave + * {@code DynamicSystem} and go back into the original system. Since the userdata for + * {@code DynamicSystem} is also newly created during the installation, running in + * {@code DynamicSystem} doesn't change user's app data.</p> + * + * <p>With {@link #setOnStatusChangedListener}, API users can register an + * {@link #OnStatusChangedListener} and get status updates and cause when the installation is + * started, stopped, or cancelled. It also sends progress updates during the installation. With + * {@link #start}, API users can start an installation with the {@link Uri} to a gzipped system + * image. The {@link Uri} can be a web URL or a content Uri to a local path.</p> + * * @hide */ @SystemApi -public class DynamicAndroidClient { +public class DynamicSystemClient { /** @hide */ @IntDef(prefix = { "STATUS_" }, value = { STATUS_UNKNOWN, @@ -64,23 +86,23 @@ public class DynamicAndroidClient { @Retention(RetentionPolicy.SOURCE) public @interface StatusChangedCause {} - private static final String TAG = "DynAndroidClient"; + private static final String TAG = "DynSystemClient"; private static final long DEFAULT_USERDATA_SIZE = (10L << 30); - /** Listener for installation status update. */ + /** Listener for installation status updates. */ public interface OnStatusChangedListener { /** * This callback is called when installation status is changed, and when the - * client is {@link #bind} to DynamicAndroid installation service. + * client is {@link #bind} to {@code DynamicSystem} installation service. * - * @param status status code, also defined in {@code DynamicAndroidClient}. - * @param cause cause code, also defined in {@code DynamicAndroidClient}. + * @param status status code, also defined in {@code DynamicSystemClient}. + * @param cause cause code, also defined in {@code DynamicSystemClient}. * @param progress number of bytes installed. */ void onStatusChanged(@InstallationStatus int status, @StatusChangedCause int cause, - long progress); + @BytesLong long progress); } /* @@ -98,7 +120,7 @@ public class DynamicAndroidClient { /** Installation is finished but the user has not launched it. */ public static final int STATUS_READY = 3; - /** Device is running in Dynamic Android. */ + /** Device is running in {@code DynamicSystem}. */ public static final int STATUS_IN_USE = 4; /* @@ -113,7 +135,7 @@ public class DynamicAndroidClient { /** Status changed because installation is cancelled. */ public static final int CAUSE_INSTALL_CANCELLED = 2; - /** Installation failed due to IOException. */ + /** Installation failed due to {@code IOException}. */ public static final int CAUSE_ERROR_IO = 3; /** Installation failed because the image URL source is not supported. */ @@ -141,7 +163,7 @@ public class DynamicAndroidClient { public static final int MSG_UNREGISTER_LISTENER = 2; /** - * Message for status update. + * Message for status updates. * @hide */ public static final int MSG_POST_STATUS = 3; @@ -150,7 +172,7 @@ public class DynamicAndroidClient { * Messages keys */ /** - * Message key, for progress update. + * Message key, for progress updates. * @hide */ public static final String KEY_INSTALLED_SIZE = "KEY_INSTALLED_SIZE"; @@ -163,14 +185,14 @@ public class DynamicAndroidClient { * @hide */ public static final String ACTION_START_INSTALL = - "android.content.action.START_INSTALL"; + "android.os.image.action.START_INSTALL"; /** - * Intent action: notify user if we are currently running in Dynamic Android. + * Intent action: notify user if we are currently running in {@code DynamicSystem}. * @hide */ public static final String ACTION_NOTIFY_IF_IN_USE = - "android.content.action.NOTIFY_IF_IN_USE"; + "android.os.image.action.NOTIFY_IF_IN_USE"; /* * Intent Keys @@ -195,16 +217,16 @@ public class DynamicAndroidClient { private static class IncomingHandler extends Handler { - private final WeakReference<DynamicAndroidClient> mWeakClient; + private final WeakReference<DynamicSystemClient> mWeakClient; - IncomingHandler(DynamicAndroidClient service) { + IncomingHandler(DynamicSystemClient service) { super(Looper.getMainLooper()); mWeakClient = new WeakReference<>(service); } @Override public void handleMessage(Message msg) { - DynamicAndroidClient service = mWeakClient.get(); + DynamicSystemClient service = mWeakClient.get(); if (service != null) { service.handleMessage(msg); @@ -212,9 +234,9 @@ public class DynamicAndroidClient { } } - private class DynAndroidServiceConnection implements ServiceConnection { + private class DynSystemServiceConnection implements ServiceConnection { public void onServiceConnected(ComponentName className, IBinder service) { - Slog.v(TAG, "DynAndroidService connected"); + Slog.v(TAG, "DynSystemService connected"); mService = new Messenger(service); @@ -232,13 +254,13 @@ public class DynamicAndroidClient { } public void onServiceDisconnected(ComponentName className) { - Slog.v(TAG, "DynAndroidService disconnected"); + Slog.v(TAG, "DynSystemService disconnected"); mService = null; } } private final Context mContext; - private final DynAndroidServiceConnection mConnection; + private final DynSystemServiceConnection mConnection; private final Messenger mMessenger; private boolean mBound; @@ -247,12 +269,16 @@ public class DynamicAndroidClient { private Messenger mService; /** + * Create a new {@code DynamicSystem} client. + * + * @param context a {@link Context} will be used to bind the installation service. + * * @hide */ @SystemApi - public DynamicAndroidClient(@NonNull Context context) { + public DynamicSystemClient(@NonNull Context context) { mContext = context; - mConnection = new DynAndroidServiceConnection(); + mConnection = new DynSystemServiceConnection(); mMessenger = new Messenger(new IncomingHandler(this)); } @@ -261,8 +287,8 @@ public class DynamicAndroidClient { * the executor. */ public void setOnStatusChangedListener( - @NonNull OnStatusChangedListener listener, - @NonNull @CallbackExecutor Executor executor) { + @NonNull @CallbackExecutor Executor executor, + @NonNull OnStatusChangedListener listener) { mListener = listener; mExecutor = executor; } @@ -278,12 +304,15 @@ public class DynamicAndroidClient { } /** - * Bind to DynamicAndroidInstallationService. + * Bind to {@code DynamicSystem} installation service. Binding to the installation service + * allows it to send status updates to {@link #OnStatusChangedListener}. It is recommanded + * to bind before calling {@link #start} and get status updates. */ + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) public void bind() { Intent intent = new Intent(); - intent.setClassName("com.android.dynandroid", - "com.android.dynandroid.DynamicAndroidInstallationService"); + intent.setClassName("com.android.dynsystem", + "com.android.dynsystem.DynamicSystemInstallationService"); mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE); @@ -291,8 +320,10 @@ public class DynamicAndroidClient { } /** - * Unbind from DynamicAndroidInstallationService. + * Unbind from {@code DynamicSystem} installation service. Unbinding from the installation + * service stops it from sending following status updates. */ + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) public void unbind() { if (!mBound) { return; @@ -315,27 +346,40 @@ public class DynamicAndroidClient { } /** - * Start installing DynamicAndroid from URL with default userdata size. + * Start installing {@code DynamicSystem} from URL with default userdata size. + * + * Calling this function will first start an Activity to confirm device credential, using + * {@link KeyguardManager}. If it's confirmed, the installation service will be started. + * + * This function doesn't require prior calling {@link #bind}. * * @param systemUrl A network URL or a file URL to system image. * @param systemSize size of system image. */ - public void start(String systemUrl, long systemSize) { + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) + public void start(@NonNull String systemUrl, @BytesLong long systemSize) { start(systemUrl, systemSize, DEFAULT_USERDATA_SIZE); } /** - * Start installing DynamicAndroid from URL. + * Start installing {@code DynamicSystem} from URL. + * + * Calling this function will first start an Activity to confirm device credential, using + * {@link KeyguardManager}. If it's confirmed, the installation service will be started. + * + * This function doesn't require prior calling {@link #bind}. * * @param systemUrl A network URL or a file URL to system image. * @param systemSize size of system image. * @param userdataSize bytes reserved for userdata. */ - public void start(String systemUrl, long systemSize, long userdataSize) { + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) + public void start(@NonNull String systemUrl, @BytesLong long systemSize, + @BytesLong long userdataSize) { Intent intent = new Intent(); - intent.setClassName("com.android.dynandroid", - "com.android.dynandroid.VerificationActivity"); + intent.setClassName("com.android.dynsystem", + "com.android.dynsystem.VerificationActivity"); intent.setAction(ACTION_START_INSTALL); diff --git a/core/java/android/os/DynamicAndroidManager.java b/core/java/android/os/image/DynamicSystemManager.java index 5238896016ee..0458c2a8b735 100644 --- a/core/java/android/os/DynamicAndroidManager.java +++ b/core/java/android/os/image/DynamicSystemManager.java @@ -14,50 +14,51 @@ * limitations under the License. */ -package android.os; +package android.os.image; import android.annotation.RequiresPermission; import android.annotation.SystemService; import android.content.Context; import android.gsi.GsiProgress; +import android.os.RemoteException; /** - * The DynamicAndroidManager offers a mechanism to use a new Android image temporarily. After the + * The DynamicSystemManager offers a mechanism to use a new system image temporarily. After the * installation, the device can reboot into this image with a new created /data. This image will * last until the next reboot and then the device will go back to the original image. However the * installed image and the new created /data are not deleted but disabled. Thus the application can * either re-enable the installed image by calling {@link #toggle} or use the {@link #remove} to * delete it completely. In other words, there are three device states: no installation, installed - * and running. The procedure to install a DynamicAndroid starts with a {@link #startInstallation}, + * and running. The procedure to install a DynamicSystem starts with a {@link #startInstallation}, * followed by a series of {@link #write} and ends with a {@link commit}. Once the installation is * complete, the device state changes from no installation to the installed state and a followed - * reboot will change its state to running. Note one instance of dynamic android can exist on a - * given device thus the {@link #startInstallation} will fail if the device is currently running a - * DynamicAndroid. + * reboot will change its state to running. Note one instance of DynamicSystem can exist on a given + * device thus the {@link #startInstallation} will fail if the device is currently running a + * DynamicSystem. * * @hide */ -@SystemService(Context.DYNAMIC_ANDROID_SERVICE) -public class DynamicAndroidManager { - private static final String TAG = "DynamicAndroidManager"; +@SystemService(Context.DYNAMIC_SYSTEM_SERVICE) +public class DynamicSystemManager { + private static final String TAG = "DynamicSystemManager"; - private final IDynamicAndroidService mService; + private final IDynamicSystemService mService; /** {@hide} */ - public DynamicAndroidManager(IDynamicAndroidService service) { + public DynamicSystemManager(IDynamicSystemService service) { mService = service; } - /** The DynamicAndroidManager.Session represents a started session for the installation. */ + /** The DynamicSystemManager.Session represents a started session for the installation. */ public class Session { private Session() {} /** - * Write a chunk of the DynamicAndroid system image + * Write a chunk of the DynamicSystem system image * * @return {@code true} if the call succeeds. {@code false} if there is any native runtime * error. */ - @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) public boolean write(byte[] buf) { try { return mService.write(buf); @@ -72,7 +73,7 @@ public class DynamicAndroidManager { * @return {@code true} if the call succeeds. {@code false} if there is any native runtime * error. */ - @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) public boolean commit() { try { return mService.commit(); @@ -82,16 +83,16 @@ public class DynamicAndroidManager { } } /** - * Start DynamicAndroid installation. This call may take an unbounded amount of time. The caller + * Start DynamicSystem installation. This call may take an unbounded amount of time. The caller * may use another thread to call the getStartProgress() to get the progress. * * @param systemSize system size in bytes * @param userdataSize userdata size in bytes * @return {@code true} if the call succeeds. {@code false} either the device does not contain - * enough space or a DynamicAndroid is currently in use where the {@link #isInUse} would be + * enough space or a DynamicSystem is currently in use where the {@link #isInUse} would be * true. */ - @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) public Session startInstallation(long systemSize, long userdataSize) { try { if (mService.startInstallation(systemSize, userdataSize)) { @@ -112,7 +113,7 @@ public class DynamicAndroidManager { * status field can be IGsiService.STATUS_NO_OPERATION, IGsiService.STATUS_WORKING or * IGsiService.STATUS_COMPLETE. */ - @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) public GsiProgress getInstallationProgress() { try { return mService.getInstallationProgress(); @@ -129,7 +130,7 @@ public class DynamicAndroidManager { * @return {@code true} if the call succeeds. {@code false} if there is no installation * currently. */ - @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) public boolean abort() { try { return mService.abort(); @@ -138,8 +139,8 @@ public class DynamicAndroidManager { } } - /** @return {@code true} if the device is running a dynamic android */ - @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) + /** @return {@code true} if the device is running a dynamic system */ + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) public boolean isInUse() { try { return mService.isInUse(); @@ -148,8 +149,8 @@ public class DynamicAndroidManager { } } - /** @return {@code true} if the device has a dynamic android installed */ - @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) + /** @return {@code true} if the device has a dynamic system installed */ + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) public boolean isInstalled() { try { return mService.isInstalled(); @@ -159,11 +160,11 @@ public class DynamicAndroidManager { } /** - * Remove DynamicAndroid installation if present + * Remove DynamicSystem installation if present * * @return {@code true} if the call succeeds. {@code false} if there is no installed image. */ - @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) public boolean remove() { try { return mService.remove(); @@ -173,11 +174,11 @@ public class DynamicAndroidManager { } /** - * Enable DynamicAndroid when it's not enabled, otherwise, disable it. + * Enable DynamicSystem when it's not enabled, otherwise, disable it. * * @return {@code true} if the call succeeds. {@code false} if there is no installed image. */ - @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) public boolean toggle() { try { return mService.toggle(); diff --git a/core/java/android/os/IDynamicAndroidService.aidl b/core/java/android/os/image/IDynamicSystemService.aidl index 0b28799c8dd0..15f5b68e354b 100644 --- a/core/java/android/os/IDynamicAndroidService.aidl +++ b/core/java/android/os/image/IDynamicSystemService.aidl @@ -13,15 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.os; +package android.os.image; import android.gsi.GsiProgress; /** {@hide} */ -interface IDynamicAndroidService +interface IDynamicSystemService { /** - * Start DynamicAndroid installation. This call may take 60~90 seconds. The caller + * Start DynamicSystem installation. This call may take 60~90 seconds. The caller * may use another thread to call the getStartProgress() to get the progress. * * @param systemSize system size in bytes @@ -53,26 +53,26 @@ interface IDynamicAndroidService boolean isInUse(); /** - * @return true if the device has an DynamicAndroid image installed + * @return true if the device has an DynamicSystem image installed */ boolean isInstalled(); /** - * Remove DynamicAndroid installation if present + * Remove DynamicSystem installation if present * * @return true if the call succeeds */ boolean remove(); /** - * Enable DynamicAndroid when it's not enabled, otherwise, disable it. + * Enable DynamicSystem when it's not enabled, otherwise, disable it. * * @return true if the call succeeds */ boolean toggle(); /** - * Write a chunk of the DynamicAndroid system image + * Write a chunk of the DynamicSystem system image * * @return true if the call succeeds */ diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java index 4322a59cd3cd..728d77ef941e 100644 --- a/core/java/android/provider/DeviceConfig.java +++ b/core/java/android/provider/DeviceConfig.java @@ -27,6 +27,8 @@ import android.annotation.SystemApi; import android.annotation.TestApi; import android.app.ActivityThread; import android.content.ContentResolver; +import android.content.Context; +import android.content.pm.PackageManager; import android.database.ContentObserver; import android.net.Uri; import android.provider.Settings.ResetMode; @@ -37,6 +39,7 @@ import android.util.Pair; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.Preconditions; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -257,6 +260,14 @@ public final class DeviceConfig { public static final String NAMESPACE_TEXTCLASSIFIER = "textclassifier"; /** + * List of namespaces which can be read without READ_DEVICE_CONFIG permission + * + * @hide + */ + @NonNull + private static final List<String> PUBLIC_NAMESPACES = + Arrays.asList(NAMESPACE_TEXTCLASSIFIER, NAMESPACE_RUNTIME); + /** * Privacy related properties definitions. * * @hide @@ -527,6 +538,8 @@ public final class DeviceConfig { @NonNull String namespace, @NonNull @CallbackExecutor Executor executor, @NonNull OnPropertyChangedListener onPropertyChangedListener) { + enforceReadPermission(ActivityThread.currentApplication().getApplicationContext(), + namespace); synchronized (sLock) { Pair<String, Executor> oldNamespace = sSingleListeners.get(onPropertyChangedListener); if (oldNamespace == null) { @@ -566,6 +579,8 @@ public final class DeviceConfig { @NonNull String namespace, @NonNull @CallbackExecutor Executor executor, @NonNull OnPropertiesChangedListener onPropertiesChangedListener) { + enforceReadPermission(ActivityThread.currentApplication().getApplicationContext(), + namespace); synchronized (sLock) { Pair<String, Executor> oldNamespace = sListeners.get(onPropertiesChangedListener); if (oldNamespace == null) { @@ -667,7 +682,7 @@ public final class DeviceConfig { } /** - * Decrement the count used to represent th enumber of listeners subscribed to the given + * Decrement the count used to represent the number of listeners subscribed to the given * namespace. If this is the final decrement call (i.e. decrementing from 1 to 0) for the given * namespace, the ContentObserver that had been tracking it will be removed. * @@ -696,7 +711,14 @@ public final class DeviceConfig { // pathSegments(0) is "config" final String namespace = pathSegments.get(1); final String name = pathSegments.get(2); - final String value = getProperty(namespace, name); + final String value; + try { + value = getProperty(namespace, name); + } catch (SecurityException e) { + // Silently failing to not crash binder or listener threads. + Log.e(TAG, "OnPropertyChangedListener update failed: permission violation."); + return; + } synchronized (sLock) { // OnPropertiesChangedListeners for (int i = 0; i < sListeners.size(); i++) { @@ -730,6 +752,22 @@ public final class DeviceConfig { } } + + /** + * Enforces READ_DEVICE_CONFIG permission if namespace is not one of public namespaces. + * @hide + */ + public static void enforceReadPermission(Context context, String namespace) { + if (context.checkCallingOrSelfPermission(READ_DEVICE_CONFIG) + != PackageManager.PERMISSION_GRANTED) { + if (!PUBLIC_NAMESPACES.contains(namespace)) { + throw new SecurityException("Permission denial: reading from settings requires:" + + READ_DEVICE_CONFIG); + } + } + } + + /** * Interface for monitoring single property changes. * <p> diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java index 14863338f182..dc5fdc0ba67c 100644 --- a/core/java/android/provider/MediaStore.java +++ b/core/java/android/provider/MediaStore.java @@ -136,6 +136,7 @@ public final class MediaStore { * removing nomedia files * @hide */ + @Deprecated public static final String UNHIDE_CALL = "unhide"; /** @@ -873,7 +874,7 @@ public final class MediaStore { */ public interface MediaColumns extends BaseColumns { /** - * Path to the media item on disk. + * Absolute filesystem path to the media item on disk. * <p> * Note that apps may not have filesystem permissions to directly access * this path. Instead of trying to open this path directly, apps should @@ -920,6 +921,10 @@ public final class MediaStore { /** * The display name of the media item. + * <p> + * For example, an item stored at + * {@code /storage/0000-0000/DCIM/Vacation/IMG1024.JPG} would have a + * display name of {@code IMG1024.JPG}. */ @Column(Cursor.FIELD_TYPE_STRING) public static final String DISPLAY_NAME = "_display_name"; @@ -985,7 +990,8 @@ public final class MediaStore { /** * Flag indicating if a media item is pending, and still being inserted - * by its owner. + * by its owner. While this flag is set, only the owner of the item can + * open the underlying file; requests from other apps will be rejected. * * @see MediaStore#setIncludePending(Uri) */ @@ -1033,17 +1039,53 @@ public final class MediaStore { public static final String OWNER_PACKAGE_NAME = "owner_package_name"; /** + * Relative path of this media item within the storage device where it + * is persisted. For example, an item stored at + * {@code /storage/0000-0000/DCIM/Vacation/IMG1024.JPG} would have a + * path of {@code DCIM/Vacation}. + * <p> + * This value should only be used for organizational purposes, and you + * should not attempt to construct or access a raw filesystem path using + * this value. If you need to open a media item, use an API like + * {@link ContentResolver#openFileDescriptor(Uri, String)}. + * <p> + * When this value is set to {@code NULL} during an + * {@link ContentResolver#insert} operation, the newly created item will + * be placed in a relevant default location based on the type of media + * being inserted. For example, a {@code image/jpeg} item will be placed + * under {@link Environment#DIRECTORY_PICTURES}. + * <p> + * You can modify this column during an {@link ContentResolver#update} + * call, which will move the underlying file on disk. + * <p> + * In both cases above, content must be placed under a top-level + * directory that is relevant to the media type. For example, attempting + * to place a {@code audio/mpeg} file under + * {@link Environment#DIRECTORY_PICTURES} will be rejected. + */ + @Column(Cursor.FIELD_TYPE_STRING) + public static final String RELATIVE_PATH = "relative_path"; + + /** * The primary directory name this media exists under. The value may be * {@code NULL} if the media doesn't have a primary directory name. + * + * @removed + * @deprecated Replaced by {@link #RELATIVE_PATH}. */ @Column(Cursor.FIELD_TYPE_STRING) + @Deprecated public static final String PRIMARY_DIRECTORY = "primary_directory"; /** * The secondary directory name this media exists under. The value may * be {@code NULL} if the media doesn't have a secondary directory name. + * + * @removed + * @deprecated Replaced by {@link #RELATIVE_PATH}. */ @Column(Cursor.FIELD_TYPE_STRING) + @Deprecated public static final String SECONDARY_DIRECTORY = "secondary_directory"; /** @@ -1340,6 +1382,11 @@ public final class MediaStore { } /** @hide */ + public static @NonNull Uri getContentUri(@NonNull String volumeName, long id) { + return ContentUris.withAppendedId(getContentUri(volumeName), id); + } + + /** @hide */ public static @NonNull Uri getContentUriForPath(@NonNull String path) { return getContentUri(getVolumeName(new File(path))); } @@ -1711,6 +1758,11 @@ public final class MediaStore { .appendPath("media").build(); } + /** @hide */ + public static @NonNull Uri getContentUri(@NonNull String volumeName, long id) { + return ContentUris.withAppendedId(getContentUri(volumeName), id); + } + /** * The content:// style URI for the internal storage. */ @@ -2199,6 +2251,11 @@ public final class MediaStore { .appendPath("media").build(); } + /** @hide */ + public static @NonNull Uri getContentUri(@NonNull String volumeName, long id) { + return ContentUris.withAppendedId(getContentUri(volumeName), id); + } + /** * Get the content:// style URI for the given audio media file. * @@ -2977,6 +3034,11 @@ public final class MediaStore { .appendPath("media").build(); } + /** @hide */ + public static @NonNull Uri getContentUri(@NonNull String volumeName, long id) { + return ContentUris.withAppendedId(getContentUri(volumeName), id); + } + /** * The content:// style URI for the internal storage. */ @@ -3344,6 +3406,10 @@ public final class MediaStore { * substantial changes, and that data should be rescanned. * <p> * No other assumptions should be made about the meaning of the version. + * + * @param volumeName specific volume to obtain an opaque version string for. + * Must be one of the values returned from + * {@link #getAllVolumeNames(Context)}. */ public static @NonNull String getVersion(@NonNull Context context, @NonNull String volumeName) { final ContentResolver resolver = context.getContentResolver(); @@ -3471,4 +3537,17 @@ public final class MediaStore { throw new IOException("User " + user + " must be unlocked and running"); } } + + /** @hide */ + public static Uri scanFile(Context context, File file) { + final ContentResolver resolver = context.getContentResolver(); + try (ContentProviderClient client = resolver.acquireContentProviderClient(AUTHORITY)) { + final Bundle in = new Bundle(); + in.putParcelable(Intent.EXTRA_STREAM, Uri.fromFile(file)); + final Bundle out = client.call(SCAN_FILE_CALL, null, in); + return out.getParcelable(Intent.EXTRA_STREAM); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 7c80a0bff2f5..702dc74f7748 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -73,6 +73,7 @@ import android.os.Bundle; import android.os.DropBoxManager; import android.os.IBinder; import android.os.LocaleList; +import android.os.PowerManager.AutoPowerSaveModeTriggers; import android.os.Process; import android.os.RemoteException; import android.os.ResultReceiver; @@ -875,7 +876,8 @@ public final class Settings { /** * Activity Action: Show screen for controlling app usage properties for an app. - * Input: Intent's extra EXTRA_PACKAGE_NAME must specify the application package name. + * Input: Intent's extra {@link android.content.Intent#EXTRA_PACKAGE_NAME} must specify the + * application package name. * Output: Nothing. */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) @@ -1261,6 +1263,25 @@ public final class Settings { = "android.settings.NOTIFICATION_POLICY_ACCESS_SETTINGS"; /** + * Activity Action: Show do not disturb setting page for app. + * <p> + * Users can grant and deny access to Do Not Disturb configuration for an app from here. + * See {@link android.app.NotificationManager#isNotificationPolicyAccessGranted()} for more + * details. + * <p> + * Input: Intent's data URI set with an application name, using the + * "package" schema (like "package:com.my.app"). + * <p> + * Output: Nothing. + * + * @hide + */ + @SystemApi + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_NOTIFICATION_POLICY_ACCESS_DETAIL_SETTINGS = + "android.settings.NOTIFICATION_POLICY_ACCESS_DETAIL_SETTINGS"; + + /** * @hide */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) @@ -8024,17 +8045,6 @@ public final class Settings { BOOLEAN_VALIDATOR; /** - * Whether the swipe up gesture to switch apps should be enabled. - * - * @hide - */ - public static final String SWIPE_UP_TO_SWITCH_APPS_ENABLED = - "swipe_up_to_switch_apps_enabled"; - - private static final Validator SWIPE_UP_TO_SWITCH_APPS_ENABLED_VALIDATOR = - BOOLEAN_VALIDATOR; - - /** * Whether or not the smart camera lift trigger that launches the camera when the user moves * the phone into a position for taking photos should be enabled. * @@ -8587,38 +8597,6 @@ public final class Settings { "packages_to_clear_data_before_full_restore"; /** - * Indicates the location state should be maintained after sensor privacy is disabled. - * @hide - */ - public static final String MAINTAIN_LOCATION_AFTER_SP_DISABLED = "0"; - - /** - * Indicates location should be reenabled after sensor privacy is disabled. - * @hide - */ - public static final String REENABLE_LOCATION_AFTER_SP_DISABLED = "1"; - - /** - * Indicates the state of airplane mode should be maintained after sensor privacy is - * disabled. - * @hide - */ - public static final String MAINTAIN_AIRPLANE_MODE_AFTER_SP_DISABLED = "0"; - - /** - * Indicates airplane mode should be disabled after sensor privacy is disabled. - * @hide - */ - public static final String DISABLE_AIRPLANE_MODE_AFTER_SP_DISABLED = "1"; - - /** - * The state of all sensors managed by SensorPrivacyService when sensor privacy is enabled. - * @hide - */ - public static final String SENSOR_PRIVACY_SENSOR_STATE = - "sensor_privacy_sensor_state"; - - /** * Setting to determine whether to use the new notification priority handling features. * @hide */ @@ -8750,7 +8728,6 @@ public final class Settings { DISPLAY_WHITE_BALANCE_ENABLED, SYNC_PARENT_SOUNDS, CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, - SWIPE_UP_TO_SWITCH_APPS_ENABLED, CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, SYSTEM_NAVIGATION_KEYS_ENABLED, QS_TILES, @@ -8913,8 +8890,6 @@ public final class Settings { VALIDATORS.put(SYNC_PARENT_SOUNDS, SYNC_PARENT_SOUNDS_VALIDATOR); VALIDATORS.put(CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED_VALIDATOR); - VALIDATORS.put(SWIPE_UP_TO_SWITCH_APPS_ENABLED, - SWIPE_UP_TO_SWITCH_APPS_ENABLED_VALIDATOR); VALIDATORS.put(CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED_VALIDATOR); VALIDATORS.put(SYSTEM_NAVIGATION_KEYS_ENABLED, @@ -12612,12 +12587,11 @@ public final class Settings { /** * Battery level [1-100] at which low power mode automatically turns on. * If 0, it will not automatically turn on. For Q and newer, it will only automatically - * turn on if the value is greater than 0 and the {@link #AUTOMATIC_POWER_SAVER_MODE} + * turn on if the value is greater than 0 and the {@link #AUTOMATIC_POWER_SAVE_MODE} * setting is also set to - * {@link android.os.PowerManager.AutoPowerSaverMode#POWER_SAVER_MODE_PERCENTAGE}. - * - * @see #AUTOMATIC_POWER_SAVER_MODE - * @see android.os.PowerManager#getPowerSaveMode() + * {@link android.os.PowerManager.AutoPowerSaveMode#POWER_SAVE_MODE_TRIGGER_PERCENTAGE}. + * @see #AUTOMATIC_POWER_SAVE_MODE + * @see android.os.PowerManager#getPowerSaveModeTrigger() * @hide */ public static final String LOW_POWER_MODE_TRIGGER_LEVEL = "low_power_trigger_level"; @@ -12627,22 +12601,22 @@ public final class Settings { /** * Whether battery saver is currently set to trigger based on percentage, dynamic power - * savings trigger, or none. See {@link android.os.PowerManager.AutoPowerSaverMode} for + * savings trigger, or none. See {@link AutoPowerSaveModeTriggers} for * accepted values. * * @hide */ @TestApi - public static final String AUTOMATIC_POWER_SAVER_MODE = "automatic_power_saver_mode"; + public static final String AUTOMATIC_POWER_SAVE_MODE = "automatic_power_save_mode"; - private static final Validator AUTOMATIC_POWER_SAVER_MODE_VALIDATOR = + private static final Validator AUTOMATIC_POWER_SAVE_MODE_VALIDATOR = new SettingsValidators.DiscreteValueValidator(new String[] {"0", "1"}); /** * The setting that backs the disable threshold for the setPowerSavingsWarning api in * PowerManager * - * @see android.os.PowerManager#setDynamicPowerSavings(boolean, int) + * @see android.os.PowerManager#setDynamicPowerSaveHint(boolean, int) * @hide */ @TestApi @@ -12652,9 +12626,9 @@ public final class Settings { new SettingsValidators.InclusiveIntegerRangeValidator(0, 100); /** - * The setting which backs the setDynamicPowerSavings api in PowerManager. + * The setting which backs the setDynamicPowerSaveHint api in PowerManager. * - * @see android.os.PowerManager#setDynamicPowerSavings(boolean, int) + * @see android.os.PowerManager#setDynamicPowerSaveHint(boolean, int) * @hide */ @TestApi @@ -13643,7 +13617,7 @@ public final class Settings { VALIDATORS.put(LOW_POWER_MODE_TRIGGER_LEVEL, LOW_POWER_MODE_TRIGGER_LEVEL_VALIDATOR); VALIDATORS.put(LOW_POWER_MODE_TRIGGER_LEVEL_MAX, LOW_POWER_MODE_TRIGGER_LEVEL_VALIDATOR); - VALIDATORS.put(AUTOMATIC_POWER_SAVER_MODE, AUTOMATIC_POWER_SAVER_MODE_VALIDATOR); + VALIDATORS.put(AUTOMATIC_POWER_SAVE_MODE, AUTOMATIC_POWER_SAVE_MODE_VALIDATOR); VALIDATORS.put(DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, DYNAMIC_POWER_SAVINGS_VALIDATOR); VALIDATORS.put(BLUETOOTH_ON, BLUETOOTH_ON_VALIDATOR); diff --git a/core/java/android/service/appprediction/AppPredictionService.java b/core/java/android/service/appprediction/AppPredictionService.java index ff13e0361ab8..c1323bc8fd4c 100644 --- a/core/java/android/service/appprediction/AppPredictionService.java +++ b/core/java/android/service/appprediction/AppPredictionService.java @@ -86,11 +86,12 @@ public abstract class AppPredictionService extends Service { } @Override - public void notifyLocationShown(AppPredictionSessionId sessionId, String launchLocation, - ParceledListSlice targetIds) { + public void notifyLaunchLocationShown(AppPredictionSessionId sessionId, + String launchLocation, ParceledListSlice targetIds) { mHandler.sendMessage( - obtainMessage(AppPredictionService::onLocationShown, AppPredictionService.this, - sessionId, launchLocation, targetIds.getList())); + obtainMessage(AppPredictionService::onLaunchLocationShown, + AppPredictionService.this, sessionId, launchLocation, + targetIds.getList())); } @Override @@ -158,7 +159,7 @@ public abstract class AppPredictionService extends Service { * Called by a client app to indication a particular location has been shown to the user. */ @MainThread - public abstract void onLocationShown(@NonNull AppPredictionSessionId sessionId, + public abstract void onLaunchLocationShown(@NonNull AppPredictionSessionId sessionId, @NonNull String launchLocation, @NonNull List<AppTargetId> targetIds); private void doCreatePredictionSession(@NonNull AppPredictionContext context, diff --git a/core/java/android/service/appprediction/IPredictionService.aidl b/core/java/android/service/appprediction/IPredictionService.aidl index 3a6d1666f4b9..0f3df8561743 100644 --- a/core/java/android/service/appprediction/IPredictionService.aidl +++ b/core/java/android/service/appprediction/IPredictionService.aidl @@ -35,7 +35,7 @@ oneway interface IPredictionService { void notifyAppTargetEvent(in AppPredictionSessionId sessionId, in AppTargetEvent event); - void notifyLocationShown(in AppPredictionSessionId sessionId, in String launchLocation, + void notifyLaunchLocationShown(in AppPredictionSessionId sessionId, in String launchLocation, in ParceledListSlice targetIds); void sortAppTargets(in AppPredictionSessionId sessionId, in ParceledListSlice targets, diff --git a/core/java/android/service/attention/AttentionService.java b/core/java/android/service/attention/AttentionService.java index 32f4ea9a23ed..6172ce501590 100644 --- a/core/java/android/service/attention/AttentionService.java +++ b/core/java/android/service/attention/AttentionService.java @@ -21,11 +21,13 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.app.Service; +import android.attention.AttentionManagerInternal; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; import com.android.internal.util.Preconditions; +import com.android.server.LocalServices; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -38,7 +40,7 @@ import java.lang.annotation.RetentionPolicy; * The system's default AttentionService implementation is configured in * {@code config_AttentionComponent}. If this config has no value, a stub is returned. * - * See: {@link AttentionManagerService}. + * See: {@link com.android.server.attention.AttentionManagerService}. * * <pre> * {@literal @@ -65,14 +67,20 @@ public abstract class AttentionService extends Service { /** Attention is present. */ public static final int ATTENTION_SUCCESS_PRESENT = 1; + /** Unknown reasons for failing to determine the attention. */ + public static final int ATTENTION_FAILURE_UNKNOWN = 2; + + /** Request has been cancelled. */ + public static final int ATTENTION_FAILURE_CANCELLED = 3; + /** Preempted by other client. */ - public static final int ATTENTION_FAILURE_PREEMPTED = 2; + public static final int ATTENTION_FAILURE_PREEMPTED = 4; /** Request timed out. */ - public static final int ATTENTION_FAILURE_TIMED_OUT = 3; + public static final int ATTENTION_FAILURE_TIMED_OUT = 5; - /** Unknown reasons for failing to determine the attention. */ - public static final int ATTENTION_FAILURE_UNKNOWN = 4; + /** Camera permission is not granted. */ + public static final int ATTENTION_FAILURE_CAMERA_PERMISSION_ABSENT = 6; /** * Result codes for when attention check was successful. @@ -90,8 +98,9 @@ public abstract class AttentionService extends Service { * * @hide */ - @IntDef(prefix = {"ATTENTION_FAILURE_"}, value = {ATTENTION_FAILURE_PREEMPTED, - ATTENTION_FAILURE_TIMED_OUT, ATTENTION_FAILURE_UNKNOWN}) + @IntDef(prefix = {"ATTENTION_FAILURE_"}, value = {ATTENTION_FAILURE_UNKNOWN, + ATTENTION_FAILURE_CANCELLED, ATTENTION_FAILURE_PREEMPTED, ATTENTION_FAILURE_TIMED_OUT, + ATTENTION_FAILURE_CAMERA_PERMISSION_ABSENT}) @Retention(RetentionPolicy.SOURCE) public @interface AttentionFailureCodes { } @@ -100,15 +109,16 @@ public abstract class AttentionService extends Service { /** {@inheritDoc} */ @Override - public void checkAttention(int requestCode, IAttentionCallback callback) { + public void checkAttention(IAttentionCallback callback) { Preconditions.checkNotNull(callback); - AttentionService.this.onCheckAttention(requestCode, new AttentionCallback(callback)); + AttentionService.this.onCheckAttention(new AttentionCallback(callback)); } /** {@inheritDoc} */ @Override - public void cancelAttentionCheck(int requestCode) { - AttentionService.this.onCancelAttentionCheck(requestCode); + public void cancelAttentionCheck(IAttentionCallback callback) { + Preconditions.checkNotNull(callback); + AttentionService.this.onCancelAttentionCheck(new AttentionCallback(callback)); } }; @@ -122,38 +132,58 @@ public abstract class AttentionService extends Service { } /** - * Checks the user attention and calls into the provided callback. + * Disables the dependants. * - * @param requestCode an identifier that could be used to cancel the request - * @param callback the callback to return the result to + * Example: called if the service does not have sufficient permissions to perform the task. */ - public abstract void onCheckAttention(int requestCode, @NonNull AttentionCallback callback); + public final void disableSelf() { + AttentionManagerInternal attentionManager = LocalServices.getService( + AttentionManagerInternal.class); + if (attentionManager != null) { + attentionManager.disableSelf(); + } + } - /** Cancels the attention check for a given request code. */ - public abstract void onCancelAttentionCheck(int requestCode); + /** + * Checks the user attention and calls into the provided callback. + * + * @param callback the callback to return the result to + */ + public abstract void onCheckAttention(@NonNull AttentionCallback callback); + /** + * Cancels pending work for a given callback. + * + * Implementation must call back with a failure code of {@link #ATTENTION_FAILURE_CANCELLED}. + */ + public abstract void onCancelAttentionCheck(@NonNull AttentionCallback callback); /** Callbacks for AttentionService results. */ public static final class AttentionCallback { - private final IAttentionCallback mCallback; + @NonNull private final IAttentionCallback mCallback; - private AttentionCallback(IAttentionCallback callback) { + private AttentionCallback(@NonNull IAttentionCallback callback) { mCallback = callback; } - /** Returns the result. */ - public void onSuccess(int requestCode, @AttentionSuccessCodes int result, long timestamp) { + /** + * Signals a success and provides the result code. + * + * @param timestamp of when the attention signal was computed; system throttles the requests + * so this is useful to know how fresh the result is. + */ + public void onSuccess(@AttentionSuccessCodes int result, long timestamp) { try { - mCallback.onSuccess(requestCode, result, timestamp); + mCallback.onSuccess(result, timestamp); } catch (RemoteException e) { e.rethrowFromSystemServer(); } } - /** Signals a failure. */ - public void onFailure(int requestCode, @AttentionFailureCodes int error) { + /** Signals a failure and provides the error code. */ + public void onFailure(@AttentionFailureCodes int error) { try { - mCallback.onFailure(requestCode, error); + mCallback.onFailure(error); } catch (RemoteException e) { e.rethrowFromSystemServer(); } diff --git a/core/java/android/service/attention/IAttentionCallback.aidl b/core/java/android/service/attention/IAttentionCallback.aidl index 0e8a1e75c14b..f65b9c095428 100644 --- a/core/java/android/service/attention/IAttentionCallback.aidl +++ b/core/java/android/service/attention/IAttentionCallback.aidl @@ -22,6 +22,6 @@ package android.service.attention; * @hide */ oneway interface IAttentionCallback { - void onSuccess(int requestCode, int result, long timestamp); - void onFailure(int requestCode, int error); + void onSuccess(int result, long timestamp); + void onFailure(int error); } diff --git a/core/java/android/service/attention/IAttentionService.aidl b/core/java/android/service/attention/IAttentionService.aidl index c3b6f48a5b2e..99e79973cfd2 100644 --- a/core/java/android/service/attention/IAttentionService.aidl +++ b/core/java/android/service/attention/IAttentionService.aidl @@ -24,6 +24,6 @@ import android.service.attention.IAttentionCallback; * @hide */ oneway interface IAttentionService { - void checkAttention(int requestCode, IAttentionCallback callback); - void cancelAttentionCheck(int requestCode); + void checkAttention(IAttentionCallback callback); + void cancelAttentionCheck(IAttentionCallback callback); }
\ No newline at end of file diff --git a/core/java/android/service/contentcapture/ContentCaptureService.java b/core/java/android/service/contentcapture/ContentCaptureService.java index df113979bacf..fb07abaa34a1 100644 --- a/core/java/android/service/contentcapture/ContentCaptureService.java +++ b/core/java/android/service/contentcapture/ContentCaptureService.java @@ -298,12 +298,12 @@ public abstract class ContentCaptureService extends Service { /** * Disables the Content Capture service for the given user. */ - public final void disableContentCaptureServices() { - if (sDebug) Log.d(TAG, "disableContentCaptureServices()"); + public final void disableSelf() { + if (sDebug) Log.d(TAG, "disableSelf()"); final IContentCaptureServiceCallback callback = mCallback; if (callback == null) { - Log.w(TAG, "disableContentCaptureServices(): no server callback"); + Log.w(TAG, "disableSelf(): no server callback"); return; } try { @@ -367,7 +367,6 @@ public abstract class ContentCaptureService extends Service { stateFlags = initialState; } else { stateFlags |= ContentCaptureSession.STATE_DISABLED; - } setClientState(clientReceiver, stateFlags, mClientInterface.asBinder()); } diff --git a/core/java/android/service/contentcapture/ContentCaptureServiceInfo.java b/core/java/android/service/contentcapture/ContentCaptureServiceInfo.java index 6ecd82f50fdb..fb6061916d99 100644 --- a/core/java/android/service/contentcapture/ContentCaptureServiceInfo.java +++ b/core/java/android/service/contentcapture/ContentCaptureServiceInfo.java @@ -139,6 +139,7 @@ public final class ContentCaptureServiceInfo { mSettingsActivity = settingsActivity; } + @NonNull public ServiceInfo getServiceInfo() { return mServiceInfo; } diff --git a/core/java/android/service/notification/NotificationAssistantService.java b/core/java/android/service/notification/NotificationAssistantService.java index a1932b8861b0..b81725d99d2b 100644 --- a/core/java/android/service/notification/NotificationAssistantService.java +++ b/core/java/android/service/notification/NotificationAssistantService.java @@ -234,7 +234,7 @@ public abstract class NotificationAssistantService extends NotificationListenerS public final void adjustNotification(@NonNull Adjustment adjustment) { if (!isBound()) return; try { - getNotificationInterface().applyAdjustmentFromAssistant(mWrapper, adjustment); + getNotificationInterface().applyEnqueuedAdjustmentFromAssistant(mWrapper, adjustment); } catch (android.os.RemoteException ex) { Log.v(TAG, "Unable to contact notification manager", ex); throw ex.rethrowFromSystemServer(); diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index 23607ebe78fe..333868a2f08a 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -476,7 +476,7 @@ public abstract class NotificationListenerService extends Service { * @param hideSilentStatusIcons whether or not status bar icons should be hidden for silent * notifications */ - public void onStatusBarIconsBehaviorChanged(boolean hideSilentStatusIcons) { + public void onSilentStatusBarIconsVisibilityChanged(boolean hideSilentStatusIcons) { // optional } @@ -2255,7 +2255,7 @@ public abstract class NotificationListenerService extends Service { } break; case MSG_ON_STATUS_BAR_ICON_BEHAVIOR_CHANGED: { - onStatusBarIconsBehaviorChanged((Boolean) msg.obj); + onSilentStatusBarIconsVisibilityChanged((Boolean) msg.obj); } break; } } diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index c042a8c8ae1c..e1762dffeef5 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -320,7 +320,7 @@ public abstract class WallpaperService extends Service { public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, MergedConfiguration mergedConfiguration, Rect backDropRect, boolean forceLayout, - boolean alwaysConsumeNavBar, int displayId, + boolean alwaysConsumeSystemBars, int displayId, DisplayCutout.ParcelableWrapper displayCutout) { Message msg = mCaller.obtainMessageIO(MSG_WINDOW_RESIZED, reportDraw ? 1 : 0, outsets); diff --git a/core/java/android/service/watchdog/ExplicitHealthCheckService.java b/core/java/android/service/watchdog/ExplicitHealthCheckService.java new file mode 100644 index 000000000000..015fba19d785 --- /dev/null +++ b/core/java/android/service/watchdog/ExplicitHealthCheckService.java @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.service.watchdog; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SdkConstant; +import android.annotation.SystemApi; +import android.app.Service; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.IBinder; +import android.os.Looper; +import android.os.RemoteCallback; +import android.os.RemoteException; +import android.util.Log; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * A service to provide packages supporting explicit health checks and route checks to these + * packages on behalf of the package watchdog. + * + * <p>To extend this class, you must declare the service in your manifest file with the + * {@link android.Manifest.permission#BIND_EXPLICIT_HEALTH_CHECK_SERVICE} permission, + * and include an intent filter with the {@link #SERVICE_INTERFACE} action. In adddition, + * your implementation must live in {@link PackageManger#SYSTEM_SHARED_LIBRARY_SERVICES}. + * For example:</p> + * <pre> + * <service android:name=".FooExplicitHealthCheckService" + * android:exported="true" + * android:priority="100" + * android:permission="android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE"> + * <intent-filter> + * <action android:name="android.service.watchdog.ExplicitHealthCheckService" /> + * </intent-filter> + * </service> + * </pre> + * @hide + */ +@SystemApi +public abstract class ExplicitHealthCheckService extends Service { + + private static final String TAG = "ExplicitHealthCheckService"; + + /** + * {@link Bundle} key for a {@link List} of {@link String} value. + * + * {@hide} + */ + public static final String EXTRA_SUPPORTED_PACKAGES = + "android.service.watchdog.extra.supported_packages"; + + /** + * {@link Bundle} key for a {@link List} of {@link String} value. + * + * {@hide} + */ + public static final String EXTRA_REQUESTED_PACKAGES = + "android.service.watchdog.extra.requested_packages"; + + /** + * {@link Bundle} key for a {@link String} value. + * + * {@hide} + */ + public static final String EXTRA_HEALTH_CHECK_PASSED_PACKAGE = + "android.service.watchdog.extra.health_check_passed_package"; + + /** + * 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.watchdog.ExplicitHealthCheckService"; + + /** + * 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_EXPLICIT_HEALTH_CHECK_SERVICE"; + + private final ExplicitHealthCheckServiceWrapper mWrapper = + new ExplicitHealthCheckServiceWrapper(); + + /** + * Called when the system requests an explicit health check for {@code packageName}. + * + * <p> When {@code packageName} passes the check, implementors should call + * {@link #notifyHealthCheckPassed} to inform the system. + * + * <p> It could take many hours before a {@code packageName} passes a check and implementors + * should never drop requests unless {@link onCancel} is called or the service dies. + * + * <p> Requests should not be queued and additional calls while expecting a result for + * {@code packageName} should have no effect. + */ + public abstract void onRequestHealthCheck(@NonNull String packageName); + + /** + * Called when the system cancels the explicit health check request for {@code packageName}. + * Should do nothing if there are is no active request for {@code packageName}. + */ + public abstract void onCancelHealthCheck(@NonNull String packageName); + + /** + * Called when the system requests for all the packages supporting explicit health checks. The + * system may request an explicit health check for any of these packages with + * {@link #onRequestHealthCheck}. + * + * @return all packages supporting explicit health checks + */ + @NonNull public abstract List<String> onGetSupportedPackages(); + + /** + * Called when the system requests for all the packages that it has currently requested + * an explicit health check for. + * + * @return all packages expecting an explicit health check result + */ + @NonNull public abstract List<String> onGetRequestedPackages(); + + private final Handler mHandler = new Handler(Looper.getMainLooper(), null, true); + @Nullable private RemoteCallback mCallback; + + @Override + @NonNull + public final IBinder onBind(@NonNull Intent intent) { + return mWrapper; + } + + /** + * Implementors should call this to notify the system when explicit health check passes + * for {@code packageName}; + */ + public final void notifyHealthCheckPassed(@NonNull String packageName) { + mHandler.post(() -> { + if (mCallback != null) { + Objects.requireNonNull(packageName, + "Package passing explicit health check must be non-null"); + Bundle bundle = new Bundle(); + bundle.putString(EXTRA_HEALTH_CHECK_PASSED_PACKAGE, packageName); + mCallback.sendResult(bundle); + } else { + Log.wtf(TAG, "System missed explicit health check result for " + packageName); + } + }); + } + + private class ExplicitHealthCheckServiceWrapper extends IExplicitHealthCheckService.Stub { + @Override + public void setCallback(RemoteCallback callback) throws RemoteException { + mHandler.post(() -> { + mCallback = callback; + }); + } + + @Override + public void request(String packageName) throws RemoteException { + mHandler.post(() -> ExplicitHealthCheckService.this.onRequestHealthCheck(packageName)); + } + + @Override + public void cancel(String packageName) throws RemoteException { + mHandler.post(() -> ExplicitHealthCheckService.this.onCancelHealthCheck(packageName)); + } + + @Override + public void getSupportedPackages(RemoteCallback callback) throws RemoteException { + mHandler.post(() -> sendPackages(callback, EXTRA_SUPPORTED_PACKAGES, + ExplicitHealthCheckService.this.onGetSupportedPackages())); + } + + @Override + public void getRequestedPackages(RemoteCallback callback) throws RemoteException { + mHandler.post(() -> sendPackages(callback, EXTRA_REQUESTED_PACKAGES, + ExplicitHealthCheckService.this.onGetRequestedPackages())); + } + + private void sendPackages(RemoteCallback callback, String key, List<String> packages) { + Objects.requireNonNull(packages, + "Supported and requested package list must be non-null"); + Bundle bundle = new Bundle(); + bundle.putStringArrayList(key, new ArrayList<>(packages)); + callback.sendResult(bundle); + } + } +} diff --git a/core/java/android/service/watchdog/IExplicitHealthCheckService.aidl b/core/java/android/service/watchdog/IExplicitHealthCheckService.aidl new file mode 100644 index 000000000000..78c0328d36f0 --- /dev/null +++ b/core/java/android/service/watchdog/IExplicitHealthCheckService.aidl @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.service.watchdog; + +import android.os.RemoteCallback; + +/** + * @hide + */ +oneway interface IExplicitHealthCheckService +{ + void setCallback(in @nullable RemoteCallback callback); + void request(String packageName); + void cancel(String packageName); + void getSupportedPackages(in RemoteCallback callback); + void getRequestedPackages(in RemoteCallback callback); +} diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java index de10ffb80bee..da6ef4cb591e 100644 --- a/core/java/android/util/FeatureFlagUtils.java +++ b/core/java/android/util/FeatureFlagUtils.java @@ -52,14 +52,14 @@ public class FeatureFlagUtils { DEFAULT_FLAGS.put("settings_slice_injection", "true"); DEFAULT_FLAGS.put("settings_systemui_theme", "true"); DEFAULT_FLAGS.put("settings_mainline_module", "true"); - DEFAULT_FLAGS.put("settings_dynamic_android", "false"); + DEFAULT_FLAGS.put("settings_dynamic_system", "false"); DEFAULT_FLAGS.put(SEAMLESS_TRANSFER, "false"); DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "false"); DEFAULT_FLAGS.put(SAFETY_HUB, "false"); DEFAULT_FLAGS.put(SCREENRECORD_LONG_PRESS, "false"); DEFAULT_FLAGS.put(GLOBAL_ACTIONS_GRID_ENABLED, "true"); DEFAULT_FLAGS.put(GLOBAL_ACTIONS_PANEL_ENABLED, "true"); - DEFAULT_FLAGS.put("settings_wifi_details_saved_screen", "false"); + DEFAULT_FLAGS.put("settings_wifi_details_saved_screen", "true"); DEFAULT_FLAGS.put("settings_wifi_details_datausage_header", "false"); } diff --git a/core/java/android/util/StatsLog.java b/core/java/android/util/StatsLog.java index bf46e95c7b09..30d3d7d069b5 100644 --- a/core/java/android/util/StatsLog.java +++ b/core/java/android/util/StatsLog.java @@ -22,6 +22,7 @@ import static android.Manifest.permission.PACKAGE_USAGE_STATS; import android.Manifest; import android.annotation.NonNull; import android.annotation.RequiresPermission; +import android.annotation.SystemApi; import android.app.IActivityManager; import android.content.Context; import android.os.IStatsManager; @@ -199,6 +200,16 @@ public final class StatsLog extends StatsLogInternal { } } + /** + * Write an event to stats log using the raw format. + * + * @param buffer The encoded buffer of data to write.. + * @param size The number of bytes from the buffer to write. + * @hide + */ + @SystemApi + public static native void writeRaw(@NonNull byte[] buffer, int size); + private static void enforceDumpCallingPermission(Context context) { context.enforceCallingPermission(android.Manifest.permission.DUMP, "Need DUMP permission."); } diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java index f37c9162d98a..0051d01eec13 100644 --- a/core/java/android/view/AccessibilityInteractionController.java +++ b/core/java/android/view/AccessibilityInteractionController.java @@ -16,6 +16,7 @@ package android.view; +import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ARGUMENT_ACCESSIBLE_CLICKABLE_SPAN; import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_REQUESTED_KEY; import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY; @@ -797,11 +798,19 @@ public final class AccessibilityInteractionController { } Rect boundsInScreen = mTempRect; info.getBoundsInScreen(boundsInScreen); - if (interactiveRegion.quickReject(boundsInScreen)) { + if (interactiveRegion.quickReject(boundsInScreen) && !shouldBypassAdjustIsVisible()) { info.setVisibleToUser(false); } } + private boolean shouldBypassAdjustIsVisible() { + final int windowType = mViewRootImpl.mOrigWindowType; + if (windowType == TYPE_INPUT_METHOD) { + return true; + } + return false; + } + private void applyAppScaleAndMagnificationSpecIfNeeded(AccessibilityNodeInfo info, MagnificationSpec spec) { if (info == null) { diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl index c06a1fe0a257..699e795be980 100644 --- a/core/java/android/view/IWindow.aidl +++ b/core/java/android/view/IWindow.aidl @@ -53,7 +53,7 @@ oneway interface IWindow { void resized(in Rect frame, in Rect overscanInsets, in Rect contentInsets, in Rect visibleInsets, in Rect stableInsets, in Rect outsets, boolean reportDraw, in MergedConfiguration newMergedConfiguration, in Rect backDropFrame, - boolean forceLayout, boolean alwaysConsumeNavBar, int displayId, + boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId, in DisplayCutout.ParcelableWrapper displayCutout); /** diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index b91b93f7e09c..6c37319c6303 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -304,6 +304,16 @@ interface IWindowManager oneway void statusBarVisibilityChanged(int displayId, int visibility); /** + * When set to {@code true} the system bars will always be shown. This is true even if an app + * requests to be fullscreen by setting the system ui visibility flags. The + * functionality was added for the automotive case as a way to guarantee required content stays + * on screen at all times. + * + * @hide + */ + oneway void setForceShowSystemBars(boolean show); + + /** * Called by System UI to notify of changes to the visibility of Recents. */ oneway void setRecentsVisibility(boolean visible); diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index 08f2e8d87352..bf16e3dedd49 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -134,7 +134,7 @@ public class InsetsController implements WindowInsetsController { } WindowInsets insets = state.calculateInsets(mFrame, mLastInsets.isRound(), - mLastInsets.shouldAlwaysConsumeNavBar(), mLastInsets.getDisplayCutout(), + mLastInsets.shouldAlwaysConsumeSystemBars(), mLastInsets.getDisplayCutout(), mLastLegacyContentInsets, mLastLegacyStableInsets, mLastLegacySoftInputMode, null /* typeSideMap */); mViewRoot.mView.dispatchWindowInsetsAnimationProgress(insets); @@ -177,12 +177,12 @@ public class InsetsController implements WindowInsetsController { */ @VisibleForTesting public WindowInsets calculateInsets(boolean isScreenRound, - boolean alwaysConsumeNavBar, DisplayCutout cutout, Rect legacyContentInsets, + boolean alwaysConsumeSystemBars, DisplayCutout cutout, Rect legacyContentInsets, Rect legacyStableInsets, int legacySoftInputMode) { mLastLegacyContentInsets.set(legacyContentInsets); mLastLegacyStableInsets.set(legacyStableInsets); mLastLegacySoftInputMode = legacySoftInputMode; - mLastInsets = mState.calculateInsets(mFrame, isScreenRound, alwaysConsumeNavBar, cutout, + mLastInsets = mState.calculateInsets(mFrame, isScreenRound, alwaysConsumeSystemBars, cutout, legacyContentInsets, legacyStableInsets, legacySoftInputMode, null /* typeSideMap */); return mLastInsets; diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java index 6129b38104af..13b0cc038fce 100644 --- a/core/java/android/view/InsetsState.java +++ b/core/java/android/view/InsetsState.java @@ -17,9 +17,6 @@ package android.view; import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL; -import static android.view.ViewRootImpl.NEW_INSETS_MODE_IME; -import static android.view.ViewRootImpl.NEW_INSETS_MODE_NONE; -import static android.view.WindowInsets.Type.IME; import static android.view.WindowInsets.Type.SIZE; import static android.view.WindowInsets.Type.indexOf; @@ -31,7 +28,6 @@ import android.os.Parcel; import android.os.Parcelable; import android.util.ArrayMap; import android.util.ArraySet; -import android.util.SparseArray; import android.util.SparseIntArray; import android.view.WindowInsets.Type; import android.view.WindowInsets.Type.InsetType; @@ -40,7 +36,6 @@ import android.view.WindowManager.LayoutParams; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.util.ArrayList; import java.util.Objects; /** @@ -130,7 +125,7 @@ public class InsetsState implements Parcelable { * @return The calculated insets. */ public WindowInsets calculateInsets(Rect frame, boolean isScreenRound, - boolean alwaysConsumeNavBar, DisplayCutout cutout, + boolean alwaysConsumeSystemBars, DisplayCutout cutout, @Nullable Rect legacyContentInsets, @Nullable Rect legacyStableInsets, int legacySoftInputMode, @Nullable @InsetSide SparseIntArray typeSideMap) { Insets[] typeInsetsMap = new Insets[Type.SIZE]; @@ -180,7 +175,7 @@ public class InsetsState implements Parcelable { } } return new WindowInsets(typeInsetsMap, typeMaxInsetsMap, typeVisibilityMap, isScreenRound, - alwaysConsumeNavBar, cutout); + alwaysConsumeSystemBars, cutout); } private void processSource(InsetsSource source, Rect relativeFrame, boolean ignoreVisibility, diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index cd075bf65e4a..0043d3258772 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -88,10 +88,10 @@ public final class SurfaceControl implements Parcelable { private static native void nativeDestroy(long nativeObject); private static native void nativeDisconnect(long nativeObject); - private static native GraphicBuffer nativeScreenshot(IBinder displayToken, + private static native ScreenshotGraphicBuffer nativeScreenshot(IBinder displayToken, Rect sourceCrop, int width, int height, boolean useIdentityTransform, int rotation, boolean captureSecureLayers); - private static native GraphicBuffer nativeCaptureLayers(IBinder layerHandleToken, + private static native ScreenshotGraphicBuffer nativeCaptureLayers(IBinder layerHandleToken, Rect sourceCrop, float frameScale); private static native long nativeCreateTransaction(); @@ -431,7 +431,52 @@ public final class SurfaceControl implements Parcelable { public static final int METADATA_TASK_ID = 3; /** + * A wrapper around GraphicBuffer that contains extra information about how to + * interpret the screenshot GraphicBuffer. + * @hide + */ + public static class ScreenshotGraphicBuffer { + private final GraphicBuffer mGraphicBuffer; + private final ColorSpace mColorSpace; + + public ScreenshotGraphicBuffer(GraphicBuffer graphicBuffer, ColorSpace colorSpace) { + mGraphicBuffer = graphicBuffer; + mColorSpace = colorSpace; + } + + /** + * Create ScreenshotGraphicBuffer from existing native GraphicBuffer object. + * @param width The width in pixels of the buffer + * @param height The height in pixels of the buffer + * @param format The format of each pixel as specified in {@link PixelFormat} + * @param usage Hint indicating how the buffer will be used + * @param unwrappedNativeObject The native object of GraphicBuffer + * @param namedColorSpace Integer value of a named color space {@link ColorSpace.Named} + */ + private static ScreenshotGraphicBuffer createFromNative(int width, int height, int format, + int usage, long unwrappedNativeObject, int namedColorSpace) { + GraphicBuffer graphicBuffer = GraphicBuffer.createFromExisting(width, height, format, + usage, unwrappedNativeObject); + ColorSpace colorSpace = ColorSpace.get(ColorSpace.Named.values()[namedColorSpace]); + return new ScreenshotGraphicBuffer(graphicBuffer, colorSpace); + } + + public ColorSpace getColorSpace() { + return mColorSpace; + } + + public GraphicBuffer getGraphicBuffer() { + return mGraphicBuffer; + } + } + + /** * Builder class for {@link SurfaceControl} objects. + * + * By default the surface will be hidden, and have "unset" bounds, meaning it can + * be as large as the bounds of its parent if a buffer or child so requires. + * + * It is necessary to set at least a name via {@link Builder#setName} */ public static class Builder { private SurfaceSession mSession; @@ -466,11 +511,11 @@ public final class SurfaceControl implements Parcelable { @NonNull public SurfaceControl build() { if (mWidth < 0 || mHeight < 0) { - throw new IllegalArgumentException( + throw new IllegalStateException( "width and height must be positive or unset"); } if ((mWidth > 0 || mHeight > 0) && (isColorLayerSet() || isContainerLayerSet())) { - throw new IllegalArgumentException( + throw new IllegalStateException( "Only buffer layers can set a valid buffer size."); } return new SurfaceControl( @@ -860,7 +905,9 @@ public final class SurfaceControl implements Parcelable { * Release the local reference to the server-side surface. The surface * may continue to exist on-screen as long as its parent continues * to exist. To explicitly remove a surface from the screen use - * {@link Transaction#reparent} with a null-parent. + * {@link Transaction#reparent} with a null-parent. After release, + * {@link #isValid} will return false and other methods will throw + * an exception. * * Always call release() when you're done with a SurfaceControl. */ @@ -902,7 +949,8 @@ public final class SurfaceControl implements Parcelable { /** * Check whether this instance points to a valid layer with the system-compositor. For - * example this may be false if construction failed, or the layer was released. + * example this may be false if construction failed, or the layer was released + * ({@link #release}). * * @return Whether this SurfaceControl is valid. */ @@ -1815,10 +1863,10 @@ public final class SurfaceControl implements Parcelable { throw new IllegalArgumentException("consumer must not be null"); } - final GraphicBuffer buffer = screenshotToBuffer(display, sourceCrop, width, height, - useIdentityTransform, rotation); + final ScreenshotGraphicBuffer buffer = screenshotToBuffer(display, sourceCrop, width, + height, useIdentityTransform, rotation); try { - consumer.attachAndQueueBuffer(buffer); + consumer.attachAndQueueBuffer(buffer.getGraphicBuffer()); } catch (RuntimeException e) { Log.w(TAG, "Failed to take screenshot - " + e.getMessage()); } @@ -1861,17 +1909,16 @@ public final class SurfaceControl implements Parcelable { } SurfaceControl.rotateCropForSF(sourceCrop, rotation); - final GraphicBuffer buffer = screenshotToBuffer(displayToken, sourceCrop, width, height, - useIdentityTransform, rotation); + final ScreenshotGraphicBuffer buffer = screenshotToBuffer(displayToken, sourceCrop, width, + height, useIdentityTransform, rotation); if (buffer == null) { Log.w(TAG, "Failed to take screenshot"); return null; } - // TODO(b/116112787) Now that hardware bitmap creation can take color space, we - // should continue to fix screenshot. - return Bitmap.wrapHardwareBuffer(HardwareBuffer.createFromGraphicBuffer(buffer), - ColorSpace.get(ColorSpace.Named.SRGB)); + return Bitmap.wrapHardwareBuffer( + HardwareBuffer.createFromGraphicBuffer(buffer.getGraphicBuffer()), + buffer.getColorSpace()); } /** @@ -1897,8 +1944,8 @@ public final class SurfaceControl implements Parcelable { * @return Returns a GraphicBuffer that contains the captured content. * @hide */ - public static GraphicBuffer screenshotToBuffer(IBinder display, Rect sourceCrop, int width, - int height, boolean useIdentityTransform, int rotation) { + public static ScreenshotGraphicBuffer screenshotToBuffer(IBinder display, Rect sourceCrop, + int width, int height, boolean useIdentityTransform, int rotation) { if (display == null) { throw new IllegalArgumentException("displayToken must not be null"); } @@ -1917,7 +1964,7 @@ public final class SurfaceControl implements Parcelable { * * @hide */ - public static GraphicBuffer screenshotToBufferWithSecureLayersUnsafe(IBinder display, + public static ScreenshotGraphicBuffer screenshotToBufferWithSecureLayersUnsafe(IBinder display, Rect sourceCrop, int width, int height, boolean useIdentityTransform, int rotation) { if (display == null) { @@ -1951,7 +1998,7 @@ public final class SurfaceControl implements Parcelable { * @return Returns a GraphicBuffer that contains the layer capture. * @hide */ - public static GraphicBuffer captureLayers(IBinder layerHandleToken, Rect sourceCrop, + public static ScreenshotGraphicBuffer captureLayers(IBinder layerHandleToken, Rect sourceCrop, float frameScale) { return nativeCaptureLayers(layerHandleToken, sourceCrop, frameScale); } @@ -2042,8 +2089,7 @@ public final class SurfaceControl implements Parcelable { } /** - * Close the transaction, if the transaction was not already applied this will cancel the - * transaction. + * Release the native transaction object, without applying it. */ @Override public void close() { @@ -2128,8 +2174,8 @@ public final class SurfaceControl implements Parcelable { } /** - * Set the default buffer size for the SurfaceControl, if there is an - * {@link Surface} assosciated with the control, then + * Set the default buffer size for the SurfaceControl, if there is a + * {@link Surface} associated with the control, then * this will be the default size for buffers dequeued from it. * @param sc The surface to set the buffer size for. * @param w The default width diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index ee8d66313ea2..e931448652c0 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -491,7 +491,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb if (mBackgroundControl == null) { return; } - if ((mSurfaceFlags & SurfaceControl.OPAQUE) != 0) { + if ((mSubLayer > 0) && ((mSurfaceFlags & SurfaceControl.OPAQUE) != 0)) { mBackgroundControl.show(); mBackgroundControl.setLayer(Integer.MIN_VALUE); } else { diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 75067d3668b3..2357db46771a 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -28200,11 +28200,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, final Rect mOutsets = new Rect(); /** - * In multi-window we force show the navigation bar. Because we don't want that the surface - * size changes in this mode, we instead have a flag whether the navigation bar size should - * always be consumed, so the app is treated like there is no virtual navigation bar at all. + * In multi-window we force show the system bars. Because we don't want that the surface + * size changes in this mode, we instead have a flag whether the system bars sizes should + * always be consumed, so the app is treated like there are no virtual system bars at all. */ - boolean mAlwaysConsumeNavBar; + boolean mAlwaysConsumeSystemBars; /** * The internal insets given by this window. This value is diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index a4d80dcfe7d2..4851476e3d70 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -142,7 +142,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * This field should be made private, so it is hidden from the SDK. * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768704) protected OnHierarchyChangeListener mOnHierarchyChangeListener; // The view contained within this ViewGroup that has or contains focus. @@ -239,7 +239,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager @ViewDebug.FlagToString(mask = FLAG_PADDING_NOT_NULL, equals = FLAG_PADDING_NOT_NULL, name = "PADDING_NOT_NULL") }, formatToHexString = true) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769411) protected int mGroupFlags; /** @@ -300,7 +300,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769377) protected static final int FLAG_USE_CHILD_DRAWING_ORDER = 0x400; /** @@ -314,7 +314,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769647) protected static final int FLAG_SUPPORT_STATIC_TRANSFORMATIONS = 0x800; // UNUSED FLAG VALUE: 0x1000; @@ -368,7 +368,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * When set, this ViewGroup should not intercept touch events. * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123983692) protected static final int FLAG_DISALLOW_INTERCEPT = 0x80000; /** diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 6d04cd3187ef..2880e7f13545 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -512,7 +512,7 @@ public final class ViewRootImpl implements ViewParent, final Rect mPendingBackDropFrame = new Rect(); final DisplayCutout.ParcelableWrapper mPendingDisplayCutout = new DisplayCutout.ParcelableWrapper(DisplayCutout.NO_CUTOUT); - boolean mPendingAlwaysConsumeNavBar; + boolean mPendingAlwaysConsumeSystemBars; private InsetsState mTempInsets = new InsetsState(); final ViewTreeObserver.InternalInsetsInfo mLastGivenInsets = new ViewTreeObserver.InternalInsetsInfo(); @@ -921,9 +921,9 @@ public final class ViewRootImpl implements ViewParent, mPendingStableInsets.set(mAttachInfo.mStableInsets); mPendingDisplayCutout.set(mAttachInfo.mDisplayCutout); mPendingVisibleInsets.set(0, 0, 0, 0); - mAttachInfo.mAlwaysConsumeNavBar = - (res & WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_NAV_BAR) != 0; - mPendingAlwaysConsumeNavBar = mAttachInfo.mAlwaysConsumeNavBar; + mAttachInfo.mAlwaysConsumeSystemBars = + (res & WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_SYSTEM_BARS) != 0; + mPendingAlwaysConsumeSystemBars = mAttachInfo.mAlwaysConsumeSystemBars; mInsetsController.onStateChanged(mTempInsets); if (DEBUG_LAYOUT) Log.v(mTag, "Added window " + mWindow); if (res < WindowManagerGlobal.ADD_OKAY) { @@ -1918,12 +1918,12 @@ public final class ViewRootImpl implements ViewParent, if (sNewInsetsMode != NEW_INSETS_MODE_NONE) { mLastWindowInsets = mInsetsController.calculateInsets( mContext.getResources().getConfiguration().isScreenRound(), - mAttachInfo.mAlwaysConsumeNavBar, displayCutout, + mAttachInfo.mAlwaysConsumeSystemBars, displayCutout, contentInsets, stableInsets, mWindowAttributes.softInputMode); } else { mLastWindowInsets = new WindowInsets(contentInsets, stableInsets, mContext.getResources().getConfiguration().isScreenRound(), - mAttachInfo.mAlwaysConsumeNavBar, displayCutout); + mAttachInfo.mAlwaysConsumeSystemBars, displayCutout); } } return mLastWindowInsets; @@ -2126,7 +2126,7 @@ public final class ViewRootImpl implements ViewParent, if (!mPendingOutsets.equals(mAttachInfo.mOutsets)) { insetsChanged = true; } - if (mPendingAlwaysConsumeNavBar != mAttachInfo.mAlwaysConsumeNavBar) { + if (mPendingAlwaysConsumeSystemBars != mAttachInfo.mAlwaysConsumeSystemBars) { insetsChanged = true; } if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT @@ -2326,8 +2326,8 @@ public final class ViewRootImpl implements ViewParent, final boolean surfaceSizeChanged = (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED) != 0; surfaceChanged |= surfaceSizeChanged; - final boolean alwaysConsumeNavBarChanged = - mPendingAlwaysConsumeNavBar != mAttachInfo.mAlwaysConsumeNavBar; + final boolean alwaysConsumeSystemBarsChanged = + mPendingAlwaysConsumeSystemBars != mAttachInfo.mAlwaysConsumeSystemBars; final boolean colorModeChanged = hasColorModeChanged(lp.getColorMode()); if (contentInsetsChanged) { mAttachInfo.mContentInsets.set(mPendingContentInsets); @@ -2356,8 +2356,8 @@ public final class ViewRootImpl implements ViewParent, // Need to relayout with content insets. contentInsetsChanged = true; } - if (alwaysConsumeNavBarChanged) { - mAttachInfo.mAlwaysConsumeNavBar = mPendingAlwaysConsumeNavBar; + if (alwaysConsumeSystemBarsChanged) { + mAttachInfo.mAlwaysConsumeSystemBars = mPendingAlwaysConsumeSystemBars; contentInsetsChanged = true; } if (contentInsetsChanged || mLastSystemUiVisibility != @@ -4633,7 +4633,7 @@ public final class ViewRootImpl implements ViewParent, mPendingOutsets.set((Rect) args.arg7); mPendingBackDropFrame.set((Rect) args.arg8); mForceNextWindowRelayout = args.argi1 != 0; - mPendingAlwaysConsumeNavBar = args.argi2 != 0; + mPendingAlwaysConsumeSystemBars = args.argi2 != 0; args.recycle(); @@ -7084,8 +7084,8 @@ public final class ViewRootImpl implements ViewParent, destroySurface(); } - mPendingAlwaysConsumeNavBar = - (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_NAV_BAR) != 0; + mPendingAlwaysConsumeSystemBars = + (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS) != 0; if (restore) { params.restore(); @@ -7374,7 +7374,7 @@ public final class ViewRootImpl implements ViewParent, private void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout, - boolean alwaysConsumeNavBar, int displayId, + boolean alwaysConsumeSystemBars, int displayId, DisplayCutout.ParcelableWrapper displayCutout) { if (DEBUG_LAYOUT) Log.v(mTag, "Resizing " + this + ": frame=" + frame.toShortString() + " contentInsets=" + contentInsets.toShortString() @@ -7414,7 +7414,7 @@ public final class ViewRootImpl implements ViewParent, args.arg8 = sameProcessCall ? new Rect(backDropFrame) : backDropFrame; args.arg9 = displayCutout.get(); // DisplayCutout is immutable. args.argi1 = forceLayout ? 1 : 0; - args.argi2 = alwaysConsumeNavBar ? 1 : 0; + args.argi2 = alwaysConsumeSystemBars ? 1 : 0; args.argi3 = displayId; msg.obj = args; mHandler.sendMessage(msg); @@ -8498,13 +8498,14 @@ public final class ViewRootImpl implements ViewParent, public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout, - boolean alwaysConsumeNavBar, int displayId, + boolean alwaysConsumeSystemBars, int displayId, DisplayCutout.ParcelableWrapper displayCutout) { final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { viewAncestor.dispatchResized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets, outsets, reportDraw, mergedConfiguration, - backDropFrame, forceLayout, alwaysConsumeNavBar, displayId, displayCutout); + backDropFrame, forceLayout, alwaysConsumeSystemBars, displayId, + displayCutout); } } diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java index aac0e34de0da..ffa769a424a9 100644 --- a/core/java/android/view/WindowInsets.java +++ b/core/java/android/view/WindowInsets.java @@ -83,7 +83,7 @@ public final class WindowInsets { * changes in this mode, we instead have a flag whether the navigation bar size should always * be consumed, so the app is treated like there is no virtual navigation bar at all. */ - private final boolean mAlwaysConsumeNavBar; + private final boolean mAlwaysConsumeSystemBars; private final boolean mSystemWindowInsetsConsumed; private final boolean mStableInsetsConsumed; @@ -111,10 +111,10 @@ public final class WindowInsets { * @deprecated Use {@link WindowInsets(SparseArray, SparseArray, boolean, boolean, DisplayCutout)} */ public WindowInsets(Rect systemWindowInsetsRect, Rect stableInsetsRect, - boolean isRound, boolean alwaysConsumeNavBar, DisplayCutout displayCutout) { + boolean isRound, boolean alwaysConsumeSystemBars, DisplayCutout displayCutout) { this(createCompatTypeMap(systemWindowInsetsRect), createCompatTypeMap(stableInsetsRect), createCompatVisibilityMap(createCompatTypeMap(systemWindowInsetsRect)), - isRound, alwaysConsumeNavBar, displayCutout); + isRound, alwaysConsumeSystemBars, displayCutout); } /** @@ -133,7 +133,7 @@ public final class WindowInsets { @Nullable Insets[] typeMaxInsetsMap, boolean[] typeVisibilityMap, boolean isRound, - boolean alwaysConsumeNavBar, DisplayCutout displayCutout) { + boolean alwaysConsumeSystemBars, DisplayCutout displayCutout) { mSystemWindowInsetsConsumed = typeInsetsMap == null; mTypeInsetsMap = mSystemWindowInsetsConsumed ? new Insets[SIZE] @@ -146,7 +146,7 @@ public final class WindowInsets { mTypeVisibilityMap = typeVisibilityMap; mIsRound = isRound; - mAlwaysConsumeNavBar = alwaysConsumeNavBar; + mAlwaysConsumeSystemBars = alwaysConsumeSystemBars; mDisplayCutoutConsumed = displayCutout == null; mDisplayCutout = (mDisplayCutoutConsumed || displayCutout.isEmpty()) @@ -160,7 +160,7 @@ public final class WindowInsets { */ public WindowInsets(WindowInsets src) { this(src.mTypeInsetsMap, src.mTypeMaxInsetsMap, src.mTypeVisibilityMap, src.mIsRound, - src.mAlwaysConsumeNavBar, displayCutoutCopyConstructorArgument(src)); + src.mAlwaysConsumeSystemBars, displayCutoutCopyConstructorArgument(src)); } private static DisplayCutout displayCutoutCopyConstructorArgument(WindowInsets w) { @@ -443,7 +443,7 @@ public final class WindowInsets { return new WindowInsets(mSystemWindowInsetsConsumed ? null : mTypeInsetsMap, mStableInsetsConsumed ? null : mTypeMaxInsetsMap, mTypeVisibilityMap, - mIsRound, mAlwaysConsumeNavBar, + mIsRound, mAlwaysConsumeSystemBars, null /* displayCutout */); } @@ -489,7 +489,7 @@ public final class WindowInsets { public WindowInsets consumeSystemWindowInsets() { return new WindowInsets(null, mStableInsetsConsumed ? null : mTypeMaxInsetsMap, mTypeVisibilityMap, - mIsRound, mAlwaysConsumeNavBar, + mIsRound, mAlwaysConsumeSystemBars, displayCutoutCopyConstructorArgument(this)); } @@ -729,15 +729,15 @@ public final class WindowInsets { @NonNull public WindowInsets consumeStableInsets() { return new WindowInsets(mSystemWindowInsetsConsumed ? null : mTypeInsetsMap, null, - mTypeVisibilityMap, mIsRound, mAlwaysConsumeNavBar, + mTypeVisibilityMap, mIsRound, mAlwaysConsumeSystemBars, displayCutoutCopyConstructorArgument(this)); } /** * @hide */ - public boolean shouldAlwaysConsumeNavBar() { - return mAlwaysConsumeNavBar; + public boolean shouldAlwaysConsumeSystemBars() { + return mAlwaysConsumeSystemBars; } @Override @@ -809,7 +809,7 @@ public final class WindowInsets { ? null : insetInsets(mTypeMaxInsetsMap, left, top, right, bottom), mTypeVisibilityMap, - mIsRound, mAlwaysConsumeNavBar, + mIsRound, mAlwaysConsumeSystemBars, mDisplayCutoutConsumed ? null : mDisplayCutout == null @@ -824,7 +824,7 @@ public final class WindowInsets { WindowInsets that = (WindowInsets) o; return mIsRound == that.mIsRound - && mAlwaysConsumeNavBar == that.mAlwaysConsumeNavBar + && mAlwaysConsumeSystemBars == that.mAlwaysConsumeSystemBars && mSystemWindowInsetsConsumed == that.mSystemWindowInsetsConsumed && mStableInsetsConsumed == that.mStableInsetsConsumed && mDisplayCutoutConsumed == that.mDisplayCutoutConsumed @@ -837,8 +837,9 @@ public final class WindowInsets { @Override public int hashCode() { return Objects.hash(Arrays.hashCode(mTypeInsetsMap), Arrays.hashCode(mTypeMaxInsetsMap), - Arrays.hashCode(mTypeVisibilityMap), mIsRound, mDisplayCutout, mAlwaysConsumeNavBar, - mSystemWindowInsetsConsumed, mStableInsetsConsumed, mDisplayCutoutConsumed); + Arrays.hashCode(mTypeVisibilityMap), mIsRound, mDisplayCutout, + mAlwaysConsumeSystemBars, mSystemWindowInsetsConsumed, mStableInsetsConsumed, + mDisplayCutoutConsumed); } @@ -900,7 +901,7 @@ public final class WindowInsets { private DisplayCutout mDisplayCutout; private boolean mIsRound; - private boolean mAlwaysConsumeNavBar; + private boolean mAlwaysConsumeSystemBars; /** * Creates a builder where all insets are initially consumed. @@ -924,7 +925,7 @@ public final class WindowInsets { mStableInsetsConsumed = insets.mStableInsetsConsumed; mDisplayCutout = displayCutoutCopyConstructorArgument(insets); mIsRound = insets.mIsRound; - mAlwaysConsumeNavBar = insets.mAlwaysConsumeNavBar; + mAlwaysConsumeSystemBars = insets.mAlwaysConsumeSystemBars; } /** @@ -1119,8 +1120,8 @@ public final class WindowInsets { /** @hide */ @NonNull - public Builder setAlwaysConsumeNavBar(boolean alwaysConsumeNavBar) { - mAlwaysConsumeNavBar = alwaysConsumeNavBar; + public Builder setAlwaysConsumeSystemBars(boolean alwaysConsumeSystemBars) { + mAlwaysConsumeSystemBars = alwaysConsumeSystemBars; return this; } @@ -1133,7 +1134,7 @@ public final class WindowInsets { public WindowInsets build() { return new WindowInsets(mSystemInsetsConsumed ? null : mTypeInsetsMap, mStableInsetsConsumed ? null : mTypeMaxInsetsMap, mTypeVisibilityMap, - mIsRound, mAlwaysConsumeNavBar, mDisplayCutout); + mIsRound, mAlwaysConsumeSystemBars, mDisplayCutout); } } diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java index 453c5e32a178..8a111cf86658 100644 --- a/core/java/android/view/WindowManagerGlobal.java +++ b/core/java/android/view/WindowManagerGlobal.java @@ -93,11 +93,11 @@ public final class WindowManagerGlobal { public static final int RELAYOUT_RES_SURFACE_RESIZED = 0x20; /** - * In multi-window we force show the navigation bar. Because we don't want that the surface size - * changes in this mode, we instead have a flag whether the navigation bar size should always be - * consumed, so the app is treated like there is no virtual navigation bar at all. + * In multi-window we force show the system bars. Because we don't want that the surface size + * changes in this mode, we instead have a flag whether the system bar sizes should always be + * consumed, so the app is treated like there is no virtual system bars at all. */ - public static final int RELAYOUT_RES_CONSUME_ALWAYS_NAV_BAR = 0x40; + public static final int RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS = 0x40; /** * Flag for relayout: the client will be later giving @@ -118,9 +118,10 @@ public final class WindowManagerGlobal { public static final int ADD_FLAG_IN_TOUCH_MODE = RELAYOUT_RES_IN_TOUCH_MODE; /** - * Like {@link #RELAYOUT_RES_CONSUME_ALWAYS_NAV_BAR}, but as a "hint" when adding the window. + * Like {@link #RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS}, but as a "hint" when adding the + * window. */ - public static final int ADD_FLAG_ALWAYS_CONSUME_NAV_BAR = 0x4; + public static final int ADD_FLAG_ALWAYS_CONSUME_SYSTEM_BARS = 0x4; public static final int ADD_OKAY = 0; public static final int ADD_BAD_APP_TOKEN = -1; diff --git a/core/java/android/view/WindowManagerPolicyConstants.java b/core/java/android/view/WindowManagerPolicyConstants.java index 35ed7bfa2ce6..46a59f09eca7 100644 --- a/core/java/android/view/WindowManagerPolicyConstants.java +++ b/core/java/android/view/WindowManagerPolicyConstants.java @@ -54,6 +54,16 @@ public interface WindowManagerPolicyConstants { int NAV_BAR_RIGHT = 1 << 1; int NAV_BAR_BOTTOM = 1 << 2; + // Navigation bar interaction modes + int NAV_BAR_MODE_3BUTTON = 0; + int NAV_BAR_MODE_2BUTTON = 1; + int NAV_BAR_MODE_GESTURAL = 2; + + // Associated overlays for each nav bar mode + String NAV_BAR_MODE_3BUTTON_OVERLAY = "com.android.internal.systemui.navbar.threebutton"; + String NAV_BAR_MODE_2BUTTON_OVERLAY = "com.android.internal.systemui.navbar.twobutton"; + String NAV_BAR_MODE_GESTURAL_OVERLAY = "com.android.internal.systemui.navbar.gestural"; + /** * Broadcast sent when a user activity is detected. */ diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java index 384cdbb3831c..d12777fe908e 100644 --- a/core/java/android/view/accessibility/AccessibilityManager.java +++ b/core/java/android/view/accessibility/AccessibilityManager.java @@ -848,7 +848,7 @@ public final class AccessibilityManager { if (mRequestPreparerLists == null) { mRequestPreparerLists = new SparseArray<>(1); } - int id = preparer.getView().getAccessibilityViewId(); + int id = preparer.getAccessibilityViewId(); List<AccessibilityRequestPreparer> requestPreparerList = mRequestPreparerLists.get(id); if (requestPreparerList == null) { requestPreparerList = new ArrayList<>(1); @@ -864,7 +864,7 @@ public final class AccessibilityManager { if (mRequestPreparerLists == null) { return; } - int viewId = preparer.getView().getAccessibilityViewId(); + int viewId = preparer.getAccessibilityViewId(); List<AccessibilityRequestPreparer> requestPreparerList = mRequestPreparerLists.get(viewId); if (requestPreparerList != null) { requestPreparerList.remove(preparer); diff --git a/core/java/android/view/accessibility/AccessibilityRequestPreparer.java b/core/java/android/view/accessibility/AccessibilityRequestPreparer.java index 4dcb18766347..8108d37a8814 100644 --- a/core/java/android/view/accessibility/AccessibilityRequestPreparer.java +++ b/core/java/android/view/accessibility/AccessibilityRequestPreparer.java @@ -51,6 +51,7 @@ public abstract class AccessibilityRequestPreparer { public @interface RequestTypes {} private final WeakReference<View> mViewRef; + private final int mAccessibilityViewId; private final int mRequestTypes; /** @@ -68,6 +69,7 @@ public abstract class AccessibilityRequestPreparer { throw new IllegalStateException("View must be attached to a window"); } mViewRef = new WeakReference<>(view); + mAccessibilityViewId = view.getAccessibilityViewId(); mRequestTypes = requestTypes; view.addOnAttachStateChangeListener(new ViewAttachStateListener()); } @@ -118,4 +120,8 @@ public abstract class AccessibilityRequestPreparer { v.removeOnAttachStateChangeListener(this); } } + + int getAccessibilityViewId() { + return mAccessibilityViewId; + } } diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index 8cb04cbdc994..77a0c4c5f4ee 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -16,7 +16,6 @@ package android.view.autofill; -import static android.service.autofill.FillRequest.FLAG_AUGMENTED_AUTOFILL_REQUEST; import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST; import static android.view.autofill.Helper.sDebug; import static android.view.autofill.Helper.sVerbose; @@ -228,6 +227,7 @@ public final class AutofillManager { /** @hide */ public static final int FLAG_ADD_CLIENT_ENABLED = 0x1; /** @hide */ public static final int FLAG_ADD_CLIENT_DEBUG = 0x2; /** @hide */ public static final int FLAG_ADD_CLIENT_VERBOSE = 0x4; + /** @hide */ public static final int FLAG_ADD_CLIENT_ENABLED_FOR_AUGMENTED_AUTOFILL_ONLY = 0x8; /** @hide */ public static final int FLAG_SESSION_FOR_AUGMENTED_AUTOFILL_ONLY = 0x1; @@ -520,6 +520,13 @@ public final class AutofillManager { @GuardedBy("mLock") private boolean mForAugmentedAutofillOnly; + /** + * When set, standard autofill is enabled, but sessions can still be created for augmented + * autofill only. + */ + @GuardedBy("mLock") + private boolean mEnabledForAugmentedAutofillOnly; + /** @hide */ public interface AutofillClient { /** @@ -946,7 +953,7 @@ public final class AutofillManager { ensureServiceClientAddedIfNeededLocked(); - if (!mEnabled) { + if (!mEnabled && !mEnabledForAugmentedAutofillOnly) { if (sVerbose) Log.v(TAG, "ignoring notifyViewEntered(" + id + "): disabled"); if (mCallback != null) { @@ -988,7 +995,7 @@ public final class AutofillManager { void notifyViewExitedLocked(@NonNull View view) { ensureServiceClientAddedIfNeededLocked(); - if (mEnabled && isActiveLocked()) { + if ((mEnabled || mEnabledForAugmentedAutofillOnly) && isActiveLocked()) { // dont notify exited when Activity is already in background if (!isClientDisablingEnterExitEvent()) { final AutofillId id = view.getAutofillId(); @@ -1104,7 +1111,7 @@ public final class AutofillManager { ensureServiceClientAddedIfNeededLocked(); - if (!mEnabled) { + if (!mEnabled && !mEnabledForAugmentedAutofillOnly) { if (sVerbose) { Log.v(TAG, "ignoring notifyViewEntered(" + id + "): disabled"); } @@ -1155,7 +1162,7 @@ public final class AutofillManager { private void notifyViewExitedLocked(@NonNull View view, int virtualId) { ensureServiceClientAddedIfNeededLocked(); - if (mEnabled && isActiveLocked()) { + if ((mEnabled || mEnabledForAugmentedAutofillOnly) && isActiveLocked()) { // don't notify exited when Activity is already in background if (!isClientDisablingEnterExitEvent()) { final AutofillId id = getAutofillId(view, virtualId); @@ -1674,14 +1681,17 @@ public final class AutofillManager { private void startSessionLocked(@NonNull AutofillId id, @NonNull Rect bounds, @NonNull AutofillValue value, int flags) { if (mEnteredForAugmentedAutofillIds != null - && mEnteredForAugmentedAutofillIds.contains(id)) { + && mEnteredForAugmentedAutofillIds.contains(id) + || mEnabledForAugmentedAutofillOnly) { if (sVerbose) Log.v(TAG, "Starting session for augmented autofill on " + id); - flags |= FLAG_AUGMENTED_AUTOFILL_REQUEST; + flags |= FLAG_ADD_CLIENT_ENABLED_FOR_AUGMENTED_AUTOFILL_ONLY; } if (sVerbose) { Log.v(TAG, "startSessionLocked(): id=" + id + ", bounds=" + bounds + ", value=" + value + ", flags=" + flags + ", state=" + getStateAsStringLocked() + ", compatMode=" + isCompatibilityModeEnabledLocked() + + ", augmentedOnly=" + mForAugmentedAutofillOnly + + ", enabledAugmentedOnly=" + mEnabledForAugmentedAutofillOnly + ", enteredIds=" + mEnteredIds); } if (mState != STATE_UNKNOWN && !isFinishedLocked() && (flags & FLAG_MANUAL_REQUEST) == 0) { @@ -1776,7 +1786,8 @@ public final class AutofillManager { @GuardedBy("mLock") private void ensureServiceClientAddedIfNeededLocked() { - if (getClient() == null) { + final AutofillClient client = getClient(); + if (client == null) { return; } @@ -1785,11 +1796,18 @@ public final class AutofillManager { try { final int userId = mContext.getUserId(); final SyncResultReceiver receiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS); - mService.addClient(mServiceClient, userId, receiver); + mService.addClient(mServiceClient, client.autofillClientGetComponentName(), + userId, receiver); final int flags = receiver.getIntResult(); mEnabled = (flags & FLAG_ADD_CLIENT_ENABLED) != 0; sDebug = (flags & FLAG_ADD_CLIENT_DEBUG) != 0; sVerbose = (flags & FLAG_ADD_CLIENT_VERBOSE) != 0; + mEnabledForAugmentedAutofillOnly = (flags + & FLAG_ADD_CLIENT_ENABLED_FOR_AUGMENTED_AUTOFILL_ONLY) != 0; + if (sVerbose) { + Log.v(TAG, "receiver results: flags=" + flags + " enabled=" + mEnabled + + ", enabledForAugmentedOnly: " + mEnabledForAugmentedAutofillOnly); + } final IAutoFillManager service = mService; final IAutoFillManagerClient serviceClient = mServiceClient; mServiceClientCleaner = Cleaner.create(this, () -> { @@ -2406,6 +2424,7 @@ public final class AutofillManager { pw.print(" ("); pw.print(client.autofillClientGetActivityToken()); pw.println(')'); } pw.print(pfx); pw.print("enabled: "); pw.println(mEnabled); + pw.print(pfx); pw.print("enabledAugmentedOnly: "); pw.println(mForAugmentedAutofillOnly); pw.print(pfx); pw.print("hasService: "); pw.println(mService != null); pw.print(pfx); pw.print("hasCallback: "); pw.println(mCallback != null); pw.print(pfx); pw.print("onInvisibleCalled "); pw.println(mOnInvisibleCalled); diff --git a/core/java/android/view/autofill/IAutoFillManager.aidl b/core/java/android/view/autofill/IAutoFillManager.aidl index 9e6a4afe5414..a507e74c30ab 100644 --- a/core/java/android/view/autofill/IAutoFillManager.aidl +++ b/core/java/android/view/autofill/IAutoFillManager.aidl @@ -37,7 +37,8 @@ import com.android.internal.os.IResultReceiver; */ oneway interface IAutoFillManager { // Returns flags: FLAG_ADD_CLIENT_ENABLED | FLAG_ADD_CLIENT_DEBUG | FLAG_ADD_CLIENT_VERBOSE - void addClient(in IAutoFillManagerClient client, int userId, in IResultReceiver result); + void addClient(in IAutoFillManagerClient client, in ComponentName componentName, int userId, + in IResultReceiver result); void removeClient(in IAutoFillManagerClient client, int userId); void startSession(IBinder activityToken, in IBinder appCallback, in AutofillId autoFillId, in Rect bounds, in AutofillValue value, int userId, boolean hasCallback, int flags, diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java index a3e65496bcd0..9e546a80dfd3 100644 --- a/core/java/android/view/contentcapture/ContentCaptureManager.java +++ b/core/java/android/view/contentcapture/ContentCaptureManager.java @@ -32,6 +32,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.RemoteException; +import android.os.ServiceManager; import android.util.Log; import android.view.contentcapture.ContentCaptureSession.FlushReason; @@ -52,11 +53,13 @@ public final class ContentCaptureManager { private static final String TAG = ContentCaptureManager.class.getSimpleName(); /** @hide */ + public static final int RESULT_CODE_OK = 0; + /** @hide */ public static final int RESULT_CODE_TRUE = 1; /** @hide */ public static final int RESULT_CODE_FALSE = 2; /** @hide */ - public static final int RESULT_CODE_NOT_SERVICE = -1; + public static final int RESULT_CODE_SECURITY_EXCEPTION = -1; /** * Timeout for calls to system_server. @@ -243,6 +246,7 @@ public final class ContentCaptureManager { @UiThread public void onActivityCreated(@NonNull IBinder applicationToken, @NonNull ComponentName activityComponent, int flags) { + if (mOptions.lite) return; synchronized (mLock) { mFlags |= flags; getMainContentCaptureSession().start(applicationToken, activityComponent, mFlags); @@ -252,18 +256,21 @@ public final class ContentCaptureManager { /** @hide */ @UiThread public void onActivityResumed() { + if (mOptions.lite) return; getMainContentCaptureSession().notifySessionLifecycle(/* started= */ true); } /** @hide */ @UiThread public void onActivityPaused() { + if (mOptions.lite) return; getMainContentCaptureSession().notifySessionLifecycle(/* started= */ false); } /** @hide */ @UiThread public void onActivityDestroyed() { + if (mOptions.lite) return; getMainContentCaptureSession().destroy(); } @@ -276,6 +283,7 @@ public final class ContentCaptureManager { */ @UiThread public void flush(@FlushReason int reason) { + if (mOptions.lite) return; getMainContentCaptureSession().flush(reason); } @@ -285,7 +293,7 @@ public final class ContentCaptureManager { */ @Nullable public ComponentName getServiceComponentName() { - if (!isContentCaptureEnabled()) return null; + if (!isContentCaptureEnabled() && !mOptions.lite) return null; final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS); try { @@ -297,6 +305,35 @@ public final class ContentCaptureManager { } /** + * Gets the (optional) intent used to launch the service-specific settings. + * + * <p>This method is static because it's called by Settings, which might not be whitelisted + * for content capture (in which case the ContentCaptureManager on its context would be null). + * + * @hide + */ + // TODO: use "lite" options as it's done by activities from the content capture service + @Nullable + public static ComponentName getServiceSettingsComponentName() { + final IBinder binder = ServiceManager + .checkService(Context.CONTENT_CAPTURE_MANAGER_SERVICE); + if (binder == null) return null; + + final IContentCaptureManager service = IContentCaptureManager.Stub.asInterface(binder); + final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS); + try { + service.getServiceSettingsActivity(resultReceiver); + final int resultCode = resultReceiver.getIntResult(); + if (resultCode == RESULT_CODE_SECURITY_EXCEPTION) { + throw new SecurityException(resultReceiver.getStringResult()); + } + return resultReceiver.getParcelableResult(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Checks whether content capture is enabled for this activity. * * <p>There are many reasons it could be disabled, such as: @@ -311,6 +348,8 @@ public final class ContentCaptureManager { * </ul> */ public boolean isContentCaptureEnabled() { + if (mOptions.lite) return false; + final MainContentCaptureSession mainSession; synchronized (mLock) { mainSession = mMainSession; @@ -365,7 +404,7 @@ public final class ContentCaptureManager { return true; case RESULT_CODE_FALSE: return false; - case RESULT_CODE_NOT_SERVICE: + case RESULT_CODE_SECURITY_EXCEPTION: throw new SecurityException("caller is not user's ContentCapture service"); default: Log.wtf(TAG, "received invalid result: " + resultCode); diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java index 6d41b289460a..ed1ca2a48850 100644 --- a/core/java/android/view/contentcapture/ContentCaptureSession.java +++ b/core/java/android/view/contentcapture/ContentCaptureSession.java @@ -135,11 +135,18 @@ public abstract class ContentCaptureSession implements AutoCloseable { public static final int STATE_SERVICE_DIED = 0x400; /** + * Session is disabled because the service package is being udpated. + * + * @hide + */ + public static final int STATE_SERVICE_UPDATING = 0x800; + + /** * Session is enabled, after the service died and came back to live. * * @hide */ - public static final int STATE_SERVICE_RESURRECTED = 0x800; + public static final int STATE_SERVICE_RESURRECTED = 0x1000; private static final int INITIAL_CHILDREN_CAPACITY = 5; diff --git a/core/java/android/view/contentcapture/IContentCaptureManager.aidl b/core/java/android/view/contentcapture/IContentCaptureManager.aidl index e3b0372a8cc7..15fbaa2d7dab 100644 --- a/core/java/android/view/contentcapture/IContentCaptureManager.aidl +++ b/core/java/android/view/contentcapture/IContentCaptureManager.aidl @@ -67,4 +67,9 @@ oneway interface IContentCaptureManager { * Returns whether the content capture feature is enabled for the calling user. */ void isContentCaptureFeatureEnabled(in IResultReceiver result); + + /** + * Returns a ComponentName with the name of custom service activity, if defined. + */ + void getServiceSettingsActivity(in IResultReceiver result); } diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java index 666af5968f69..790b8f9dde46 100644 --- a/core/java/android/view/contentcapture/MainContentCaptureSession.java +++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java @@ -230,7 +230,8 @@ public final class MainContentCaptureSession extends ContentCaptureSession { /** * Callback from {@code system_server} after call to - * {@link IContentCaptureManager#startSession(IBinder, ComponentName, String, int, IBinder)} + * {@link IContentCaptureManager#startSession(IBinder, ComponentName, String, int, + * IResultReceiver)}. * * @param resultCode session state * @param binder handle to {@code IContentCaptureDirectManager} diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java index cb44f79465ef..0f2e702ecd0d 100644 --- a/core/java/android/view/textclassifier/TextClassifierImpl.java +++ b/core/java/android/view/textclassifier/TextClassifierImpl.java @@ -86,7 +86,8 @@ public final class TextClassifierImpl implements TextClassifier { new File("/data/misc/textclassifier/lang_id.model"); // Actions - private static final String ACTIONS_FACTORY_MODEL_FILENAME_REGEX = "actions_suggestions.model"; + private static final String ACTIONS_FACTORY_MODEL_FILENAME_REGEX = + "actions_suggestions\\.(.*)\\.model"; private static final File UPDATED_ACTIONS_MODEL = new File("/data/misc/textclassifier/actions_suggestions.model"); diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SettingsCompat.java b/core/java/com/android/internal/annotations/VisibleForNative.java index c16cf92a5e8f..e6a3fc67b7d3 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SettingsCompat.java +++ b/core/java/com/android/internal/annotations/VisibleForNative.java @@ -11,15 +11,18 @@ * 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 + * limitations under the License. */ -package com.android.systemui.shared.system; +package com.android.internal.annotations; -import android.provider.Settings; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; -public class SettingsCompat { - - public static final String SWIPE_UP_SETTING_NAME - = Settings.Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED; +/** + * Denotes that the class, method or field has its visibility relaxed so + * that native code can access it. + */ +@Retention(RetentionPolicy.CLASS) +public @interface VisibleForNative { } diff --git a/core/java/com/android/internal/app/AbstractResolverComparator.java b/core/java/com/android/internal/app/AbstractResolverComparator.java new file mode 100644 index 000000000000..3576b6bb4236 --- /dev/null +++ b/core/java/com/android/internal/app/AbstractResolverComparator.java @@ -0,0 +1,63 @@ +package com.android.internal.app; + +import android.content.ComponentName; +import com.android.internal.app.ResolverActivity.ResolvedComponentInfo; +import java.util.Comparator; +import java.util.List; + +/** + * Used to sort resolved activities in {@link ResolverListController}. + */ +abstract class AbstractResolverComparator implements Comparator<ResolvedComponentInfo> { + + protected AfterCompute mAfterCompute; + + /** + * Callback to be called when {@link #compute(List)} finishes. This signals to stop waiting. + */ + public interface AfterCompute { + + public void afterCompute(); + } + + public void setCallBack(AfterCompute afterCompute) { + mAfterCompute = afterCompute; + } + + /** + * Computes features for each target. This will be called before calls to {@link + * #getScore(ComponentName)} or {@link #compare(Object, Object)}, in order to prepare the + * comparator for those calls. Note that {@link #getScore(ComponentName)} uses {@link + * ComponentName}, so the implementation will have to be prepared to identify a {@link + * ResolvedComponentInfo} by {@link ComponentName}. + */ + public abstract void compute(List<ResolvedComponentInfo> targets); + + /** + * Returns the score that was calculated for the corresponding {@link ResolvedComponentInfo} + * when {@link #compute(List)} was called before this. + */ + public abstract float getScore(ComponentName name); + + /** + * Reports to UsageStats what was chosen. + */ + // TODO(b/129014961) Move implemetation here and make final. + public abstract void updateChooserCounts(String packageName, int userId, String action); + + /** + * Updates the model used to rank the componentNames. + * + * <p>Default implementation does nothing, as we could have simple model that does not train + * online. + * + * @param componentName the component that the user clicked + */ + public void updateModel(ComponentName componentName) { + } + + /** + * Called when the {@link ResolverActivity} is destroyed. + */ + public abstract void destroy(); +} diff --git a/core/java/com/android/internal/app/AlertActivity.java b/core/java/com/android/internal/app/AlertActivity.java index 999a908251dd..0b08099b51ed 100644 --- a/core/java/com/android/internal/app/AlertActivity.java +++ b/core/java/com/android/internal/app/AlertActivity.java @@ -16,6 +16,7 @@ package com.android.internal.app; +import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.Dialog; import android.content.DialogInterface; @@ -38,11 +39,13 @@ public abstract class AlertActivity extends Activity implements DialogInterface * * @see #mAlertParams */ + @UnsupportedAppUsage protected AlertController mAlert; /** * The parameters for the alert. */ + @UnsupportedAppUsage protected AlertController.AlertParams mAlertParams; @Override @@ -90,6 +93,7 @@ public abstract class AlertActivity extends Activity implements DialogInterface * @see #mAlert * @see #mAlertParams */ + @UnsupportedAppUsage protected void setupAlert() { mAlert.installContent(mAlertParams); } diff --git a/core/java/com/android/internal/app/AssistUtils.java b/core/java/com/android/internal/app/AssistUtils.java index d0102a72e703..efcdb9a29dd8 100644 --- a/core/java/com/android/internal/app/AssistUtils.java +++ b/core/java/com/android/internal/app/AssistUtils.java @@ -17,6 +17,7 @@ package com.android.internal.app; import android.annotation.NonNull; +import android.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.pm.ApplicationInfo; @@ -42,6 +43,7 @@ public class AssistUtils { private final Context mContext; private final IVoiceInteractionManagerService mVoiceInteractionManagerService; + @UnsupportedAppUsage public AssistUtils(Context context) { mContext = context; mVoiceInteractionManagerService = IVoiceInteractionManagerService.Stub.asInterface( @@ -168,6 +170,7 @@ public class AssistUtils { } } + @UnsupportedAppUsage public ComponentName getAssistComponentForUser(int userId) { final String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(), Settings.Secure.ASSISTANT, userId); diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index faf0c7dbed37..4f5678a5ff24 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -24,6 +24,7 @@ import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.annotation.IntDef; +import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.ActivityManager; import android.app.prediction.AppPredictionContext; @@ -58,6 +59,7 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; +import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.metrics.LogMaker; @@ -236,7 +238,7 @@ public class ChooserActivity extends ResolverActivity { if (DEBUG) { Log.d(TAG, "CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT; unbinding services"); } - if (isDestroyed()) { + if (mChooserListAdapter == null || isDestroyed()) { break; } unbindRemainingServices(); @@ -821,6 +823,7 @@ public class ChooserActivity extends ResolverActivity { mRefinementResultReceiver = null; } unbindRemainingServices(); + mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT); mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_RESULT); if (USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) { mAppPredictor.unregisterPredictionUpdates(mAppPredictorCallback); @@ -876,10 +879,17 @@ public class ChooserActivity extends ResolverActivity { } mChooserRowAdapter = new ChooserRowAdapter(mChooserListAdapter); mChooserRowAdapter.registerDataSetObserver(new OffsetDataSetObserver(adapterView)); - adapterView.setAdapter(mChooserRowAdapter); if (listView != null) { listView.setItemsCanFocus(true); + listView.addOnLayoutChangeListener( + (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { + if (mChooserRowAdapter.calculateMaxTargetsPerRow(right - left)) { + adapterView.setAdapter(mChooserRowAdapter); + } + }); } + + adapterView.setAdapter(mChooserRowAdapter); } @Override @@ -1269,11 +1279,10 @@ public class ChooserActivity extends ResolverActivity { } mAppPredictor.notifyAppTargetEvent( new AppTargetEvent.Builder( - new AppTarget( - new AppTargetId(shortcutId), - componentName.getPackageName(), - componentName.getClassName(), - getUser()), + new AppTarget.Builder(new AppTargetId(shortcutId)) + .setTarget(componentName.getPackageName(), getUser()) + .setClassName(componentName.getClassName()) + .build(), AppTargetEvent.ACTION_LAUNCH ).setLaunchLocation(LAUNCH_LOCATON_DIRECT_SHARE) .build()); @@ -1465,14 +1474,6 @@ public class ChooserActivity extends ResolverActivity { return null; } - public Drawable getBadgeIcon() { - return null; - } - - public CharSequence getBadgeContentDescription() { - return null; - } - public TargetInfo cloneFilledIn(Intent fillInIntent, int flags) { return null; } @@ -1561,31 +1562,49 @@ public class ChooserActivity extends ResolverActivity { */ // TODO(121287224): Refactor code to apply the suggestion above private Drawable getChooserTargetIconDrawable(ChooserTarget target) { + Drawable directShareIcon = null; + + // First get the target drawable and associated activity info final Icon icon = target.getIcon(); if (icon != null) { - return icon.loadDrawable(ChooserActivity.this); - } - if (!USE_SHORTCUT_MANAGER_FOR_DIRECT_TARGETS) { - return null; + directShareIcon = icon.loadDrawable(ChooserActivity.this); + } else if (USE_SHORTCUT_MANAGER_FOR_DIRECT_TARGETS) { + Bundle extras = target.getIntentExtras(); + if (extras != null && extras.containsKey(Intent.EXTRA_SHORTCUT_ID)) { + CharSequence shortcutId = extras.getCharSequence(Intent.EXTRA_SHORTCUT_ID); + LauncherApps launcherApps = (LauncherApps) getSystemService( + Context.LAUNCHER_APPS_SERVICE); + final LauncherApps.ShortcutQuery q = new LauncherApps.ShortcutQuery(); + q.setPackage(target.getComponentName().getPackageName()); + q.setShortcutIds(Arrays.asList(shortcutId.toString())); + q.setQueryFlags(LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC); + final List<ShortcutInfo> shortcuts = launcherApps.getShortcuts(q, getUser()); + if (shortcuts != null && shortcuts.size() > 0) { + directShareIcon = launcherApps.getShortcutIconDrawable(shortcuts.get(0), 0); + } + } } - Bundle extras = target.getIntentExtras(); - if (extras == null || !extras.containsKey(Intent.EXTRA_SHORTCUT_ID)) { - return null; - } - CharSequence shortcutId = extras.getCharSequence(Intent.EXTRA_SHORTCUT_ID); - LauncherApps launcherApps = (LauncherApps) getSystemService( - Context.LAUNCHER_APPS_SERVICE); - final LauncherApps.ShortcutQuery q = new LauncherApps.ShortcutQuery(); - q.setPackage(target.getComponentName().getPackageName()); - q.setShortcutIds(Arrays.asList(shortcutId.toString())); - q.setQueryFlags(LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC); - final List<ShortcutInfo> shortcuts = launcherApps.getShortcuts(q, getUser()); - if (shortcuts != null && shortcuts.size() > 0) { - return launcherApps.getShortcutIconDrawable(shortcuts.get(0), 0); + if (directShareIcon == null) return null; + + ActivityInfo info = null; + try { + info = mPm.getActivityInfo(target.getComponentName(), 0); + } catch (NameNotFoundException error) { + Log.e(TAG, "Could not find activity associated with ChooserTarget"); } - return null; + if (info == null) return null; + + // Now fetch app icon and raster with no badging even in work profile + Bitmap appIcon = (new ActivityInfoPresentationGetter(info)).getIconBitmap(); + + // Raster target drawable with appIcon as a badge + SimpleIconFactory sif = SimpleIconFactory.obtain(ChooserActivity.this); + Bitmap directShareBadgedIcon = sif.createAppBadgedIconBitmap(directShareIcon, appIcon); + sif.recycle(); + + return new BitmapDrawable(getResources(), directShareBadgedIcon); } public float getModifiedScore() { @@ -1683,16 +1702,6 @@ public class ChooserActivity extends ResolverActivity { return mDisplayIcon; } - @Override - public Drawable getBadgeIcon() { - return mBadgeIcon; - } - - @Override - public CharSequence getBadgeContentDescription() { - return mBadgeContentDescription; - } - public ChooserTarget getChooserTarget() { return mChooserTarget; } @@ -2062,7 +2071,7 @@ public class ChooserActivity extends ResolverActivity { class ChooserRowAdapter extends BaseAdapter { private ChooserListAdapter mChooserListAdapter; private final LayoutInflater mLayoutInflater; - private int mAnimationCount = 0; + private int mCalculatedMaxTargetsPerRow = MAX_TARGETS_PER_ROW_LANDSCAPE; private DirectShareViewHolder mDirectShareViewHolder; @@ -2070,6 +2079,9 @@ public class ChooserActivity extends ResolverActivity { private static final int VIEW_TYPE_NORMAL = 1; private static final int VIEW_TYPE_CONTENT_PREVIEW = 2; + private static final int MAX_TARGETS_PER_ROW_PORTRAIT = 4; + private static final int MAX_TARGETS_PER_ROW_LANDSCAPE = 8; + public ChooserRowAdapter(ChooserListAdapter wrappedAdapter) { mChooserListAdapter = wrappedAdapter; mLayoutInflater = LayoutInflater.from(ChooserActivity.this); @@ -2089,9 +2101,40 @@ public class ChooserActivity extends ResolverActivity { }); } + /** + * Determine how many targets can comfortably fit in a single row. + * + * @param width The new row width to use for recalculation + * @return true if the numbers of targets per row has changed + */ + public boolean calculateMaxTargetsPerRow(int width) { + int targetWidth = getResources().getDimensionPixelSize( + R.dimen.chooser_target_width); + + if (targetWidth == 0 || width == 0) { + return false; + } + + int margin = getResources().getDimensionPixelSize( + R.dimen.chooser_edge_margin_normal); + + int newCount = (width - margin * 2) / targetWidth; + if (newCount != mCalculatedMaxTargetsPerRow) { + mCalculatedMaxTargetsPerRow = newCount; + return true; + } + + return false; + } + private int getMaxTargetsPerRow() { - // this will soon hold logic for portrait/landscape - return 4; + int maxTargets = MAX_TARGETS_PER_ROW_PORTRAIT; + if (getResources().getConfiguration().orientation + == Configuration.ORIENTATION_LANDSCAPE) { + maxTargets = MAX_TARGETS_PER_ROW_LANDSCAPE; + } + + return Math.min(maxTargets, mCalculatedMaxTargetsPerRow); } @Override @@ -2158,9 +2201,7 @@ public class ChooserActivity extends ResolverActivity { holder = (RowViewHolder) convertView.getTag(); } - bindViewHolder(position, holder, - viewType == VIEW_TYPE_DIRECT_SHARE - ? ChooserListAdapter.MAX_SERVICE_TARGETS : getMaxTargetsPerRow()); + bindViewHolder(position, holder); return holder.getViewGroup(); } @@ -2277,7 +2318,7 @@ public class ChooserActivity extends ResolverActivity { } } - void bindViewHolder(int rowPosition, RowViewHolder holder, int columnCount) { + void bindViewHolder(int rowPosition, RowViewHolder holder) { final int start = getFirstRowPosition(rowPosition); final int startType = mChooserListAdapter.getPositionTargetType(start); @@ -2294,6 +2335,7 @@ public class ChooserActivity extends ResolverActivity { setVertPadding(row, 0, 0); } + int columnCount = holder.getColumnCount(); int end = start + columnCount - 1; while (mChooserListAdapter.getPositionTargetType(end) != startType && end >= start) { end--; @@ -2328,36 +2370,15 @@ public class ChooserActivity extends ResolverActivity { for (int i = 0; i < columnCount; i++) { final View v = holder.getView(i); if (start + i <= end) { - setCellVisibility(holder, i, View.VISIBLE); + holder.setViewVisibility(i, View.VISIBLE); holder.setItemIndex(i, start + i); mChooserListAdapter.bindView(holder.getItemIndex(i), v); } else { - setCellVisibility(holder, i, View.INVISIBLE); + holder.setViewVisibility(i, View.INVISIBLE); } } } - private void setCellVisibility(RowViewHolder holder, int i, int visibility) { - final View v = holder.getView(i); - if (visibility == View.VISIBLE) { - holder.setViewVisibility(i, true); - v.setVisibility(visibility); - v.setAlpha(1.0f); - } else if (visibility == View.INVISIBLE && holder.getViewVisibility(i)) { - holder.setViewVisibility(i, false); - - ValueAnimator fadeAnim = ObjectAnimator.ofFloat(v, "alpha", 1.0f, 0f); - fadeAnim.setDuration(NO_DIRECT_SHARE_ANIM_IN_MILLIS); - fadeAnim.setInterpolator(new AccelerateInterpolator(1.0f)); - fadeAnim.addListener(new AnimatorListenerAdapter() { - public void onAnimationEnd(Animator animation) { - v.setVisibility(View.INVISIBLE); - } - }); - fadeAnim.start(); - } - } - private void setVertPadding(ViewGroup row, int top, int bottom) { row.setPadding(row.getPaddingLeft(), top, row.getPaddingRight(), bottom); } @@ -2393,13 +2414,11 @@ public class ChooserActivity extends ResolverActivity { protected int mMeasuredRowHeight; private int[] mItemIndices; protected final View[] mCells; - private final boolean[] mCellVisibility; private final int mColumnCount; RowViewHolder(int cellCount) { this.mCells = new View[cellCount]; this.mItemIndices = new int[cellCount]; - this.mCellVisibility = new boolean[cellCount]; this.mColumnCount = cellCount; } @@ -2409,18 +2428,12 @@ public class ChooserActivity extends ResolverActivity { abstract ViewGroup getRow(int index); + abstract void setViewVisibility(int i, int visibility); + public int getColumnCount() { return mColumnCount; } - public void setViewVisibility(int index, boolean visibility) { - mCellVisibility[index] = visibility; - } - - public boolean getViewVisibility(int index) { - return mCellVisibility[index]; - } - public void measure() { final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); getViewGroup().measure(spec, spec); @@ -2476,6 +2489,10 @@ public class ChooserActivity extends ResolverActivity { return mRow; } + + public void setViewVisibility(int i, int visibility) { + getView(i).setVisibility(visibility); + } } class DirectShareViewHolder extends RowViewHolder { @@ -2488,12 +2505,15 @@ public class ChooserActivity extends ResolverActivity { private int mDirectShareCurrHeight = 0; private int mDirectShareMaxHeight = 0; + private final boolean[] mCellVisibility; + DirectShareViewHolder(ViewGroup parent, List<ViewGroup> rows, int cellCountPerRow) { super(rows.size() * cellCountPerRow); this.mParent = parent; this.mRows = rows; this.mCellCountPerRow = cellCountPerRow; + this.mCellVisibility = new boolean[rows.size() * cellCountPerRow]; } public ViewGroup addView(int index, View v) { @@ -2532,6 +2552,27 @@ public class ChooserActivity extends ResolverActivity { return mDirectShareCurrHeight; } + public void setViewVisibility(int i, int visibility) { + final View v = getView(i); + if (visibility == View.VISIBLE) { + mCellVisibility[i] = true; + v.setVisibility(visibility); + v.setAlpha(1.0f); + } else if (visibility == View.INVISIBLE && mCellVisibility[i]) { + mCellVisibility[i] = false; + + ValueAnimator fadeAnim = ObjectAnimator.ofFloat(v, "alpha", 1.0f, 0f); + fadeAnim.setDuration(NO_DIRECT_SHARE_ANIM_IN_MILLIS); + fadeAnim.setInterpolator(new AccelerateInterpolator(1.0f)); + fadeAnim.addListener(new AnimatorListenerAdapter() { + public void onAnimationEnd(Animator animation) { + v.setVisibility(View.INVISIBLE); + } + }); + fadeAnim.start(); + } + } + public void handleScroll(AbsListView view, int y, int oldy, int maxTargetsPerRow) { // only expand if we have more than 4 targets, and delay that decision until // they start to scroll diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java index 64f00103eb4b..3811fe44255d 100644 --- a/core/java/com/android/internal/app/IntentForwarderActivity.java +++ b/core/java/com/android/internal/app/IntentForwarderActivity.java @@ -20,6 +20,7 @@ import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY; import android.annotation.Nullable; import android.annotation.StringRes; +import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.ActivityTaskManager; import android.app.ActivityThread; @@ -54,6 +55,7 @@ import java.util.Set; * be passed in and out of a managed profile. */ public class IntentForwarderActivity extends Activity { + @UnsupportedAppUsage public static String TAG = "IntentForwarderActivity"; public static String FORWARD_INTENT_TO_PARENT diff --git a/core/java/com/android/internal/app/LocaleHelper.java b/core/java/com/android/internal/app/LocaleHelper.java index 0a230a90a735..aef4dbf41d35 100644 --- a/core/java/com/android/internal/app/LocaleHelper.java +++ b/core/java/com/android/internal/app/LocaleHelper.java @@ -17,6 +17,7 @@ package com.android.internal.app; import android.annotation.IntRange; +import android.annotation.UnsupportedAppUsage; import android.icu.text.ListFormatter; import android.icu.util.ULocale; import android.os.LocaleList; @@ -84,6 +85,7 @@ public class LocaleHelper { * @param locale the locale that might be used for certain operations (i.e. case conversion) * @return the string normalized for search */ + @UnsupportedAppUsage public static String normalizeForSearch(String str, Locale locale) { // TODO: tbd if it needs to be smarter (real normalization, remove accents, etc.) // If needed we might use case folding and ICU/CLDR's collation-based loose searching. @@ -109,6 +111,7 @@ public class LocaleHelper { * @param sentenceCase true if the result should be sentence-cased * @return the localized name of the locale. */ + @UnsupportedAppUsage public static String getDisplayName(Locale locale, Locale displayLocale, boolean sentenceCase) { final ULocale displayULocale = ULocale.forLocale(displayLocale); String result = shouldUseDialectName(locale) @@ -135,6 +138,7 @@ public class LocaleHelper { * @param displayLocale the locale in which to display the name. * @return the localized country name. */ + @UnsupportedAppUsage public static String getDisplayCountry(Locale locale, Locale displayLocale) { final String languageTag = locale.toLanguageTag(); final ULocale uDisplayLocale = ULocale.forLocale(displayLocale); @@ -226,6 +230,7 @@ public class LocaleHelper { * * @param sortLocale the locale to be used for sorting. */ + @UnsupportedAppUsage public LocaleInfoComparator(Locale sortLocale, boolean countryMode) { mCollator = Collator.getInstance(sortLocale); mCountryMode = countryMode; @@ -253,6 +258,7 @@ public class LocaleHelper { * @return a negative integer, zero, or a positive integer as the first * argument is less than, equal to, or greater than the second. */ + @UnsupportedAppUsage @Override public int compare(LocaleStore.LocaleInfo lhs, LocaleStore.LocaleInfo rhs) { // We don't care about the various suggestion types, just "suggested" (!= 0) diff --git a/core/java/com/android/internal/app/LocalePicker.java b/core/java/com/android/internal/app/LocalePicker.java index c8c2fcf60d1f..75174246cd99 100644 --- a/core/java/com/android/internal/app/LocalePicker.java +++ b/core/java/com/android/internal/app/LocalePicker.java @@ -18,6 +18,7 @@ package com.android.internal.app; import com.android.internal.R; +import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; import android.app.IActivityManager; import android.app.ListFragment; @@ -70,6 +71,7 @@ public class LocalePicker extends ListFragment { return label; } + @UnsupportedAppUsage public Locale getLocale() { return locale; } @@ -251,6 +253,7 @@ public class LocalePicker extends ListFragment { * * @see #updateLocales(LocaleList) */ + @UnsupportedAppUsage public static void updateLocale(Locale locale) { updateLocales(new LocaleList(locale)); } @@ -260,6 +263,7 @@ public class LocalePicker extends ListFragment { * Note that the system looks halted for a while during the Locale migration, * so the caller need to take care of it. */ + @UnsupportedAppUsage public static void updateLocales(LocaleList locales) { try { final IActivityManager am = ActivityManager.getService(); @@ -281,6 +285,7 @@ public class LocalePicker extends ListFragment { * * @return The locale list. */ + @UnsupportedAppUsage public static LocaleList getLocales() { try { return ActivityManager.getService() diff --git a/core/java/com/android/internal/app/LocaleStore.java b/core/java/com/android/internal/app/LocaleStore.java index 1d997f5767d3..c11089ba19bd 100644 --- a/core/java/com/android/internal/app/LocaleStore.java +++ b/core/java/com/android/internal/app/LocaleStore.java @@ -16,6 +16,7 @@ package com.android.internal.app; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.LocaleList; import android.provider.Settings; @@ -81,14 +82,17 @@ public class LocaleStore { return mId; } + @UnsupportedAppUsage public Locale getLocale() { return mLocale; } + @UnsupportedAppUsage public Locale getParent() { return mParent; } + @UnsupportedAppUsage public String getId() { return mId; } @@ -115,6 +119,7 @@ public class LocaleStore { return (mSuggestionFlags & suggestionMask) == suggestionMask; } + @UnsupportedAppUsage public String getFullNameNative() { if (mFullNameNative == null) { mFullNameNative = @@ -140,6 +145,7 @@ public class LocaleStore { * For instance German will show as "Deutsch" in the list, but we will also search for * "allemand" if the system UI is in French. */ + @UnsupportedAppUsage public String getFullNameInUiLanguage() { // We don't cache the UI name because the default locale keeps changing return LocaleHelper.getDisplayName(mLocale, true /* sentence case */); @@ -254,6 +260,7 @@ public class LocaleStore { } } + @UnsupportedAppUsage public static void fillCache(Context context) { if (sFullyInitialized) { return; @@ -340,6 +347,7 @@ public class LocaleStore { * Example: if the parent is "ar", then the region list will contain all Arabic locales. * (this is not language based, but language-script, so that it works for zh-Hant and so on. */ + @UnsupportedAppUsage public static Set<LocaleInfo> getLevelLocales(Context context, Set<String> ignorables, LocaleInfo parent, boolean translatedOnly) { fillCache(context); @@ -365,6 +373,7 @@ public class LocaleStore { return result; } + @UnsupportedAppUsage public static LocaleInfo getLocaleInfo(Locale locale) { String id = locale.toLanguageTag(); LocaleInfo result; diff --git a/core/java/com/android/internal/app/NetInitiatedActivity.java b/core/java/com/android/internal/app/NetInitiatedActivity.java index d3bae16d03a7..9a802a9c0fa9 100644 --- a/core/java/com/android/internal/app/NetInitiatedActivity.java +++ b/core/java/com/android/internal/app/NetInitiatedActivity.java @@ -16,6 +16,7 @@ package com.android.internal.app; +import android.annotation.UnsupportedAppUsage; import android.app.AlertDialog; import android.content.BroadcastReceiver; import android.content.Context; @@ -141,6 +142,7 @@ public class NetInitiatedActivity extends AlertActivity implements DialogInterfa locationManager.sendNiResponse(notificationId, response); } + @UnsupportedAppUsage private void handleNIVerify(Intent intent) { int notifId = intent.getIntExtra(GpsNetInitiatedHandler.NI_INTENT_KEY_NOTIF_ID, -1); notificationId = notifId; diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index 12942abc8159..84a1bed36e55 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -21,6 +21,7 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import android.annotation.Nullable; import android.annotation.StringRes; import android.annotation.UiThread; +import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityTaskManager; @@ -42,7 +43,7 @@ import android.content.pm.ResolveInfo; import android.content.pm.UserInfo; import android.content.res.Configuration; import android.content.res.Resources; -import android.graphics.Color; +import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; @@ -99,6 +100,7 @@ public class ResolverActivity extends Activity { // Temporary flag for new chooser delegate behavior. boolean mEnableChooserDelegate = true; + @UnsupportedAppUsage protected ResolveListAdapter mAdapter; private boolean mSafeForwardingMode; protected AbsListView mAdapterView; @@ -121,6 +123,7 @@ public class ResolverActivity extends Activity { // Whether or not this activity supports choosing a default handler for the intent. private boolean mSupportsAlwaysUseOption; protected ResolverDrawerLayout mResolverDrawerLayout; + @UnsupportedAppUsage protected PackageManager mPm; protected int mLaunchedFromUid; @@ -133,8 +136,6 @@ public class ResolverActivity extends Activity { /** See {@link #setRetainInOnStop}. */ private boolean mRetainInOnStop; - SimpleIconFactory mSimpleIconFactory; - private final PackageMonitor mPackageMonitor = new PackageMonitor() { @Override public void onSomePackagesChanged() { mAdapter.handlePackagesChanged(); @@ -259,6 +260,7 @@ public class ResolverActivity extends Activity { * Compatibility version for other bundled services that use this overload without * a default title resource */ + @UnsupportedAppUsage protected void onCreate(Bundle savedInstanceState, Intent intent, CharSequence title, Intent[] initialIntents, List<ResolveInfo> rList, boolean supportsAlwaysUseOption) { @@ -311,11 +313,6 @@ public class ResolverActivity extends Activity { // as to mitigate Intent Capturing vulnerability mSupportsAlwaysUseOption = supportsAlwaysUseOption && !mUseLayoutForBrowsables; - final int iconSize = getResources().getDimensionPixelSize(R.dimen.resolver_icon_size); - final int badgeSize = getResources().getDimensionPixelSize(R.dimen.resolver_badge_size); - mSimpleIconFactory = new SimpleIconFactory(this, mIconDpi, iconSize, badgeSize); - mSimpleIconFactory.setWrapperBackgroundColor(Color.WHITE); - if (configureContentView(mIntents, initialIntents, rList)) { return; } @@ -500,64 +497,150 @@ public class ResolverActivity extends Activity { } } - @Nullable - Drawable getIcon(Resources res, int resId) { - Drawable result; - try { - result = res.getDrawableForDensity(resId, mIconDpi); - } catch (Resources.NotFoundException e) { - result = null; - } - - return result; - } /** - * Loads the icon for the provided ResolveInfo. Defaults to using the application icon over + * Loads the icon for the provided ApplicationInfo. Defaults to using the application icon over * any IntentFilter or Activity icon to increase user understanding, with an exception for * applications that hold the right permission. Always attempts to use icon resources over * PackageManager loading mechanisms so badging can be done by iconloader. */ - Drawable loadIconForResolveInfo(ResolveInfo ri) { - Drawable dr = null; + private abstract class TargetPresentationGetter { + @Nullable abstract Drawable getIconSubstitute(); + @Nullable abstract String getAppSubLabel(); - // Allow for app icon override given the right permission - if (PackageManager.PERMISSION_GRANTED == mPm.checkPermission( - android.Manifest.permission.SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON, - ri.activityInfo.applicationInfo.packageName)) { - try { - if (ri.resolvePackageName != null && ri.icon != 0) { - dr = getIcon(mPm.getResourcesForApplication(ri.resolvePackageName), ri.icon); - } - if (dr == null) { - final int iconRes = ri.getIconResource(); - if (iconRes != 0) { - dr = getIcon(mPm.getResourcesForApplication(ri.activityInfo.packageName), - iconRes); + private final ApplicationInfo mAi; + private final boolean mHasSubstitutePermission; + + TargetPresentationGetter(ApplicationInfo ai) { + mAi = ai; + mHasSubstitutePermission = PackageManager.PERMISSION_GRANTED == mPm.checkPermission( + android.Manifest.permission.SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON, + mAi.packageName); + } + + Drawable getIcon() { + return new BitmapDrawable(getResources(), getIconBitmap()); + } + + Bitmap getIconBitmap() { + Drawable dr = null; + if (mHasSubstitutePermission) { + dr = getIconSubstitute(); + } + + if (dr == null) { + try { + if (mAi.icon != 0) { + dr = loadIconFromResource(mPm.getResourcesForApplication(mAi), mAi.icon); } + } catch (NameNotFoundException ignore) { + } + } + + // Fall back to ApplicationInfo#loadIcon if nothing has been loaded + if (dr == null) { + dr = mAi.loadIcon(mPm); + } + + SimpleIconFactory sif = SimpleIconFactory.obtain(ResolverActivity.this); + Bitmap icon = sif.createUserBadgedIconBitmap(dr, Process.myUserHandle()); + sif.recycle(); + + return icon; + } + + String getLabel() { + String label = null; + // Apps with the substitute permission will always show the sublabel as their label + if (mHasSubstitutePermission) { + label = getAppSubLabel(); + } + + if (label == null) { + label = (String) mAi.loadLabel(mPm); + } + + return label; + } + + String getSubLabel() { + // Apps with the substitute permission will never have a sublabel + if (mHasSubstitutePermission) return null; + return getAppSubLabel(); + } + + @Nullable + protected Drawable loadIconFromResource(Resources res, int resId) { + return res.getDrawableForDensity(resId, mIconDpi); + } + + } + + protected class ResolveInfoPresentationGetter extends TargetPresentationGetter { + + private final ResolveInfo mRi; + + ResolveInfoPresentationGetter(ResolveInfo ri) { + super(ri.activityInfo.applicationInfo); + mRi = ri; + } + + @Override + Drawable getIconSubstitute() { + Drawable dr = null; + try { + // Do not use ResolveInfo#getIconResource() as it defaults to the app + if (mRi.resolvePackageName != null && mRi.icon != 0) { + dr = loadIconFromResource( + mPm.getResourcesForApplication(mRi.resolvePackageName), mRi.icon); } } catch (NameNotFoundException e) { Log.e(TAG, "SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON permission granted but " + "couldn't find resources for package", e); } + + return dr; + } + + @Override + String getAppSubLabel() { + return (String) mRi.loadLabel(mPm); + } + } + + protected class ActivityInfoPresentationGetter extends TargetPresentationGetter { + private final ActivityInfo mActivityInfo; + protected ActivityInfoPresentationGetter(ActivityInfo activityInfo) { + super(activityInfo.applicationInfo); + mActivityInfo = activityInfo; } - // Use app icons for better user association - if (dr == null) { + @Override + Drawable getIconSubstitute() { + Drawable dr = null; try { - dr = getIcon(mPm.getResourcesForApplication(ri.activityInfo.applicationInfo), - ri.activityInfo.applicationInfo.icon); - } catch (NameNotFoundException ignore) { + // Do not use ActivityInfo#getIconResource() as it defaults to the app + if (mActivityInfo.icon != 0) { + dr = loadIconFromResource( + mPm.getResourcesForApplication(mActivityInfo.applicationInfo), + mActivityInfo.icon); + } + } catch (NameNotFoundException e) { + Log.e(TAG, "SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON permission granted but " + + "couldn't find resources for package", e); } + + return dr; } - // Fall back to ApplicationInfo#loadIcon if nothing has been loaded - if (dr == null) { - dr = ri.activityInfo.applicationInfo.loadIcon(mPm); + @Override + String getAppSubLabel() { + return (String) mActivityInfo.loadLabel(mPm); } + } - return new BitmapDrawable(this.getResources(), - mSimpleIconFactory.createUserBadgedIconBitmap(dr, Process.myUserHandle())); + Drawable loadIconForResolveInfo(ResolveInfo ri) { + return (new ResolveInfoPresentationGetter(ri)).getIcon(); } @Override @@ -1250,33 +1333,6 @@ public class ResolverActivity extends Activity { return mDisplayIcon; } - public Drawable getBadgeIcon() { - // We only expose a badge if we have extended info. - // The badge is a higher-priority disambiguation signal - // but we don't need one if we wouldn't show extended info at all. - if (TextUtils.isEmpty(getExtendedInfo())) { - return null; - } - - if (mBadge == null && mResolveInfo != null && mResolveInfo.activityInfo != null - && mResolveInfo.activityInfo.applicationInfo != null) { - if (mResolveInfo.activityInfo.icon == 0 || mResolveInfo.activityInfo.icon - == mResolveInfo.activityInfo.applicationInfo.icon) { - // Badging an icon with exactly the same icon is silly. - // If the activityInfo icon resid is 0 it will fall back - // to the application's icon, making it a match. - return null; - } - mBadge = mResolveInfo.activityInfo.applicationInfo.loadIcon(mPm); - } - return mBadge; - } - - @Override - public CharSequence getBadgeContentDescription() { - return null; - } - @Override public TargetInfo cloneFilledIn(Intent fillInIntent, int flags) { return new DisplayResolveInfo(this, fillInIntent, flags); @@ -1413,21 +1469,11 @@ public class ResolverActivity extends Activity { CharSequence getExtendedInfo(); /** - * @return The drawable that should be used to represent this target + * @return The drawable that should be used to represent this target including badge */ Drawable getDisplayIcon(); /** - * @return The (small) icon to badge the target with - */ - Drawable getBadgeIcon(); - - /** - * @return The content description for the badge icon - */ - CharSequence getBadgeContentDescription(); - - /** * Clone this target with the given fill-in information. */ TargetInfo cloneFilledIn(Intent fillInIntent, int flags); @@ -1963,16 +2009,6 @@ public class ResolverActivity extends Activity { new LoadAdapterIconTask((DisplayResolveInfo) info).execute(); } holder.icon.setImageDrawable(info.getDisplayIcon()); - if (holder.badge != null) { - final Drawable badge = info.getBadgeIcon(); - if (badge != null) { - holder.badge.setImageDrawable(badge); - holder.badge.setContentDescription(info.getBadgeContentDescription()); - holder.badge.setVisibility(View.VISIBLE); - } else { - holder.badge.setVisibility(View.GONE); - } - } } } @@ -2027,13 +2063,11 @@ public class ResolverActivity extends Activity { public TextView text; public TextView text2; public ImageView icon; - public ImageView badge; public ViewHolder(View view) { text = (TextView) view.findViewById(com.android.internal.R.id.text1); text2 = (TextView) view.findViewById(com.android.internal.R.id.text2); icon = (ImageView) view.findViewById(R.id.icon); - badge = (ImageView) view.findViewById(R.id.target_badge); } } diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java index f48102a9fcd4..156baf03f563 100644 --- a/core/java/com/android/internal/app/ResolverListController.java +++ b/core/java/com/android/internal/app/ResolverListController.java @@ -55,7 +55,7 @@ public class ResolverListController { private static final String TAG = "ResolverListController"; private static final boolean DEBUG = false; - private ResolverComparator mResolverComparator; + private AbstractResolverComparator mResolverComparator; private boolean isComputed = false; public ResolverListController( @@ -70,7 +70,8 @@ public class ResolverListController { mTargetIntent = targetIntent; mReferrerPackage = referrerPackage; mResolverComparator = - new ResolverComparator(mContext, mTargetIntent, mReferrerPackage, null); + new ResolverRankerServiceResolverComparator( + mContext, mTargetIntent, mReferrerPackage, null); } @VisibleForTesting @@ -221,7 +222,7 @@ public class ResolverListController { return listToReturn; } - private class ComputeCallback implements ResolverComparator.AfterCompute { + private class ComputeCallback implements AbstractResolverComparator.AfterCompute { private CountDownLatch mFinishComputeSignal; diff --git a/core/java/com/android/internal/app/ResolverComparator.java b/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java index b9f67e6e0521..a88a80f199a4 100644 --- a/core/java/com/android/internal/app/ResolverComparator.java +++ b/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java @@ -46,7 +46,6 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import java.text.Collator; import java.util.ArrayList; -import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -54,10 +53,10 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; /** - * Ranks and compares packages based on usage stats. + * Ranks and compares packages based on usage stats and uses the {@link ResolverRankerService}. */ -class ResolverComparator implements Comparator<ResolvedComponentInfo> { - private static final String TAG = "ResolverComparator"; +class ResolverRankerServiceResolverComparator extends AbstractResolverComparator { + private static final String TAG = "RRSResolverComparator"; private static final boolean DEBUG = false; @@ -100,7 +99,6 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> { private ComponentName mRankerServiceName; private IResolverRankerService mRanker; private ResolverRankerServiceConnection mConnection; - private AfterCompute mAfterCompute; private Context mContext; private CountDownLatch mConnectSignal; @@ -155,12 +153,8 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> { } }; - public interface AfterCompute { - public void afterCompute (); - } - - public ResolverComparator(Context context, Intent intent, String referrerPackage, - AfterCompute afterCompute) { + public ResolverRankerServiceResolverComparator(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); @@ -185,7 +179,7 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> { } // get annotations of content from intent. - public void getContentAnnotations(Intent intent) { + private void getContentAnnotations(Intent intent) { ArrayList<String> annotations = intent.getStringArrayListExtra( Intent.EXTRA_CONTENT_ANNOTATIONS); if (annotations != null) { @@ -200,11 +194,8 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> { } } - public void setCallBack(AfterCompute afterCompute) { - mAfterCompute = afterCompute; - } - // compute features for each target according to usage stats of targets. + @Override public void compute(List<ResolvedComponentInfo> targets) { reset(); @@ -349,6 +340,7 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> { return mCollator.compare(sa.toString().trim(), sb.toString().trim()); } + @Override public float getScore(ComponentName name) { final ResolverTarget target = mTargetsDict.get(name); if (target != null) { @@ -357,6 +349,7 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> { return 0; } + @Override public void updateChooserCounts(String packageName, int userId, String action) { if (mUsm != null) { mUsm.reportChooserSelection(packageName, userId, mContentType, mAnnotations, action); @@ -364,6 +357,7 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> { } // update ranking model when the connection to it is valid. + @Override public void updateModel(ComponentName componentName) { synchronized (mLock) { if (mRanker != null) { @@ -397,6 +391,7 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> { } // unbind the service and clear unhandled messges. + @Override public void destroy() { mHandler.removeMessages(RESOLVER_RANKER_SERVICE_RESULT); mHandler.removeMessages(RESOLVER_RANKER_RESULT_TIMEOUT); @@ -478,8 +473,8 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> { 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=\"" + + " - this service will not be queried for " + + "ResolverRankerServiceResolverComparator. add android:permission=\"" + ResolverRankerService.BIND_PERMISSION + "\"" + " to the <service> tag for " + componentName + " in the manifest."); @@ -490,7 +485,8 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> { resolveInfo.serviceInfo.packageName)) { Log.w(TAG, "ResolverRankerService " + componentName + " does not hold" + " permission " + ResolverRankerService.HOLD_PERMISSION - + " - this service will not be queried for ResolverComparator."); + + " - this service will not be queried for " + + "ResolverRankerServiceResolverComparator."); continue; } } catch (NameNotFoundException e) { diff --git a/core/java/com/android/internal/app/SimpleIconFactory.java b/core/java/com/android/internal/app/SimpleIconFactory.java index eb1530e97b7f..a85485d3969b 100644 --- a/core/java/com/android/internal/app/SimpleIconFactory.java +++ b/core/java/com/android/internal/app/SimpleIconFactory.java @@ -16,11 +16,13 @@ package com.android.internal.app; +import static android.content.Context.ACTIVITY_SERVICE; import static android.graphics.Paint.DITHER_FLAG; import static android.graphics.Paint.FILTER_BITMAP_FLAG; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.ActivityManager; import android.content.Context; import android.content.pm.PackageManager; import android.content.res.Resources; @@ -42,6 +44,7 @@ import android.graphics.drawable.DrawableWrapper; import android.os.Process; import android.os.UserHandle; import android.util.AttributeSet; +import android.util.Pools.SynchronizedPool; import com.android.internal.R; @@ -58,6 +61,9 @@ import java.nio.ByteBuffer; @Deprecated public class SimpleIconFactory { + private static final SynchronizedPool<SimpleIconFactory> sPool = + new SynchronizedPool<>(Runtime.getRuntime().availableProcessors()); + private static final int DEFAULT_WRAPPER_BACKGROUND = Color.WHITE; private static final float BLUR_FACTOR = 0.5f / 48; @@ -74,10 +80,45 @@ public class SimpleIconFactory { private final Rect mOldBounds = new Rect(); /** + * Obtain a SimpleIconFactory from a pool objects. + * + * @deprecated Do not use, functionality will be replaced by iconloader lib eventually. + */ + @Deprecated + public static SimpleIconFactory obtain(Context ctx) { + SimpleIconFactory instance = sPool.acquire(); + if (instance == null) { + final ActivityManager am = (ActivityManager) ctx.getSystemService(ACTIVITY_SERVICE); + final int iconDpi = (am == null) ? 0 : am.getLauncherLargeIconDensity(); + + final Resources r = ctx.getResources(); + final int iconSize = r.getDimensionPixelSize(R.dimen.resolver_icon_size); + final int badgeSize = r.getDimensionPixelSize(R.dimen.resolver_badge_size); + + instance = new SimpleIconFactory(ctx, iconDpi, iconSize, badgeSize); + instance.setWrapperBackgroundColor(Color.WHITE); + } + + return instance; + } + + /** + * Recycles the SimpleIconFactory so others may use it. + * + * @deprecated Do not use, functionality will be replaced by iconloader lib eventually. + */ + @Deprecated + public void recycle() { + // Return to default background color + setWrapperBackgroundColor(Color.WHITE); + sPool.release(this); + } + + /** * @deprecated Do not use, functionality will be replaced by iconloader lib eventually. */ @Deprecated - SimpleIconFactory(Context context, int fillResIconDpi, int iconBitmapSize, + private SimpleIconFactory(Context context, int fillResIconDpi, int iconBitmapSize, int badgeBitmapSize) { mContext = context.getApplicationContext(); mPm = mContext.getPackageManager(); @@ -170,7 +211,7 @@ public class SimpleIconFactory { * @deprecated Do not use, functionality will be replaced by iconloader lib eventually. */ @Deprecated - public Bitmap createAppBadgedIconBitmap(@Nullable Drawable icon, Bitmap renderedAppIcon) { + Bitmap createAppBadgedIconBitmap(@Nullable Drawable icon, Bitmap renderedAppIcon) { // Flatten the passed in icon float [] scale = new float[1]; diff --git a/core/java/com/android/internal/app/WindowDecorActionBar.java b/core/java/com/android/internal/app/WindowDecorActionBar.java index 119f30df8946..e71ee66c677c 100644 --- a/core/java/com/android/internal/app/WindowDecorActionBar.java +++ b/core/java/com/android/internal/app/WindowDecorActionBar.java @@ -84,6 +84,7 @@ public class WindowDecorActionBar extends ActionBar implements private ActionBarContextView mContextView; private ActionBarContainer mSplitView; private View mContentView; + @UnsupportedAppUsage private ScrollingTabContainerView mTabScrollView; private ArrayList<TabImpl> mTabs = new ArrayList<TabImpl>(); @@ -331,6 +332,7 @@ public class WindowDecorActionBar extends ActionBar implements * * @param enabled true to animate, false to not animate. */ + @UnsupportedAppUsage public void setShowHideAnimationEnabled(boolean enabled) { mShowHideAnimationEnabled = enabled; if (!enabled && mCurrentShowAnim != null) { @@ -1147,6 +1149,7 @@ public class WindowDecorActionBar extends ActionBar implements * @hide */ public class TabImpl extends ActionBar.Tab { + @UnsupportedAppUsage private ActionBar.TabListener mCallback; private Object mTag; private Drawable mIcon; diff --git a/core/java/com/android/internal/database/SortCursor.java b/core/java/com/android/internal/database/SortCursor.java index 00255128972c..7fe809ee319b 100644 --- a/core/java/com/android/internal/database/SortCursor.java +++ b/core/java/com/android/internal/database/SortCursor.java @@ -16,6 +16,7 @@ package com.android.internal.database; +import android.annotation.UnsupportedAppUsage; import android.database.AbstractCursor; import android.database.Cursor; import android.database.DataSetObserver; @@ -28,7 +29,9 @@ import android.util.Log; public class SortCursor extends AbstractCursor { private static final String TAG = "SortCursor"; + @UnsupportedAppUsage private Cursor mCursor; // updated in onMove + @UnsupportedAppUsage private Cursor[] mCursors; private int [] mSortColumns; private final int ROWCACHESIZE = 64; @@ -52,6 +55,7 @@ public class SortCursor extends AbstractCursor } }; + @UnsupportedAppUsage public SortCursor(Cursor[] cursors, String sortcolumn) { mCursors = cursors; diff --git a/core/java/com/android/internal/http/HttpDateTime.java b/core/java/com/android/internal/http/HttpDateTime.java index 8ebd4aaf1ac0..f7706e310952 100644 --- a/core/java/com/android/internal/http/HttpDateTime.java +++ b/core/java/com/android/internal/http/HttpDateTime.java @@ -16,6 +16,7 @@ package com.android.internal.http; +import android.annotation.UnsupportedAppUsage; import android.text.format.Time; import java.util.Calendar; @@ -82,6 +83,7 @@ public final class HttpDateTime { int second; } + @UnsupportedAppUsage public static long parse(String timeString) throws IllegalArgumentException { diff --git a/core/java/com/android/internal/infra/AbstractRemoteService.java b/core/java/com/android/internal/infra/AbstractRemoteService.java index 5c144d3b5752..0a83fcc6db61 100644 --- a/core/java/com/android/internal/infra/AbstractRemoteService.java +++ b/core/java/com/android/internal/infra/AbstractRemoteService.java @@ -481,7 +481,11 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I @Override public String toString() { - return getClass().getSimpleName() + "[" + mComponentName + "]"; + return getClass().getSimpleName() + "[" + mComponentName + + " " + System.identityHashCode(this) + + (mService != null ? " (bound)" : " (unbound)") + + (mDestroyed ? " (destroyed)" : "") + + "]"; } /** diff --git a/core/java/com/android/internal/os/AndroidPrintStream.java b/core/java/com/android/internal/os/AndroidPrintStream.java index 7f4807a5b863..fe2341144d28 100644 --- a/core/java/com/android/internal/os/AndroidPrintStream.java +++ b/core/java/com/android/internal/os/AndroidPrintStream.java @@ -16,6 +16,7 @@ package com.android.internal.os; +import android.annotation.UnsupportedAppUsage; import android.util.Log; /** @@ -34,6 +35,7 @@ class AndroidPrintStream extends LoggingPrintStream { * @param priority from {@link android.util.Log} * @param tag to log */ + @UnsupportedAppUsage public AndroidPrintStream(int priority, String tag) { if (tag == null) { throw new NullPointerException("tag"); diff --git a/core/java/com/android/internal/os/BaseCommand.java b/core/java/com/android/internal/os/BaseCommand.java index 05ec9e90513e..278f40660ee9 100644 --- a/core/java/com/android/internal/os/BaseCommand.java +++ b/core/java/com/android/internal/os/BaseCommand.java @@ -17,12 +17,14 @@ package com.android.internal.os; +import android.annotation.UnsupportedAppUsage; import android.os.ShellCommand; import java.io.PrintStream; public abstract class BaseCommand { + @UnsupportedAppUsage final protected ShellCommand mArgs = new ShellCommand() { @Override public int onCommand(String cmd) { return 0; diff --git a/core/java/com/android/internal/os/BinderInternal.java b/core/java/com/android/internal/os/BinderInternal.java index aa4846f6059e..4901e1f67d92 100644 --- a/core/java/com/android/internal/os/BinderInternal.java +++ b/core/java/com/android/internal/os/BinderInternal.java @@ -17,6 +17,7 @@ package com.android.internal.os; import android.annotation.NonNull; +import android.annotation.UnsupportedAppUsage; import android.os.Binder; import android.os.Handler; import android.os.IBinder; @@ -157,6 +158,7 @@ public class BinderInternal { * an implementation of IServiceManager, which you can use to find * other services. */ + @UnsupportedAppUsage public static final native IBinder getContextObject(); /** @@ -168,6 +170,7 @@ public class BinderInternal { public static final native void setMaxThreads(int numThreads); + @UnsupportedAppUsage static native final void handleGc(); public static void forceGc(String reason) { diff --git a/core/java/com/android/internal/os/ClassLoaderFactory.java b/core/java/com/android/internal/os/ClassLoaderFactory.java index 99a1a19686e4..d32349834dd8 100644 --- a/core/java/com/android/internal/os/ClassLoaderFactory.java +++ b/core/java/com/android/internal/os/ClassLoaderFactory.java @@ -16,6 +16,7 @@ package com.android.internal.os; +import android.annotation.UnsupportedAppUsage; import android.os.Trace; import dalvik.system.DelegateLastClassLoader; @@ -132,6 +133,7 @@ public class ClassLoaderFactory { return classLoader; } + @UnsupportedAppUsage private static native String createClassloaderNamespace(ClassLoader classLoader, int targetSdkVersion, String librarySearchPath, diff --git a/core/java/com/android/internal/os/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java index 4b878c7c4808..61799183e595 100644 --- a/core/java/com/android/internal/os/ProcessCpuTracker.java +++ b/core/java/com/android/internal/os/ProcessCpuTracker.java @@ -18,6 +18,7 @@ package com.android.internal.os; import static android.os.Process.*; +import android.annotation.UnsupportedAppUsage; import android.os.FileUtils; import android.os.Process; import android.os.StrictMode; @@ -191,6 +192,7 @@ public class ProcessCpuTracker { public boolean interesting; public String baseName; + @UnsupportedAppUsage public String name; public int nameWidth; @@ -206,6 +208,7 @@ public class ProcessCpuTracker { /** * Time in milliseconds. */ + @UnsupportedAppUsage public long rel_uptime; /** @@ -221,11 +224,13 @@ public class ProcessCpuTracker { /** * Time in milliseconds. */ + @UnsupportedAppUsage public int rel_utime; /** * Time in milliseconds. */ + @UnsupportedAppUsage public int rel_stime; public long base_minfaults; @@ -286,6 +291,7 @@ public class ProcessCpuTracker { }; + @UnsupportedAppUsage public ProcessCpuTracker(boolean includeThreads) { mIncludeThreads = includeThreads; long jiffyHz = Os.sysconf(OsConstants._SC_CLK_TCK); @@ -305,6 +311,7 @@ public class ProcessCpuTracker { update(); } + @UnsupportedAppUsage public void update() { if (DEBUG) Slog.v(TAG, "Update: " + this); @@ -707,11 +714,13 @@ public class ProcessCpuTracker { return statses; } + @UnsupportedAppUsage final public int countWorkingStats() { buildWorkingProcs(); return mWorkingProcs.size(); } + @UnsupportedAppUsage final public Stats getWorkingStats(int index) { return mWorkingProcs.get(index); } diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java index e37e650f6e50..eac150dbd320 100644 --- a/core/java/com/android/internal/os/RuntimeInit.java +++ b/core/java/com/android/internal/os/RuntimeInit.java @@ -16,6 +16,7 @@ package com.android.internal.os; +import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; import android.app.ActivityThread; import android.app.ApplicationErrorReport; @@ -48,8 +49,10 @@ public class RuntimeInit { final static boolean DEBUG = false; /** true if commonInit() has been called */ + @UnsupportedAppUsage private static boolean initialized; + @UnsupportedAppUsage private static IBinder mApplicationObject; private static volatile boolean mCrashing = false; @@ -186,6 +189,7 @@ public class RuntimeInit { } } + @UnsupportedAppUsage protected static final void commonInit() { if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!"); @@ -315,6 +319,7 @@ public class RuntimeInit { return new MethodAndArgsCaller(m, argv); } + @UnsupportedAppUsage public static final void main(String[] argv) { enableDdms(); if (argv.length == 2 && argv[1].equals("application")) { @@ -402,6 +407,7 @@ public class RuntimeInit { mApplicationObject = app; } + @UnsupportedAppUsage public static final IBinder getApplicationObject() { return mApplicationObject; } diff --git a/core/java/com/android/internal/os/ZygoteConfig.java b/core/java/com/android/internal/os/ZygoteConfig.java index c8ff51e77866..c6af8c2f4316 100644 --- a/core/java/com/android/internal/os/ZygoteConfig.java +++ b/core/java/com/android/internal/os/ZygoteConfig.java @@ -24,14 +24,14 @@ package com.android.internal.os; public class ZygoteConfig { /** If {@code true}, enables the unspecialized app process (USAP) pool feature */ - public static final String USAP_POOL_ENABLED = "blastula_pool_enabled"; + public static final String USAP_POOL_ENABLED = "usap_pool_enabled"; /** The threshold used to determine if the pool should be refilled */ - public static final String USAP_POOL_REFILL_THRESHOLD = "blastula_refill_threshold"; + public static final String USAP_POOL_REFILL_THRESHOLD = "usap_refill_threshold"; /** The maximum number of processes to keep in the USAP pool */ - public static final String USAP_POOL_SIZE_MAX = "blastula_pool_size_max"; + public static final String USAP_POOL_SIZE_MAX = "usap_pool_size_max"; /** The minimum number of processes to keep in the USAP pool */ - public static final String USAP_POOL_SIZE_MIN = "blastula_pool_size_min"; + public static final String USAP_POOL_SIZE_MIN = "usap_pool_size_min"; } diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java index 87adce7c3a62..922c7218c44a 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java @@ -26,6 +26,7 @@ import static android.system.OsConstants.STDOUT_FILENO; import static com.android.internal.os.ZygoteConnectionConstants.CONNECTION_TIMEOUT_MILLIS; import static com.android.internal.os.ZygoteConnectionConstants.WRAPPED_PID_TIMEOUT_MILLIS; +import android.annotation.UnsupportedAppUsage; import android.content.pm.ApplicationInfo; import android.metrics.LogMaker; import android.net.Credentials; @@ -69,9 +70,12 @@ class ZygoteConnection { * that it closes when the child process terminates. In other cases, * it is closed in the peer. */ + @UnsupportedAppUsage private final LocalSocket mSocket; + @UnsupportedAppUsage private final DataOutputStream mSocketOutStream; private final BufferedReader mSocketReader; + @UnsupportedAppUsage private final Credentials peer; private final String abiList; private boolean isEof; @@ -522,6 +526,7 @@ class ZygoteConnection { /** * Closes socket associated with this connection. */ + @UnsupportedAppUsage void closeSocket() { try { mSocket.close(); diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 07b82d006cc8..dd180601d537 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -19,6 +19,7 @@ package com.android.internal.os; import static android.system.OsConstants.S_IRWXG; import static android.system.OsConstants.S_IRWXO; +import android.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.content.res.TypedArray; import android.os.Build; @@ -102,6 +103,7 @@ public class ZygoteInit { /** * Used to pre-load resources. */ + @UnsupportedAppUsage private static Resources mResources; /** @@ -777,6 +779,7 @@ public class ZygoteInit { return result; } + @UnsupportedAppUsage public static void main(String argv[]) { ZygoteServer zygoteServer = null; diff --git a/core/java/com/android/internal/os/ZygoteSecurityException.java b/core/java/com/android/internal/os/ZygoteSecurityException.java index 13b47597c1eb..7e50cb885324 100644 --- a/core/java/com/android/internal/os/ZygoteSecurityException.java +++ b/core/java/com/android/internal/os/ZygoteSecurityException.java @@ -16,10 +16,13 @@ package com.android.internal.os; +import android.annotation.UnsupportedAppUsage; + /** * Exception thrown when a security policy is violated. */ class ZygoteSecurityException extends RuntimeException { + @UnsupportedAppUsage ZygoteSecurityException(String message) { super(message); } diff --git a/core/java/com/android/internal/os/ZygoteServer.java b/core/java/com/android/internal/os/ZygoteServer.java index 3f3aba9b6682..5d1911b9c29a 100644 --- a/core/java/com/android/internal/os/ZygoteServer.java +++ b/core/java/com/android/internal/os/ZygoteServer.java @@ -353,6 +353,8 @@ class ZygoteServer { return null; } + Log.i(TAG, "USAP Pool status change: " + (newStatus ? "ENABLED" : "DISABLED")); + mUsapPoolEnabled = newStatus; if (newStatus) { diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java index c4626c2093e8..ca5db940a4d0 100644 --- a/core/java/com/android/internal/policy/DecorView.java +++ b/core/java/com/android/internal/policy/DecorView.java @@ -46,6 +46,7 @@ import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.annotation.Nullable; import android.annotation.TestApi; +import android.annotation.UnsupportedAppUsage; import android.app.WindowConfiguration; import android.content.Context; import android.content.res.Configuration; @@ -210,18 +211,22 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind private final BackgroundFallback mBackgroundFallback = new BackgroundFallback(); private int mLastTopInset = 0; + @UnsupportedAppUsage private int mLastBottomInset = 0; + @UnsupportedAppUsage private int mLastRightInset = 0; + @UnsupportedAppUsage private int mLastLeftInset = 0; private boolean mLastHasTopStableInset = false; private boolean mLastHasBottomStableInset = false; private boolean mLastHasRightStableInset = false; private boolean mLastHasLeftStableInset = false; private int mLastWindowFlags = 0; - private boolean mLastShouldAlwaysConsumeNavBar = false; + private boolean mLastShouldAlwaysConsumeSystemBars = false; private int mRootScrollY = 0; + @UnsupportedAppUsage private PhoneWindow mWindow; ViewGroup mContentRoot; @@ -1102,7 +1107,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind disallowAnimate |= (hasLeftStableInset != mLastHasLeftStableInset); mLastHasLeftStableInset = hasLeftStableInset; - mLastShouldAlwaysConsumeNavBar = insets.shouldAlwaysConsumeNavBar(); + mLastShouldAlwaysConsumeSystemBars = insets.shouldAlwaysConsumeSystemBars(); } boolean navBarToRightEdge = isNavBarToRightEdge(mLastBottomInset, mLastRightInset); @@ -1133,7 +1138,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind (attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0 && (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) == 0 && (sysUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0 - || mLastShouldAlwaysConsumeNavBar; + || mLastShouldAlwaysConsumeSystemBars; // If we didn't request fullscreen layout, but we still got it because of the // mForceWindowDrawsStatusBarBackground flag, also consume top inset. @@ -1142,7 +1147,8 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind && (attrs.flags & FLAG_LAYOUT_IN_SCREEN) == 0 && (attrs.flags & FLAG_LAYOUT_INSET_DECOR) == 0 && mForceWindowDrawsStatusBarBackground - && mLastTopInset != 0; + && mLastTopInset != 0 + || mLastShouldAlwaysConsumeSystemBars; int consumedTop = consumingStatusBar ? mLastTopInset : 0; int consumedRight = consumingNavBar ? mLastRightInset : 0; diff --git a/core/java/com/android/internal/policy/PhoneFallbackEventHandler.java b/core/java/com/android/internal/policy/PhoneFallbackEventHandler.java index d8ee4dd34269..791c2d7aa4b2 100644 --- a/core/java/com/android/internal/policy/PhoneFallbackEventHandler.java +++ b/core/java/com/android/internal/policy/PhoneFallbackEventHandler.java @@ -16,6 +16,7 @@ package com.android.internal.policy; +import android.annotation.UnsupportedAppUsage; import android.app.KeyguardManager; import android.app.SearchManager; import android.content.ActivityNotFoundException; @@ -41,7 +42,9 @@ public class PhoneFallbackEventHandler implements FallbackEventHandler { private static String TAG = "PhoneFallbackEventHandler"; private static final boolean DEBUG = false; + @UnsupportedAppUsage Context mContext; + @UnsupportedAppUsage View mView; AudioManager mAudioManager; @@ -50,6 +53,7 @@ public class PhoneFallbackEventHandler implements FallbackEventHandler { TelephonyManager mTelephonyManager; MediaSessionManager mMediaSessionManager; + @UnsupportedAppUsage public PhoneFallbackEventHandler(Context context) { mContext = context; } @@ -74,6 +78,7 @@ public class PhoneFallbackEventHandler implements FallbackEventHandler { } } + @UnsupportedAppUsage boolean onKeyDown(int keyCode, KeyEvent event) { /* **************************************************************************** * HOW TO DECIDE WHERE YOUR KEY HANDLING GOES. @@ -207,6 +212,7 @@ public class PhoneFallbackEventHandler implements FallbackEventHandler { && (getKeyguardManager().inKeyguardRestrictedInputMode() || dispatcher == null); } + @UnsupportedAppUsage boolean onKeyUp(int keyCode, KeyEvent event) { if (DEBUG) { Log.d(TAG, "up " + keyCode); @@ -270,6 +276,7 @@ public class PhoneFallbackEventHandler implements FallbackEventHandler { return false; } + @UnsupportedAppUsage void startCallActivity() { sendCloseSystemWindows(); Intent intent = new Intent(Intent.ACTION_CALL_BUTTON); diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java index 69efb2b10af0..890ee860fae1 100644 --- a/core/java/com/android/internal/policy/PhoneWindow.java +++ b/core/java/com/android/internal/policy/PhoneWindow.java @@ -34,6 +34,7 @@ import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_M import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND; import android.annotation.NonNull; +import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; import android.app.KeyguardManager; import android.app.SearchManager; @@ -246,6 +247,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { private boolean mForcedStatusBarColor = false; private boolean mForcedNavigationBarColor = false; + @UnsupportedAppUsage private CharSequence mTitle = null; private int mTitleColor = 0; @@ -309,6 +311,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { static final RotationWatcher sRotationWatcher = new RotationWatcher(); + @UnsupportedAppUsage public PhoneWindow(Context context) { super(context); mLayoutInflater = LayoutInflater.from(context); diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java index ff5b9968a408..3303374fd6c4 100644 --- a/core/java/com/android/internal/util/ArrayUtils.java +++ b/core/java/com/android/internal/util/ArrayUtils.java @@ -18,6 +18,7 @@ package com.android.internal.util; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.UnsupportedAppUsage; import android.util.ArraySet; import dalvik.system.VMRuntime; @@ -55,6 +56,7 @@ public class ArrayUtils { return (char[])VMRuntime.getRuntime().newUnpaddedArray(char.class, minLen); } + @UnsupportedAppUsage public static int[] newUnpaddedIntArray(int minLen) { return (int[])VMRuntime.getRuntime().newUnpaddedArray(int.class, minLen); } @@ -75,6 +77,7 @@ public class ArrayUtils { return (Object[])VMRuntime.getRuntime().newUnpaddedArray(Object.class, minLen); } + @UnsupportedAppUsage @SuppressWarnings("unchecked") public static <T> T[] newUnpaddedArray(Class<T> clazz, int minLen) { return (T[])VMRuntime.getRuntime().newUnpaddedArray(clazz, minLen); @@ -112,6 +115,7 @@ public class ArrayUtils { * it will return the same empty array every time to avoid reallocation, * although this is not guaranteed. */ + @UnsupportedAppUsage @SuppressWarnings("unchecked") public static <T> T[] emptyArray(Class<T> kind) { if (kind == Object.class) { @@ -148,6 +152,7 @@ public class ArrayUtils { /** * Checks if given array is null or has zero elements. */ + @UnsupportedAppUsage public static <T> boolean isEmpty(@Nullable T[] array) { return array == null || array.length == 0; } @@ -200,6 +205,7 @@ public class ArrayUtils { * @param value the value to check for * @return true if the value is present in the array */ + @UnsupportedAppUsage public static <T> boolean contains(@Nullable T[] array, T value) { return indexOf(array, value) != -1; } @@ -208,6 +214,7 @@ public class ArrayUtils { * Return first index of {@code value} in {@code array}, or {@code -1} if * not found. */ + @UnsupportedAppUsage public static <T> int indexOf(@Nullable T[] array, T value) { if (array == null) return -1; for (int i = 0; i < array.length; i++) { @@ -242,6 +249,7 @@ public class ArrayUtils { return false; } + @UnsupportedAppUsage public static boolean contains(@Nullable int[] array, int value) { if (array == null) return false; for (int element : array) { @@ -333,6 +341,7 @@ public class ArrayUtils { * Adds value to given array if not already present, providing set-like * behavior. */ + @UnsupportedAppUsage @SuppressWarnings("unchecked") public static @NonNull <T> T[] appendElement(Class<T> kind, @Nullable T[] array, T element) { return appendElement(kind, array, element, false); @@ -362,6 +371,7 @@ public class ArrayUtils { /** * Removes value from given array if present, providing set-like behavior. */ + @UnsupportedAppUsage @SuppressWarnings("unchecked") public static @Nullable <T> T[] removeElement(Class<T> kind, @Nullable T[] array, T element) { if (array != null) { @@ -408,6 +418,7 @@ public class ArrayUtils { * Adds value to given array if not already present, providing set-like * behavior. */ + @UnsupportedAppUsage public static @NonNull int[] appendInt(@Nullable int[] cur, int val) { return appendInt(cur, val, false); } diff --git a/core/java/com/android/internal/util/BitwiseInputStream.java b/core/java/com/android/internal/util/BitwiseInputStream.java index 86f74f302518..6ff67e9b9718 100644 --- a/core/java/com/android/internal/util/BitwiseInputStream.java +++ b/core/java/com/android/internal/util/BitwiseInputStream.java @@ -16,6 +16,8 @@ package com.android.internal.util; +import android.annotation.UnsupportedAppUsage; + /** * An object that provides bitwise incremental read access to a byte array. * @@ -49,6 +51,7 @@ public class BitwiseInputStream { * * @param buf a byte array containing data */ + @UnsupportedAppUsage public BitwiseInputStream(byte buf[]) { mBuf = buf; mEnd = buf.length << 3; @@ -58,6 +61,7 @@ public class BitwiseInputStream { /** * Return the number of bit still available for reading. */ + @UnsupportedAppUsage public int available() { return mEnd - mPos; } @@ -71,6 +75,7 @@ public class BitwiseInputStream { * @param bits the amount of data to read (gte 0, lte 8) * @return byte of read data (possibly partially filled, from lsb) */ + @UnsupportedAppUsage public int read(int bits) throws AccessException { int index = mPos >>> 3; int offset = 16 - (mPos & 0x07) - bits; // &7==%8 @@ -92,6 +97,7 @@ public class BitwiseInputStream { * @param bits the amount of data to read * @return newly allocated byte array of read data */ + @UnsupportedAppUsage public byte[] readByteArray(int bits) throws AccessException { int bytes = (bits >>> 3) + ((bits & 0x07) > 0 ? 1 : 0); // &7==%8 byte[] arr = new byte[bytes]; @@ -107,6 +113,7 @@ public class BitwiseInputStream { * * @param bits the amount by which to increment the position */ + @UnsupportedAppUsage public void skip(int bits) throws AccessException { if ((mPos + bits) > mEnd) { throw new AccessException("illegal skip " + diff --git a/core/java/com/android/internal/util/BitwiseOutputStream.java b/core/java/com/android/internal/util/BitwiseOutputStream.java index ddecbed1d97c..cdd6f173484c 100644 --- a/core/java/com/android/internal/util/BitwiseOutputStream.java +++ b/core/java/com/android/internal/util/BitwiseOutputStream.java @@ -16,6 +16,8 @@ package com.android.internal.util; +import android.annotation.UnsupportedAppUsage; + /** * An object that provides bitwise incremental write access to a byte array. * @@ -49,6 +51,7 @@ public class BitwiseOutputStream { * * @param startingLength initial internal byte array length in bytes */ + @UnsupportedAppUsage public BitwiseOutputStream(int startingLength) { mBuf = new byte[startingLength]; mEnd = startingLength << 3; @@ -60,6 +63,7 @@ public class BitwiseOutputStream { * * @return newly allocated byte array */ + @UnsupportedAppUsage public byte[] toByteArray() { int len = (mPos >>> 3) + ((mPos & 0x07) > 0 ? 1 : 0); // &7==%8 byte[] newBuf = new byte[len]; @@ -89,6 +93,7 @@ public class BitwiseOutputStream { * @param bits the amount of data to write (gte 0, lte 8) * @param data to write, will be masked to expose only bits param from lsb */ + @UnsupportedAppUsage public void write(int bits, int data) throws AccessException { if ((bits < 0) || (bits > 8)) { throw new AccessException("illegal write (" + bits + " bits)"); @@ -109,6 +114,7 @@ public class BitwiseOutputStream { * @param bits the amount of data to write * @param arr the byte array containing data to be written */ + @UnsupportedAppUsage public void writeByteArray(int bits, byte[] arr) throws AccessException { for (int i = 0; i < arr.length; i++) { int increment = Math.min(8, bits - (i << 3)); diff --git a/core/java/com/android/internal/util/CharSequences.java b/core/java/com/android/internal/util/CharSequences.java index fdaa4bce25db..6b6c43ce8195 100644 --- a/core/java/com/android/internal/util/CharSequences.java +++ b/core/java/com/android/internal/util/CharSequences.java @@ -16,6 +16,8 @@ package com.android.internal.util; +import android.annotation.UnsupportedAppUsage; + /** * {@link CharSequence} utility methods. */ @@ -93,6 +95,7 @@ public class CharSequences { /** * Compares two character sequences for equality. */ + @UnsupportedAppUsage public static boolean equals(CharSequence a, CharSequence b) { if (a.length() != b.length()) { return false; @@ -114,6 +117,7 @@ public class CharSequences { * @param another The other CharSequence. * @return See {@link Comparable#compareTo}. */ + @UnsupportedAppUsage public static int compareToIgnoreCase(CharSequence me, CharSequence another) { // Code adapted from String#compareTo int myLen = me.length(), anotherLen = another.length(); diff --git a/core/java/com/android/internal/util/FastMath.java b/core/java/com/android/internal/util/FastMath.java index 88a17e6ba259..35efe708795e 100644 --- a/core/java/com/android/internal/util/FastMath.java +++ b/core/java/com/android/internal/util/FastMath.java @@ -16,6 +16,8 @@ package com.android.internal.util; +import android.annotation.UnsupportedAppUsage; + /** * Fast and loose math routines. */ @@ -26,6 +28,7 @@ public class FastMath { * thought it may return slightly different results. It does not try to * handle (in any meaningful way) NaN or infinities. */ + @UnsupportedAppUsage public static int round(float value) { long lx = (long) (value * (65536 * 256f)); return (int) ((lx + 0x800000) >> 24); diff --git a/core/java/com/android/internal/util/FastXmlSerializer.java b/core/java/com/android/internal/util/FastXmlSerializer.java index b85b84fb3dc8..9f76aeb663c5 100644 --- a/core/java/com/android/internal/util/FastXmlSerializer.java +++ b/core/java/com/android/internal/util/FastXmlSerializer.java @@ -18,6 +18,7 @@ package com.android.internal.util; import org.xmlpull.v1.XmlSerializer; +import android.annotation.UnsupportedAppUsage; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; @@ -69,6 +70,7 @@ public class FastXmlSerializer implements XmlSerializer { private int mNesting = 0; private boolean mLineStart = true; + @UnsupportedAppUsage public FastXmlSerializer() { this(DEFAULT_BUFFER_LEN); } diff --git a/core/java/com/android/internal/util/GrowingArrayUtils.java b/core/java/com/android/internal/util/GrowingArrayUtils.java index 968d9204b106..9f563667e019 100644 --- a/core/java/com/android/internal/util/GrowingArrayUtils.java +++ b/core/java/com/android/internal/util/GrowingArrayUtils.java @@ -16,6 +16,8 @@ package com.android.internal.util; +import android.annotation.UnsupportedAppUsage; + /** * A helper class that aims to provide comparable growth performance to ArrayList, but on primitive * arrays. Common array operations are implemented for efficient use in dynamic containers. @@ -37,6 +39,7 @@ public final class GrowingArrayUtils { * @return the array to which the element was appended. This may be different than the given * array. */ + @UnsupportedAppUsage public static <T> T[] append(T[] array, int currentSize, T element) { assert currentSize <= array.length; @@ -54,6 +57,7 @@ public final class GrowingArrayUtils { /** * Primitive int version of {@link #append(Object[], int, Object)}. */ + @UnsupportedAppUsage public static int[] append(int[] array, int currentSize, int element) { assert currentSize <= array.length; diff --git a/core/java/com/android/internal/util/HexDump.java b/core/java/com/android/internal/util/HexDump.java index af004009e1ee..6ffc92853b08 100644 --- a/core/java/com/android/internal/util/HexDump.java +++ b/core/java/com/android/internal/util/HexDump.java @@ -17,6 +17,7 @@ package com.android.internal.util; import android.annotation.Nullable; +import android.annotation.UnsupportedAppUsage; public class HexDump { @@ -100,16 +101,19 @@ public class HexDump return toHexString(toByteArray(b)); } + @UnsupportedAppUsage public static String toHexString(byte[] array) { return toHexString(array, 0, array.length, true); } + @UnsupportedAppUsage public static String toHexString(byte[] array, boolean upperCase) { return toHexString(array, 0, array.length, upperCase); } + @UnsupportedAppUsage public static String toHexString(byte[] array, int offset, int length) { return toHexString(array, offset, length, true); @@ -131,6 +135,7 @@ public class HexDump return new String(buf); } + @UnsupportedAppUsage public static String toHexString(int i) { return toHexString(toByteArray(i)); @@ -164,6 +169,7 @@ public class HexDump throw new RuntimeException ("Invalid hex char '" + c + "'"); } + @UnsupportedAppUsage public static byte[] hexStringToByteArray(String hexString) { int length = hexString.length(); diff --git a/core/java/com/android/internal/util/IState.java b/core/java/com/android/internal/util/IState.java index 056f8e9b0424..eb66e2ce94d7 100644 --- a/core/java/com/android/internal/util/IState.java +++ b/core/java/com/android/internal/util/IState.java @@ -16,6 +16,7 @@ package com.android.internal.util; +import android.annotation.UnsupportedAppUsage; import android.os.Message; /** @@ -67,5 +68,6 @@ public interface IState { * * @return name of state. */ + @UnsupportedAppUsage String getName(); } diff --git a/core/java/com/android/internal/util/MemInfoReader.java b/core/java/com/android/internal/util/MemInfoReader.java index 8d7166679b78..630916ebeecb 100644 --- a/core/java/com/android/internal/util/MemInfoReader.java +++ b/core/java/com/android/internal/util/MemInfoReader.java @@ -16,12 +16,14 @@ package com.android.internal.util; +import android.annotation.UnsupportedAppUsage; import android.os.Debug; import android.os.StrictMode; public final class MemInfoReader { final long[] mInfos = new long[Debug.MEMINFO_COUNT]; + @UnsupportedAppUsage public void readMemInfo() { // Permit disk reads here, as /proc/meminfo isn't really "on // disk" and should be fast. TODO: make BlockGuard ignore @@ -37,6 +39,7 @@ public final class MemInfoReader { /** * Total amount of RAM available to the kernel. */ + @UnsupportedAppUsage public long getTotalSize() { return mInfos[Debug.MEMINFO_TOTAL] * 1024; } @@ -44,6 +47,7 @@ public final class MemInfoReader { /** * Amount of RAM that is not being used for anything. */ + @UnsupportedAppUsage public long getFreeSize() { return mInfos[Debug.MEMINFO_FREE] * 1024; } @@ -52,6 +56,7 @@ public final class MemInfoReader { * Amount of RAM that the kernel is being used for caches, not counting caches * that are mapped in to processes. */ + @UnsupportedAppUsage public long getCachedSize() { return getCachedSizeKb() * 1024; } @@ -107,6 +112,7 @@ public final class MemInfoReader { return mInfos[Debug.MEMINFO_ZRAM_TOTAL]; } + @UnsupportedAppUsage public long[] getRawInfo() { return mInfos; } diff --git a/core/java/com/android/internal/util/Preconditions.java b/core/java/com/android/internal/util/Preconditions.java index 2c6a0e06f6e7..731b93c18b09 100644 --- a/core/java/com/android/internal/util/Preconditions.java +++ b/core/java/com/android/internal/util/Preconditions.java @@ -18,6 +18,7 @@ package com.android.internal.util; import android.annotation.IntRange; import android.annotation.NonNull; +import android.annotation.UnsupportedAppUsage; import android.text.TextUtils; import java.util.Collection; @@ -28,6 +29,7 @@ import java.util.Collection; */ public class Preconditions { + @UnsupportedAppUsage public static void checkArgument(boolean expression) { if (!expression) { throw new IllegalArgumentException(); @@ -42,6 +44,7 @@ public class Preconditions { * be converted to a string using {@link String#valueOf(Object)} * @throws IllegalArgumentException if {@code expression} is false */ + @UnsupportedAppUsage public static void checkArgument(boolean expression, final Object errorMessage) { if (!expression) { throw new IllegalArgumentException(String.valueOf(errorMessage)); @@ -106,6 +109,7 @@ public class Preconditions { * @return the non-null reference that was validated * @throws NullPointerException if {@code reference} is null */ + @UnsupportedAppUsage public static @NonNull <T> T checkNotNull(final T reference) { if (reference == null) { throw new NullPointerException(); @@ -123,6 +127,7 @@ public class Preconditions { * @return the non-null reference that was validated * @throws NullPointerException if {@code reference} is null */ + @UnsupportedAppUsage public static @NonNull <T> T checkNotNull(final T reference, final Object errorMessage) { if (reference == null) { throw new NullPointerException(String.valueOf(errorMessage)); @@ -158,6 +163,7 @@ public class Preconditions { * @param message exception message * @throws IllegalStateException if {@code expression} is false */ + @UnsupportedAppUsage public static void checkState(final boolean expression, String message) { if (!expression) { throw new IllegalStateException(message); @@ -171,6 +177,7 @@ public class Preconditions { * @param expression a boolean expression * @throws IllegalStateException if {@code expression} is false */ + @UnsupportedAppUsage public static void checkState(final boolean expression) { checkState(expression, null); } @@ -368,6 +375,7 @@ public class Preconditions { * * @throws IllegalArgumentException if {@code value} was not within the range */ + @UnsupportedAppUsage public static int checkArgumentInRange(int value, int lower, int upper, String valueName) { if (value < lower) { diff --git a/core/java/com/android/internal/util/State.java b/core/java/com/android/internal/util/State.java index 3eadff58bc09..3c61e035e886 100644 --- a/core/java/com/android/internal/util/State.java +++ b/core/java/com/android/internal/util/State.java @@ -16,6 +16,7 @@ package com.android.internal.util; +import android.annotation.UnsupportedAppUsage; import android.os.Message; /** @@ -28,12 +29,14 @@ public class State implements IState { /** * Constructor */ + @UnsupportedAppUsage protected State() { } /* (non-Javadoc) * @see com.android.internal.util.IState#enter() */ + @UnsupportedAppUsage @Override public void enter() { } @@ -41,6 +44,7 @@ public class State implements IState { /* (non-Javadoc) * @see com.android.internal.util.IState#exit() */ + @UnsupportedAppUsage @Override public void exit() { } @@ -48,6 +52,7 @@ public class State implements IState { /* (non-Javadoc) * @see com.android.internal.util.IState#processMessage(android.os.Message) */ + @UnsupportedAppUsage @Override public boolean processMessage(Message msg) { return false; @@ -65,6 +70,7 @@ public class State implements IState { * * @see com.android.internal.util.IState#processMessage(android.os.Message) */ + @UnsupportedAppUsage @Override public String getName() { String name = getClass().getName(); diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java index 7398e9526a42..dacdae6fd6c6 100644 --- a/core/java/com/android/internal/util/StateMachine.java +++ b/core/java/com/android/internal/util/StateMachine.java @@ -1301,6 +1301,7 @@ public class StateMachine { * * @param name of the state machine */ + @UnsupportedAppUsage protected StateMachine(String name) { mSmThread = new HandlerThread(name); mSmThread.start(); @@ -1314,6 +1315,7 @@ public class StateMachine { * * @param name of the state machine */ + @UnsupportedAppUsage protected StateMachine(String name, Looper looper) { initStateMachine(name, looper); } @@ -1323,6 +1325,7 @@ public class StateMachine { * * @param name of the state machine */ + @UnsupportedAppUsage protected StateMachine(String name, Handler handler) { initStateMachine(name, handler.getLooper()); } @@ -1678,6 +1681,7 @@ public class StateMachine { * @param arg2 is assigned to Message.arg2 * @return A Message object from the global pool */ + @UnsupportedAppUsage public final Message obtainMessage(int what, int arg1, int arg2) { return Message.obtain(mSmHandler, what, arg1, arg2); } @@ -1697,6 +1701,7 @@ public class StateMachine { * @param obj is assigned to Message.obj * @return A Message object from the global pool */ + @UnsupportedAppUsage public final Message obtainMessage(int what, int arg1, int arg2, Object obj) { return Message.obtain(mSmHandler, what, arg1, arg2, obj); } @@ -1706,6 +1711,7 @@ public class StateMachine { * * Message is ignored if state machine has quit. */ + @UnsupportedAppUsage public void sendMessage(int what) { // mSmHandler can be null if the state machine has quit. SmHandler smh = mSmHandler; @@ -1719,6 +1725,7 @@ public class StateMachine { * * Message is ignored if state machine has quit. */ + @UnsupportedAppUsage public void sendMessage(int what, Object obj) { // mSmHandler can be null if the state machine has quit. SmHandler smh = mSmHandler; @@ -1732,6 +1739,7 @@ public class StateMachine { * * Message is ignored if state machine has quit. */ + @UnsupportedAppUsage public void sendMessage(int what, int arg1) { // mSmHandler can be null if the state machine has quit. SmHandler smh = mSmHandler; @@ -1758,6 +1766,7 @@ public class StateMachine { * * Message is ignored if state machine has quit. */ + @UnsupportedAppUsage public void sendMessage(int what, int arg1, int arg2, Object obj) { // mSmHandler can be null if the state machine has quit. SmHandler smh = mSmHandler; @@ -1771,6 +1780,7 @@ public class StateMachine { * * Message is ignored if state machine has quit. */ + @UnsupportedAppUsage public void sendMessage(Message msg) { // mSmHandler can be null if the state machine has quit. SmHandler smh = mSmHandler; @@ -2074,6 +2084,7 @@ public class StateMachine { * @param pw * @param args */ + @UnsupportedAppUsage public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println(getName() + ":"); pw.println(" total records=" + getLogRecCount()); diff --git a/core/java/com/android/internal/view/ActionBarPolicy.java b/core/java/com/android/internal/view/ActionBarPolicy.java index 755faf333a1e..d18c35e703da 100644 --- a/core/java/com/android/internal/view/ActionBarPolicy.java +++ b/core/java/com/android/internal/view/ActionBarPolicy.java @@ -18,6 +18,7 @@ package com.android.internal.view; import com.android.internal.R; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; @@ -29,12 +30,15 @@ import android.os.Build; * about how the action bar should lay out and behave on the current device. */ public class ActionBarPolicy { + @UnsupportedAppUsage private Context mContext; + @UnsupportedAppUsage public static ActionBarPolicy get(Context context) { return new ActionBarPolicy(context); } + @UnsupportedAppUsage private ActionBarPolicy(Context context) { mContext = context; } @@ -44,6 +48,7 @@ public class ActionBarPolicy { * bar/action mode. This will be used to determine how many showAsAction="ifRoom" items can fit. * "always" items can override this. */ + @UnsupportedAppUsage public int getMaxActionButtons() { final Configuration config = mContext.getResources().getConfiguration(); final int width = config.screenWidthDp; @@ -62,14 +67,17 @@ public class ActionBarPolicy { return 2; } } + @UnsupportedAppUsage public boolean showsOverflowMenuButton() { return true; } + @UnsupportedAppUsage public int getEmbeddedMenuWidthLimit() { return mContext.getResources().getDisplayMetrics().widthPixels / 2; } + @UnsupportedAppUsage public boolean hasEmbeddedTabs() { final int targetSdk = mContext.getApplicationInfo().targetSdkVersion; if (targetSdk >= Build.VERSION_CODES.JELLY_BEAN) { @@ -85,6 +93,7 @@ public class ActionBarPolicy { width >= 480 || (width >= 640 && height >= 480); } + @UnsupportedAppUsage public int getTabContainerHeight() { TypedArray a = mContext.obtainStyledAttributes(null, R.styleable.ActionBar, com.android.internal.R.attr.actionBarStyle, 0); @@ -106,6 +115,7 @@ public class ActionBarPolicy { Build.VERSION_CODES.ICE_CREAM_SANDWICH; } + @UnsupportedAppUsage public int getStackedTabMaxWidth() { return mContext.getResources().getDimensionPixelSize( R.dimen.action_bar_stacked_tab_max_width); diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java index ae5c67df8f1e..fb9ff15c79ac 100644 --- a/core/java/com/android/internal/view/BaseIWindow.java +++ b/core/java/com/android/internal/view/BaseIWindow.java @@ -44,7 +44,7 @@ public class BaseIWindow extends IWindow.Stub { public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout, - boolean alwaysConsumeNavBar, int displayId, + boolean alwaysConsumeSystemBars, int displayId, DisplayCutout.ParcelableWrapper displayCutout) { if (reportDraw) { try { diff --git a/core/java/com/android/internal/view/InputConnectionWrapper.java b/core/java/com/android/internal/view/InputConnectionWrapper.java index 3bd3072c0ebe..0c057ea6df59 100644 --- a/core/java/com/android/internal/view/InputConnectionWrapper.java +++ b/core/java/com/android/internal/view/InputConnectionWrapper.java @@ -19,6 +19,7 @@ package com.android.internal.view; import android.annotation.AnyThread; import android.annotation.BinderThread; import android.annotation.NonNull; +import android.annotation.UnsupportedAppUsage; import android.inputmethodservice.AbstractInputMethodService; import android.os.Bundle; import android.os.Handler; @@ -78,6 +79,7 @@ public class InputConnectionWrapper implements InputConnection { * sequence number is set to a new integer. We use a sequence number so that replies that * occur after a timeout has expired are not interpreted as replies to a later request. */ + @UnsupportedAppUsage @AnyThread private static InputContextCallback getInstance() { synchronized (InputContextCallback.class) { @@ -102,6 +104,7 @@ public class InputConnectionWrapper implements InputConnection { /** * Makes the given InputContextCallback available for use in the future. */ + @UnsupportedAppUsage @AnyThread private void dispose() { synchronized (InputContextCallback.class) { diff --git a/core/java/com/android/internal/view/WindowManagerPolicyThread.java b/core/java/com/android/internal/view/WindowManagerPolicyThread.java index c8c38bb01886..b009a2d8ca30 100644 --- a/core/java/com/android/internal/view/WindowManagerPolicyThread.java +++ b/core/java/com/android/internal/view/WindowManagerPolicyThread.java @@ -16,6 +16,7 @@ package com.android.internal.view; +import android.annotation.UnsupportedAppUsage; import android.os.Looper; /** @@ -35,6 +36,7 @@ public class WindowManagerPolicyThread { return mThread; } + @UnsupportedAppUsage public static Looper getLooper() { return mLooper; } diff --git a/core/java/com/android/internal/view/menu/ActionMenu.java b/core/java/com/android/internal/view/menu/ActionMenu.java index c657b872e71e..977c1f6fda7b 100644 --- a/core/java/com/android/internal/view/menu/ActionMenu.java +++ b/core/java/com/android/internal/view/menu/ActionMenu.java @@ -19,6 +19,7 @@ package com.android.internal.view.menu; import java.util.ArrayList; import java.util.List; +import android.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -39,6 +40,7 @@ public class ActionMenu implements Menu { private ArrayList<ActionMenuItem> mItems; + @UnsupportedAppUsage public ActionMenu(Context context) { mContext = context; mItems = new ArrayList<ActionMenuItem>(); diff --git a/core/java/com/android/internal/view/menu/ActionMenuItem.java b/core/java/com/android/internal/view/menu/ActionMenuItem.java index b807a42e922e..ed253d58fb82 100644 --- a/core/java/com/android/internal/view/menu/ActionMenuItem.java +++ b/core/java/com/android/internal/view/menu/ActionMenuItem.java @@ -17,6 +17,7 @@ package com.android.internal.view.menu; import android.annotation.Nullable; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.res.ColorStateList; @@ -69,6 +70,7 @@ public class ActionMenuItem implements MenuItem { private static final int HIDDEN = 0x00000008; private static final int ENABLED = 0x00000010; + @UnsupportedAppUsage public ActionMenuItem(Context context, int group, int id, int categoryOrder, int ordering, CharSequence title) { mContext = context; diff --git a/core/java/com/android/internal/view/menu/ContextMenuBuilder.java b/core/java/com/android/internal/view/menu/ContextMenuBuilder.java index 82f061cb86ca..3d3aceb4a85f 100644 --- a/core/java/com/android/internal/view/menu/ContextMenuBuilder.java +++ b/core/java/com/android/internal/view/menu/ContextMenuBuilder.java @@ -16,6 +16,7 @@ package com.android.internal.view.menu; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.drawable.Drawable; import android.os.IBinder; @@ -39,6 +40,7 @@ import android.view.View; */ public class ContextMenuBuilder extends MenuBuilder implements ContextMenu { + @UnsupportedAppUsage public ContextMenuBuilder(Context context) { super(context); } diff --git a/core/java/com/android/internal/view/menu/IconMenuItemView.java b/core/java/com/android/internal/view/menu/IconMenuItemView.java index 6c8f330fbcc8..3d888d347d65 100644 --- a/core/java/com/android/internal/view/menu/IconMenuItemView.java +++ b/core/java/com/android/internal/view/menu/IconMenuItemView.java @@ -18,6 +18,7 @@ package com.android.internal.view.menu; import com.android.internal.view.menu.MenuBuilder.ItemInvoker; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Rect; @@ -213,6 +214,7 @@ public final class IconMenuItemView extends TextView implements MenuView.ItemVie } } + @UnsupportedAppUsage public void setItemInvoker(ItemInvoker itemInvoker) { mItemInvoker = itemInvoker; } @@ -232,6 +234,7 @@ public final class IconMenuItemView extends TextView implements MenuView.ItemVie } } + @UnsupportedAppUsage void setIconMenuView(IconMenuView iconMenuView) { mIconMenuView = iconMenuView; } @@ -267,6 +270,7 @@ public final class IconMenuItemView extends TextView implements MenuView.ItemVie * @return layout params appropriate for this view. If layout params already exist, it will * augment them to be appropriate to the current text size. */ + @UnsupportedAppUsage IconMenuView.LayoutParams getTextAppropriateLayoutParams() { IconMenuView.LayoutParams lp = (IconMenuView.LayoutParams) getLayoutParams(); if (lp == null) { diff --git a/core/java/com/android/internal/view/menu/IconMenuView.java b/core/java/com/android/internal/view/menu/IconMenuView.java index dab43ebfe5d5..6f264341f7b4 100644 --- a/core/java/com/android/internal/view/menu/IconMenuView.java +++ b/core/java/com/android/internal/view/menu/IconMenuView.java @@ -18,6 +18,7 @@ package com.android.internal.view.menu; import com.android.internal.view.menu.MenuBuilder.ItemInvoker; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; @@ -51,6 +52,7 @@ import java.util.ArrayList; public final class IconMenuView extends ViewGroup implements ItemInvoker, MenuView, Runnable { private static final int ITEM_CAPTION_CYCLE_DELAY = 1000; + @UnsupportedAppUsage private MenuBuilder mMenu; /** Height of each row */ @@ -58,6 +60,7 @@ public final class IconMenuView extends ViewGroup implements ItemInvoker, MenuVi /** Maximum number of rows to be shown */ private int mMaxRows; /** Maximum number of items to show in the icon menu. */ + @UnsupportedAppUsage private int mMaxItems; /** Maximum number of items per row */ private int mMaxItemsPerRow; @@ -82,6 +85,7 @@ public final class IconMenuView extends ViewGroup implements ItemInvoker, MenuVi private Drawable mMoreIcon; /** Background of each item (should contain the selected and focused states) */ + @UnsupportedAppUsage private Drawable mItemBackground; /** Default animations for this menu */ @@ -288,6 +292,7 @@ public final class IconMenuView extends ViewGroup implements ItemInvoker, MenuVi * have a MenuItemData backing it. * @return The IconMenuItemView for the 'More' button */ + @UnsupportedAppUsage IconMenuItemView createMoreItemView() { Context context = getContext(); LayoutInflater inflater = LayoutInflater.from(context); @@ -494,6 +499,7 @@ public final class IconMenuView extends ViewGroup implements ItemInvoker, MenuVi * {@link MenuView.ItemView} implementation--eg: excludes More * item). */ + @UnsupportedAppUsage int getNumActualItemsShown() { return mNumActualItemsShown; } @@ -717,6 +723,7 @@ public final class IconMenuView extends ViewGroup implements ItemInvoker, MenuVi /** * Constructor called from {@link #CREATOR} */ + @UnsupportedAppUsage private SavedState(Parcel in) { super(in); focusedPosition = in.readInt(); diff --git a/core/java/com/android/internal/view/menu/MenuDialogHelper.java b/core/java/com/android/internal/view/menu/MenuDialogHelper.java index ecab29fdbbd4..88d0a03bd55f 100644 --- a/core/java/com/android/internal/view/menu/MenuDialogHelper.java +++ b/core/java/com/android/internal/view/menu/MenuDialogHelper.java @@ -16,6 +16,7 @@ package com.android.internal.view.menu; +import android.annotation.UnsupportedAppUsage; import android.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; @@ -36,6 +37,7 @@ public class MenuDialogHelper implements MenuHelper, DialogInterface.OnKeyListen ListMenuPresenter mPresenter; private MenuPresenter.Callback mPresenterCallback; + @UnsupportedAppUsage public MenuDialogHelper(MenuBuilder menu) { mMenu = menu; } @@ -45,6 +47,7 @@ public class MenuDialogHelper implements MenuHelper, DialogInterface.OnKeyListen * * @param windowToken Optional token to assign to the window. */ + @UnsupportedAppUsage public void show(IBinder windowToken) { // Many references to mMenu, create local reference final MenuBuilder menu = mMenu; @@ -132,6 +135,7 @@ public class MenuDialogHelper implements MenuHelper, DialogInterface.OnKeyListen * * @see Dialog#dismiss() */ + @UnsupportedAppUsage @Override public void dismiss() { if (mDialog != null) { diff --git a/core/java/com/android/internal/widget/AbsActionBarView.java b/core/java/com/android/internal/widget/AbsActionBarView.java index 582c4f1dd669..9ccee7fc32ff 100644 --- a/core/java/com/android/internal/widget/AbsActionBarView.java +++ b/core/java/com/android/internal/widget/AbsActionBarView.java @@ -27,6 +27,7 @@ import android.animation.Animator; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.TimeInterpolator; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.TypedArray; @@ -294,6 +295,7 @@ public abstract class AbsActionBarView extends ViewGroup { return isOverflowReserved() && getVisibility() == VISIBLE; } + @UnsupportedAppUsage public void dismissPopupMenus() { if (mActionMenuPresenter != null) { mActionMenuPresenter.dismissPopupMenus(); diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java index 693b194caa8b..78ed53fa918c 100644 --- a/core/java/com/android/internal/widget/ActionBarContextView.java +++ b/core/java/com/android/internal/widget/ActionBarContextView.java @@ -21,6 +21,7 @@ import android.widget.ActionMenuPresenter; import android.widget.ActionMenuView; import com.android.internal.view.menu.MenuBuilder; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; @@ -58,6 +59,7 @@ public class ActionBarContextView extends AbsActionBarView { this(context, null); } + @UnsupportedAppUsage public ActionBarContextView(Context context, AttributeSet attrs) { this(context, attrs, com.android.internal.R.attr.actionModeStyle); } diff --git a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java index ba0ff01b68de..e9e3cdab7a10 100644 --- a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java +++ b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java @@ -18,6 +18,7 @@ package com.android.internal.widget; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.res.Configuration; @@ -168,6 +169,7 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar init(context); } + @UnsupportedAppUsage public ActionBarOverlayLayout(Context context, AttributeSet attrs) { super(context, attrs); init(context); @@ -671,6 +673,7 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar return finalY > mActionBarTop.getHeight(); } + @UnsupportedAppUsage @Override public void setWindowCallback(Window.Callback cb) { pullChildren(); diff --git a/core/java/com/android/internal/widget/EditableInputConnection.java b/core/java/com/android/internal/widget/EditableInputConnection.java index 78688edb3f88..2b648e90f7dd 100644 --- a/core/java/com/android/internal/widget/EditableInputConnection.java +++ b/core/java/com/android/internal/widget/EditableInputConnection.java @@ -16,6 +16,7 @@ package com.android.internal.widget; +import android.annotation.UnsupportedAppUsage; import android.os.Bundle; import android.text.Editable; import android.text.method.KeyListener; @@ -39,6 +40,7 @@ public class EditableInputConnection extends BaseInputConnection { // A negative value means that this connection has been finished by the InputMethodManager. private int mBatchEditNesting; + @UnsupportedAppUsage public EditableInputConnection(TextView textview) { super(textview, true); mTextView = textview; diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl index 41e2fc84593e..b36c3fa79251 100644 --- a/core/java/com/android/internal/widget/ILockSettings.aidl +++ b/core/java/com/android/internal/widget/ILockSettings.aidl @@ -42,7 +42,7 @@ interface ILockSettings { long getLong(in String key, in long defaultValue, in int userId); @UnsupportedAppUsage String getString(in String key, in String defaultValue, in int userId); - void setLockCredential(in byte[] credential, int type, in byte[] savedCredential, int requestedQuality, int userId); + void setLockCredential(in byte[] credential, int type, in byte[] savedCredential, int requestedQuality, int userId, boolean allowUntrustedChange); void resetKeyStore(int userId); VerifyCredentialResponse checkCredential(in byte[] credential, int type, int userId, in ICheckCredentialProgressCallback progressCallback); diff --git a/core/java/com/android/internal/widget/LinearLayoutWithDefaultTouchRecepient.java b/core/java/com/android/internal/widget/LinearLayoutWithDefaultTouchRecepient.java index b2001cbe15ef..cc7911da0b96 100644 --- a/core/java/com/android/internal/widget/LinearLayoutWithDefaultTouchRecepient.java +++ b/core/java/com/android/internal/widget/LinearLayoutWithDefaultTouchRecepient.java @@ -16,6 +16,7 @@ package com.android.internal.widget; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; @@ -36,6 +37,7 @@ public class LinearLayoutWithDefaultTouchRecepient extends LinearLayout { private final Rect mTempRect = new Rect(); private View mDefaultTouchRecepient; + @UnsupportedAppUsage public LinearLayoutWithDefaultTouchRecepient(Context context) { super(context); } @@ -44,6 +46,7 @@ public class LinearLayoutWithDefaultTouchRecepient extends LinearLayout { super(context, attrs); } + @UnsupportedAppUsage public void setDefaultTouchRecepient(View defaultTouchRecepient) { mDefaultTouchRecepient = defaultTouchRecepient; } diff --git a/core/java/com/android/internal/widget/LockPatternChecker.java b/core/java/com/android/internal/widget/LockPatternChecker.java index bda3b5728fdc..09bc28c1f5ec 100644 --- a/core/java/com/android/internal/widget/LockPatternChecker.java +++ b/core/java/com/android/internal/widget/LockPatternChecker.java @@ -1,5 +1,6 @@ package com.android.internal.widget; +import android.annotation.UnsupportedAppUsage; import android.os.AsyncTask; import com.android.internal.widget.LockPatternUtils.RequestThrottledException; @@ -245,6 +246,7 @@ public final class LockPatternChecker { * @param callback The callback to be invoked with the check result. * @deprecated Pass passwords as byte[] */ + @UnsupportedAppUsage @Deprecated public static AsyncTask<?, ?, ?> checkPassword(final LockPatternUtils utils, final String password, diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index 1965609ff959..07f8ee077c21 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -27,6 +27,7 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED import android.annotation.IntDef; import android.annotation.Nullable; +import android.annotation.UnsupportedAppUsage; import android.app.admin.DevicePolicyManager; import android.app.admin.PasswordMetrics; import android.app.trust.IStrongAuthTracker; @@ -78,7 +79,6 @@ import java.util.StringJoiner; public class LockPatternUtils { private static final String TAG = "LockPatternUtils"; - private static final boolean DEBUG = false; private static final boolean FRP_CREDENTIAL_ENABLED = true; /** @@ -87,12 +87,6 @@ public class LockPatternUtils { public static final String LEGACY_LOCK_PATTERN_ENABLED = "legacy_lock_pattern_enabled"; /** - * The number of incorrect attempts before which we fall back on an alternative - * method of verifying the user, and resetting their lock pattern. - */ - public static final int FAILED_ATTEMPTS_BEFORE_RESET = 20; - - /** * The interval of the countdown for showing progress of the lockout. */ public static final long FAILED_ATTEMPT_COUNTDOWN_INTERVAL_MS = 1000L; @@ -115,18 +109,23 @@ public class LockPatternUtils { public static final int MIN_LOCK_PASSWORD_SIZE = 4; /** - * The minimum number of dots the user must include in a wrong pattern - * attempt for it to be counted against the counts that affect - * {@link #FAILED_ATTEMPTS_BEFORE_TIMEOUT} and {@link #FAILED_ATTEMPTS_BEFORE_RESET} + * The minimum number of dots the user must include in a wrong pattern attempt for it to be + * counted. */ public static final int MIN_PATTERN_REGISTER_FAIL = MIN_LOCK_PATTERN_SIZE; public static final int CREDENTIAL_TYPE_NONE = -1; - public static final int CREDENTIAL_TYPE_PATTERN = 1; - public static final int CREDENTIAL_TYPE_PASSWORD = 2; + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"CREDENTIAL_TYPE_"}, value = { + CREDENTIAL_TYPE_NONE, + CREDENTIAL_TYPE_PATTERN, + CREDENTIAL_TYPE_PASSWORD, // Either pin or password. + }) + public @interface CredentialType {} + /** * Special user id for triggering the FRP verification flow. */ @@ -171,7 +170,9 @@ public class LockPatternUtils { public static final String SYNTHETIC_PASSWORD_ENABLED_KEY = "enable-sp"; private static final String HISTORY_DELIMITER = ","; + @UnsupportedAppUsage private final Context mContext; + @UnsupportedAppUsage private final ContentResolver mContentResolver; private DevicePolicyManager mDevicePolicyManager; private ILockSettings mLockSettingsService; @@ -215,6 +216,7 @@ public class LockPatternUtils { public static final class RequestThrottledException extends Exception { private int mTimeoutMs; + @UnsupportedAppUsage public RequestThrottledException(int timeoutMs) { mTimeoutMs = timeoutMs; } @@ -223,12 +225,14 @@ public class LockPatternUtils { * @return The amount of time in ms before another request may * be executed */ + @UnsupportedAppUsage public int getTimeoutMs() { return mTimeoutMs; } } + @UnsupportedAppUsage public DevicePolicyManager getDevicePolicyManager() { if (mDevicePolicyManager == null) { mDevicePolicyManager = @@ -257,6 +261,7 @@ public class LockPatternUtils { return trust; } + @UnsupportedAppUsage public LockPatternUtils(Context context) { mContext = context; mContentResolver = context.getContentResolver(); @@ -265,6 +270,7 @@ public class LockPatternUtils { mHandler = looper != null ? new Handler(looper) : null; } + @UnsupportedAppUsage @VisibleForTesting public ILockSettings getLockSettings() { if (mLockSettingsService == null) { @@ -319,6 +325,7 @@ public class LockPatternUtils { return getDevicePolicyManager().getPasswordMinimumNonLetter(null, userId); } + @UnsupportedAppUsage public void reportFailedPasswordAttempt(int userId) { if (userId == USER_FRP && frpCredentialEnabled(mContext)) { return; @@ -327,6 +334,7 @@ public class LockPatternUtils { getTrustManager().reportUnlockAttempt(false /* authenticated */, userId); } + @UnsupportedAppUsage public void reportSuccessfulPasswordAttempt(int userId) { if (userId == USER_FRP && frpCredentialEnabled(mContext)) { return; @@ -487,6 +495,7 @@ public class LockPatternUtils { * @param password The password to check. * @return Whether the password matches the stored one. */ + @UnsupportedAppUsage public boolean checkPassword(String password, int userId) throws RequestThrottledException { byte[] passwordBytes = password != null ? password.getBytes() : null; return checkPassword(passwordBytes, userId, null /* progressCallback */); @@ -640,6 +649,7 @@ public class LockPatternUtils { * Used by device policy manager to validate the current password * information it has. */ + @UnsupportedAppUsage public int getActivePasswordQuality(int userId) { int quality = getKeyguardStoredPasswordQuality(userId); @@ -671,17 +681,25 @@ public class LockPatternUtils { /** * Clear any lock pattern or password. */ - public void clearLock(byte[] savedCredential, int userHandle) { + public boolean clearLock(byte[] savedCredential, int userHandle) { + return clearLock(savedCredential, userHandle, false); + } + + /** + * Clear any lock pattern or password, with the option to ignore incorrect existing credential. + */ + public boolean clearLock(byte[] savedCredential, int userHandle, boolean allowUntrustedChange) { final int currentQuality = getKeyguardStoredPasswordQuality(userHandle); setKeyguardStoredPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED, userHandle); try{ getLockSettings().setLockCredential(null, CREDENTIAL_TYPE_NONE, - savedCredential, PASSWORD_QUALITY_UNSPECIFIED, userHandle); + savedCredential, PASSWORD_QUALITY_UNSPECIFIED, userHandle, + allowUntrustedChange); } catch (Exception e) { Log.e(TAG, "Failed to clear lock", e); setKeyguardStoredPasswordQuality(currentQuality, userHandle); - return; + return false; } if (userHandle == UserHandle.USER_SYSTEM) { @@ -691,6 +709,7 @@ public class LockPatternUtils { } onAfterChangingPassword(userHandle); + return true; } /** @@ -710,6 +729,7 @@ public class LockPatternUtils { * * @return true if lock screen is disabled */ + @UnsupportedAppUsage public boolean isLockScreenDisabled(int userId) { if (isSecure(userId)) { return false; @@ -728,19 +748,28 @@ public class LockPatternUtils { /** * Save a lock pattern. * @param pattern The new pattern to save. + * @param savedPattern The previously saved pattern, converted to byte[] format * @param userId the user whose pattern is to be saved. + * + * @return whether this was successful or not. */ - public void saveLockPattern(List<LockPatternView.Cell> pattern, int userId) { - this.saveLockPattern(pattern, null, userId); + public boolean saveLockPattern(List<LockPatternView.Cell> pattern, byte[] savedPattern, + int userId) { + return saveLockPattern(pattern, savedPattern, userId, false); } + /** * Save a lock pattern. * @param pattern The new pattern to save. * @param savedPattern The previously saved pattern, converted to byte[] format * @param userId the user whose pattern is to be saved. + * @param allowUntrustedChange whether we want to allow saving a new password if the existing + * password being provided is incorrect. + * + * @return whether this was successful or not. */ - public void saveLockPattern(List<LockPatternView.Cell> pattern, byte[] savedPattern, - int userId) { + public boolean saveLockPattern(List<LockPatternView.Cell> pattern, byte[] savedPattern, + int userId, boolean allowUntrustedChange) { if (!hasSecureLockScreen()) { throw new UnsupportedOperationException( "This operation requires the lock screen feature."); @@ -755,11 +784,11 @@ public class LockPatternUtils { setKeyguardStoredPasswordQuality(PASSWORD_QUALITY_SOMETHING, userId); try { getLockSettings().setLockCredential(bytePattern, CREDENTIAL_TYPE_PATTERN, savedPattern, - PASSWORD_QUALITY_SOMETHING, userId); + PASSWORD_QUALITY_SOMETHING, userId, allowUntrustedChange); } catch (Exception e) { Log.e(TAG, "Couldn't save lock pattern", e); setKeyguardStoredPasswordQuality(currentQuality, userId); - return; + return false; } // Update the device encryption password. if (userId == UserHandle.USER_SYSTEM @@ -773,6 +802,7 @@ public class LockPatternUtils { reportPatternWasChosen(userId); onAfterChangingPassword(userId); + return true; } private void updateCryptoUserInfo(int userId) { @@ -797,16 +827,19 @@ public class LockPatternUtils { } } + @UnsupportedAppUsage public void setOwnerInfo(String info, int userId) { setString(LOCK_SCREEN_OWNER_INFO, info, userId); updateCryptoUserInfo(userId); } + @UnsupportedAppUsage public void setOwnerInfoEnabled(boolean enabled, int userId) { setBoolean(LOCK_SCREEN_OWNER_INFO_ENABLED, enabled, userId); updateCryptoUserInfo(userId); } + @UnsupportedAppUsage public String getOwnerInfo(int userId) { return getString(LOCK_SCREEN_OWNER_INFO, userId); } @@ -875,17 +908,20 @@ public class LockPatternUtils { * password. * @param password The password to save * @param savedPassword The previously saved lock password, or null if none - * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)} + * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality( + * android.content.ComponentName)} * @param userHandle The userId of the user to change the password for * + * @return whether this was successful or not. + * * @deprecated Pass password as a byte array */ @Deprecated - public void saveLockPassword(String password, String savedPassword, int requestedQuality, + public boolean saveLockPassword(String password, String savedPassword, int requestedQuality, int userHandle) { byte[] passwordBytes = password != null ? password.getBytes() : null; byte[] savedPasswordBytes = savedPassword != null ? savedPassword.getBytes() : null; - saveLockPassword(passwordBytes, savedPasswordBytes, requestedQuality, userHandle); + return saveLockPassword(passwordBytes, savedPasswordBytes, requestedQuality, userHandle); } /** @@ -895,11 +931,34 @@ public class LockPatternUtils { * @param password The password to save * @param savedPassword The previously saved lock password, or null if none * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality( - * android.content.ComponentName)} + * android.content.ComponentName)} * @param userHandle The userId of the user to change the password for + * + * @return whether this was successful or not. */ - public void saveLockPassword(byte[] password, byte[] savedPassword, int requestedQuality, + public boolean saveLockPassword(byte[] password, byte[] savedPassword, int requestedQuality, int userHandle) { + return saveLockPassword(password, savedPassword, requestedQuality, + userHandle, false); + } + + /** + * Save a lock password. Does not ensure that the password is as good + * as the requested mode, but will adjust the mode to be as good as the + * password. + * @param password The password to save + * @param savedPassword The previously saved lock password, or null if none + * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality( + * android.content.ComponentName)} + * @param userHandle The userId of the user to change the password for + * @param allowUntrustedChange whether we want to allow saving a new password if the existing + * password being provided is incorrect. + * + * @return whether this method saved the new password successfully or not. This flow will fail + * and return false if the given credential is wrong and allowUntrustedChange is false. + */ + public boolean saveLockPassword(byte[] password, byte[] savedPassword, + int requestedQuality, int userHandle, boolean allowUntrustedChange) { if (!hasSecureLockScreen()) { throw new UnsupportedOperationException( "This operation requires the lock screen feature."); @@ -915,22 +974,36 @@ public class LockPatternUtils { } final int currentQuality = getKeyguardStoredPasswordQuality(userHandle); - setKeyguardStoredPasswordQuality( - computePasswordQuality(CREDENTIAL_TYPE_PASSWORD, password, requestedQuality), - userHandle); + final int passwordQuality = PasswordMetrics.computeForPassword(password).quality; + final int newKeyguardQuality = + computeKeyguardQuality(CREDENTIAL_TYPE_PASSWORD, requestedQuality, passwordQuality); + setKeyguardStoredPasswordQuality(newKeyguardQuality, userHandle); try { getLockSettings().setLockCredential(password, CREDENTIAL_TYPE_PASSWORD, savedPassword, - requestedQuality, userHandle); + requestedQuality, userHandle, allowUntrustedChange); } catch (Exception e) { Log.e(TAG, "Unable to save lock password", e); setKeyguardStoredPasswordQuality(currentQuality, userHandle); - return; + return false; } - updateEncryptionPasswordIfNeeded(password, - PasswordMetrics.computeForPassword(password).quality, userHandle); + updateEncryptionPasswordIfNeeded(password, passwordQuality, userHandle); updatePasswordHistory(password, userHandle); onAfterChangingPassword(userHandle); + return true; + } + + /** + * Compute keyguard credential quality to store in PASSWORD_TYPE_KEY by computing max between + * them so that digit-only password is distinguished from PIN. + * + * TODO: remove this method and make CREDENTIAL_TYPE distinguish between PIN and password, so + * that this quality is no longer needs to be persisted. + */ + private int computeKeyguardQuality( + @CredentialType int credentialType, int requestedQuality, int passwordQuality) { + return credentialType == CREDENTIAL_TYPE_PASSWORD + ? Math.max(passwordQuality, requestedQuality) : passwordQuality; } /** @@ -999,6 +1072,7 @@ public class LockPatternUtils { * encrypted with the default password. * @return true if device encryption is enabled */ + @UnsupportedAppUsage public static boolean isDeviceEncryptionEnabled() { return StorageManager.isEncrypted(); } @@ -1024,6 +1098,7 @@ public class LockPatternUtils { * * @return stored password quality */ + @UnsupportedAppUsage public int getKeyguardStoredPasswordQuality(int userHandle) { return (int) getLong(PASSWORD_TYPE_KEY, PASSWORD_QUALITY_UNSPECIFIED, userHandle); } @@ -1033,24 +1108,6 @@ public class LockPatternUtils { } /** - * Returns the password quality of the given credential, promoting it to a higher level - * if DevicePolicyManager has a stronger quality requirement. This value will be written - * to PASSWORD_TYPE_KEY. - */ - private int computePasswordQuality(int type, byte[] credential, int requestedQuality) { - final int quality; - if (type == CREDENTIAL_TYPE_PASSWORD) { - int computedQuality = PasswordMetrics.computeForPassword(credential).quality; - quality = Math.max(requestedQuality, computedQuality); - } else if (type == CREDENTIAL_TYPE_PATTERN) { - quality = PASSWORD_QUALITY_SOMETHING; - } else /* if (type == CREDENTIAL_TYPE_NONE) */ { - quality = PASSWORD_QUALITY_UNSPECIFIED; - } - return quality; - } - - /** * Enables/disables the Separate Profile Challenge for this {@param userHandle}. This is a no-op * for user handles that do not belong to a managed profile. * @@ -1159,6 +1216,7 @@ public class LockPatternUtils { * @return The pattern in string form. * @deprecated Use patternToByteArray instead. */ + @UnsupportedAppUsage @Deprecated public static String patternToString(List<LockPatternView.Cell> pattern) { return new String(patternToByteArray(pattern)); @@ -1208,6 +1266,7 @@ public class LockPatternUtils { * @param pattern the gesture pattern. * @return the hash of the pattern in a byte array. */ + @UnsupportedAppUsage public static byte[] patternToHash(List<LockPatternView.Cell> pattern) { if (pattern == null) { return null; @@ -1305,11 +1364,13 @@ public class LockPatternUtils { * @param userId the user for which to report the value * @return Whether the lock screen is secured. */ + @UnsupportedAppUsage public boolean isSecure(int userId) { int mode = getKeyguardStoredPasswordQuality(userId); return isLockPatternEnabled(mode, userId) || isLockPasswordEnabled(mode, userId); } + @UnsupportedAppUsage public boolean isLockPasswordEnabled(int userId) { return isLockPasswordEnabled(getKeyguardStoredPasswordQuality(userId), userId); } @@ -1327,6 +1388,7 @@ public class LockPatternUtils { /** * @return Whether the lock pattern is enabled */ + @UnsupportedAppUsage public boolean isLockPatternEnabled(int userId) { return isLockPatternEnabled(getKeyguardStoredPasswordQuality(userId), userId); } @@ -1351,6 +1413,7 @@ public class LockPatternUtils { /** * @return Whether the visible pattern is enabled. */ + @UnsupportedAppUsage public boolean isVisiblePatternEnabled(int userId) { return getBoolean(Settings.Secure.LOCK_PATTERN_VISIBLE, false, userId); } @@ -1410,6 +1473,7 @@ public class LockPatternUtils { /** * @return Whether tactile feedback for the pattern is enabled. */ + @UnsupportedAppUsage public boolean isTactileFeedbackEnabled() { return Settings.System.getIntForUser(mContentResolver, Settings.System.HAPTIC_FEEDBACK_ENABLED, 1, UserHandle.USER_CURRENT) != 0; @@ -1420,6 +1484,7 @@ public class LockPatternUtils { * pattern until the deadline has passed. * @return the chosen deadline. */ + @UnsupportedAppUsage public long setLockoutAttemptDeadline(int userId, int timeoutMs) { final long deadline = SystemClock.elapsedRealtime() + timeoutMs; if (userId == USER_FRP) { @@ -1472,6 +1537,7 @@ public class LockPatternUtils { } } + @UnsupportedAppUsage private void setLong(String secureSettingKey, long value, int userHandle) { try { getLockSettings().setLong(secureSettingKey, value, userHandle); @@ -1481,6 +1547,7 @@ public class LockPatternUtils { } } + @UnsupportedAppUsage private String getString(String secureSettingKey, int userHandle) { try { return getLockSettings().getString(secureSettingKey, null, userHandle); @@ -1489,6 +1556,7 @@ public class LockPatternUtils { } } + @UnsupportedAppUsage private void setString(String secureSettingKey, String value, int userHandle) { try { getLockSettings().setString(secureSettingKey, value, userHandle); @@ -1502,6 +1570,7 @@ public class LockPatternUtils { setBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, enabled, userId); } + @UnsupportedAppUsage public boolean getPowerButtonInstantlyLocks(int userId) { return getBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, true, userId); } @@ -1752,9 +1821,10 @@ public class LockPatternUtils { throw new IllegalArgumentException("password must not be null and at least " + "of length " + MIN_LOCK_PASSWORD_SIZE); } - final int quality = computePasswordQuality(type, credential, requestedQuality); + final int quality = PasswordMetrics.computeForCredential(type, credential).quality; + final int keyguardQuality = computeKeyguardQuality(type, quality, requestedQuality); if (!localService.setLockCredentialWithToken(credential, type, tokenHandle, token, - quality, userId)) { + keyguardQuality, userId)) { return false; } setKeyguardStoredPasswordQuality(quality, userId); diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java index 4b269901ccf6..22182677babe 100644 --- a/core/java/com/android/internal/widget/LockPatternView.java +++ b/core/java/com/android/internal/widget/LockPatternView.java @@ -19,6 +19,7 @@ package com.android.internal.widget; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; @@ -78,7 +79,9 @@ public class LockPatternView extends View { private boolean mDrawingProfilingStarted = false; + @UnsupportedAppUsage private final Paint mPaint = new Paint(); + @UnsupportedAppUsage private final Paint mPathPaint = new Paint(); /** @@ -98,6 +101,7 @@ public class LockPatternView extends View { private static final String TAG = "LockPatternView"; private OnPatternListener mOnPatternListener; + @UnsupportedAppUsage private final ArrayList<Cell> mPattern = new ArrayList<Cell>(9); /** @@ -119,16 +123,21 @@ public class LockPatternView extends View { private long mAnimatingPeriodStart; private long[] mLineFadeStart = new long[9]; + @UnsupportedAppUsage private DisplayMode mPatternDisplayMode = DisplayMode.Correct; private boolean mInputEnabled = true; + @UnsupportedAppUsage private boolean mInStealthMode = false; private boolean mEnableHapticFeedback = true; + @UnsupportedAppUsage private boolean mPatternInProgress = false; private boolean mFadePattern = true; private float mHitFactor = 0.6f; + @UnsupportedAppUsage private float mSquareWidth; + @UnsupportedAppUsage private float mSquareHeight; private final Path mCurrentPath = new Path(); @@ -153,7 +162,9 @@ public class LockPatternView extends View { * Represents a cell in the 3 X 3 matrix of the unlock pattern view. */ public static final class Cell { + @UnsupportedAppUsage final int row; + @UnsupportedAppUsage final int column; // keep # objects limited to 9 @@ -231,16 +242,19 @@ public class LockPatternView extends View { /** * The pattern drawn is correct (i.e draw it in a friendly color) */ + @UnsupportedAppUsage Correct, /** * Animate the pattern (for demo, and help). */ + @UnsupportedAppUsage Animate, /** * The pattern is wrong (i.e draw a foreboding color) */ + @UnsupportedAppUsage Wrong } @@ -276,6 +290,7 @@ public class LockPatternView extends View { this(context, null); } + @UnsupportedAppUsage public LockPatternView(Context context, AttributeSet attrs) { super(context, attrs); @@ -347,6 +362,7 @@ public class LockPatternView extends View { a.recycle(); } + @UnsupportedAppUsage public CellState[][] getCellStates() { return mCellStates; } @@ -371,6 +387,7 @@ public class LockPatternView extends View { * * @param inStealthMode Whether in stealth mode. */ + @UnsupportedAppUsage public void setInStealthMode(boolean inStealthMode) { mInStealthMode = inStealthMode; } @@ -389,6 +406,7 @@ public class LockPatternView extends View { * * @param tactileFeedbackEnabled Whether tactile feedback is enabled */ + @UnsupportedAppUsage public void setTactileFeedbackEnabled(boolean tactileFeedbackEnabled) { mEnableHapticFeedback = tactileFeedbackEnabled; } @@ -397,6 +415,7 @@ public class LockPatternView extends View { * Set the call back for pattern detection. * @param onPatternListener The call back. */ + @UnsupportedAppUsage public void setOnPatternListener( OnPatternListener onPatternListener) { mOnPatternListener = onPatternListener; @@ -425,6 +444,7 @@ public class LockPatternView extends View { * in progress result to correct or wrong. * @param displayMode The display mode. */ + @UnsupportedAppUsage public void setDisplayMode(DisplayMode displayMode) { mPatternDisplayMode = displayMode; if (displayMode == DisplayMode.Animate) { @@ -564,6 +584,7 @@ public class LockPatternView extends View { } } + @UnsupportedAppUsage private void notifyPatternDetected() { sendAccessEvent(R.string.lockscreen_access_pattern_detected); if (mOnPatternListener != null) { @@ -581,6 +602,7 @@ public class LockPatternView extends View { /** * Clear the pattern. */ + @UnsupportedAppUsage public void clearPattern() { resetPattern(); } @@ -621,6 +643,7 @@ public class LockPatternView extends View { * Disable input (for instance when displaying a message that will * timeout so user doesn't get view into messy state). */ + @UnsupportedAppUsage public void disableInput() { mInputEnabled = false; } @@ -628,6 +651,7 @@ public class LockPatternView extends View { /** * Enable input. */ + @UnsupportedAppUsage public void enableInput() { mInputEnabled = true; } @@ -1308,6 +1332,7 @@ public class LockPatternView extends View { /** * Constructor called from {@link LockPatternView#onSaveInstanceState()} */ + @UnsupportedAppUsage private SavedState(Parcelable superState, String serializedPattern, int displayMode, boolean inputEnabled, boolean inStealthMode, boolean tactileFeedbackEnabled) { super(superState); @@ -1321,6 +1346,7 @@ public class LockPatternView extends View { /** * Constructor called from {@link #CREATOR} */ + @UnsupportedAppUsage private SavedState(Parcel in) { super(in); mSerializedPattern = in.readString(); diff --git a/core/java/com/android/internal/widget/PointerLocationView.java b/core/java/com/android/internal/widget/PointerLocationView.java index 3205b5aef281..3881093f5540 100644 --- a/core/java/com/android/internal/widget/PointerLocationView.java +++ b/core/java/com/android/internal/widget/PointerLocationView.java @@ -16,6 +16,7 @@ package com.android.internal.widget; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; @@ -59,6 +60,7 @@ public class PointerLocationView extends View implements InputDeviceListener, private int mTraceCount; // True if the pointer is down. + @UnsupportedAppUsage private boolean mCurDown; // Most recent coordinates. @@ -123,10 +125,14 @@ public class PointerLocationView extends View implements InputDeviceListener, private final FontMetricsInt mTextMetrics = new FontMetricsInt(); private int mHeaderBottom; private int mHeaderPaddingTop = 0; + @UnsupportedAppUsage private boolean mCurDown; + @UnsupportedAppUsage private int mCurNumPointers; + @UnsupportedAppUsage private int mMaxNumPointers; private int mActivePointerId; + @UnsupportedAppUsage private final ArrayList<PointerState> mPointers = new ArrayList<PointerState>(); private final PointerCoords mTempCoords = new PointerCoords(); @@ -139,6 +145,7 @@ public class PointerLocationView extends View implements InputDeviceListener, private final FasterStringBuilder mText = new FasterStringBuilder(); + @UnsupportedAppUsage private boolean mPrintCoords = true; public PointerLocationView(Context c) { diff --git a/core/java/com/android/internal/widget/PreferenceImageView.java b/core/java/com/android/internal/widget/PreferenceImageView.java index 8730cdab258b..02a0b8d436b9 100644 --- a/core/java/com/android/internal/widget/PreferenceImageView.java +++ b/core/java/com/android/internal/widget/PreferenceImageView.java @@ -16,6 +16,7 @@ package com.android.internal.widget; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.util.AttributeSet; import android.widget.ImageView; @@ -29,6 +30,7 @@ public class PreferenceImageView extends ImageView { this(context, null); } + @UnsupportedAppUsage public PreferenceImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } diff --git a/core/java/com/android/internal/widget/RecyclerView.java b/core/java/com/android/internal/widget/RecyclerView.java index 408a4e9b02a4..b66a7b44f05d 100644 --- a/core/java/com/android/internal/widget/RecyclerView.java +++ b/core/java/com/android/internal/widget/RecyclerView.java @@ -20,6 +20,7 @@ import android.annotation.CallSuper; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.database.Observable; @@ -4953,6 +4954,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro * constructed by {@link GapWorker} prefetch from being bound to a lower priority prefetch. */ static class ScrapData { + @UnsupportedAppUsage ArrayList<ViewHolder> mScrapHeap = new ArrayList<>(); int mMaxScrap = DEFAULT_MAX_SCRAP; long mCreateRunningAverageNs = 0; diff --git a/core/java/com/android/internal/widget/ScrollBarUtils.java b/core/java/com/android/internal/widget/ScrollBarUtils.java index 0ae9f74167d5..982e3152fc7c 100644 --- a/core/java/com/android/internal/widget/ScrollBarUtils.java +++ b/core/java/com/android/internal/widget/ScrollBarUtils.java @@ -16,8 +16,11 @@ package com.android.internal.widget; +import android.annotation.UnsupportedAppUsage; + public class ScrollBarUtils { + @UnsupportedAppUsage public static int getThumbLength(int size, int thickness, int extent, int range) { // Avoid the tiny thumb. final int minLength = thickness * 2; diff --git a/core/java/com/android/internal/widget/SlidingTab.java b/core/java/com/android/internal/widget/SlidingTab.java index 79adada9cc98..4b5d62467af0 100644 --- a/core/java/com/android/internal/widget/SlidingTab.java +++ b/core/java/com/android/internal/widget/SlidingTab.java @@ -16,6 +16,7 @@ package com.android.internal.widget; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; @@ -83,7 +84,9 @@ public class SlidingTab extends ViewGroup { */ private final int mOrientation; + @UnsupportedAppUsage private final Slider mLeftSlider; + @UnsupportedAppUsage private final Slider mRightSlider; private Slider mCurrentSlider; private boolean mTracking; @@ -95,6 +98,7 @@ public class SlidingTab extends ViewGroup { /** * Listener used to reset the view when the current animation completes. */ + @UnsupportedAppUsage private final AnimationListener mAnimationDoneListener = new AnimationListener() { public void onAnimationStart(Animation animation) { @@ -178,7 +182,9 @@ public class SlidingTab extends ViewGroup { private static final int STATE_PRESSED = 1; private static final int STATE_ACTIVE = 2; + @UnsupportedAppUsage private final ImageView tab; + @UnsupportedAppUsage private final TextView text; private final ImageView target; private int currentState = STATE_NORMAL; @@ -708,6 +714,7 @@ public class SlidingTab extends ViewGroup { slider.startAnimation(trans1, trans2); } + @UnsupportedAppUsage private void onAnimationDone() { resetView(); mAnimating = false; @@ -722,6 +729,7 @@ public class SlidingTab extends ViewGroup { return mOrientation == HORIZONTAL; } + @UnsupportedAppUsage private void resetView() { mLeftSlider.reset(false); mRightSlider.reset(false); @@ -763,6 +771,7 @@ public class SlidingTab extends ViewGroup { * @param barId the resource of the bar drawable (stateful) * @param tabId the resource of the */ + @UnsupportedAppUsage public void setLeftTabResources(int iconId, int targetId, int barId, int tabId) { mLeftSlider.setIcon(iconId); mLeftSlider.setTarget(targetId); @@ -776,6 +785,7 @@ public class SlidingTab extends ViewGroup { * * @param resId */ + @UnsupportedAppUsage public void setLeftHintText(int resId) { if (isHorizontal()) { mLeftSlider.setHintText(resId); @@ -793,6 +803,7 @@ public class SlidingTab extends ViewGroup { * @param barId the resource of the bar drawable (stateful) * @param tabId the resource of the */ + @UnsupportedAppUsage public void setRightTabResources(int iconId, int targetId, int barId, int tabId) { mRightSlider.setIcon(iconId); mRightSlider.setTarget(targetId); @@ -806,12 +817,14 @@ public class SlidingTab extends ViewGroup { * * @param resId */ + @UnsupportedAppUsage public void setRightHintText(int resId) { if (isHorizontal()) { mRightSlider.setHintText(resId); } } + @UnsupportedAppUsage public void setHoldAfterTrigger(boolean holdLeft, boolean holdRight) { mHoldLeftOnTransition = holdLeft; mHoldRightOnTransition = holdRight; @@ -838,6 +851,7 @@ public class SlidingTab extends ViewGroup { * * @param listener the OnDialTriggerListener to attach to this view */ + @UnsupportedAppUsage public void setOnTriggerListener(OnTriggerListener listener) { mOnTriggerListener = listener; } diff --git a/core/java/com/android/internal/widget/TextViewInputDisabler.java b/core/java/com/android/internal/widget/TextViewInputDisabler.java index fb0b3b95b6f2..8d8f0fe52d64 100644 --- a/core/java/com/android/internal/widget/TextViewInputDisabler.java +++ b/core/java/com/android/internal/widget/TextViewInputDisabler.java @@ -16,6 +16,7 @@ package com.android.internal.widget; +import android.annotation.UnsupportedAppUsage; import android.text.InputFilter; import android.text.Spanned; import android.widget.TextView; @@ -38,11 +39,13 @@ public class TextViewInputDisabler { } }; + @UnsupportedAppUsage public TextViewInputDisabler(TextView textView) { mTextView = textView; mDefaultFilters = mTextView.getFilters(); } + @UnsupportedAppUsage public void setInputEnabled(boolean enabled) { mTextView.setFilters(enabled ? mDefaultFilters : mNoInputFilters); } diff --git a/core/java/com/android/internal/widget/ViewPager.java b/core/java/com/android/internal/widget/ViewPager.java index f48b56d7af36..7d36b02d4157 100644 --- a/core/java/com/android/internal/widget/ViewPager.java +++ b/core/java/com/android/internal/widget/ViewPager.java @@ -18,6 +18,7 @@ package com.android.internal.widget; import android.annotation.DrawableRes; import android.annotation.NonNull; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; @@ -244,6 +245,7 @@ public class ViewPager extends ViewGroup { * @param positionOffset Value from [0, 1) indicating the offset from the page at position. * @param positionOffsetPixels Value in pixels indicating the offset from position. */ + @UnsupportedAppUsage public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels); /** @@ -252,6 +254,7 @@ public class ViewPager extends ViewGroup { * * @param position Position index of the new selected page. */ + @UnsupportedAppUsage public void onPageSelected(int position); /** @@ -264,6 +267,7 @@ public class ViewPager extends ViewGroup { * @see com.android.internal.widget.ViewPager#SCROLL_STATE_DRAGGING * @see com.android.internal.widget.ViewPager#SCROLL_STATE_SETTLING */ + @UnsupportedAppUsage public void onPageScrollStateChanged(int state); } @@ -484,6 +488,7 @@ public class ViewPager extends ViewGroup { setCurrentItemInternal(item, smoothScroll, false); } + @UnsupportedAppUsage public int getCurrentItem() { return mCurItem; } diff --git a/core/java/com/android/server/ResettableTimeout.java b/core/java/com/android/server/ResettableTimeout.java index ac5b160670b0..64083f72aff5 100644 --- a/core/java/com/android/server/ResettableTimeout.java +++ b/core/java/com/android/server/ResettableTimeout.java @@ -18,6 +18,7 @@ package com.android.server; import android.os.SystemClock; +import android.annotation.UnsupportedAppUsage; import android.os.ConditionVariable; /** @@ -120,9 +121,11 @@ abstract class ResettableTimeout } } + @UnsupportedAppUsage private ConditionVariable mLock = new ConditionVariable(); // turn it off at this time. + @UnsupportedAppUsage private volatile long mOffAt; private volatile boolean mOffCalled; diff --git a/core/java/com/android/server/net/BaseNetworkObserver.java b/core/java/com/android/server/net/BaseNetworkObserver.java index 3d9fb5c872f7..a0740eee5df6 100644 --- a/core/java/com/android/server/net/BaseNetworkObserver.java +++ b/core/java/com/android/server/net/BaseNetworkObserver.java @@ -16,6 +16,7 @@ package com.android.server.net; +import android.annotation.UnsupportedAppUsage; import android.net.INetworkManagementEventObserver; import android.net.LinkAddress; import android.net.RouteInfo; diff --git a/core/java/com/android/server/net/NetlinkTracker.java b/core/java/com/android/server/net/NetlinkTracker.java index 5b421d988e0a..647fb5b9d079 100644 --- a/core/java/com/android/server/net/NetlinkTracker.java +++ b/core/java/com/android/server/net/NetlinkTracker.java @@ -16,6 +16,7 @@ package com.android.server.net; +import android.annotation.UnsupportedAppUsage; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.RouteInfo; @@ -79,6 +80,7 @@ public class NetlinkTracker extends BaseNetworkObserver { private static final boolean DBG = false; + @UnsupportedAppUsage public NetlinkTracker(String iface, Callback callback) { TAG = "NetlinkTracker/" + iface; mInterfaceName = iface; @@ -187,10 +189,12 @@ public class NetlinkTracker extends BaseNetworkObserver { /** * Returns a copy of this object's LinkProperties. */ + @UnsupportedAppUsage public synchronized LinkProperties getLinkProperties() { return new LinkProperties(mLinkProperties); } + @UnsupportedAppUsage public synchronized void clearLinkProperties() { // Clear the repository before clearing mLinkProperties. That way, if a clear() happens // while interfaceDnsServerInfo() is being called, we'll end up with no DNS servers in diff --git a/core/java/com/google/android/collect/Lists.java b/core/java/com/google/android/collect/Lists.java index 3ea873bbb0f9..8f6594aefb0a 100644 --- a/core/java/com/google/android/collect/Lists.java +++ b/core/java/com/google/android/collect/Lists.java @@ -57,6 +57,7 @@ public class Lists { * @param elements the elements that the list should contain, in order * @return a newly-created {@code ArrayList} containing those elements */ + @UnsupportedAppUsage public static <E> ArrayList<E> newArrayList(E... elements) { int capacity = (elements.length * 110) / 100 + 5; ArrayList<E> list = new ArrayList<E>(capacity); diff --git a/core/java/com/google/android/collect/Sets.java b/core/java/com/google/android/collect/Sets.java index dd3cab15d0b2..09b5e51ae2c6 100644 --- a/core/java/com/google/android/collect/Sets.java +++ b/core/java/com/google/android/collect/Sets.java @@ -16,6 +16,7 @@ package com.google.android.collect; +import android.annotation.UnsupportedAppUsage; import android.util.ArraySet; import java.util.Collections; @@ -42,6 +43,7 @@ public class Sets { * * @return a newly-created, initially-empty {@code HashSet} */ + @UnsupportedAppUsage public static <K> HashSet<K> newHashSet() { return new HashSet<K>(); } @@ -63,6 +65,7 @@ public class Sets { * @return a newly-created {@code HashSet} containing those elements (minus * duplicates) */ + @UnsupportedAppUsage public static <E> HashSet<E> newHashSet(E... elements) { int capacity = elements.length * 4 / 3 + 1; HashSet<E> set = new HashSet<E>(capacity); @@ -75,6 +78,7 @@ public class Sets { * * @return a newly-created, initially-empty {@code SortedSet}. */ + @UnsupportedAppUsage public static <E> SortedSet<E> newSortedSet() { return new TreeSet<E>(); } @@ -95,6 +99,7 @@ public class Sets { /** * Creates a {@code ArraySet} instance. */ + @UnsupportedAppUsage public static <E> ArraySet<E> newArraySet() { return new ArraySet<E>(); } @@ -102,6 +107,7 @@ public class Sets { /** * Creates a {@code ArraySet} instance containing the given elements. */ + @UnsupportedAppUsage public static <E> ArraySet<E> newArraySet(E... elements) { int capacity = elements.length * 4 / 3 + 1; ArraySet<E> set = new ArraySet<E>(capacity); diff --git a/core/java/com/google/android/util/AbstractMessageParser.java b/core/java/com/google/android/util/AbstractMessageParser.java index 1871682ee063..9d12f82aeb75 100644 --- a/core/java/com/google/android/util/AbstractMessageParser.java +++ b/core/java/com/google/android/util/AbstractMessageParser.java @@ -16,6 +16,7 @@ package com.google.android.util; +import android.annotation.UnsupportedAppUsage; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; @@ -654,15 +655,25 @@ public abstract class AbstractMessageParser { public static abstract class Token { public enum Type { + @UnsupportedAppUsage HTML ("html"), + @UnsupportedAppUsage FORMAT ("format"), // subtype of HTML + @UnsupportedAppUsage LINK ("l"), + @UnsupportedAppUsage SMILEY ("e"), + @UnsupportedAppUsage ACRONYM ("a"), + @UnsupportedAppUsage MUSIC ("m"), + @UnsupportedAppUsage GOOGLE_VIDEO ("v"), + @UnsupportedAppUsage YOUTUBE_VIDEO ("yt"), + @UnsupportedAppUsage PHOTO ("p"), + @UnsupportedAppUsage FLICKR ("f"); //stringreps for HTML and FORMAT don't really matter diff --git a/core/jni/Android.bp b/core/jni/Android.bp index cd34d2e1b441..664f7f47cf18 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -1,10 +1,10 @@ genrule { - name: "android_util_StatsLog.cpp", + name: "android_util_StatsLogInternal.cpp", tools: ["stats-log-api-gen"], - cmd: "$(location stats-log-api-gen) --jni $(genDir)/android_util_StatsLog.cpp", + cmd: "$(location stats-log-api-gen) --jni $(genDir)/android_util_StatsLogInternal.cpp", out: [ - "android_util_StatsLog.cpp", + "android_util_StatsLogInternal.cpp", ], } @@ -111,6 +111,7 @@ cc_library_shared { "android_util_Binder.cpp", "android_util_EventLog.cpp", "android_util_Log.cpp", + "android_util_StatsLog.cpp", "android_util_MemoryIntArray.cpp", "android_util_PathParser.cpp", "android_util_Process.cpp", @@ -306,7 +307,7 @@ cc_library_shared { "server_configurable_flags", ], - generated_sources: ["android_util_StatsLog.cpp"], + generated_sources: ["android_util_StatsLogInternal.cpp"], local_include_dirs: ["android/graphics"], export_include_dirs: [ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 20bed1b34940..ccd0b666865e 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -127,6 +127,7 @@ extern int register_android_app_admin_SecurityLog(JNIEnv* env); extern int register_android_content_AssetManager(JNIEnv* env); extern int register_android_util_EventLog(JNIEnv* env); extern int register_android_util_StatsLog(JNIEnv* env); +extern int register_android_util_StatsLogInternal(JNIEnv* env); extern int register_android_util_Log(JNIEnv* env); extern int register_android_util_MemoryIntArray(JNIEnv* env); extern int register_android_util_PathParser(JNIEnv* env); @@ -1400,6 +1401,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_util_MemoryIntArray), REG_JNI(register_android_util_PathParser), REG_JNI(register_android_util_StatsLog), + REG_JNI(register_android_util_StatsLogInternal), REG_JNI(register_android_app_admin_SecurityLog), REG_JNI(register_android_content_AssetManager), REG_JNI(register_android_content_StringBlock), diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp index 02dffdc2ca25..342aba024fc5 100644 --- a/core/jni/android_media_AudioRecord.cpp +++ b/core/jni/android_media_AudioRecord.cpp @@ -821,18 +821,18 @@ static jint android_media_AudioRecord_get_active_microphones(JNIEnv *env, return jStatus; } -static int android_media_AudioRecord_set_microphone_direction(JNIEnv *env, jobject thiz, - jint direction) { +static int android_media_AudioRecord_set_preferred_microphone_direction( + JNIEnv *env, jobject thiz, jint direction) { sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz); if (lpRecorder == NULL) { jniThrowException(env, "java/lang/IllegalStateException", - "Unable to retrieve AudioRecord pointer for setMicrophoneDirection()"); + "Unable to retrieve AudioRecord pointer for setPreferredMicrophoneDirection()"); return (jint)AUDIO_JAVA_ERROR; } jint jStatus = AUDIO_JAVA_SUCCESS; - status_t status = - lpRecorder->setMicrophoneDirection(static_cast<audio_microphone_direction_t>(direction)); + status_t status = lpRecorder->setPreferredMicrophoneDirection( + static_cast<audio_microphone_direction_t>(direction)); if (status != NO_ERROR) { jStatus = nativeToJavaStatus(status); } @@ -840,17 +840,17 @@ static int android_media_AudioRecord_set_microphone_direction(JNIEnv *env, jobje return jStatus; } -static int android_media_AudioRecord_set_microphone_field_dimension(JNIEnv *env, jobject thiz, - jfloat zoom) { +static int android_media_AudioRecord_set_preferred_microphone_field_dimension( + JNIEnv *env, jobject thiz, jfloat zoom) { sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz); if (lpRecorder == NULL) { jniThrowException(env, "java/lang/IllegalStateException", - "Unable to retrieve AudioRecord pointer for setMicrophoneFieldDimension()"); + "Unable to retrieve AudioRecord pointer for setPreferredMicrophoneFieldDimension()"); return (jint)AUDIO_JAVA_ERROR; } jint jStatus = AUDIO_JAVA_SUCCESS; - status_t status = lpRecorder->setMicrophoneFieldDimension(zoom); + status_t status = lpRecorder->setPreferredMicrophoneFieldDimension(zoom); if (status != NO_ERROR) { jStatus = nativeToJavaStatus(status); } @@ -913,10 +913,10 @@ static const JNINativeMethod gMethods[] = { {"native_get_active_microphones", "(Ljava/util/ArrayList;)I", (void *)android_media_AudioRecord_get_active_microphones}, {"native_getPortId", "()I", (void *)android_media_AudioRecord_get_port_id}, - {"native_set_microphone_direction", "(I)I", - (void *)android_media_AudioRecord_set_microphone_direction}, - {"native_set_microphone_field_dimension", "(F)I", - (void *)android_media_AudioRecord_set_microphone_field_dimension}, + {"native_set_preferred_microphone_direction", "(I)I", + (void *)android_media_AudioRecord_set_preferred_microphone_direction}, + {"native_set_preferred_microphone_field_dimension", "(F)I", + (void *)android_media_AudioRecord_set_preferred_microphone_field_dimension}, }; // field names found in android/media/AudioRecord.java diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp index 1a90ebfee999..c8f81e2193c8 100644 --- a/core/jni/android_media_AudioSystem.cpp +++ b/core/jni/android_media_AudioSystem.cpp @@ -2038,13 +2038,13 @@ android_media_AudioSystem_getStreamVolumeDB(JNIEnv *env, jobject thiz, static jboolean android_media_AudioSystem_isOffloadSupported(JNIEnv *env, jobject thiz, - jint encoding, jint sampleRate, jint channelMask, jint channelIndexMask) + jint encoding, jint sampleRate, jint channelMask, jint channelIndexMask, jint streamType) { audio_offload_info_t format = AUDIO_INFO_INITIALIZER; format.format = (audio_format_t) audioFormatToNative(encoding); format.sample_rate = (uint32_t) sampleRate; format.channel_mask = nativeChannelMaskFromJavaChannelMasks(channelMask, channelIndexMask); - format.stream_type = AUDIO_STREAM_MUSIC; + format.stream_type = (audio_stream_type_t) streamType; format.has_video = false; format.is_streaming = false; // offload duration unknown at this point: @@ -2292,7 +2292,7 @@ static const JNINativeMethod gMethods[] = { (void *)android_media_AudioSystem_registerRecordingCallback}, {"systemReady", "()I", (void *)android_media_AudioSystem_systemReady}, {"getStreamVolumeDB", "(III)F", (void *)android_media_AudioSystem_getStreamVolumeDB}, - {"native_is_offload_supported", "(IIII)Z", (void *)android_media_AudioSystem_isOffloadSupported}, + {"native_is_offload_supported", "(IIIII)Z", (void *)android_media_AudioSystem_isOffloadSupported}, {"getMicrophones", "(Ljava/util/ArrayList;)I", (void *)android_media_AudioSystem_getMicrophones}, {"getSurroundFormats", "(Ljava/util/Map;Z)I", (void *)android_media_AudioSystem_getSurroundFormats}, {"setSurroundFormatEnabled", "(IZ)I", (void *)android_media_AudioSystem_setSurroundFormatEnabled}, diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp index cfb2dd199f39..d7a981ed3e9d 100644 --- a/core/jni/android_net_NetUtils.cpp +++ b/core/jni/android_net_NetUtils.cpp @@ -487,6 +487,11 @@ static jbyteArray android_net_utils_resNetworkResult(JNIEnv *env, jobject thiz, return answer; } +static void android_net_utils_resNetworkCancel(JNIEnv *env, jobject thiz, jobject javaFd) { + int fd = jniGetFDFromFileDescriptor(env, javaFd); + resNetworkCancel(fd); +} + static jobject android_net_utils_getTcpRepairWindow(JNIEnv *env, jobject thiz, jobject javaFd) { if (javaFd == NULL) { jniThrowNullPointerException(env, NULL); @@ -546,6 +551,7 @@ static const JNINativeMethod gNetworkUtilMethods[] = { { "resNetworkSend", "(I[BII)Ljava/io/FileDescriptor;", (void*) android_net_utils_resNetworkSend }, { "resNetworkQuery", "(ILjava/lang/String;III)Ljava/io/FileDescriptor;", (void*) android_net_utils_resNetworkQuery }, { "resNetworkResult", "(Ljava/io/FileDescriptor;)[B", (void*) android_net_utils_resNetworkResult }, + { "resNetworkCancel", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_resNetworkCancel }, }; int register_android_net_NetworkUtils(JNIEnv* env) diff --git a/core/jni/android_util_StatsLog.cpp b/core/jni/android_util_StatsLog.cpp new file mode 100644 index 000000000000..e749d34035dd --- /dev/null +++ b/core/jni/android_util_StatsLog.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_NAMESPACE "StatsLog.tag." +#define LOG_TAG "StatsLog_println" + +#include <assert.h> +#include <cutils/properties.h> + +#include "jni.h" +#include <nativehelper/JNIHelp.h> +#include "utils/misc.h" +#include "core_jni_helpers.h" +#include "stats_event_list.h" + +namespace android { + +static void android_util_StatsLog_writeRaw(JNIEnv* env, jobject clazz, jbyteArray buf, jint size) +{ + if (buf == NULL) { + return; + } + jint actualSize = env->GetArrayLength(buf); + if (actualSize < size) { + return; + } + + jbyte* bufferArray = env->GetByteArrayElements(buf, NULL); + if (bufferArray == NULL) { + return; + } + const uint32_t statsEventTag = 1937006964; + struct iovec vec[2]; + vec[0].iov_base = (void*) &statsEventTag; + vec[0].iov_len = sizeof(statsEventTag); + vec[1].iov_base = (void*) bufferArray; + vec[1].iov_len = size; + write_to_statsd(vec, 2); + + env->ReleaseByteArrayElements(buf, bufferArray, 0); +} + +/* + * JNI registration. + */ +static const JNINativeMethod gMethods[] = { + /* name, signature, funcPtr */ + { "writeRaw", "([BI)V", (void*) android_util_StatsLog_writeRaw }, +}; + +int register_android_util_StatsLog(JNIEnv* env) +{ + return RegisterMethodsOrDie(env, "android/util/StatsLog", gMethods, NELEM(gMethods)); +} + +}; // namespace android diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 4a6c72bda283..94f96babaf90 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -126,6 +126,41 @@ static struct { jfieldID white; } gDisplayPrimariesClassInfo; +static struct { + jclass clazz; + jmethodID builder; +} gScreenshotGraphicBufferClassInfo; + +class JNamedColorSpace { +public: + // ColorSpace.Named.SRGB.ordinal() = 0; + static constexpr jint SRGB = 0; + + // ColorSpace.Named.DISPLAY_P3.ordinal() = 6; + static constexpr jint DISPLAY_P3 = 6; +}; + +constexpr jint fromDataspaceToNamedColorSpaceValue(const ui::Dataspace dataspace) { + switch (dataspace) { + case ui::Dataspace::DISPLAY_P3: + return JNamedColorSpace::DISPLAY_P3; + default: + return JNamedColorSpace::SRGB; + } +} + +constexpr ui::Dataspace pickDataspaceFromColorMode(const ui::ColorMode colorMode) { + switch (colorMode) { + case ui::ColorMode::DISPLAY_P3: + case ui::ColorMode::BT2100_PQ: + case ui::ColorMode::BT2100_HLG: + case ui::ColorMode::DISPLAY_BT2020: + return ui::Dataspace::DISPLAY_P3; + default: + return ui::Dataspace::V0_SRGB; + } +} + // ---------------------------------------------------------------------------- static jlong nativeCreateTransaction(JNIEnv* env, jclass clazz) { @@ -210,9 +245,12 @@ static jobject nativeScreenshot(JNIEnv* env, jclass clazz, if (displayToken == NULL) { return NULL; } + const ui::ColorMode colorMode = SurfaceComposerClient::getActiveColorMode(displayToken); + const ui::Dataspace dataspace = pickDataspaceFromColorMode(colorMode); + Rect sourceCrop = rectFromObj(env, sourceCropObj); sp<GraphicBuffer> buffer; - status_t res = ScreenshotClient::capture(displayToken, ui::Dataspace::V0_SRGB, + status_t res = ScreenshotClient::capture(displayToken, dataspace, ui::PixelFormat::RGBA_8888, sourceCrop, width, height, useIdentityTransform, rotation, captureSecureLayers, &buffer); @@ -220,13 +258,15 @@ static jobject nativeScreenshot(JNIEnv* env, jclass clazz, return NULL; } - return env->CallStaticObjectMethod(gGraphicBufferClassInfo.clazz, - gGraphicBufferClassInfo.builder, + const jint namedColorSpace = fromDataspaceToNamedColorSpaceValue(dataspace); + return env->CallStaticObjectMethod(gScreenshotGraphicBufferClassInfo.clazz, + gScreenshotGraphicBufferClassInfo.builder, buffer->getWidth(), buffer->getHeight(), buffer->getPixelFormat(), (jint)buffer->getUsage(), - (jlong)buffer.get()); + (jlong)buffer.get(), + namedColorSpace); } static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandleToken, @@ -243,20 +283,23 @@ static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandl } sp<GraphicBuffer> buffer; - status_t res = ScreenshotClient::captureChildLayers(layerHandle, ui::Dataspace::V0_SRGB, + const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB; + status_t res = ScreenshotClient::captureChildLayers(layerHandle, dataspace, ui::PixelFormat::RGBA_8888, sourceCrop, frameScale, &buffer); if (res != NO_ERROR) { return NULL; } - return env->CallStaticObjectMethod(gGraphicBufferClassInfo.clazz, - gGraphicBufferClassInfo.builder, + const jint namedColorSpace = fromDataspaceToNamedColorSpaceValue(dataspace); + return env->CallStaticObjectMethod(gScreenshotGraphicBufferClassInfo.clazz, + gScreenshotGraphicBufferClassInfo.builder, buffer->getWidth(), buffer->getHeight(), buffer->getPixelFormat(), (jint)buffer->getUsage(), - (jlong)buffer.get()); + (jlong)buffer.get(), + namedColorSpace); } static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) { @@ -1306,9 +1349,13 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeSetOverrideScalingMode }, {"nativeGetHandle", "(J)Landroid/os/IBinder;", (void*)nativeGetHandle }, - {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIZIZ)Landroid/graphics/GraphicBuffer;", + {"nativeScreenshot", + "(Landroid/os/IBinder;Landroid/graphics/Rect;IIZIZ)" + "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;", (void*)nativeScreenshot }, - {"nativeCaptureLayers", "(Landroid/os/IBinder;Landroid/graphics/Rect;F)Landroid/graphics/GraphicBuffer;", + {"nativeCaptureLayers", + "(Landroid/os/IBinder;Landroid/graphics/Rect;F)" + "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;", (void*)nativeCaptureLayers }, {"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V", (void*)nativeSetInputWindowInfo }, @@ -1386,6 +1433,14 @@ int register_android_view_SurfaceControl(JNIEnv* env) gGraphicBufferClassInfo.builder = GetStaticMethodIDOrDie(env, graphicsBufferClazz, "createFromExisting", "(IIIIJ)Landroid/graphics/GraphicBuffer;"); + jclass screenshotGraphicsBufferClazz = FindClassOrDie(env, + "android/view/SurfaceControl$ScreenshotGraphicBuffer"); + gScreenshotGraphicBufferClassInfo.clazz = + MakeGlobalRefOrDie(env, screenshotGraphicsBufferClazz); + gScreenshotGraphicBufferClassInfo.builder = GetStaticMethodIDOrDie(env, + screenshotGraphicsBufferClazz, + "createFromNative", "(IIIIJI)Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;"); + jclass displayedContentSampleClazz = FindClassOrDie(env, "android/hardware/display/DisplayedContentSample"); gDisplayedContentSampleClassInfo.clazz = MakeGlobalRefOrDie(env, displayedContentSampleClazz); diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto index f03740725fe1..b4be3f599604 100644 --- a/core/proto/android/app/settings_enums.proto +++ b/core/proto/android/app/settings_enums.proto @@ -590,6 +590,13 @@ enum Action { // OS: P DIALOG_SWITCH_HFP_DEVICES = 1416; + // OPEN: QS Sensor Privacy Mode tile shown + // ACTION: QS Sensor Privacy Mode tile tapped + // SUBTYPE: 0 is off, 1 is on + // CATEGORY: QUICK_SETTINGS + // OS: Q + QS_SENSOR_PRIVACY = 1598; + // ACTION: Tap & Pay -> Default Application Setting -> Use Forground ACTION_NFC_PAYMENT_FOREGROUND_SETTING = 1622; @@ -2309,4 +2316,7 @@ enum PageId { // OPEN: Settings > Face > Remove face // OS: Q DIALOG_FACE_REMOVE = 1693; + + // Settings > Display > Theme + DARK_UI_SETTINGS = 1698; } diff --git a/core/proto/android/stats/connectivity/Android.bp b/core/proto/android/stats/connectivity/Android.bp new file mode 100644 index 000000000000..5aa4ddbdf7f9 --- /dev/null +++ b/core/proto/android/stats/connectivity/Android.bp @@ -0,0 +1,25 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +java_library_static { + name: "networkstackprotosnano", + proto: { + type: "nano", + }, + srcs: [ + "network_stack.proto", + ], + sdk_version: "system_current", + no_framework_libs: true, +}
\ No newline at end of file diff --git a/media/java/android/media/session/SessionCallbackLink.aidl b/core/proto/android/stats/connectivity/network_stack.proto index c489e5bee6e2..7d9aa1c6eb23 100644 --- a/media/java/android/media/session/SessionCallbackLink.aidl +++ b/core/proto/android/stats/connectivity/network_stack.proto @@ -1,5 +1,5 @@ /* - * Copyright 2019 The Android Open Source Project + * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.media.session; -parcelable SessionCallbackLink; +syntax = "proto2"; + +package android.stats.connectivity; +option java_multiple_files = true; +option java_outer_classname = "NetworkStackProto"; + +message NetworkStackEventData { + +} + diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 5427147aa32a..8bfa038c8e8f 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1849,8 +1849,8 @@ <permission android:name="android.permission.HARDWARE_TEST" android:protectionLevel="signature" /> - <!-- @hide Allows an application to manage DynamicAndroid image --> - <permission android:name="android.permission.MANAGE_DYNAMIC_ANDROID" + <!-- @hide Allows an application to manage DynamicSystem image --> + <permission android:name="android.permission.MANAGE_DYNAMIC_SYSTEM" android:protectionLevel="signature" /> <!-- @SystemApi Allows access to Broadcast Radio @@ -1989,6 +1989,12 @@ <permission android:name="android.permission.BIND_INCALL_SERVICE" android:protectionLevel="signature|privileged" /> + <!-- Allows the app to request network scans from telephony. + <p>Not for use by third-party applications. + @SystemApi @hide--> + <permission android:name="android.permission.NETWORK_SCAN" + android:protectionLevel="signature|privileged" /> + <!-- Must be required by a link {@link android.telephony.VisualVoicemailService} to ensure that only the system can bind to it. <p>Protection level: signature|privileged @@ -3927,7 +3933,7 @@ <permission android:name="android.permission.MANAGE_ROLLBACKS" android:protectionLevel="signature|verifier" /> - <!-- @SystemApi @TestApi @hide Allows testing apk level rollbacks. --> + <!-- @TestApi @hide Allows testing apk level rollbacks. --> <permission android:name="android.permission.TEST_MANAGE_ROLLBACKS" android:protectionLevel="signature" /> @@ -4420,6 +4426,13 @@ <permission android:name="android.permission.BIND_CARRIER_MESSAGING_CLIENT_SERVICE" android:protectionLevel="signature" /> + <!-- Must be required by an {@link android.service.watchdog.ExplicitHealthCheckService} to + ensure that only the system can bind to it. + @hide This is not a third-party API (intended for OEMs and system apps). + --> + <permission android:name="android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE" + android:protectionLevel="signature|privileged" /> + <!-- @hide Permission that allows configuring appops. <p>Not for use by third-party applications. --> <permission android:name="android.permission.MANAGE_APPOPS" @@ -4484,6 +4497,11 @@ <permission android:name="android.permission.SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON" android:protectionLevel="signature|privileged" /> + <!-- @SystemApi Allows an application to access shared libraries. + @hide --> + <permission android:name="android.permission.ACCESS_SHARED_LIBRARIES" + android:protectionLevel="signature|installer" /> + <application android:process="system" android:persistent="true" android:hasCode="false" diff --git a/core/res/res/drawable-car/car_dialog_button_background.xml b/core/res/res/drawable-car/car_dialog_button_background.xml index dc742d57b147..67506cbc12bc 100644 --- a/core/res/res/drawable-car/car_dialog_button_background.xml +++ b/core/res/res/drawable-car/car_dialog_button_background.xml @@ -15,7 +15,7 @@ ~ limitations under the License. --> <ripple xmlns:android="http://schemas.android.com/apk/res/android" - android:color="@*android:color/car_card_ripple_background"> + android:color="?android:attr/colorControlHighlight"> <item android:id="@android:id/mask"> <color android:color="@*android:color/car_white_1000" /> </item> diff --git a/core/res/res/layout/chooser_row.xml b/core/res/res/layout/chooser_row.xml index d4585eb1e6fc..742d7eedaced 100644 --- a/core/res/res/layout/chooser_row.xml +++ b/core/res/res/layout/chooser_row.xml @@ -21,8 +21,8 @@ android:layout_width="match_parent" android:layout_height="100dp" android:gravity="start|top" - android:paddingStart="@dimen/chooser_grid_padding" - android:paddingEnd="@dimen/chooser_grid_padding"> + android:paddingStart="@dimen/chooser_edge_margin_normal" + android:paddingEnd="@dimen/chooser_edge_margin_normal"> <TextView android:id="@+id/chooser_row_text_option" android:layout_width="match_parent" diff --git a/core/res/res/layout/resolve_grid_item.xml b/core/res/res/layout/resolve_grid_item.xml index 71c153fa6021..4a3dfba63c6d 100644 --- a/core/res/res/layout/resolve_grid_item.xml +++ b/core/res/res/layout/resolve_grid_item.xml @@ -18,7 +18,7 @@ --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" - android:layout_width="76dp" + android:layout_width="@dimen/chooser_target_width" android:layout_height="wrap_content" android:minHeight="100dp" android:gravity="center" @@ -27,22 +27,13 @@ android:focusable="true" android:background="?attr/selectableItemBackgroundBorderless"> - <FrameLayout android:layout_width="wrap_content" - android:layout_height="wrap_content"> - <ImageView android:id="@+id/icon" - android:layout_width="48dp" - android:layout_height="48dp" - android:layout_marginLeft="3dp" - android:layout_marginRight="3dp" - android:layout_marginBottom="3dp" - android:scaleType="fitCenter" /> - <ImageView android:id="@+id/target_badge" - android:layout_width="16dp" - android:layout_height="16dp" - android:layout_gravity="end|bottom" - android:visibility="gone" - android:scaleType="fitCenter" /> - </FrameLayout> + <ImageView android:id="@+id/icon" + android:layout_width="@dimen/resolver_icon_size" + android:layout_height="@dimen/resolver_icon_size" + android:layout_marginLeft="3dp" + android:layout_marginRight="3dp" + android:layout_marginBottom="3dp" + android:scaleType="fitCenter" /> <!-- Activity name --> <TextView android:id="@android:id/text1" diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 52f6698194e9..eab056331496 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -145,8 +145,10 @@ <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"الاتصال عبر WiFi"</string> <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string> <string name="wifi_calling_off_summary" msgid="8720659586041656098">"إيقاف"</string> - <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"شبكة Wi-Fi مفضّلة"</string> - <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"شبكة بيانات الجوال مفضَّلة"</string> + <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) --> + <skip /> + <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) --> + <skip /> <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Wi-Fi فقط"</string> <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: لم تتم إعادة التوجيه"</string> <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> @@ -236,7 +238,8 @@ <string name="global_action_bug_report" msgid="7934010578922304799">"تقرير الأخطاء"</string> <string name="global_action_logout" msgid="935179188218826050">"إنهاء الجلسة"</string> <string name="global_action_screenshot" msgid="8329831278085426283">"لقطة شاشة"</string> - <string name="bugreport_title" msgid="2667494803742548533">"إعداد تقرير بالأخطاء"</string> + <!-- no translation found for bugreport_title (5981047024855257269) --> + <skip /> <string name="bugreport_message" msgid="398447048750350456">"سيجمع هذا معلومات حول حالة جهازك الحالي لإرسالها كرسالة إلكترونية، ولكنه سيستغرق وقتًا قليلاً من بدء عرض تقرير بالأخطاء. وحتى يكون جاهزًا للإرسال، يُرجى الانتظار."</string> <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"تقرير تفاعلي"</string> <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"يمكنك استخدام هذا الخيار في معظم الأحيان، حيث يتيح لك إمكانية تتبع مستوى تقدم التقرير والحصول على مزيد من المعلومات حول المشكلة وتسجيل لقطات شاشة. وقد يتم إغفال بعض الأقسام الأقل استخدامًا والتي تستغرق وقتًا طويلاً أثناء إعداد التقرير."</string> @@ -293,9 +296,12 @@ <string name="permgrouplab_location" msgid="7275582855722310164">"الموقع الجغرافي"</string> <string name="permgroupdesc_location" msgid="1346617465127855033">"الوصول إلى موقع هذا الجهاز"</string> <string name="permgrouprequest_location" msgid="3788275734953323491">"هل تريد السماح لتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بالوصول إلى الموقع الجغرافي لهذا الجهاز؟"</string> - <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"لن يكون بإمكان التطبيق الوصول إلى الموقع الجغرافي إلا عند استخدامك لهذا التطبيق."</string> - <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"هل تريد السماح دائمًا لتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بالوصول إلى الموقع الجغرافي لهذا الجهاز؟"</string> - <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"سيكون بإمكان التطبيق دائمًا الوصول إلى الموقع الجغرافي، حتى عند عدم استخدامك لهذا التطبيق."</string> + <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) --> + <skip /> <string name="permgrouplab_calendar" msgid="5863508437783683902">"التقويم"</string> <string name="permgroupdesc_calendar" msgid="3889615280211184106">"الوصول تقويمك"</string> <string name="permgrouprequest_calendar" msgid="289900767793189421">"هل تريد السماح لتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بالدخول إلى التقويم؟"</string> @@ -328,7 +334,10 @@ <string name="permgrouprequest_aural" msgid="6787926123071735620">"هل تريد السماح لتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بالوصول إلى الموسيقى؟"</string> <string name="permgrouplab_visual" msgid="6477382108771145134">"الصور والفيديوهات"</string> <string name="permgroupdesc_visual" msgid="3415827902566663546">"الوصول إلى صورك وفيديوهاتك"</string> - <string name="permgrouprequest_visual" msgid="3043752127595243314">"هل تريد السماح للتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بالوصول إلى صورك وفيديوهاتك، بما في ذلك المواقع الجغرافية ذات العلامات؟"</string> + <!-- no translation found for permgrouprequest_visual (4926581398380334943) --> + <skip /> + <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) --> + <skip /> <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"استرداد محتوى النافذة"</string> <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"فحص محتوى نافذة يتم التفاعل معها"</string> <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"تشغيل الاستكشاف باللمس"</string> @@ -521,8 +530,10 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"للسماح للتطبيق بالاتصال بعلامات الاتصال قريب المدى (NFC)، والبطاقات وبرامج القراءة."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"إيقاف قفل الشاشة"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"للسماح للتطبيق بإيقاف تأمين المفاتيح وأي أمان لكلمة مرور مرتبطة. على سبيل المثال، يعطل الهاتف تأمين المفاتيح عند استقبال مكالمة هاتفية واردة، ثم يعيد تفعيل تأمين المفاتيح عند انتهاء المكالمة."</string> - <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"طلب معرفة مستوى صعوبة قفل الشاشة"</string> - <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"للسماح للتطبيق بمعرفة مستوى صعوبة قفل الشاشة (عالي أو متوسط أو منخفض الصعوبة أو بدون)، والذي يحدّد النطاق المحتمل لطول ونوع قفل الشاشة. ويمكن أن يقترح التطبيق للمستخدمين أيضًا تعديل قفل الشاشة إلى مستوى معيّن، ولهم مطلق الحرية في تجاهل هذا الاقتراح ورفضه. وتجدر الإشارة إلى أنه لا يتم حفظ قفل الشاشة في نص عادي، لذا لا يعرف التطبيق كلمة المرور تحديدًا."</string> + <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) --> + <skip /> + <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) --> + <skip /> <string name="permlab_useBiometric" msgid="8837753668509919318">"استخدام الأجهزة البيومترية"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"للسماح للتطبيق باستخدام الأجهزة البيومترية للمصادقة"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"لإدارة أجهزة بصمة الإصبع"</string> @@ -577,37 +588,59 @@ <string name="permdesc_manageFace" msgid="8919637120670185330">"السماح للتطبيق باستدعاء طرق لإضافة نماذج من الوجوه وحذفها"</string> <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"استخدام أجهزة مصادقة الوجه"</string> <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"السماح للتطبيق باستخدام أجهزة مصادقة الوجه"</string> - <string name="face_acquired_insufficient" msgid="5901287247766106330">"تعذَّر التعرُّف على الوجه. يُرجى إعادة المحاولة."</string> - <string name="face_acquired_too_bright" msgid="610606792381297174">"الوجه ساطع جدًا. يُرجى إعادة المحاولة بإضاءة أقل."</string> - <string name="face_acquired_too_dark" msgid="7229162716976778371">"الوجه مظلم جدًا. يُرجى الاستعانة بمصدر إضاءة."</string> - <string name="face_acquired_too_close" msgid="1980310037427755293">"يُرجى إبعاد جهاز الاستشعار عن الوجه."</string> - <string name="face_acquired_too_far" msgid="4494571381828850007">"يُرجى تقريب جهاز الاستشعار من الوجه."</string> - <string name="face_acquired_too_high" msgid="228411096134808372">"يُرجى تحريك جهاز الاستشعار للأعلى."</string> - <string name="face_acquired_too_low" msgid="4539774649296349109">"يُرجى تحريك جهاز الاستشعار للأسفل."</string> - <string name="face_acquired_too_right" msgid="1650292067226118760">"يُرجى تحريك جهاز الاستشعار جهة اليمين."</string> - <string name="face_acquired_too_left" msgid="2712489669456176505">"يُرجى تحريك جهاز الاستشعار جهة اليسار."</string> - <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"يُرجى النظر إلى جهاز الاستشعار."</string> - <string name="face_acquired_not_detected" msgid="5707782294589511391">"لم يتم رصد أي وجه."</string> - <string name="face_acquired_too_much_motion" msgid="470381210701463822">"حركة أكثر من اللازم"</string> + <!-- no translation found for face_acquired_insufficient (2767330364802375742) --> + <skip /> + <!-- no translation found for face_acquired_too_bright (5005650874582450967) --> + <skip /> + <!-- no translation found for face_acquired_too_dark (1966194696381394616) --> + <skip /> + <!-- no translation found for face_acquired_too_close (1401011882624272753) --> + <skip /> + <!-- no translation found for face_acquired_too_far (1210969240069012510) --> + <skip /> + <!-- no translation found for face_acquired_too_high (3362395713403348013) --> + <skip /> + <!-- no translation found for face_acquired_too_low (488983581737550912) --> + <skip /> + <!-- no translation found for face_acquired_too_right (941726879175375970) --> + <skip /> + <!-- no translation found for face_acquired_too_left (5873592047381190672) --> + <skip /> + <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) --> + <skip /> + <!-- no translation found for face_acquired_not_detected (4885504661626728809) --> + <skip /> + <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) --> + <skip /> <string name="face_acquired_recalibrate" msgid="8077949502893707539">"يُرجى إعادة تسجيل وجهك."</string> - <string name="face_acquired_too_different" msgid="5553210341111255124">"تم التعرّف على وجه مختلف."</string> + <!-- no translation found for face_acquired_too_different (7663983770123789694) --> + <skip /> <string name="face_acquired_too_similar" msgid="1508776858407646460">"الوجه مشابه جدًا، يُرجى تغيير وضعيتك."</string> - <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"يُرجى النظر إلى الكاميرا مباشرة أكثر."</string> - <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"يُرجى النظر إلى الكاميرا مباشرة أكثر."</string> + <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) --> + <skip /> + <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"يُرجى تثبيت الرأس في وضع عمودي."</string> - <string name="face_acquired_obscured" msgid="3055077697850272097">"يُرجى الكشف عن وجهك."</string> + <!-- no translation found for face_acquired_obscured (5747521031647744553) --> + <skip /> + <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) --> + <skip /> <string-array name="face_acquired_vendor"> </string-array> <string name="face_error_hw_not_available" msgid="6255891785768984615">"أجهزة مصادقة الوجه غير متاحة."</string> - <string name="face_error_timeout" msgid="4014326147867150054">"انتهت مهلة التعرُّف على الوجه. أعِد المحاولة."</string> + <!-- no translation found for face_error_timeout (2605673935810019129) --> + <skip /> <string name="face_error_no_space" msgid="8224993703466381314">"يتعذَّر حفظ الوجه."</string> <string name="face_error_canceled" msgid="283945501061931023">"تمّ إلغاء عملية مصادقة الوجه."</string> <string name="face_error_user_canceled" msgid="8943921120862164539">"ألغَى المستخدم مصادقة الوجه."</string> <string name="face_error_lockout" msgid="3407426963155388504">"تمّ إجراء محاولات كثيرة. أعِد المحاولة لاحقًا."</string> <string name="face_error_lockout_permanent" msgid="8198354656746088890">"تمّ إجراء محاولات كثيرة. ميزة مصادقة الوجه متوقفة."</string> - <string name="face_error_unable_to_process" msgid="238761109287767270">"يُرجى إعادة المحاولة."</string> - <string name="face_error_not_enrolled" msgid="9166792142679691323">"ليس هناك وجه مسجّل."</string> - <string name="face_error_hw_not_present" msgid="916085883581450331">"لا يحتوي هذا الجهاز على مستشعِر مصادقة للوجه."</string> + <!-- no translation found for face_error_unable_to_process (4940944939691171539) --> + <skip /> + <!-- no translation found for face_error_not_enrolled (4245760276260427472) --> + <skip /> + <!-- no translation found for face_error_hw_not_present (5296043240874659926) --> + <skip /> <string name="face_name_template" msgid="7004562145809595384">"الوجه <xliff:g id="FACEID">%d</xliff:g>"</string> <string-array name="face_error_vendor"> </string-array> @@ -1293,9 +1326,16 @@ <string name="new_app_action" msgid="6694851182870774403">"فتح <xliff:g id="NEW_APP">%1$s</xliff:g>"</string> <string name="new_app_description" msgid="5894852887817332322">"سيتم إغلاق <xliff:g id="OLD_APP">%1$s</xliff:g> من دون حفظ"</string> <string name="dump_heap_notification" msgid="2618183274836056542">"لقد تجاوزت <xliff:g id="PROC">%1$s</xliff:g> حد الذاكرة."</string> + <!-- no translation found for dump_heap_ready_notification (1162196579925048701) --> + <skip /> <string name="dump_heap_notification_detail" msgid="3993078784053054141">"تم جمع مقدار كبير من بيانات الذاكرة. انقر للمشاركة."</string> <string name="dump_heap_title" msgid="5864292264307651673">"هل تريد مشاركة نَسْخ الذاكرة؟"</string> - <string name="dump_heap_text" msgid="4809417337240334941">"تجاوزت عملية <xliff:g id="PROC">%1$s</xliff:g> حد الذاكرة المخصص لها وقدره <xliff:g id="SIZE">%2$s</xliff:g>، ويتوفر نَسْخ للذاكرة لمشاركته مع مطور برامج العملية ولكن توخ الحذر حيث قد يحتوي نَسْخ الذاكرة هذا على معلومات شخصية يملك التطبيق حق الوصول إليها."</string> + <!-- no translation found for dump_heap_text (8546022920319781701) --> + <skip /> + <!-- no translation found for dump_heap_system_text (1205466256312104134) --> + <skip /> + <!-- no translation found for dump_heap_ready_text (6759394977904051000) --> + <skip /> <string name="sendText" msgid="5209874571959469142">"اختيار إجراء للنص"</string> <string name="volume_ringtone" msgid="6885421406845734650">"مستوى صوت الرنين"</string> <string name="volume_music" msgid="5421651157138628171">"مستوى صوت الوسائط"</string> @@ -1342,8 +1382,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"انقر للاطلاع على جميع الشبكات"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"اتصال"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"جميع الشبكات"</string> - <string name="wifi_suggestion_title" msgid="8951405130379148709">"تتوفَّر شبكة Wi‑Fi مقترَحة من قِبَل <xliff:g id="NAME">%s</xliff:g>."</string> - <string name="wifi_suggestion_content" msgid="2658317015552324848">"هل ترغب في الاتصال بالشبكات المقترَحة من <xliff:g id="NAME">%s</xliff:g>؟"</string> + <!-- no translation found for wifi_suggestion_title (9099832833531486167) --> + <skip /> + <!-- no translation found for wifi_suggestion_content (5883181205841582873) --> + <skip /> <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"نعم"</string> <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"لا"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"سيتم تشغيل شبكة Wi-Fi تلقائيًا."</string> @@ -1355,9 +1397,14 @@ <string name="network_available_sign_in" msgid="1848877297365446605">"تسجيل الدخول إلى الشبكة"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> <skip /> - <string name="wifi_no_internet" msgid="8938267198124654938">"شبكة Wi-Fi غير متصلة بالإنترنت"</string> + <!-- no translation found for wifi_no_internet (5198100389964214865) --> + <skip /> <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"انقر للحصول على الخيارات."</string> <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"تمّ الاتصال."</string> + <!-- no translation found for network_partial_connectivity (7774883385494762741) --> + <skip /> + <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) --> + <skip /> <string name="wifi_softap_config_change" msgid="8475911871165857607">"التغييرات التي طرأت على إعدادات نقطة الاتصال"</string> <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"تمّ تغيير نطاق نقطة الاتصال الخاصة بك."</string> <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"لا يتوافق هذا الجهاز مع إعدادك المفضّل الخاص باستخدام النطاق 5 غيغاهرتز فقط. وسيستخدم الجهاز بدلاً من ذلك النطاق 5 غيغاهرتز عندما يكون متاحًا."</string> @@ -1442,6 +1489,10 @@ <string name="adb_active_notification_title" msgid="6729044778949189918">"تم توصيل تصحيح أخطاء USB"</string> <string name="adb_active_notification_message" msgid="7463062450474107752">"انقر لإيقاف تصحيح أخطاء USB."</string> <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"اختيار إيقاف تصحيح أخطاء USB."</string> + <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) --> + <skip /> + <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) --> + <skip /> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"السوائل والشوائب في منفذ USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"تمّ إيقاف منفذ USB تلقائيًا. انقُر لمعرفة المزيد من المعلومات."</string> <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"الأمان في استخدام منفذ USB"</string> @@ -2041,8 +2092,6 @@ <string name="profile_encrypted_message" msgid="6964994232310195874">"انقر لإلغاء قفل الملف الشخصي للعمل"</string> <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"تم الاتصال بـ <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string> <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"انقر لعرض الملفات"</string> - <string name="pin_target" msgid="3052256031352291362">"تثبيت"</string> - <string name="unpin_target" msgid="3556545602439143442">"إزالة تثبيت"</string> <string name="app_info" msgid="6856026610594615344">"معلومات عن التطبيق"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="demo_starting_message" msgid="5268556852031489931">"جارٍ بدء العرض التوضيحي…"</string> @@ -2137,6 +2186,22 @@ <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"إشعار معلومات \"وضع سلسلة الإجراءات\""</string> <string name="dynamic_mode_notification_title" msgid="508815255807182035">"قد تنفد طاقة البطارية قبل الشحن المعتاد"</string> <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"تم تفعيل \"توفير شحن البطارية\" لإطالة عمرها."</string> + <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) --> + <skip /> + <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) --> + <skip /> + <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) --> + <skip /> <string name="mime_type_folder" msgid="7111951698626315204">"مجلّد"</string> <string name="mime_type_apk" msgid="5518003630972506900">"تطبيق Android"</string> <string name="mime_type_generic" msgid="6833871596845900027">"ملف"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 3e784b9c8ece..da6ccb0ba68b 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -141,8 +141,10 @@ <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Trucades per Wi‑Fi"</string> <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string> <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desactivat"</string> - <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Preferència per la Wi-Fi"</string> - <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferència per dades mòbils"</string> + <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) --> + <skip /> + <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) --> + <skip /> <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Només Wi-Fi"</string> <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: no s\'ha desviat"</string> <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> @@ -228,7 +230,8 @@ <string name="global_action_bug_report" msgid="7934010578922304799">"Informe d\'error"</string> <string name="global_action_logout" msgid="935179188218826050">"Finalitza la sessió"</string> <string name="global_action_screenshot" msgid="8329831278085426283">"Captura de pantalla"</string> - <string name="bugreport_title" msgid="2667494803742548533">"Crea informe d\'errors"</string> + <!-- no translation found for bugreport_title (5981047024855257269) --> + <skip /> <string name="bugreport_message" msgid="398447048750350456">"Es recopilarà informació sobre l\'estat actual del dispositiu i se t\'enviarà per correu electrònic. Passaran uns quants minuts des de l\'inici de l\'informe d\'errors fins al seu enviament, per la qual cosa et recomanem que tinguis paciència."</string> <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Informe interactiu"</string> <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Utilitza aquesta opció en la majoria de circumstàncies. Et permet fer un seguiment del progrés de l\'informe, introduir més dades sobre el problema i fer captures de pantalla. És possible que ometi seccions poc utilitzades que requereixen molt de temps."</string> @@ -281,9 +284,12 @@ <string name="permgrouplab_location" msgid="7275582855722310164">"Ubicació"</string> <string name="permgroupdesc_location" msgid="1346617465127855033">"accedir a la ubicació del dispositiu"</string> <string name="permgrouprequest_location" msgid="3788275734953323491">"Vols permetre que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> accedeixi a la ubicació del dispositiu?"</string> - <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"L\'aplicació només tindrà accés a la ubicació quan l\'estiguis utilitzant."</string> - <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Vols permetre que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> accedeixi sempre a la ubicació del dispositiu?"</string> - <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"L\'aplicació tindrà accés sempre a la ubicació, fins i tot quan no l\'estiguis utilitzant."</string> + <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) --> + <skip /> <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendari"</string> <string name="permgroupdesc_calendar" msgid="3889615280211184106">"accedir al calendari"</string> <string name="permgrouprequest_calendar" msgid="289900767793189421">"Vols permetre que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> accedeixi al calendari?"</string> @@ -316,7 +322,10 @@ <string name="permgrouprequest_aural" msgid="6787926123071735620">"Vols permetre que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> accedeixi a la teva música?"</string> <string name="permgrouplab_visual" msgid="6477382108771145134">"Fotos i vídeos"</string> <string name="permgroupdesc_visual" msgid="3415827902566663546">"accedir a les teves fotos i als teus vídeos"</string> - <string name="permgrouprequest_visual" msgid="3043752127595243314">"Vols permetre que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> accedeixi a les fotos i als vídeos, incloses les ubicacions etiquetades?"</string> + <!-- no translation found for permgrouprequest_visual (4926581398380334943) --> + <skip /> + <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) --> + <skip /> <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperar el contingut de la finestra"</string> <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecciona el contingut d\'una finestra amb què estàs interaccionant."</string> <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activar Exploració tàctil"</string> @@ -509,8 +518,10 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Permet que l\'aplicació es comuniqui amb les etiquetes, les targetes i els lectors de Comunicació de camp proper (NFC)."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"desactivació del bloqueig de pantalla"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permet que l\'aplicació desactivi el bloqueig del teclat i qualsevol element de seguretat de contrasenyes associat. Per exemple, el telèfon desactiva el bloqueig del teclat en rebre una trucada entrant i, a continuació, reactiva el bloqueig del teclat quan finalitza la trucada."</string> - <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"sol·licita una determinada complexitat del bloqueig de pantalla"</string> - <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Permet que l\'aplicació conegui el nivell de complexitat del bloqueig de pantalla (alt, mitjà, baix o cap), que indica la llargària i el tipus de bloqueig de pantalla possibles. L\'aplicació també pot suggerir que els usuaris actualitzin el bloqueig de pantalla a un nivell determinat, però els usuaris poden ignorar aquestes recomanacions. Tingues en compte que el bloqueig de pantalla no s\'emmagatzema com a text sense format, de manera que l\'aplicació no coneix la contrasenya exacta."</string> + <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) --> + <skip /> + <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) --> + <skip /> <string name="permlab_useBiometric" msgid="8837753668509919318">"utilitza maquinari biomètric"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Permet que l\'aplicació faci servir maquinari biomètric per a l\'autenticació"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"Gestionar el maquinari d\'empremtes digitals"</string> @@ -565,37 +576,59 @@ <string name="permdesc_manageFace" msgid="8919637120670185330">"Permet que l\'aplicació afegeixi i suprimeixi plantilles de cares que es puguin fer servir."</string> <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"utilitza el maquinari d\'autenticació facial"</string> <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Permet que l\'aplicació faci servir maquinari d\'autenticació facial"</string> - <string name="face_acquired_insufficient" msgid="5901287247766106330">"Error en processar la cara. Torna-ho a provar."</string> - <string name="face_acquired_too_bright" msgid="610606792381297174">"La cara brilla massa. Prova amb menys llum."</string> - <string name="face_acquired_too_dark" msgid="7229162716976778371">"La cara és massa fosca. Prova amb més llum."</string> - <string name="face_acquired_too_close" msgid="1980310037427755293">"Allunya el sensor de la cara."</string> - <string name="face_acquired_too_far" msgid="4494571381828850007">"Apropa el sensor a la cara."</string> - <string name="face_acquired_too_high" msgid="228411096134808372">"Puja el sensor més amunt."</string> - <string name="face_acquired_too_low" msgid="4539774649296349109">"Baixa el sensor més avall."</string> - <string name="face_acquired_too_right" msgid="1650292067226118760">"Mou el sensor cap a la dreta."</string> - <string name="face_acquired_too_left" msgid="2712489669456176505">"Mou el sensor cap a l\'esquerra."</string> - <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Mira el sensor."</string> - <string name="face_acquired_not_detected" msgid="5707782294589511391">"No s\'ha detectat cap cara."</string> - <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Massa moviment."</string> + <!-- no translation found for face_acquired_insufficient (2767330364802375742) --> + <skip /> + <!-- no translation found for face_acquired_too_bright (5005650874582450967) --> + <skip /> + <!-- no translation found for face_acquired_too_dark (1966194696381394616) --> + <skip /> + <!-- no translation found for face_acquired_too_close (1401011882624272753) --> + <skip /> + <!-- no translation found for face_acquired_too_far (1210969240069012510) --> + <skip /> + <!-- no translation found for face_acquired_too_high (3362395713403348013) --> + <skip /> + <!-- no translation found for face_acquired_too_low (488983581737550912) --> + <skip /> + <!-- no translation found for face_acquired_too_right (941726879175375970) --> + <skip /> + <!-- no translation found for face_acquired_too_left (5873592047381190672) --> + <skip /> + <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) --> + <skip /> + <!-- no translation found for face_acquired_not_detected (4885504661626728809) --> + <skip /> + <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) --> + <skip /> <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Torna a registrar la teva cara."</string> - <string name="face_acquired_too_different" msgid="5553210341111255124">"S\'ha detectat una altra cara."</string> + <!-- no translation found for face_acquired_too_different (7663983770123789694) --> + <skip /> <string name="face_acquired_too_similar" msgid="1508776858407646460">"És massa semblant; canvia de postura."</string> - <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Mira més directament cap a la càmera."</string> - <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Mira més directament cap a la càmera."</string> + <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) --> + <skip /> + <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Mantén el cap recte, sense inclinar-lo."</string> - <string name="face_acquired_obscured" msgid="3055077697850272097">"No et tapis la cara."</string> + <!-- no translation found for face_acquired_obscured (5747521031647744553) --> + <skip /> + <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) --> + <skip /> <string-array name="face_acquired_vendor"> </string-array> <string name="face_error_hw_not_available" msgid="6255891785768984615">"Maquinari de reconeixement facial no disponible."</string> - <string name="face_error_timeout" msgid="4014326147867150054">"S\'ha esgotat el temps d\'espera. Torna-ho a provar."</string> + <!-- no translation found for face_error_timeout (2605673935810019129) --> + <skip /> <string name="face_error_no_space" msgid="8224993703466381314">"La cara no es pot desar."</string> <string name="face_error_canceled" msgid="283945501061931023">"S\'ha cancel·lat el reconeixement facial."</string> <string name="face_error_user_canceled" msgid="8943921120862164539">"Autenticació facial cancel·lada per l\'usuari."</string> <string name="face_error_lockout" msgid="3407426963155388504">"Massa intents. Torna-ho a provar més tard."</string> <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Massa intents. Autenticació facial desactivada."</string> - <string name="face_error_unable_to_process" msgid="238761109287767270">"Torna-ho a provar."</string> - <string name="face_error_not_enrolled" msgid="9166792142679691323">"No s\'ha registrat cap cara."</string> - <string name="face_error_hw_not_present" msgid="916085883581450331">"Aquest dispositiu no té sensor d\'autenticació facial."</string> + <!-- no translation found for face_error_unable_to_process (4940944939691171539) --> + <skip /> + <!-- no translation found for face_error_not_enrolled (4245760276260427472) --> + <skip /> + <!-- no translation found for face_error_hw_not_present (5296043240874659926) --> + <skip /> <string name="face_name_template" msgid="7004562145809595384">"Cara <xliff:g id="FACEID">%d</xliff:g>"</string> <string-array name="face_error_vendor"> </string-array> @@ -1213,9 +1246,16 @@ <string name="new_app_action" msgid="6694851182870774403">"Obre <xliff:g id="NEW_APP">%1$s</xliff:g>"</string> <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> es tancarà sense desar els canvis"</string> <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> ha superat el límit de memòria"</string> + <!-- no translation found for dump_heap_ready_notification (1162196579925048701) --> + <skip /> <string name="dump_heap_notification_detail" msgid="3993078784053054141">"S\'ha recopilat un procés \"heap dump\". Toca per compartir-lo."</string> <string name="dump_heap_title" msgid="5864292264307651673">"Vols compartir el \"heap dump\"?"</string> - <string name="dump_heap_text" msgid="4809417337240334941">"El procés <xliff:g id="PROC">%1$s</xliff:g> ha superat el límit de <xliff:g id="SIZE">%2$s</xliff:g> de memòria del procés. Hi ha un procés \"heap dump\" disponible perquè el comparteixis amb el desenvolupador. Ves amb compte: aquest \"heap dump\" pot contenir les dades personals a les quals l\'aplicació tingui accés."</string> + <!-- no translation found for dump_heap_text (8546022920319781701) --> + <skip /> + <!-- no translation found for dump_heap_system_text (1205466256312104134) --> + <skip /> + <!-- no translation found for dump_heap_ready_text (6759394977904051000) --> + <skip /> <string name="sendText" msgid="5209874571959469142">"Tria una acció per al text"</string> <string name="volume_ringtone" msgid="6885421406845734650">"Volum del timbre"</string> <string name="volume_music" msgid="5421651157138628171">"Volum de multimèdia"</string> @@ -1254,8 +1294,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toca per veure totes les xarxes"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connecta"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Totes les xarxes"</string> - <string name="wifi_suggestion_title" msgid="8951405130379148709">"Hi ha disponible una xarxa Wi‑Fi proposada per <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_content" msgid="2658317015552324848">"Vols connectar-te a les xarxes proposades per <xliff:g id="NAME">%s</xliff:g>?"</string> + <!-- no translation found for wifi_suggestion_title (9099832833531486167) --> + <skip /> + <!-- no translation found for wifi_suggestion_content (5883181205841582873) --> + <skip /> <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Sí"</string> <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"La Wi-Fi s\'activarà automàticament"</string> @@ -1267,9 +1309,14 @@ <string name="network_available_sign_in" msgid="1848877297365446605">"Inicia la sessió a la xarxa"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> <skip /> - <string name="wifi_no_internet" msgid="8938267198124654938">"La Wi-Fi no té accés a Internet"</string> + <!-- no translation found for wifi_no_internet (5198100389964214865) --> + <skip /> <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Toca per veure les opcions"</string> - <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"S\'ha establert la connexió"</string> + <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Connectat"</string> + <!-- no translation found for network_partial_connectivity (7774883385494762741) --> + <skip /> + <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) --> + <skip /> <string name="wifi_softap_config_change" msgid="8475911871165857607">"Canvis en la configuració del punt d\'accés Wi-Fi"</string> <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Ha canviat la teva banda del punt d\'accés Wi-Fi."</string> <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Aquest dispositiu no admet utilitzar exclusivament una banda de 5 GHz. El dispositiu utilitzarà una banda de 5 GHz quan estigui disponible."</string> @@ -1354,6 +1401,10 @@ <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuració per USB activada"</string> <string name="adb_active_notification_message" msgid="7463062450474107752">"Toca per desactivar la depuració per USB"</string> <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecciona per desactivar la depuració per USB"</string> + <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) --> + <skip /> + <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) --> + <skip /> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Hi ha líquid o pols al port USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"El port USB es desactiva automàticament. Toca per obtenir més informació."</string> <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"És segur utilitzar el port USB"</string> @@ -1905,8 +1956,6 @@ <string name="profile_encrypted_message" msgid="6964994232310195874">"Toca per desbloquejar el perfil"</string> <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"S\'ha connectat a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string> <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Toca per veure els fitxers"</string> - <string name="pin_target" msgid="3052256031352291362">"Fixa"</string> - <string name="unpin_target" msgid="3556545602439143442">"No fixis"</string> <string name="app_info" msgid="6856026610594615344">"Informació de l\'aplicació"</string> <string name="negative_duration" msgid="5688706061127375131">"-<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="demo_starting_message" msgid="5268556852031489931">"S\'està iniciant la demostració…"</string> @@ -1997,6 +2046,22 @@ <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Notificació d\'informació del mode de rutina"</string> <string name="dynamic_mode_notification_title" msgid="508815255807182035">"És possible que la bateria s\'esgoti abans de la càrrega habitual"</string> <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"S\'ha activat l\'estalvi de bateria per allargar-ne la durada"</string> + <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) --> + <skip /> + <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) --> + <skip /> + <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) --> + <skip /> <string name="mime_type_folder" msgid="7111951698626315204">"Carpeta"</string> <string name="mime_type_apk" msgid="5518003630972506900">"Aplicació per a Android"</string> <string name="mime_type_generic" msgid="6833871596845900027">"Fitxer"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index a790b504eaf2..4344b3d8eff3 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -63,7 +63,7 @@ <string name="CfMmi" msgid="5123218989141573515">"Rufweiterleitung"</string> <string name="CwMmi" msgid="9129678056795016867">"Anklopfen"</string> <string name="BaMmi" msgid="455193067926770581">"Anrufsperre"</string> - <string name="PwdMmi" msgid="7043715687905254199">"Passwort-Änderung"</string> + <string name="PwdMmi" msgid="7043715687905254199">"Passwortänderung"</string> <string name="PinMmi" msgid="3113117780361190304">"PIN-Änderung"</string> <string name="CnipMmi" msgid="3110534680557857162">"Rufnummer vorhanden"</string> <string name="CnirMmi" msgid="3062102121430548731">"Rufnummer begrenzt"</string> @@ -141,8 +141,10 @@ <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"WLAN-Telefonie"</string> <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string> <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Aus"</string> - <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"WLAN bevorzugt"</string> - <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobilverbindung bevorzugt"</string> + <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) --> + <skip /> + <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) --> + <skip /> <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Nur WLAN"</string> <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nicht weitergeleitet"</string> <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> @@ -228,7 +230,8 @@ <string name="global_action_bug_report" msgid="7934010578922304799">"Fehlerbericht"</string> <string name="global_action_logout" msgid="935179188218826050">"Sitzung beenden"</string> <string name="global_action_screenshot" msgid="8329831278085426283">"Screenshot"</string> - <string name="bugreport_title" msgid="2667494803742548533">"Fehlerbericht abrufen"</string> + <!-- no translation found for bugreport_title (5981047024855257269) --> + <skip /> <string name="bugreport_message" msgid="398447048750350456">"Bei diesem Fehlerbericht werden Daten zum aktuellen Status deines Geräts erfasst und als E-Mail versandt. Vom Start des Berichts bis zu seinem Versand kann es eine Weile dauern. Bitte habe etwas Geduld."</string> <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktiver Bericht"</string> <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Diese Option kann in den meisten Fällen verwendet werden. Du kannst darüber den aktuellen Stand der Berichterstellung verfolgen, genauere Angaben zu dem Problem machen und Screenshots aufnehmen. Einige selten genutzte Bereiche, deren Berichterstellung längere Zeit in Anspruch nimmt, werden unter Umständen ausgelassen."</string> @@ -281,9 +284,12 @@ <string name="permgrouplab_location" msgid="7275582855722310164">"Standort"</string> <string name="permgroupdesc_location" msgid="1346617465127855033">"auf den Standort deines Geräts zugreifen"</string> <string name="permgrouprequest_location" msgid="3788275734953323491">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> erlauben, den Gerätestandort abzurufen?"</string> - <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Die App hat nur Zugriff auf den Gerätestandort, wenn du sie verwendest."</string> - <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> immer erlauben, den Gerätestandort abzurufen?"</string> - <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Die App hat immer Zugriff auf den Gerätestandort, auch wenn du sie gerade nicht verwendest."</string> + <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) --> + <skip /> <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string> <string name="permgroupdesc_calendar" msgid="3889615280211184106">"auf deinen Kalender zugreifen"</string> <string name="permgrouprequest_calendar" msgid="289900767793189421">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> Zugriff auf deinen Kalender erlauben?"</string> @@ -316,7 +322,10 @@ <string name="permgrouprequest_aural" msgid="6787926123071735620">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> Zugriff auf deine Musik gewähren?"</string> <string name="permgrouplab_visual" msgid="6477382108771145134">"Fotos & Videos"</string> <string name="permgroupdesc_visual" msgid="3415827902566663546">"auf meine Fotos und Videos zugreifen"</string> - <string name="permgrouprequest_visual" msgid="3043752127595243314">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> Zugriff auf deine Fotos und Videos gewähren, einschließlich gekennzeichneter Standorte?"</string> + <!-- no translation found for permgrouprequest_visual (4926581398380334943) --> + <skip /> + <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) --> + <skip /> <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Fensterinhalte abrufen"</string> <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Die Inhalte eines Fensters, mit dem du interagierst, werden abgerufen."</string> <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"\"Tippen & Entdecken\" aktivieren"</string> @@ -509,8 +518,10 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Ermöglicht der App die Kommunikation mit Tags für die Nahfeldkommunikation, Karten und Readern"</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"Displaysperre deaktivieren"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Ermöglicht der App, die Tastensperre sowie den damit verbundenen Passwortschutz zu deaktivieren. Das Telefon deaktiviert die Tastensperre beispielsweise, wenn ein Anruf eingeht, und aktiviert sie wieder, nachdem das Gespräch beendet wurde."</string> - <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"Komplexitätsstufe der Displaysperre anfragen"</string> - <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Ermöglicht es der App, die Komplexitätsstufe der Displaysperre (hoch, mittel, niedrig oder keine) zu erfahren, was auf die mögliche Dauer und Art der Displaysperre hinweist. Die App kann Nutzern auch vorschlagen, dass sie die Displaysperre auf eine bestimmte Stufe aktualisieren, Nutzer können diesen Vorschlag jedoch einfach ignorieren und fortfahren. Beachten Sie, dass die Displaysperre nicht im Klartext gespeichert ist, sodass die App nicht das genaue Passwort kennt."</string> + <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) --> + <skip /> + <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) --> + <skip /> <string name="permlab_useBiometric" msgid="8837753668509919318">"Biometrische Hardware verwenden"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Erlaubt der App, biometrische Hardware zur Authentifizierung zu verwenden"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"Fingerabdruckhardware verwalten"</string> @@ -565,37 +576,59 @@ <string name="permdesc_manageFace" msgid="8919637120670185330">"Ermöglicht der App, Gesichtsvorlagen hinzuzufügen oder zu entfernen."</string> <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"Gesichtserkennungshardware verwenden"</string> <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Ermöglicht der App, für die Authentifizierung Gesichtserkennungshardware zu verwenden"</string> - <string name="face_acquired_insufficient" msgid="5901287247766106330">"Kann Gesicht nicht verarbeiten. Versuch es erneut."</string> - <string name="face_acquired_too_bright" msgid="610606792381297174">"Gesicht zu hell. Bei weniger Licht versuchen."</string> - <string name="face_acquired_too_dark" msgid="7229162716976778371">"Gesicht zu dunkel. Bei mehr Licht versuchen."</string> - <string name="face_acquired_too_close" msgid="1980310037427755293">"Sensor weiter weg vom Gesicht halten."</string> - <string name="face_acquired_too_far" msgid="4494571381828850007">"Sensor näher an das Gesicht halten."</string> - <string name="face_acquired_too_high" msgid="228411096134808372">"Sensor höher halten."</string> - <string name="face_acquired_too_low" msgid="4539774649296349109">"Sensor niedriger halten."</string> - <string name="face_acquired_too_right" msgid="1650292067226118760">"Sensor nach rechts bewegen."</string> - <string name="face_acquired_too_left" msgid="2712489669456176505">"Sensor nach links bewegen."</string> - <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Blick auf den Sensor richten."</string> - <string name="face_acquired_not_detected" msgid="5707782294589511391">"Kein Gesicht erkannt."</string> - <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Bitte halte das Gerät ruhig."</string> + <!-- no translation found for face_acquired_insufficient (2767330364802375742) --> + <skip /> + <!-- no translation found for face_acquired_too_bright (5005650874582450967) --> + <skip /> + <!-- no translation found for face_acquired_too_dark (1966194696381394616) --> + <skip /> + <!-- no translation found for face_acquired_too_close (1401011882624272753) --> + <skip /> + <!-- no translation found for face_acquired_too_far (1210969240069012510) --> + <skip /> + <!-- no translation found for face_acquired_too_high (3362395713403348013) --> + <skip /> + <!-- no translation found for face_acquired_too_low (488983581737550912) --> + <skip /> + <!-- no translation found for face_acquired_too_right (941726879175375970) --> + <skip /> + <!-- no translation found for face_acquired_too_left (5873592047381190672) --> + <skip /> + <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) --> + <skip /> + <!-- no translation found for face_acquired_not_detected (4885504661626728809) --> + <skip /> + <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) --> + <skip /> <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Bitte registriere dein Gesicht noch einmal."</string> - <string name="face_acquired_too_different" msgid="5553210341111255124">"Anderes Gesicht erkannt."</string> + <!-- no translation found for face_acquired_too_different (7663983770123789694) --> + <skip /> <string name="face_acquired_too_similar" msgid="1508776858407646460">"Zu ähnlich. Bitte dreh deinen Kopf etwas."</string> - <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Bitte sieh direkt in die Kamera."</string> - <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Bitte sieh direkt in die Kamera."</string> + <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) --> + <skip /> + <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Bitte halte deinen Kopf gerade."</string> - <string name="face_acquired_obscured" msgid="3055077697850272097">"Dein Gesicht darf nicht verdeckt sein."</string> + <!-- no translation found for face_acquired_obscured (5747521031647744553) --> + <skip /> + <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) --> + <skip /> <string-array name="face_acquired_vendor"> </string-array> <string name="face_error_hw_not_available" msgid="6255891785768984615">"Hardware zur Gesichtserkennung nicht verfügbar."</string> - <string name="face_error_timeout" msgid="4014326147867150054">"Zeitüberschreitung für Gesicht. Versuch es erneut."</string> + <!-- no translation found for face_error_timeout (2605673935810019129) --> + <skip /> <string name="face_error_no_space" msgid="8224993703466381314">"Gesicht kann nicht gespeichert werden."</string> <string name="face_error_canceled" msgid="283945501061931023">"Gesichtserkennung abgebrochen."</string> <string name="face_error_user_canceled" msgid="8943921120862164539">"Gesichtsauthentifizierung vom Nutzer abgebrochen."</string> <string name="face_error_lockout" msgid="3407426963155388504">"Zu viele Versuche, bitte später noch einmal versuchen"</string> <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Zu viele Versuche. Gesichtserkennung deaktiviert."</string> - <string name="face_error_unable_to_process" msgid="238761109287767270">"Versuch es noch einmal."</string> - <string name="face_error_not_enrolled" msgid="9166792142679691323">"Kein Gesicht erfasst."</string> - <string name="face_error_hw_not_present" msgid="916085883581450331">"Dieses Gerät hat keinen Sensor zur Gesichtserkennung."</string> + <!-- no translation found for face_error_unable_to_process (4940944939691171539) --> + <skip /> + <!-- no translation found for face_error_not_enrolled (4245760276260427472) --> + <skip /> + <!-- no translation found for face_error_hw_not_present (5296043240874659926) --> + <skip /> <string name="face_name_template" msgid="7004562145809595384">"Gesicht <xliff:g id="FACEID">%d</xliff:g>"</string> <string-array name="face_error_vendor"> </string-array> @@ -1213,9 +1246,16 @@ <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g> öffnen"</string> <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> wird ohne Speichern geschlossen"</string> <string name="dump_heap_notification" msgid="2618183274836056542">"Speicherlimit für \"<xliff:g id="PROC">%1$s</xliff:g>\" überschritten"</string> + <!-- no translation found for dump_heap_ready_notification (1162196579925048701) --> + <skip /> <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Heap-Dump wurde erfasst. Tippe, um ihn zu teilen."</string> <string name="dump_heap_title" msgid="5864292264307651673">"Heap-Dump teilen?"</string> - <string name="dump_heap_text" msgid="4809417337240334941">"Für den Prozess \"<xliff:g id="PROC">%1$s</xliff:g>\" wurde das Prozessspeicherlimit von <xliff:g id="SIZE">%2$s</xliff:g> überschritten. Es steht ein Heap-Dump zur Verfügung, den du mit dem Entwickler teilen kannst. Beachte jedoch unbedingt, dass der Heap-Dump personenbezogene Daten von dir enthalten kann, auf die die App zugreifen kann."</string> + <!-- no translation found for dump_heap_text (8546022920319781701) --> + <skip /> + <!-- no translation found for dump_heap_system_text (1205466256312104134) --> + <skip /> + <!-- no translation found for dump_heap_ready_text (6759394977904051000) --> + <skip /> <string name="sendText" msgid="5209874571959469142">"Aktion für Text auswählen"</string> <string name="volume_ringtone" msgid="6885421406845734650">"Klingeltonlautstärke"</string> <string name="volume_music" msgid="5421651157138628171">"Medienlautstärke"</string> @@ -1254,8 +1294,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tippen, um alle Netzwerke zu sehen"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Verbinden"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Alle Netzwerke"</string> - <string name="wifi_suggestion_title" msgid="8951405130379148709">"Ein von <xliff:g id="NAME">%s</xliff:g> vorgeschlagenes WLAN-Netzwerk ist verfügbar"</string> - <string name="wifi_suggestion_content" msgid="2658317015552324848">"Möchtest du eine Verbindung zu den von <xliff:g id="NAME">%s</xliff:g> vorgeschlagenen Netzwerken herstellen?"</string> + <!-- no translation found for wifi_suggestion_title (9099832833531486167) --> + <skip /> + <!-- no translation found for wifi_suggestion_content (5883181205841582873) --> + <skip /> <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ja"</string> <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nein"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"WLAN wird automatisch aktiviert"</string> @@ -1267,9 +1309,14 @@ <string name="network_available_sign_in" msgid="1848877297365446605">"Im Netzwerk anmelden"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> <skip /> - <string name="wifi_no_internet" msgid="8938267198124654938">"WLAN hat keinen Internetzugriff"</string> + <!-- no translation found for wifi_no_internet (5198100389964214865) --> + <skip /> <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Für Optionen tippen"</string> <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Verbunden"</string> + <!-- no translation found for network_partial_connectivity (7774883385494762741) --> + <skip /> + <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) --> + <skip /> <string name="wifi_softap_config_change" msgid="8475911871165857607">"Änderungen an deinen Hotspot-Einstellungen"</string> <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Dein Hotspot-Band hat sich geändert."</string> <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Dieses Gerät unterstützt die ausschließliche Nutzung von 5 GHz nicht. Es greift aber immer auf das 5-GHz-Band zurück, wenn dieses verfügbar ist."</string> @@ -1354,6 +1401,10 @@ <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-Debugging aktiviert"</string> <string name="adb_active_notification_message" msgid="7463062450474107752">"Zum Deaktivieren von USB-Debugging tippen"</string> <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB-Debugging deaktivieren: auswählen"</string> + <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) --> + <skip /> + <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) --> + <skip /> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Flüssigkeiten oder Fremdkörper im USB-Port"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Der USB-Port wird automatisch deaktiviert. Für weitere Informationen tippen."</string> <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB-Port kann wieder sicher verwendet werden"</string> @@ -1905,8 +1956,6 @@ <string name="profile_encrypted_message" msgid="6964994232310195874">"Zum Entsperren des Arbeitsprofils tippen"</string> <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Verbunden mit <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string> <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Zum Ansehen der Dateien tippen"</string> - <string name="pin_target" msgid="3052256031352291362">"Markieren"</string> - <string name="unpin_target" msgid="3556545602439143442">"Markierung entfernen"</string> <string name="app_info" msgid="6856026610594615344">"App-Informationen"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="demo_starting_message" msgid="5268556852031489931">"Demo wird gestartet…"</string> @@ -1997,6 +2046,22 @@ <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Infomitteilung zum Ablaufmodus"</string> <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Dein Akku könnte vor der gewöhnlichen Ladezeit leer sein"</string> <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Energiesparmodus aktiviert, um die Akkulaufzeit zu verlängern"</string> + <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) --> + <skip /> + <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) --> + <skip /> + <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) --> + <skip /> <string name="mime_type_folder" msgid="7111951698626315204">"Ordner"</string> <string name="mime_type_apk" msgid="5518003630972506900">"Android-App"</string> <string name="mime_type_generic" msgid="6833871596845900027">"Datei"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 017f31bf76c0..54a3860df985 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -141,9 +141,11 @@ <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Llamada por Wi‑Fi"</string> <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWiFi"</string> <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desactivado"</string> - <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Dar preferencia a Wi-Fi"</string> - <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferir datos móviles"</string> - <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Solo conexión Wi-Fi"</string> + <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) --> + <skip /> + <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) --> + <skip /> + <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Solo Wi-Fi"</string> <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: No desviada"</string> <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> <string name="cfTemplateForwardedTime" msgid="9206251736527085256">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> transcurridos <xliff:g id="TIME_DELAY">{2}</xliff:g> segundos"</string> @@ -228,7 +230,8 @@ <string name="global_action_bug_report" msgid="7934010578922304799">"Informe de error"</string> <string name="global_action_logout" msgid="935179188218826050">"Finalizar sesión"</string> <string name="global_action_screenshot" msgid="8329831278085426283">"Captura de pantalla"</string> - <string name="bugreport_title" msgid="2667494803742548533">"Crear informe de errores"</string> + <!-- no translation found for bugreport_title (5981047024855257269) --> + <skip /> <string name="bugreport_message" msgid="398447048750350456">"Se recopilará información sobre el estado actual de tu dispositivo y se enviará por correo electrónico. Pasarán unos minutos desde que empiece a generarse el informe de errores hasta que se envíe."</string> <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Informe interactivo"</string> <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Usa esta opción en la mayoría de los casos. Te permite realizar un seguimiento del progreso del informe, introducir más información sobre el problema y hacer capturas de pantalla. Es posible que se omitan algunas secciones menos utilizadas y que requieran más tiempo."</string> @@ -281,9 +284,12 @@ <string name="permgrouplab_location" msgid="7275582855722310164">"Ubicación"</string> <string name="permgroupdesc_location" msgid="1346617465127855033">"acceder a la ubicación de este dispositivo"</string> <string name="permgrouprequest_location" msgid="3788275734953323491">"¿Quieres permitir que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> acceda a la ubicación de este dispositivo?"</string> - <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"La aplicación solo podrá acceder a la ubicación cuando estés usando la aplicación."</string> - <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"¿Permites que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> acceda a ubic. del disp.?"</string> - <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"La aplicación siempre podrá acceder a la ubicación, aunque no estés usando la aplicación."</string> + <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) --> + <skip /> <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendario"</string> <string name="permgroupdesc_calendar" msgid="3889615280211184106">"acceder a tu calendario"</string> <string name="permgrouprequest_calendar" msgid="289900767793189421">"¿Quieres permitir que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> acceda a tu calendario?"</string> @@ -316,7 +322,10 @@ <string name="permgrouprequest_aural" msgid="6787926123071735620">"¿Quieres permitir que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> acceda a tu música?"</string> <string name="permgrouplab_visual" msgid="6477382108771145134">"Fotos y vídeos"</string> <string name="permgroupdesc_visual" msgid="3415827902566663546">"acceder a tus fotos y vídeos"</string> - <string name="permgrouprequest_visual" msgid="3043752127595243314">"¿Quieres permitir que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> acceda a tus fotos y vídeos, así como a las ubicaciones etiquetadas?"</string> + <!-- no translation found for permgrouprequest_visual (4926581398380334943) --> + <skip /> + <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) --> + <skip /> <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Comprobar el contenido de la ventana"</string> <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecciona el contenido de una ventana con la que estés interactuando."</string> <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activar la exploración táctil"</string> @@ -509,8 +518,10 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Permite que la aplicación se comunique con lectores, tarjetas y etiquetas de Comunicación de campo cercano (NFC)."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"inhabilitar el bloqueo de pantalla"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permite que la aplicación inhabilite el bloqueo del teclado y cualquier protección con contraseña asociada. Por ejemplo, el teléfono puede inhabilitar el bloqueo del teclado cuando se recibe una llamada telefónica y volver a habilitarlo cuando finaliza la llamada."</string> - <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"solicitar complejidad del bloqueo de pantalla"</string> - <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Permite que la aplicación entienda el nivel de complejidad del bloqueo de pantalla (alto, medio, bajo o ninguno) que indica la longitud y el tipo del bloqueo de pantalla posibles. La aplicación también puede sugerir a los usuarios que actualicen el bloqueo de pantalla para que tenga un nivel concreto de complejidad, pero los usuarios pueden ignorar la advertencia libremente. El bloqueo de pantalla no se almacena en texto sin formato, así que la aplicación no puede saber cuál es la contraseña exacta."</string> + <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) --> + <skip /> + <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) --> + <skip /> <string name="permlab_useBiometric" msgid="8837753668509919318">"usar hardware biométrico"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Permite que la aplicación utilice el hardware biométrico para realizar la autenticación"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"administrar hardware de huellas digitales"</string> @@ -565,37 +576,59 @@ <string name="permdesc_manageFace" msgid="8919637120670185330">"Permite que la app use métodos para añadir y suprimir plantillas de caras para su uso."</string> <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"usar el hardware de autenticación facial"</string> <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Permite que la aplicación utilice el hardware de autenticación facial para autenticarte"</string> - <string name="face_acquired_insufficient" msgid="5901287247766106330">"No se ha reconocido la cara. Vuelve a intentarlo."</string> - <string name="face_acquired_too_bright" msgid="610606792381297174">"La cara se ve muy clara. Inténtalo con menos luz."</string> - <string name="face_acquired_too_dark" msgid="7229162716976778371">"La cara se ve muy oscura. Inténtalo con más luz."</string> - <string name="face_acquired_too_close" msgid="1980310037427755293">"Aleja la cara del sensor."</string> - <string name="face_acquired_too_far" msgid="4494571381828850007">"Acerca la cara al sensor."</string> - <string name="face_acquired_too_high" msgid="228411096134808372">"Coloca el sensor más arriba."</string> - <string name="face_acquired_too_low" msgid="4539774649296349109">"Coloca el sensor más abajo."</string> - <string name="face_acquired_too_right" msgid="1650292067226118760">"Mueve el sensor hacia la derecha."</string> - <string name="face_acquired_too_left" msgid="2712489669456176505">"Mueve el sensor hacia la izquierda."</string> - <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Mira al sensor."</string> - <string name="face_acquired_not_detected" msgid="5707782294589511391">"No se ha detectado ninguna cara."</string> - <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Te mueves demasiado."</string> + <!-- no translation found for face_acquired_insufficient (2767330364802375742) --> + <skip /> + <!-- no translation found for face_acquired_too_bright (5005650874582450967) --> + <skip /> + <!-- no translation found for face_acquired_too_dark (1966194696381394616) --> + <skip /> + <!-- no translation found for face_acquired_too_close (1401011882624272753) --> + <skip /> + <!-- no translation found for face_acquired_too_far (1210969240069012510) --> + <skip /> + <!-- no translation found for face_acquired_too_high (3362395713403348013) --> + <skip /> + <!-- no translation found for face_acquired_too_low (488983581737550912) --> + <skip /> + <!-- no translation found for face_acquired_too_right (941726879175375970) --> + <skip /> + <!-- no translation found for face_acquired_too_left (5873592047381190672) --> + <skip /> + <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) --> + <skip /> + <!-- no translation found for face_acquired_not_detected (4885504661626728809) --> + <skip /> + <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) --> + <skip /> <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Vuelve a registrar tu cara."</string> - <string name="face_acquired_too_different" msgid="5553210341111255124">"Se ha detectado otra cara."</string> + <!-- no translation found for face_acquired_too_different (7663983770123789694) --> + <skip /> <string name="face_acquired_too_similar" msgid="1508776858407646460">"Se parece mucha a la anterior. Pon otra cara."</string> - <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Mira más fijamente a la cámara."</string> - <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Mira más fijamente a la cámara."</string> + <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) --> + <skip /> + <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Mantén la cabeza en posición vertical."</string> - <string name="face_acquired_obscured" msgid="3055077697850272097">"No te tapes la cara."</string> + <!-- no translation found for face_acquired_obscured (5747521031647744553) --> + <skip /> + <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) --> + <skip /> <string-array name="face_acquired_vendor"> </string-array> <string name="face_error_hw_not_available" msgid="6255891785768984615">"Hardware de reconocimiento facial no disponible."</string> - <string name="face_error_timeout" msgid="4014326147867150054">"Has sobrepasado el tiempo. Inténtalo de nuevo."</string> + <!-- no translation found for face_error_timeout (2605673935810019129) --> + <skip /> <string name="face_error_no_space" msgid="8224993703466381314">"No se pueden registrar más caras."</string> <string name="face_error_canceled" msgid="283945501061931023">"Se ha cancelado el reconocimiento facial."</string> <string name="face_error_user_canceled" msgid="8943921120862164539">"El usuario ha cancelado la autenticación de la cara."</string> <string name="face_error_lockout" msgid="3407426963155388504">"Demasiados intentos. Inténtalo de nuevo más tarde."</string> <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Demasiados intentos. Autent. facial inhabilitada."</string> - <string name="face_error_unable_to_process" msgid="238761109287767270">"Inténtalo de nuevo."</string> - <string name="face_error_not_enrolled" msgid="9166792142679691323">"No has registrado ninguna cara."</string> - <string name="face_error_hw_not_present" msgid="916085883581450331">"Este dispositivo no tiene sensor de autenticación facial."</string> + <!-- no translation found for face_error_unable_to_process (4940944939691171539) --> + <skip /> + <!-- no translation found for face_error_not_enrolled (4245760276260427472) --> + <skip /> + <!-- no translation found for face_error_hw_not_present (5296043240874659926) --> + <skip /> <string name="face_name_template" msgid="7004562145809595384">"Cara <xliff:g id="FACEID">%d</xliff:g>"</string> <string-array name="face_error_vendor"> </string-array> @@ -1213,9 +1246,16 @@ <string name="new_app_action" msgid="6694851182870774403">"Abrir <xliff:g id="NEW_APP">%1$s</xliff:g>"</string> <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> se cerrará sin guardar"</string> <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> ha superado el límite de memoria"</string> + <!-- no translation found for dump_heap_ready_notification (1162196579925048701) --> + <skip /> <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Se ha recopilado un volcado de pila. Toca para compartir."</string> <string name="dump_heap_title" msgid="5864292264307651673">"¿Compartir volcado de pila?"</string> - <string name="dump_heap_text" msgid="4809417337240334941">"El proceso <xliff:g id="PROC">%1$s</xliff:g> ha superado su límite de memoria de <xliff:g id="SIZE">%2$s</xliff:g>. Hay un volcado de pila disponible que puedes compartir con su desarrollador (ten cuidado, ya que puede incluir información personal a la que tenga acceso la aplicación)."</string> + <!-- no translation found for dump_heap_text (8546022920319781701) --> + <skip /> + <!-- no translation found for dump_heap_system_text (1205466256312104134) --> + <skip /> + <!-- no translation found for dump_heap_ready_text (6759394977904051000) --> + <skip /> <string name="sendText" msgid="5209874571959469142">"Selecciona una acción para el texto"</string> <string name="volume_ringtone" msgid="6885421406845734650">"Volumen del timbre"</string> <string name="volume_music" msgid="5421651157138628171">"Volumen de multimedia"</string> @@ -1254,8 +1294,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toca para ver todas las redes"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectarse"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Todas las redes"</string> - <string name="wifi_suggestion_title" msgid="8951405130379148709">"Hay disponible una red Wi‑Fi propuesta por <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_content" msgid="2658317015552324848">"¿Quieres conectarte a las redes propuestas por <xliff:g id="NAME">%s</xliff:g>?"</string> + <!-- no translation found for wifi_suggestion_title (9099832833531486167) --> + <skip /> + <!-- no translation found for wifi_suggestion_content (5883181205841582873) --> + <skip /> <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Sí"</string> <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"La conexión Wi‑Fi se activará automáticamente"</string> @@ -1267,9 +1309,14 @@ <string name="network_available_sign_in" msgid="1848877297365446605">"Iniciar sesión en la red"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> <skip /> - <string name="wifi_no_internet" msgid="8938267198124654938">"La red Wi-Fi no tiene acceso a Internet"</string> + <!-- no translation found for wifi_no_internet (5198100389964214865) --> + <skip /> <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Toca para ver opciones"</string> <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Conectado"</string> + <!-- no translation found for network_partial_connectivity (7774883385494762741) --> + <skip /> + <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) --> + <skip /> <string name="wifi_softap_config_change" msgid="8475911871165857607">"Cambios en los ajustes de tu punto de acceso"</string> <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"La banda de tu punto de acceso ha cambiado."</string> <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Este dispositivo no admite la opción de conectarse exclusivamente a bandas de 5 GHz, pero las usará cuando estén disponibles."</string> @@ -1354,6 +1401,10 @@ <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración USB habilitada"</string> <string name="adb_active_notification_message" msgid="7463062450474107752">"Toca para desactivar la depuración USB."</string> <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Seleccionar para inhabilitar la depuración USB"</string> + <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) --> + <skip /> + <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) --> + <skip /> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Se ha detectado líquido o suciedad en el puerto USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"El puerto USB se ha inhabilitado automáticamente. Toca para obtener más información."</string> <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Ya puedes usar el puerto USB"</string> @@ -1905,8 +1956,6 @@ <string name="profile_encrypted_message" msgid="6964994232310195874">"Toca para desbloquear"</string> <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Conectado a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string> <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Toca para ver archivos"</string> - <string name="pin_target" msgid="3052256031352291362">"Fijar"</string> - <string name="unpin_target" msgid="3556545602439143442">"No fijar"</string> <string name="app_info" msgid="6856026610594615344">"Información de la aplicación"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="demo_starting_message" msgid="5268556852031489931">"Iniciando demostración…"</string> @@ -1997,6 +2046,22 @@ <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Notificación sobre el modo rutina"</string> <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Es posible que te quedes sin batería antes de lo habitual"</string> <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Se ha activado el ahorro de batería para aumentar la duración de la batería"</string> + <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) --> + <skip /> + <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) --> + <skip /> + <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) --> + <skip /> <string name="mime_type_folder" msgid="7111951698626315204">"Carpeta"</string> <string name="mime_type_apk" msgid="5518003630972506900">"Aplicación de Android"</string> <string name="mime_type_generic" msgid="6833871596845900027">"Archivo"</string> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index adc4dc465dd7..1ba4da2d0c1c 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -141,8 +141,10 @@ <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Wi-Fi bidezko deiak"</string> <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string> <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desaktibatuta"</string> - <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi sarea hobesten da"</string> - <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Datu-konexioa hobesten da"</string> + <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) --> + <skip /> + <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) --> + <skip /> <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Wi-Fi sarea soilik"</string> <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ez da desbideratu"</string> <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> @@ -228,7 +230,8 @@ <string name="global_action_bug_report" msgid="7934010578922304799">"Akatsen txostena"</string> <string name="global_action_logout" msgid="935179188218826050">"Amaitu saioa"</string> <string name="global_action_screenshot" msgid="8329831278085426283">"Pantaila-argazkia"</string> - <string name="bugreport_title" msgid="2667494803742548533">"Sortu akatsen txostena"</string> + <!-- no translation found for bugreport_title (5981047024855257269) --> + <skip /> <string name="bugreport_message" msgid="398447048750350456">"Gailuaren uneko egoerari buruzko informazioa bilduko da, mezu elektroniko gisa bidaltzeko. Minutu batzuk igaroko dira akatsen txostena sortzen hasten denetik bidaltzeko prest egon arte. Itxaron, mesedez."</string> <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Txosten dinamikoa"</string> <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Aukera hau erabili beharko zenuke ia beti. Txostenaren jarraipena egin ahal izango duzu eta arazoari buruzko xehetasunak eman ahal izango dituzu. Baliteke gutxitan erabili behar izaten diren atalak ez agertzea, denbora aurrezteko."</string> @@ -281,9 +284,12 @@ <string name="permgrouplab_location" msgid="7275582855722310164">"Kokapena"</string> <string name="permgroupdesc_location" msgid="1346617465127855033">"atzitu gailuaren kokapena"</string> <string name="permgrouprequest_location" msgid="3788275734953323491">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari gailuaren kokapena atzitzea baimendu nahi diozu?"</string> - <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Aplikazioa erabiltzen ari zarenean soilik atzituko du aplikazioak kokapena."</string> - <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Gailuaren kokapena beti atzitzeko baimena eman nahi diozu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari?"</string> - <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Aplikazioak beti atzituko du kokapena, baita aplikazioa erabiltzen ari ez bazara ere."</string> + <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) --> + <skip /> <string name="permgrouplab_calendar" msgid="5863508437783683902">"Egutegia"</string> <string name="permgroupdesc_calendar" msgid="3889615280211184106">"atzitu egutegia"</string> <string name="permgrouprequest_calendar" msgid="289900767793189421">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari egutegia atzitzea baimendu nahi diozu?"</string> @@ -316,7 +322,10 @@ <string name="permgrouprequest_aural" msgid="6787926123071735620">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari musika atzitzea baimendu nahi diozu?"</string> <string name="permgrouplab_visual" msgid="6477382108771145134">"Argazkiak eta bideoak"</string> <string name="permgroupdesc_visual" msgid="3415827902566663546">"argazkiak eta bideoak atzitu"</string> - <string name="permgrouprequest_visual" msgid="3043752127595243314">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari zure argazkiak eta bideoak (etiketatutako kokapenak barne) atzitzeko baimena eman?"</string> + <!-- no translation found for permgrouprequest_visual (4926581398380334943) --> + <skip /> + <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) --> + <skip /> <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Eskuratu leihoko edukia"</string> <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Arakatu irekita daukazun leihoko edukia."</string> <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Aktibatu \"Arakatu ukituta\""</string> @@ -509,8 +518,10 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Near Field Communication (NFC) etiketekin, txartelekin eta irakurgailuekin komunikatzea baimentzen die aplikazioei."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"desgaitu pantailaren blokeoa"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Teklen blokeoa eta erlazionatutako pasahitz-segurtasuna desgaitzeko baimena ematen die aplikazioei. Adibidez, telefonoak teklen blokeoa desgaitzen du telefono-deiak jasotzen dituenean, eta berriro gaitzen du deiak amaitzean."</string> - <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"eskatu pantailaren blokeoaren konplexutasuna"</string> - <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Pantailaren blokeoaren konplexutasun-maila (handia, ertaina, txikia edo bat ere ez) ezagutzeko aukera ematen dio aplikazioari; haren bidez, pantailaren blokeoaren luzeraren barruti edo mota posiblea adierazten da. Halaber, erabiltzaileei pantailaren blokeoa maila jakin batera igotzeko iradoki diezaieke aplikazioak, baina erabiltzaileek horri ez ikusi egiteko eta aplikazioa erabiltzen jarraitzeko aukera dute. Kontuan izan pantailaren blokeoa ez dela gordetzen testu arrunt gisa; beraz, aplikazioak ez du jakingo zein den pasahitz zehatza."</string> + <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) --> + <skip /> + <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) --> + <skip /> <string name="permlab_useBiometric" msgid="8837753668509919318">"Erabili hardware biometrikoa"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Autentifikatzeko hardware biometrikoa erabiltzea baimentzen die aplikazioei."</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"kudeatu erreferentzia-gako digitalen hardwarea"</string> @@ -565,37 +576,59 @@ <string name="permdesc_manageFace" msgid="8919637120670185330">"Aurpegi-txantiloiak gehitu eta ezabatzeko metodoei dei egitea baimentzen dio aplikazioari."</string> <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"erabili aurpegi bidez autentifikatzeko hardwarea"</string> <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Aurpegi bidez autentifikatzeko hardwarea erabiltzea baimentzen dio aplikazioari"</string> - <string name="face_acquired_insufficient" msgid="5901287247766106330">"Ezin izan da prozesatu aurpegia. Saiatu berriro."</string> - <string name="face_acquired_too_bright" msgid="610606792381297174">"Aurpegiak distira gehiegi du. Murriztu argitasuna."</string> - <string name="face_acquired_too_dark" msgid="7229162716976778371">"Aurpegia ilunegi dago. Estalgabetu argi-iturburua."</string> - <string name="face_acquired_too_close" msgid="1980310037427755293">"Urrundu sentsorea aurpegitik."</string> - <string name="face_acquired_too_far" msgid="4494571381828850007">"Hurbildu sentsorea aurpegira."</string> - <string name="face_acquired_too_high" msgid="228411096134808372">"Eraman sentsorea gora."</string> - <string name="face_acquired_too_low" msgid="4539774649296349109">"Eraman sentsorea behera."</string> - <string name="face_acquired_too_right" msgid="1650292067226118760">"Eraman sentsorea eskuinera."</string> - <string name="face_acquired_too_left" msgid="2712489669456176505">"Eraman sentsorea ezkerrera."</string> - <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Begiratu sentsoreari."</string> - <string name="face_acquired_not_detected" msgid="5707782294589511391">"Ez dugu hauteman aurpegirik."</string> - <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Gailua gehiegi mugitu da."</string> + <!-- no translation found for face_acquired_insufficient (2767330364802375742) --> + <skip /> + <!-- no translation found for face_acquired_too_bright (5005650874582450967) --> + <skip /> + <!-- no translation found for face_acquired_too_dark (1966194696381394616) --> + <skip /> + <!-- no translation found for face_acquired_too_close (1401011882624272753) --> + <skip /> + <!-- no translation found for face_acquired_too_far (1210969240069012510) --> + <skip /> + <!-- no translation found for face_acquired_too_high (3362395713403348013) --> + <skip /> + <!-- no translation found for face_acquired_too_low (488983581737550912) --> + <skip /> + <!-- no translation found for face_acquired_too_right (941726879175375970) --> + <skip /> + <!-- no translation found for face_acquired_too_left (5873592047381190672) --> + <skip /> + <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) --> + <skip /> + <!-- no translation found for face_acquired_not_detected (4885504661626728809) --> + <skip /> + <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) --> + <skip /> <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Erregistratu berriro aurpegia."</string> - <string name="face_acquired_too_different" msgid="5553210341111255124">"Beste aurpegi bat hauteman da."</string> + <!-- no translation found for face_acquired_too_different (7663983770123789694) --> + <skip /> <string name="face_acquired_too_similar" msgid="1508776858407646460">"Jarrera berdintsuegia da. Alda ezazu."</string> - <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Begiratu zuzenago kamerari."</string> - <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Begiratu zuzenago kamerari."</string> + <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) --> + <skip /> + <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Jarri burua zuzen."</string> - <string name="face_acquired_obscured" msgid="3055077697850272097">"Kendua aurpegia estaltzen dizun hori."</string> + <!-- no translation found for face_acquired_obscured (5747521031647744553) --> + <skip /> + <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) --> + <skip /> <string-array name="face_acquired_vendor"> </string-array> <string name="face_error_hw_not_available" msgid="6255891785768984615">"Aurpegia hautemateko hardwarea ez dago erabilgarri."</string> - <string name="face_error_timeout" msgid="4014326147867150054">"Gainditu da aurpegiak prozesatzeko denbora-muga. Saiatu berriro."</string> + <!-- no translation found for face_error_timeout (2605673935810019129) --> + <skip /> <string name="face_error_no_space" msgid="8224993703466381314">"Ezin da gorde aurpegia."</string> <string name="face_error_canceled" msgid="283945501061931023">"Utzi da aurpegiaren bidezko eragiketa."</string> <string name="face_error_user_canceled" msgid="8943921120862164539">"Erabiltzaileak utzi du aurpegi-autentifikazioa."</string> <string name="face_error_lockout" msgid="3407426963155388504">"Saiakera gehiegi egin dituzu. Saiatu berriro geroago."</string> <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Saiakera gehiegi egin dituzu. Desgaitu egin da autentifikazioa."</string> - <string name="face_error_unable_to_process" msgid="238761109287767270">"Saiatu berriro."</string> - <string name="face_error_not_enrolled" msgid="9166792142679691323">"Ez dago aurpegirik erregistratuta."</string> - <string name="face_error_hw_not_present" msgid="916085883581450331">"Gailu honek ez du aurpegia autentifikatzeko sentsorerik."</string> + <!-- no translation found for face_error_unable_to_process (4940944939691171539) --> + <skip /> + <!-- no translation found for face_error_not_enrolled (4245760276260427472) --> + <skip /> + <!-- no translation found for face_error_hw_not_present (5296043240874659926) --> + <skip /> <string name="face_name_template" msgid="7004562145809595384">"<xliff:g id="FACEID">%d</xliff:g> aurpegia"</string> <string-array name="face_error_vendor"> </string-array> @@ -1213,9 +1246,16 @@ <string name="new_app_action" msgid="6694851182870774403">"Ireki <xliff:g id="NEW_APP">%1$s</xliff:g>"</string> <string name="new_app_description" msgid="5894852887817332322">"Gorde gabe itxiko da <xliff:g id="OLD_APP">%1$s</xliff:g>"</string> <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> prozesuak memoria-muga gainditu du"</string> + <!-- no translation found for dump_heap_ready_notification (1162196579925048701) --> + <skip /> <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Sortu da uneko memoria-prozesuaren txostena. Sakatu partekatzeko."</string> <string name="dump_heap_title" msgid="5864292264307651673">"Uneko memoria-prozesuaren txostena partekatu nahi duzu?"</string> - <string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g> prozesuak memoria-prozesuaren muga (<xliff:g id="SIZE">%2$s</xliff:g>) gainditu du. Uneko memoria-prozesuaren txostena sortu da, garatzailearekin parteka dezazun. Kontuz ibili: txosten horrek aplikazioak atzi dezakeen informazio pertsonala izan dezake."</string> + <!-- no translation found for dump_heap_text (8546022920319781701) --> + <skip /> + <!-- no translation found for dump_heap_system_text (1205466256312104134) --> + <skip /> + <!-- no translation found for dump_heap_ready_text (6759394977904051000) --> + <skip /> <string name="sendText" msgid="5209874571959469142">"Aukeratu testurako ekintza"</string> <string name="volume_ringtone" msgid="6885421406845734650">"Tonu-jotzailearen bolumena"</string> <string name="volume_music" msgid="5421651157138628171">"Multimedia-edukiaren bolumena"</string> @@ -1254,8 +1294,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Sakatu hau sare guztiak ikusteko"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Konektatu"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Sare guztiak"</string> - <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g> aplikazioak iradokitako wifi sare bat erabil daiteke"</string> - <string name="wifi_suggestion_content" msgid="2658317015552324848">"<xliff:g id="NAME">%s</xliff:g> aplikazioak iradokitako sareetara konektatu nahi zara?"</string> + <!-- no translation found for wifi_suggestion_title (9099832833531486167) --> + <skip /> + <!-- no translation found for wifi_suggestion_content (5883181205841582873) --> + <skip /> <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Bai"</string> <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ez"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi konexioa automatikoki aktibatuko da"</string> @@ -1267,9 +1309,14 @@ <string name="network_available_sign_in" msgid="1848877297365446605">"Hasi saioa sarean"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> <skip /> - <string name="wifi_no_internet" msgid="8938267198124654938">"Ezin da konektatu Internetera Wi-Fi bidez"</string> + <!-- no translation found for wifi_no_internet (5198100389964214865) --> + <skip /> <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Sakatu aukerak ikusteko"</string> <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Konektatuta"</string> + <!-- no translation found for network_partial_connectivity (7774883385494762741) --> + <skip /> + <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) --> + <skip /> <string name="wifi_softap_config_change" msgid="8475911871165857607">"Aldaketak egin dira sare publikoaren ezarpenetan"</string> <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Aldatu da sare publikoaren banda."</string> <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Gailuak ez du onartzen 5 GHz-ko banda soilik erabiltzeko hobespena. Horren ordez, erabilgarri dagoen bakoitzean erabiliko da 5 GHz-ko banda."</string> @@ -1355,6 +1402,10 @@ <string name="adb_active_notification_title" msgid="6729044778949189918">"USB arazketa konektatuta"</string> <string name="adb_active_notification_message" msgid="7463062450474107752">"Sakatu USB arazketa desaktibatzeko"</string> <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Hautatu USB arazketa desgaitzeko."</string> + <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) --> + <skip /> + <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) --> + <skip /> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Likidoa edo zikinkeriak daude USB atakan"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ataka automatikoki desgaitu da. Informazio gehiago lortzeko, sakatu hau."</string> <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Segurtasunez erabil daiteke USB ataka"</string> @@ -1906,8 +1957,6 @@ <string name="profile_encrypted_message" msgid="6964994232310195874">"Sakatu profila desblokeatzeko"</string> <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> zerbitzura konektatuta"</string> <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Sakatu fitxategiak ikusteko"</string> - <string name="pin_target" msgid="3052256031352291362">"Ainguratu"</string> - <string name="unpin_target" msgid="3556545602439143442">"Kendu aingura"</string> <string name="app_info" msgid="6856026610594615344">"Aplikazioari buruzko informazioa"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="demo_starting_message" msgid="5268556852031489931">"Demoa abiarazten…"</string> @@ -1998,6 +2047,22 @@ <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Ohitura moduaren informazio-jakinarazpena"</string> <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Baliteke bateria ohi baino lehenago agortzea"</string> <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Bateria-aurrezlea aktibatuta dago bateriaren iraupena luzatzeko"</string> + <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) --> + <skip /> + <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) --> + <skip /> + <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) --> + <skip /> <string name="mime_type_folder" msgid="7111951698626315204">"Karpeta"</string> <string name="mime_type_apk" msgid="5518003630972506900">"Android aplikazioa"</string> <string name="mime_type_generic" msgid="6833871596845900027">"Fitxategia"</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 9e8b92cbe1ff..41597434215b 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -141,8 +141,10 @@ <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Appels Wi-Fi"</string> <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"Voix par Wi-Fi"</string> <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Désactivé"</string> - <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Réseau Wi-Fi de préférence"</string> - <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Connexion cellulaire de préférence"</string> + <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) --> + <skip /> + <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) --> + <skip /> <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Wi-Fi seulement"</string> <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> : non transféré"</string> <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> : <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> @@ -228,7 +230,8 @@ <string name="global_action_bug_report" msgid="7934010578922304799">"Rapport de bogue"</string> <string name="global_action_logout" msgid="935179188218826050">"Fermer la session"</string> <string name="global_action_screenshot" msgid="8329831278085426283">"Capture d\'écran"</string> - <string name="bugreport_title" msgid="2667494803742548533">"Créer un rapport de bogue"</string> + <!-- no translation found for bugreport_title (5981047024855257269) --> + <skip /> <string name="bugreport_message" msgid="398447048750350456">"Cela permet de recueillir des informations concernant l\'état actuel de votre appareil. Ces informations sont ensuite envoyées sous forme de courriel. Merci de patienter pendant la préparation du rapport de bogue. Cette opération peut prendre quelques instants."</string> <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Rapport interactif"</string> <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Utilisez cette option dans la plupart des circonstances. Elle vous permet de suivre la progression du rapport, d\'entrer plus d\'information sur le problème et d\'effectuer des saisies d\'écran. Certaines sections moins utilisées et dont le remplissage demande beaucoup de temps peuvent être omises."</string> @@ -281,9 +284,12 @@ <string name="permgrouplab_location" msgid="7275582855722310164">"Localisation"</string> <string name="permgroupdesc_location" msgid="1346617465127855033">"accéder à la position de cet appareil"</string> <string name="permgrouprequest_location" msgid="3788275734953323491">"Autoriser <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> à accéder à la position de cet appareil?"</string> - <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"L\'application aura uniquement accès à la position lorsque vous l\'utilisez."</string> - <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Toujours autoriser <xliff:g id="APP_NAME">%1$s</xliff:g> à accéder à la position de cet appareil?"</string> - <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"L\'application aura toujours accès à la position, même lorsque vous ne l\'utilisez pas."</string> + <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) --> + <skip /> <string name="permgrouplab_calendar" msgid="5863508437783683902">"Agenda"</string> <string name="permgroupdesc_calendar" msgid="3889615280211184106">"accéder à votre agenda"</string> <string name="permgrouprequest_calendar" msgid="289900767793189421">"Autoriser <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> à accéder à votre agenda?"</string> @@ -316,7 +322,10 @@ <string name="permgrouprequest_aural" msgid="6787926123071735620">"Autoriser <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> à accéder à votre musique?"</string> <string name="permgrouplab_visual" msgid="6477382108771145134">"Photos et vidéos"</string> <string name="permgroupdesc_visual" msgid="3415827902566663546">"accéder à vos photos et à vos vidéos"</string> - <string name="permgrouprequest_visual" msgid="3043752127595243314">"Autoriser « <xliff:g id="APP_NAME">%1$s</xliff:g> » à accéder à vos photos et vos videos, y compris les lieux balisés?"</string> + <!-- no translation found for permgrouprequest_visual (4926581398380334943) --> + <skip /> + <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) --> + <skip /> <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Récupérer le contenu d\'une fenêtre"</string> <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecter le contenu d\'une fenêtre avec laquelle vous interagissez."</string> <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activer la fonctionnalité Explorer au toucher"</string> @@ -509,8 +518,10 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Permet à l\'application de communiquer avec des bornes, des cartes et des lecteurs compatibles avec la technologie NFC (communication en champ proche)."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"désactiver le verrouillage de l\'écran"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permet à l\'application de désactiver le verrouillage des touches et toute mesure de sécurité par mot de passe associée. Par exemple, votre téléphone désactive le verrouillage des touches lorsque vous recevez un appel, puis le réactive lorsque vous raccrochez."</string> - <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"demander la complexité du verrouillage d\'écran"</string> - <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Autorise l\'application à apprendre le niveau de complexité de l\'écran de verrouillage (élevé, moyen, faible ou aucun), qui indique la gamme possible de longueur et de type de verrouillage d\'écran. L\'application peut aussi suggérer aux utilisateurs de mettre à jour l\'écran de verrouillage afin d\'utiliser un certain niveau de complexité, mais ils peuvent ignorer la suggestion. Notez que le verrouillage d\'écran n\'est pas stocké en texte brut pour de manière à ce que l\'application n\'ait pas accès au mot de passe exact."</string> + <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) --> + <skip /> + <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) --> + <skip /> <string name="permlab_useBiometric" msgid="8837753668509919318">"utiliser le matériel biométrique"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Permet à l\'application d\'utiliser du matériel biométrique pour l\'authentification"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"gérer le matériel d\'empreinte digitale"</string> @@ -565,37 +576,59 @@ <string name="permdesc_manageFace" msgid="8919637120670185330">"Permet à l\'appli d\'employer des méthodes d\'aj. et de suppr. de modèles de reconn. visage."</string> <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"utiliser le matériel d\'authentification de visage"</string> <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Permet à l\'appli d\'utiliser du matériel de reconnaissance du visage pour l\'authentification"</string> - <string name="face_acquired_insufficient" msgid="5901287247766106330">"Impossible de traiter le visage. Réessayez."</string> - <string name="face_acquired_too_bright" msgid="610606792381297174">"Visage trop lumineux. Essayez avec moins de lumière."</string> - <string name="face_acquired_too_dark" msgid="7229162716976778371">"Visage trop sombre. Essayez avec plus de lumière."</string> - <string name="face_acquired_too_close" msgid="1980310037427755293">"Veuillez éloigner le capteur du visage."</string> - <string name="face_acquired_too_far" msgid="4494571381828850007">"Veuillez rapprocher le capteur du visage."</string> - <string name="face_acquired_too_high" msgid="228411096134808372">"Veuillez déplacer le capteur plus haut."</string> - <string name="face_acquired_too_low" msgid="4539774649296349109">"Veuillez déplacer le capteur plus bas."</string> - <string name="face_acquired_too_right" msgid="1650292067226118760">"Veuillez déplacer le capteur vers la droite."</string> - <string name="face_acquired_too_left" msgid="2712489669456176505">"Veuillez déplacer le capteur vers la gauche."</string> - <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Veuillez regarder le capteur."</string> - <string name="face_acquired_not_detected" msgid="5707782294589511391">"Aucun visage détecté."</string> - <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Trop de mouvement."</string> + <!-- no translation found for face_acquired_insufficient (2767330364802375742) --> + <skip /> + <!-- no translation found for face_acquired_too_bright (5005650874582450967) --> + <skip /> + <!-- no translation found for face_acquired_too_dark (1966194696381394616) --> + <skip /> + <!-- no translation found for face_acquired_too_close (1401011882624272753) --> + <skip /> + <!-- no translation found for face_acquired_too_far (1210969240069012510) --> + <skip /> + <!-- no translation found for face_acquired_too_high (3362395713403348013) --> + <skip /> + <!-- no translation found for face_acquired_too_low (488983581737550912) --> + <skip /> + <!-- no translation found for face_acquired_too_right (941726879175375970) --> + <skip /> + <!-- no translation found for face_acquired_too_left (5873592047381190672) --> + <skip /> + <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) --> + <skip /> + <!-- no translation found for face_acquired_not_detected (4885504661626728809) --> + <skip /> + <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) --> + <skip /> <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Veuillez inscrire votre visage à nouveau."</string> - <string name="face_acquired_too_different" msgid="5553210341111255124">"Un visage différent a été détecté."</string> + <!-- no translation found for face_acquired_too_different (7663983770123789694) --> + <skip /> <string name="face_acquired_too_similar" msgid="1508776858407646460">"Trop similaire. Changez de pose."</string> - <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Veuillez regarder l\'appareil photo plus directement."</string> - <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Veuillez regarder l\'appareil photo plus directement."</string> + <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) --> + <skip /> + <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Veuillez redresse votre tête verticalement."</string> - <string name="face_acquired_obscured" msgid="3055077697850272097">"Veuillez découvrir votre visage."</string> + <!-- no translation found for face_acquired_obscured (5747521031647744553) --> + <skip /> + <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) --> + <skip /> <string-array name="face_acquired_vendor"> </string-array> <string name="face_error_hw_not_available" msgid="6255891785768984615">"Matériel de reconnaissance du visage indisponible."</string> - <string name="face_error_timeout" msgid="4014326147867150054">"Temps de reconn. visage écoulé. Veuillez réessayer."</string> + <!-- no translation found for face_error_timeout (2605673935810019129) --> + <skip /> <string name="face_error_no_space" msgid="8224993703466381314">"Impossible de stocker le visage."</string> <string name="face_error_canceled" msgid="283945501061931023">"Opération de reconnaissance du visage annulée."</string> <string name="face_error_user_canceled" msgid="8943921120862164539">"Authentification du visage annulée par l\'utilisateur"</string> <string name="face_error_lockout" msgid="3407426963155388504">"Trop de tentatives. Veuillez réessayer plus tard."</string> <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Trop de tentatives. Capt. reconn. visage désactivé."</string> - <string name="face_error_unable_to_process" msgid="238761109287767270">"Réessayez."</string> - <string name="face_error_not_enrolled" msgid="9166792142679691323">"Aucun visage inscrit."</string> - <string name="face_error_hw_not_present" msgid="916085883581450331">"Cet appareil ne possède pas de capteur de reconn. du visage."</string> + <!-- no translation found for face_error_unable_to_process (4940944939691171539) --> + <skip /> + <!-- no translation found for face_error_not_enrolled (4245760276260427472) --> + <skip /> + <!-- no translation found for face_error_hw_not_present (5296043240874659926) --> + <skip /> <string name="face_name_template" msgid="7004562145809595384">"Visage <xliff:g id="FACEID">%d</xliff:g>"</string> <string-array name="face_error_vendor"> </string-array> @@ -1213,9 +1246,16 @@ <string name="new_app_action" msgid="6694851182870774403">"Ouvrir <xliff:g id="NEW_APP">%1$s</xliff:g>"</string> <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> va fermer sans enregistrement"</string> <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> a dépassé la limite de mémoire"</string> + <!-- no translation found for dump_heap_ready_notification (1162196579925048701) --> + <skip /> <string name="dump_heap_notification_detail" msgid="3993078784053054141">"L\'empreinte de mémoire a été recueillie. Touchez ici pour la partager."</string> <string name="dump_heap_title" msgid="5864292264307651673">"Partager l\'empreinte de mémoire?"</string> - <string name="dump_heap_text" msgid="4809417337240334941">"Le processus <xliff:g id="PROC">%1$s</xliff:g> a dépassé sa limite de mémoire de <xliff:g id="SIZE">%2$s</xliff:g>. Vous pouvez partager son empreinte de mémoire avec son développeur. Attention : cette empreinte peut contenir certains de vos renseignements personnels auxquels l\'application a accès."</string> + <!-- no translation found for dump_heap_text (8546022920319781701) --> + <skip /> + <!-- no translation found for dump_heap_system_text (1205466256312104134) --> + <skip /> + <!-- no translation found for dump_heap_ready_text (6759394977904051000) --> + <skip /> <string name="sendText" msgid="5209874571959469142">"Sélectionner une action pour le texte"</string> <string name="volume_ringtone" msgid="6885421406845734650">"Volume de la sonnerie"</string> <string name="volume_music" msgid="5421651157138628171">"Volume"</string> @@ -1254,8 +1294,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Touchez pour afficher tous les réseaux"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connexion"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Tous les réseaux"</string> - <string name="wifi_suggestion_title" msgid="8951405130379148709">"Un réseau Wi‑Fi proposé par <xliff:g id="NAME">%s</xliff:g> est proposé"</string> - <string name="wifi_suggestion_content" msgid="2658317015552324848">"Voulez-vous vous connecter aux réseaux proposés par <xliff:g id="NAME">%s</xliff:g>?"</string> + <!-- no translation found for wifi_suggestion_title (9099832833531486167) --> + <skip /> + <!-- no translation found for wifi_suggestion_content (5883181205841582873) --> + <skip /> <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Oui"</string> <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Non"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Le Wi-Fi s\'activera automatiquement"</string> @@ -1267,9 +1309,14 @@ <string name="network_available_sign_in" msgid="1848877297365446605">"Connectez-vous au réseau"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> <skip /> - <string name="wifi_no_internet" msgid="8938267198124654938">"Le réseau Wi-Fi ne dispose d\'aucun accès à Internet"</string> + <!-- no translation found for wifi_no_internet (5198100389964214865) --> + <skip /> <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Touchez pour afficher les options"</string> <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Connecté"</string> + <!-- no translation found for network_partial_connectivity (7774883385494762741) --> + <skip /> + <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) --> + <skip /> <string name="wifi_softap_config_change" msgid="8475911871165857607">"Modifications apportées à vos paramètres de point d\'accès"</string> <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"La bande de votre point d\'accès a changé."</string> <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Cet appareil ne prend pas en charge votre préférence pour la bande de 5 GHz seulement. Au lieu de cela, cet appareil utilisera la bande de 5 GHz lorsqu\'elle sera disponible."</string> @@ -1354,6 +1401,10 @@ <string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB activé"</string> <string name="adb_active_notification_message" msgid="7463062450474107752">"Touchez l\'écran pour désactiver le débogage USB"</string> <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Sélectionnez cette option pour désactiver le débogage USB."</string> + <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) --> + <skip /> + <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) --> + <skip /> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquide ou débris dans le port USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Le port USB est désactivé automatiquement. Touchez ici pour en savoir plus."</string> <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Vous pouvez maintenant utiliser le port USB"</string> @@ -1905,8 +1956,6 @@ <string name="profile_encrypted_message" msgid="6964994232310195874">"Touch. pr déver. profil profess."</string> <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Connecté à <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string> <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Touchez ici pour afficher les fichiers"</string> - <string name="pin_target" msgid="3052256031352291362">"Épingler"</string> - <string name="unpin_target" msgid="3556545602439143442">"Annuler l\'épinglage"</string> <string name="app_info" msgid="6856026610594615344">"Détails de l\'application"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="demo_starting_message" msgid="5268556852031489931">"Démarrage de la démonstration en cours…"</string> @@ -1997,6 +2046,22 @@ <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Notification d\'information du mode Routine"</string> <string name="dynamic_mode_notification_title" msgid="508815255807182035">"La pile pourrait s\'épuiser avant la charge habituelle"</string> <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Le mode Économiseur de pile est activé afin de prolonger l\'autonomie"</string> + <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) --> + <skip /> + <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) --> + <skip /> + <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) --> + <skip /> <string name="mime_type_folder" msgid="7111951698626315204">"Dossier"</string> <string name="mime_type_apk" msgid="5518003630972506900">"Application Android"</string> <string name="mime_type_generic" msgid="6833871596845900027">"Fichier"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 17230391a5c5..72fe0d67718c 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -141,8 +141,10 @@ <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Appels Wi-Fi"</string> <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWiFi"</string> <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Désactivé"</string> - <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi de préférence"</string> - <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Données mobiles de préférence"</string> + <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) --> + <skip /> + <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) --> + <skip /> <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Wi-Fi uniquement"</string> <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> : non transféré"</string> <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> : <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> @@ -228,7 +230,8 @@ <string name="global_action_bug_report" msgid="7934010578922304799">"Rapport de bug"</string> <string name="global_action_logout" msgid="935179188218826050">"Fermer la session"</string> <string name="global_action_screenshot" msgid="8329831278085426283">"Capture d\'écran"</string> - <string name="bugreport_title" msgid="2667494803742548533">"Créer un rapport de bug"</string> + <!-- no translation found for bugreport_title (5981047024855257269) --> + <skip /> <string name="bugreport_message" msgid="398447048750350456">"Cela permet de recueillir des informations concernant l\'état actuel de votre appareil. Ces informations sont ensuite envoyées sous forme d\'e-mail. Merci de patienter pendant la préparation du rapport de bug. Cette opération peut prendre quelques instants."</string> <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Rapport interactif"</string> <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Utilisez cette option dans la plupart des circonstances. Elle vous permet de suivre la progression du rapport, de saisir plus d\'informations sur le problème et d\'effectuer des captures d\'écran. Certaines sections moins utilisées et dont le remplissage demande beaucoup de temps peuvent être omises."</string> @@ -281,9 +284,12 @@ <string name="permgrouplab_location" msgid="7275582855722310164">"Localisation"</string> <string name="permgroupdesc_location" msgid="1346617465127855033">"accéder à la position de l\'appareil"</string> <string name="permgrouprequest_location" msgid="3788275734953323491">"Permettre à <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> d\'accéder à la position de cet appareil ?"</string> - <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"L\'application n\'a accès à la position de l\'appareil que lorsqu\'elle est en cours d\'utilisation."</string> - <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Toujours autoriser <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> à accéder à la position de l\'appareil ?"</string> - <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"L\'application a toujours accès à la position de l\'appareil, même lorsqu\'elle n\'est pas en cours d\'utilisation."</string> + <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) --> + <skip /> <string name="permgrouplab_calendar" msgid="5863508437783683902">"Agenda"</string> <string name="permgroupdesc_calendar" msgid="3889615280211184106">"accéder à votre agenda"</string> <string name="permgrouprequest_calendar" msgid="289900767793189421">"Permettre à <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> d\'accéder à votre agenda ?"</string> @@ -316,7 +322,10 @@ <string name="permgrouprequest_aural" msgid="6787926123071735620">"Autoriser <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> à accéder à votre musique ?"</string> <string name="permgrouplab_visual" msgid="6477382108771145134">"Photos et vidéos"</string> <string name="permgroupdesc_visual" msgid="3415827902566663546">"accéder à vos photos et vos vidéos"</string> - <string name="permgrouprequest_visual" msgid="3043752127595243314">"Autoriser <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> à accéder à vos photos et vidéos, y compris aux tags de lieu ?"</string> + <!-- no translation found for permgrouprequest_visual (4926581398380334943) --> + <skip /> + <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) --> + <skip /> <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Récupérer le contenu d\'une fenêtre"</string> <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecte le contenu d\'une fenêtre avec laquelle vous interagissez."</string> <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activer la fonctionnalité Explorer au toucher"</string> @@ -509,8 +518,10 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Permet à l\'application de communiquer avec des tags, des cartes et des lecteurs compatibles avec la technologie NFC (communication en champ proche)."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"Désactiver le verrouillage de l\'écran"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permet à l\'application de désactiver le verrouillage des touches et toute mesure de sécurité via mot de passe associée. Par exemple, votre téléphone désactive le verrouillage des touches lorsque vous recevez un appel, puis le réactive lorsque vous raccrochez."</string> - <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"demander la complexité du verrouillage de l\'écran"</string> - <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Permet à l\'application de connaître le niveau de complexité du verrouillage de l\'écran (élevé, moyen, faible ou aucun), qui indique les possibilités en matière de longueur du mot de passe et de type de verrouillage de l\'écran. L\'application peut également suggérer aux utilisateurs de modifier la complexité du verrouillage, mais ces derniers peuvent librement l\'ignorer. Remarque : Comme le verrouillage de l\'écran n\'est pas stocké au format texte brut, l\'application ne connaît pas le mot de passe exact."</string> + <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) --> + <skip /> + <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) --> + <skip /> <string name="permlab_useBiometric" msgid="8837753668509919318">"utiliser les composants biométriques"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Autoriser l\'application à utiliser les composants biométriques pour l\'authentification"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"Gérer le matériel d\'empreintes digitales"</string> @@ -565,37 +576,59 @@ <string name="permdesc_manageFace" msgid="8919637120670185330">"Autorise l\'appli à invoquer des méthodes pour ajouter et supprimer des modèles de visages."</string> <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"utiliser le matériel d\'authentification faciale"</string> <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Autorise l\'appli à utiliser le matériel d\'authentification faciale pour l\'authentification"</string> - <string name="face_acquired_insufficient" msgid="5901287247766106330">"Impossible reconnaître visage. Veuillez réessayer."</string> - <string name="face_acquired_too_bright" msgid="610606792381297174">"Visage trop éclairé. Veuillez réduire la lumière."</string> - <string name="face_acquired_too_dark" msgid="7229162716976778371">"Visage trop sombre. Veuillez accroître la lumière."</string> - <string name="face_acquired_too_close" msgid="1980310037427755293">"Veuillez éloigner le capteur de votre visage."</string> - <string name="face_acquired_too_far" msgid="4494571381828850007">"Veuillez rapprocher le capteur de votre visage."</string> - <string name="face_acquired_too_high" msgid="228411096134808372">"Veuillez déplacer le capteur vers le haut."</string> - <string name="face_acquired_too_low" msgid="4539774649296349109">"Veuillez déplacer le capteur vers le bas."</string> - <string name="face_acquired_too_right" msgid="1650292067226118760">"Veuillez déplacer le capteur vers la droite."</string> - <string name="face_acquired_too_left" msgid="2712489669456176505">"Veuillez déplacer le capteur vers la gauche."</string> - <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Veuillez regarder le capteur."</string> - <string name="face_acquired_not_detected" msgid="5707782294589511391">"Aucun visage détecté."</string> - <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Trop de mouvement."</string> + <!-- no translation found for face_acquired_insufficient (2767330364802375742) --> + <skip /> + <!-- no translation found for face_acquired_too_bright (5005650874582450967) --> + <skip /> + <!-- no translation found for face_acquired_too_dark (1966194696381394616) --> + <skip /> + <!-- no translation found for face_acquired_too_close (1401011882624272753) --> + <skip /> + <!-- no translation found for face_acquired_too_far (1210969240069012510) --> + <skip /> + <!-- no translation found for face_acquired_too_high (3362395713403348013) --> + <skip /> + <!-- no translation found for face_acquired_too_low (488983581737550912) --> + <skip /> + <!-- no translation found for face_acquired_too_right (941726879175375970) --> + <skip /> + <!-- no translation found for face_acquired_too_left (5873592047381190672) --> + <skip /> + <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) --> + <skip /> + <!-- no translation found for face_acquired_not_detected (4885504661626728809) --> + <skip /> + <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) --> + <skip /> <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Veuillez enregistrer à nouveau votre visage."</string> - <string name="face_acquired_too_different" msgid="5553210341111255124">"Visage différent détecté."</string> + <!-- no translation found for face_acquired_too_different (7663983770123789694) --> + <skip /> <string name="face_acquired_too_similar" msgid="1508776858407646460">"Ressemble à un visage existant, changez de pose."</string> - <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Regardez l\'appareil photo plus directement."</string> - <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Regardez l\'appareil photo plus directement."</string> + <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) --> + <skip /> + <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Veuillez tenir votre tête droite."</string> - <string name="face_acquired_obscured" msgid="3055077697850272097">"Veuillez découvrir votre visage."</string> + <!-- no translation found for face_acquired_obscured (5747521031647744553) --> + <skip /> + <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) --> + <skip /> <string-array name="face_acquired_vendor"> </string-array> <string name="face_error_hw_not_available" msgid="6255891785768984615">"Matériel de reconnaissance faciale indisponible."</string> - <string name="face_error_timeout" msgid="4014326147867150054">"Délai de détection du visage expiré. Réessayez."</string> + <!-- no translation found for face_error_timeout (2605673935810019129) --> + <skip /> <string name="face_error_no_space" msgid="8224993703466381314">"Impossible de stocker les informations du visage."</string> <string name="face_error_canceled" msgid="283945501061931023">"Opération de reconnaissance faciale annulée."</string> <string name="face_error_user_canceled" msgid="8943921120862164539">"Authentification faciale annulée par l\'utilisateur."</string> <string name="face_error_lockout" msgid="3407426963155388504">"Trop de tentatives. Réessayez plus tard."</string> <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Trop d\'essais. Authentification faciale désactivée."</string> - <string name="face_error_unable_to_process" msgid="238761109287767270">"Réessayez."</string> - <string name="face_error_not_enrolled" msgid="9166792142679691323">"Aucun visage enregistré."</string> - <string name="face_error_hw_not_present" msgid="916085883581450331">"Aucun capteur d\'authentification faciale sur cet appareil."</string> + <!-- no translation found for face_error_unable_to_process (4940944939691171539) --> + <skip /> + <!-- no translation found for face_error_not_enrolled (4245760276260427472) --> + <skip /> + <!-- no translation found for face_error_hw_not_present (5296043240874659926) --> + <skip /> <string name="face_name_template" msgid="7004562145809595384">"Visage <xliff:g id="FACEID">%d</xliff:g>"</string> <string-array name="face_error_vendor"> </string-array> @@ -1213,9 +1246,16 @@ <string name="new_app_action" msgid="6694851182870774403">"Ouvrir <xliff:g id="NEW_APP">%1$s</xliff:g>"</string> <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> va se fermer sans enregistrer les données"</string> <string name="dump_heap_notification" msgid="2618183274836056542">"Le processus \"<xliff:g id="PROC">%1$s</xliff:g>\" a dépassé la limite de mémoire"</string> + <!-- no translation found for dump_heap_ready_notification (1162196579925048701) --> + <skip /> <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Une empreinte de la mémoire a bien été générée. Appuyez pour partager."</string> <string name="dump_heap_title" msgid="5864292264307651673">"Partager l\'empreinte de la mémoire ?"</string> - <string name="dump_heap_text" msgid="4809417337240334941">"Le processus \"<xliff:g id="PROC">%1$s</xliff:g>\" a dépassé sa limite de mémoire fixée à <xliff:g id="SIZE">%2$s</xliff:g>. Une empreinte de la mémoire est disponible pour que vous la communiquiez à son développeur. Attention : celle-ci peut contenir des informations personnelles auxquelles l\'application a accès."</string> + <!-- no translation found for dump_heap_text (8546022920319781701) --> + <skip /> + <!-- no translation found for dump_heap_system_text (1205466256312104134) --> + <skip /> + <!-- no translation found for dump_heap_ready_text (6759394977904051000) --> + <skip /> <string name="sendText" msgid="5209874571959469142">"Sélectionner une action pour le texte"</string> <string name="volume_ringtone" msgid="6885421406845734650">"Volume de la sonnerie"</string> <string name="volume_music" msgid="5421651157138628171">"Volume"</string> @@ -1254,8 +1294,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Appuyer pour afficher tous les réseaux"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Se connecter"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Tous les réseaux"</string> - <string name="wifi_suggestion_title" msgid="8951405130379148709">"Un réseau Wi-Fi proposé par <xliff:g id="NAME">%s</xliff:g> est disponible"</string> - <string name="wifi_suggestion_content" msgid="2658317015552324848">"Voulez-vous vous connecter aux réseaux proposés par <xliff:g id="NAME">%s</xliff:g> ?"</string> + <!-- no translation found for wifi_suggestion_title (9099832833531486167) --> + <skip /> + <!-- no translation found for wifi_suggestion_content (5883181205841582873) --> + <skip /> <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Oui"</string> <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Non"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Le Wi-Fi sera activé automatiquement"</string> @@ -1267,9 +1309,14 @@ <string name="network_available_sign_in" msgid="1848877297365446605">"Se connecter au réseau"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> <skip /> - <string name="wifi_no_internet" msgid="8938267198124654938">"Impossible de se connecter à Internet via le réseau Wi-Fi"</string> + <!-- no translation found for wifi_no_internet (5198100389964214865) --> + <skip /> <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Appuyez ici pour afficher des options."</string> <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Connecté"</string> + <!-- no translation found for network_partial_connectivity (7774883385494762741) --> + <skip /> + <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) --> + <skip /> <string name="wifi_softap_config_change" msgid="8475911871165857607">"Modifications apportées à vos paramètres de point d\'accès"</string> <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Votre bande de point d\'accès a été modifiée."</string> <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Cet appareil n\'est pas compatible avec votre préférence d\'utilisation de la bande 5 GHz uniquement. Il utilisera la bande 5 GHz lorsqu\'elle sera disponible."</string> @@ -1354,6 +1401,10 @@ <string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB activé"</string> <string name="adb_active_notification_message" msgid="7463062450474107752">"Appuyez pour désactiver le débogage USB"</string> <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Sélectionnez cette option pour désactiver le débogage USB."</string> + <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) --> + <skip /> + <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) --> + <skip /> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Présence de liquide ou de saletés dans le port USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Le port USB est désactivé automatiquement. Appuyez sur cette notification pour en savoir plus."</string> <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Possibilité d\'utiliser le port USB en toute sécurité"</string> @@ -1905,8 +1956,6 @@ <string name="profile_encrypted_message" msgid="6964994232310195874">"Appuyez pour déverrouiller profil pro"</string> <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Connecté à <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string> <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Appuyez ici pour voir les fichiers."</string> - <string name="pin_target" msgid="3052256031352291362">"Épingler"</string> - <string name="unpin_target" msgid="3556545602439143442">"Retirer"</string> <string name="app_info" msgid="6856026610594615344">"Infos sur l\'appli"</string> <string name="negative_duration" msgid="5688706061127375131">"− <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="demo_starting_message" msgid="5268556852031489931">"Lancement de la démo…"</string> @@ -1997,6 +2046,22 @@ <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Notification d\'information du mode Routine"</string> <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Vous risquez d\'être à court de batterie plus tôt que prévu"</string> <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Économiseur de batterie activé pour prolonger l\'autonomie"</string> + <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) --> + <skip /> + <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) --> + <skip /> + <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) --> + <skip /> <string name="mime_type_folder" msgid="7111951698626315204">"Dossier"</string> <string name="mime_type_apk" msgid="5518003630972506900">"Application Android"</string> <string name="mime_type_generic" msgid="6833871596845900027">"Fichier"</string> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index 7d9f8ac6a57d..5f3026cf2d96 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -48,7 +48,7 @@ <string name="invalidPin" msgid="3850018445187475377">"Մուտքագրեք PIN, որը 4-ից 8 թիվ է:"</string> <string name="invalidPuk" msgid="8761456210898036513">"Մուտքագրեք PUK, որն 8 կամ ավել թիվ ունի:"</string> <string name="needPuk" msgid="919668385956251611">"Ձեր SIM քարտը PUK-ով կողպված է: Մուտքագրեք PUK կոդը այն ապակողպելու համար:"</string> - <string name="needPuk2" msgid="4526033371987193070">"Մուտքագրեք PUK2-ը` SIM քարտն արգելաբացելու համար:"</string> + <string name="needPuk2" msgid="4526033371987193070">"Մուտքագրեք PUK2-ը` SIM քարտն արգելահանելու համար:"</string> <string name="enablePin" msgid="209412020907207950">"Ձախողվեց: Միացրեք SIM/RUIM կողպումը:"</string> <plurals name="pinpuk_attempts" formatted="false" msgid="1251012001539225582"> <item quantity="one">Մնաց <xliff:g id="NUMBER_1">%d</xliff:g> փորձ, որից հետո SIM քարտն արգելափակվելու է:</item> @@ -141,8 +141,10 @@ <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Զանգեր Wi-Fi-ի միջոցով"</string> <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string> <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Անջատված է"</string> - <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi, նախընտրելի"</string> - <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Նախընտրելի է բջջային ցանցը"</string> + <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) --> + <skip /> + <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) --> + <skip /> <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Միայն Wi-Fi"</string> <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>. Չի վերահասցեավորվել"</string> <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>. <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> @@ -228,7 +230,8 @@ <string name="global_action_bug_report" msgid="7934010578922304799">"Վրիպակի զեկույց"</string> <string name="global_action_logout" msgid="935179188218826050">"Ավարտել աշխատաշրջանը"</string> <string name="global_action_screenshot" msgid="8329831278085426283">"Սքրինշոթ"</string> - <string name="bugreport_title" msgid="2667494803742548533">"Հաղորդել սխալի մասին"</string> + <!-- no translation found for bugreport_title (5981047024855257269) --> + <skip /> <string name="bugreport_message" msgid="398447048750350456">"Սա տեղեկություններ կհավաքագրի ձեր սարքի առկա կարգավիճակի մասին և կուղարկի այն էլեկտրոնային նամակով: Որոշակի ժամանակ կպահանջվի վրիպակի մասին զեկուցելու պահից սկսած մինչ ուղարկելը: Խնդրում ենք փոքր-ինչ համբերատար լինել:"</string> <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Ինտերակտիվ զեկույց"</string> <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Հիմնականում օգտագործեք այս տարբերակը: Այն ձեզ թույլ է տալիս հետևել զեկույցի ստեղծման գործընթացին, խնդրի մասին լրացուցիչ տեղեկություններ մուտքագրել և սքրինշոթներ ստեղծել: Կարող է բաց թողնել քիչ օգտագործվող որոշ բաժիններ, որոնց ստեղծումը երկար է տևում:"</string> @@ -241,9 +244,9 @@ <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Անձայն ռեժիմ"</string> <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Ձայնը անջատված է"</string> <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Ձայնը միացված է"</string> - <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Ինքնաթիռի ռեժիմ"</string> - <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Ինքնաթիռի ռեժիմը միացված է"</string> - <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Ինքնաթիռի ռեժիմը անջատված է"</string> + <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Ավիառեժիմ"</string> + <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Ավիառեժիմը միացված է"</string> + <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Ավիառեժիմը անջատված է"</string> <string name="global_action_settings" msgid="1756531602592545966">"Կարգավորումներ"</string> <string name="global_action_assist" msgid="3892832961594295030">"Օգնական"</string> <string name="global_action_voice_assist" msgid="7751191495200504480">"Ձայնային օգնութ"</string> @@ -281,9 +284,12 @@ <string name="permgrouplab_location" msgid="7275582855722310164">"Տեղորոշում"</string> <string name="permgroupdesc_location" msgid="1346617465127855033">"տեղորոշել այս սարքը"</string> <string name="permgrouprequest_location" msgid="3788275734953323491">"Թույլ տա՞լ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> հավելվածին օգտագործել այս սարքի տեղադրության տվյալները:"</string> - <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Տեղադրության տվյալները հավելվածին հասանելի կլինեն միայն, երբ այն օգտագործելիս լինեք:"</string> - <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Միշտ թույլ տա՞լ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>-ին օգտագործել սարքի տեղադրությունը:"</string> - <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Տեղադրության տվյալները հավելվածին միշտ հասանելի կլինեն, նույնիսկ եթե այն չեք օգտագործում:"</string> + <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) --> + <skip /> <string name="permgrouplab_calendar" msgid="5863508437783683902">"Օրացույց"</string> <string name="permgroupdesc_calendar" msgid="3889615280211184106">"օգտագործել օրացույցը"</string> <string name="permgrouprequest_calendar" msgid="289900767793189421">"Թույլ տա՞լ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> հավելվածին օգտագործել ձեր օրացույցը:"</string> @@ -316,7 +322,10 @@ <string name="permgrouprequest_aural" msgid="6787926123071735620">"Հասանելի դարձնե՞լ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> հավելվածին ձեր երաժշտությունը:"</string> <string name="permgrouplab_visual" msgid="6477382108771145134">"Լուսանկարներ և տեսանյութեր"</string> <string name="permgroupdesc_visual" msgid="3415827902566663546">"լուսանկարների և տեսանյութերի հասանելիություն"</string> - <string name="permgrouprequest_visual" msgid="3043752127595243314">"Հասանելի դարձնե՞լ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> հավելվածին ձեր լուսանկարները, տեսանյութերը և տեղանշված վայրերը:"</string> + <!-- no translation found for permgrouprequest_visual (4926581398380334943) --> + <skip /> + <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) --> + <skip /> <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Առբերել պատուհանի բովանդակությունը"</string> <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Վերլուծել գործող պատուհանի բովանդակությունը"</string> <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Միացնել Հպման միջոցով հետազոտումը"</string> @@ -509,8 +518,10 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Թույլ է տալիս հավելվածին հաղորդակցվել Մոտ տարածությամբ հաղորդակցման (NFC) պիտակների, քարտերի և ընթերցիչների հետ:"</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"անջատել ձեր էկրանի կողպեքը"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Թույլ է տալիս հավելվածին անջատել ստեղնաշարի կողպումը և ցանկացած կապված գաղտնաբառի պաշտպանվածությունը: Սրա ճիշտ օրինակն է, երբ հեռախոսը անջատում է ստեղնաշարի կողպումը մուտքային զանգ ստանալիս, հետո այն կրկին միացնում է, երբ զանգը ավարտվում է:"</string> - <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"էկրանի կողպման բարդության մակարդակի մասին տեղեկությունների ստացում"</string> - <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Հավելվածին հասանելի կդառնան էկրանի կողպման բարդության մակարդակի մասին տեղեկությունները (բարձր, միջին, ցածր կամ ոչ մի), այդ թվում կողպման տեսակի և գաղտնաբառի երկարության մասին տվյալները: Բացի այդ, հավելվածը կկարողանա առաջարկել օգտատերերին բարձրացնել կողպման բարդության մակարդակը: Օգտատերերը կարող են անտեսել այդ առաջարկները: Նկատի ունեցեք, որ գաղտնաբառը չի պահվում բաց տեքստի տեսքով և հասանելի չէ հավելվածին:"</string> + <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) --> + <skip /> + <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) --> + <skip /> <string name="permlab_useBiometric" msgid="8837753668509919318">"կենսաչափական սարքի օգտագործում"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Հավելվածին թույլ է տալիս օգտագործել նույնականացման համար նախատեսված կենսաչափական սարքը"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"կառավարել մատնահետքերի գրանցման սարքը"</string> @@ -565,37 +576,59 @@ <string name="permdesc_manageFace" msgid="8919637120670185330">"Հավելվածին թույլ է տալիս ավելացնել և հեռացնել դեմքի նմուշներ:"</string> <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"օգտագործել դեմքի ճանաչման սարքը"</string> <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Հավելվածին թույլ է տալիս օգտագործել նույնականացման համար նախատեսված սարքը"</string> - <string name="face_acquired_insufficient" msgid="5901287247766106330">"Չհաջողվեց ճանաչել ձեր դեմքը: Նորից փորձեք:"</string> - <string name="face_acquired_too_bright" msgid="610606792381297174">"Դեմքը չափազանց վառ է երևում։ Թուլացրեք լույսը։"</string> - <string name="face_acquired_too_dark" msgid="7229162716976778371">"Դեմքը չափազանց մուգ է երևում։ Ուժեղացրեք լույսը։"</string> - <string name="face_acquired_too_close" msgid="1980310037427755293">"Սարքը մի փոքր հեռացրեք դեմքից։"</string> - <string name="face_acquired_too_far" msgid="4494571381828850007">"Սարքը մի փոքր մոտեցրեք դեմքին։"</string> - <string name="face_acquired_too_high" msgid="228411096134808372">"Սարքը մի փոքր վերև պահեք։"</string> - <string name="face_acquired_too_low" msgid="4539774649296349109">"Սարքը մի փոքր ներքև պահեք։"</string> - <string name="face_acquired_too_right" msgid="1650292067226118760">"Սարքը մի փոքր ձախ պահեք։"</string> - <string name="face_acquired_too_left" msgid="2712489669456176505">"Սարքը մի փոքր ձախ պահեք։"</string> - <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Նայեք սարքի տեսախցիկին։"</string> - <string name="face_acquired_not_detected" msgid="5707782294589511391">"Դեմք չի հայտնաբերվել։"</string> - <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Սարքն անշարժ պահեք։"</string> + <!-- no translation found for face_acquired_insufficient (2767330364802375742) --> + <skip /> + <!-- no translation found for face_acquired_too_bright (5005650874582450967) --> + <skip /> + <!-- no translation found for face_acquired_too_dark (1966194696381394616) --> + <skip /> + <!-- no translation found for face_acquired_too_close (1401011882624272753) --> + <skip /> + <!-- no translation found for face_acquired_too_far (1210969240069012510) --> + <skip /> + <!-- no translation found for face_acquired_too_high (3362395713403348013) --> + <skip /> + <!-- no translation found for face_acquired_too_low (488983581737550912) --> + <skip /> + <!-- no translation found for face_acquired_too_right (941726879175375970) --> + <skip /> + <!-- no translation found for face_acquired_too_left (5873592047381190672) --> + <skip /> + <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) --> + <skip /> + <!-- no translation found for face_acquired_not_detected (4885504661626728809) --> + <skip /> + <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) --> + <skip /> <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Նորից փորձեք։"</string> - <string name="face_acquired_too_different" msgid="5553210341111255124">"Հայտնաբերվել է այլ դեմք։"</string> + <!-- no translation found for face_acquired_too_different (7663983770123789694) --> + <skip /> <string name="face_acquired_too_similar" msgid="1508776858407646460">"Շատ նման է նախորդին։ Փոխեք ձեր դիրքը։"</string> - <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Նայեք ուղիղ տեսախցիկին։"</string> - <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Նայեք ուղիղ տեսախցիկին։"</string> + <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) --> + <skip /> + <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Ուղղեք գլուխը հորիզոնական գծով։"</string> - <string name="face_acquired_obscured" msgid="3055077697850272097">"Բացեք դեմքը։"</string> + <!-- no translation found for face_acquired_obscured (5747521031647744553) --> + <skip /> + <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) --> + <skip /> <string-array name="face_acquired_vendor"> </string-array> <string name="face_error_hw_not_available" msgid="6255891785768984615">"Դեմքի ճանաչման սարքն անհասանելի է։"</string> - <string name="face_error_timeout" msgid="4014326147867150054">"Ժամանակը սպառվել է: Նորից փորձեք:"</string> + <!-- no translation found for face_error_timeout (2605673935810019129) --> + <skip /> <string name="face_error_no_space" msgid="8224993703466381314">"Դեմքը հնարավոր չէ պահել։"</string> <string name="face_error_canceled" msgid="283945501061931023">"Դեմքի ճանաչումը չեղարկվել է։"</string> <string name="face_error_user_canceled" msgid="8943921120862164539">"Դեմքի ճանաչումը չեղարկվել է օգտատիրոջ կողմից:"</string> <string name="face_error_lockout" msgid="3407426963155388504">"Չափից շատ փորձեր եք կատարել: Փորձեք ավելի ուշ:"</string> <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Չափից շատ փորձեր եք կատարել: Դեմքի ճանաչման գործառույթն անջատվել է։"</string> - <string name="face_error_unable_to_process" msgid="238761109287767270">"Նորից փորձեք:"</string> - <string name="face_error_not_enrolled" msgid="9166792142679691323">"Գրանցված դեմք չկա։"</string> - <string name="face_error_hw_not_present" msgid="916085883581450331">"Այս սարքը չունի դեմքի ճանաչման սկաներ։"</string> + <!-- no translation found for face_error_unable_to_process (4940944939691171539) --> + <skip /> + <!-- no translation found for face_error_not_enrolled (4245760276260427472) --> + <skip /> + <!-- no translation found for face_error_hw_not_present (5296043240874659926) --> + <skip /> <string name="face_name_template" msgid="7004562145809595384">"Դեմք <xliff:g id="FACEID">%d</xliff:g>"</string> <string-array name="face_error_vendor"> </string-array> @@ -1213,9 +1246,16 @@ <string name="new_app_action" msgid="6694851182870774403">"Բացել <xliff:g id="NEW_APP">%1$s</xliff:g> հավելվածը"</string> <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> հավելվածը կփակվի առանց տվյալները պահելու"</string> <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> գործընթացը գերազանցել է հիշողության սահմանաչափը"</string> + <!-- no translation found for dump_heap_ready_notification (1162196579925048701) --> + <skip /> <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Դինամիկ հիշողության տվյալները հավաքվել են: Հպեք՝ դրանք ուղարկելու համար:"</string> <string name="dump_heap_title" msgid="5864292264307651673">"Տրամադրե՞լ օգտագործվող օբյեկտների վերաբերյալ տվյալները:"</string> - <string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g> գործընթացը գերազանցել է իր կողմից հիշողության օգտագործման սահմանաչափը՝ <xliff:g id="SIZE">%2$s</xliff:g>: Հավաքվել են օգտագործվող օբյեկտների վերաբերյալ տվյալներ, որոնք կարող եք ուղարկել մշակողին: Սակայն զգույշ եղեք՝ նշված տվյալները կարող են ներառել հավելվածի կողմից օգտագործվող ձեր անձնական տվյալները:"</string> + <!-- no translation found for dump_heap_text (8546022920319781701) --> + <skip /> + <!-- no translation found for dump_heap_system_text (1205466256312104134) --> + <skip /> + <!-- no translation found for dump_heap_ready_text (6759394977904051000) --> + <skip /> <string name="sendText" msgid="5209874571959469142">"Ընտրեք գործողություն տեքստի համար"</string> <string name="volume_ringtone" msgid="6885421406845734650">"Զանգակի ձայնի ուժգնությունը"</string> <string name="volume_music" msgid="5421651157138628171">"Մեդիա ձայնի բարձրություն"</string> @@ -1254,8 +1294,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Հպեք՝ բոլոր ցանցերը տեսնելու համար"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Միանալ"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Բոլոր ցանցերը"</string> - <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g> հավելվածն առաջարկում է միանալ հասանելի Wi‑Fi ցանցի"</string> - <string name="wifi_suggestion_content" msgid="2658317015552324848">"Միանա՞լ <xliff:g id="NAME">%s</xliff:g> հավելվածի առաջարկած ցանցերին:"</string> + <!-- no translation found for wifi_suggestion_title (9099832833531486167) --> + <skip /> + <!-- no translation found for wifi_suggestion_content (5883181205841582873) --> + <skip /> <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Այո"</string> <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ոչ"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi-ն ավտոմատ կմիանա"</string> @@ -1267,9 +1309,14 @@ <string name="network_available_sign_in" msgid="1848877297365446605">"Մուտք գործեք ցանց"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> <skip /> - <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi ցանցում ինտերնետ կապ չկա"</string> + <!-- no translation found for wifi_no_internet (5198100389964214865) --> + <skip /> <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Հպեք՝ ընտրանքները տեսնելու համար"</string> <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Միացված է"</string> + <!-- no translation found for network_partial_connectivity (7774883385494762741) --> + <skip /> + <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) --> + <skip /> <string name="wifi_softap_config_change" msgid="8475911871165857607">"Փոփոխություններ թեժ կետի կարգավորումներում"</string> <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Ձեր թեժ կետի հաճախականությունը փոխվել է։"</string> <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Սարքը չի կարող աշխատել միայն 5 ԳՀց հաճախականությամբ։ Այդ հաճախականությունը կօգտագործվի հնարավորության դեպքում։"</string> @@ -1354,6 +1401,10 @@ <string name="adb_active_notification_title" msgid="6729044778949189918">"USB վրիպազերծումը միացված է"</string> <string name="adb_active_notification_message" msgid="7463062450474107752">"Հպեք՝ USB-ի վրիպազերծումն անջատելու համար"</string> <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Ընտրել` USB կարգաբերումը կասեցնելու համար:"</string> + <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) --> + <skip /> + <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) --> + <skip /> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB միացքում ջուր կամ աղտ է հայտնաբերվել"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB միացքն ավտոմատ անջատվել է: Հպեք՝ ավելին իմանալու համար:"</string> <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB միացքը կարող է օգտագործվել"</string> @@ -1396,8 +1447,7 @@ <string name="ext_media_init_action" msgid="7952885510091978278">"Կարգավորել"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Անջատել"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Ուսումնասիրել"</string> - <!-- no translation found for ext_media_seamless_action (6575980560886881233) --> - <skip /> + <string name="ext_media_seamless_action" msgid="6575980560886881233">"Աուդիոելքի սարքի փոխարկում"</string> <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g>-ը տեղադրված չէ"</string> <string name="ext_media_missing_message" msgid="4012389235250987930">"Նորից տեղադրեք սարքը"</string> <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g>-ի տեղափոխում"</string> @@ -1906,8 +1956,6 @@ <string name="profile_encrypted_message" msgid="6964994232310195874">"Հպեք՝ այն ապակողպելու համար"</string> <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Միացված է <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>-ին"</string> <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Հպեք՝ ֆայլերը տեսնելու համար"</string> - <string name="pin_target" msgid="3052256031352291362">"Ամրացնել"</string> - <string name="unpin_target" msgid="3556545602439143442">"Ապամրացնել"</string> <string name="app_info" msgid="6856026610594615344">"Հավելվածի տվյալներ"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="demo_starting_message" msgid="5268556852031489931">"Ցուցադրական օգտատերը գործարկվում է…"</string> @@ -1998,6 +2046,22 @@ <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Ծանուցում լիցքավորման մասին"</string> <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Մարտկոցի լիցքը կարող է սովորականից շուտ սպառվել"</string> <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Մարտկոցի կյանքը երկարացնելու համար ակտիվացվել է մարտկոցի տնտեսման ռեժիմը"</string> + <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) --> + <skip /> + <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) --> + <skip /> + <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) --> + <skip /> <string name="mime_type_folder" msgid="7111951698626315204">"Պանակ"</string> <string name="mime_type_apk" msgid="5518003630972506900">"Android հավելված"</string> <string name="mime_type_generic" msgid="6833871596845900027">"Ֆայլ"</string> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 951c4e2afb22..5b8028d19d37 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -141,8 +141,10 @@ <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"WiFi қоңыраулары"</string> <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string> <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Өшірулі"</string> - <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Қалаулы Wi-Fi"</string> - <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Таңдаулы мобильдік байланыс"</string> + <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) --> + <skip /> + <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) --> + <skip /> <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Тек Wi-Fi"</string> <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Басқа нөмірге бағытталмады"</string> <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> @@ -228,7 +230,8 @@ <string name="global_action_bug_report" msgid="7934010578922304799">"Вирус туралы хабарлау"</string> <string name="global_action_logout" msgid="935179188218826050">"Сеансты аяқтау"</string> <string name="global_action_screenshot" msgid="8329831278085426283">"Скриншот"</string> - <string name="bugreport_title" msgid="2667494803742548533">"Қате туралы есеп құру"</string> + <!-- no translation found for bugreport_title (5981047024855257269) --> + <skip /> <string name="bugreport_message" msgid="398447048750350456">"Құрылғының қазіргі күйі туралы ақпаратты жинап, электрондық хабармен жібереді. Есеп әзір болғанша біраз уақыт кетеді, шыдай тұрыңыз."</string> <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Интерактивті есеп"</string> <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Бұл көптеген жағдайларда пайдаланылады. Ол есептің орындалу барысын бақылауға, мәселе туралы қосымша мәліметтер енгізуге және скриншоттар алуға мүмкіндік береді. Ол есеп беруіне ұзақ уақыт кететін кейбір азырақ пайдаланылатын бөлімдерді өткізіп жіберуі мүмкін."</string> @@ -281,9 +284,12 @@ <string name="permgrouplab_location" msgid="7275582855722310164">"Орналасу"</string> <string name="permgroupdesc_location" msgid="1346617465127855033">"бұл құрылғының орналасқан жерін көру"</string> <string name="permgrouprequest_location" msgid="3788275734953323491">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> қолданбасына құрылғының орналасқан жері туралы мәліметтерді пайдалануға рұқсат берілсін бе?"</string> - <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Қолданбаны пайдалану кезінде ғана оған геодеректеріңізді көруге рұқсат етіледі."</string> - <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"\"<xliff:g id="APP_NAME">%1$s</xliff:g>\" кез келген уақытта құрылғы геодеректерін пайдалансын ба?"</string> - <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Қолданба пайдаланылмаса да, оған геодеректеріңізді көруге рұқсат етіледі."</string> + <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) --> + <skip /> <string name="permgrouplab_calendar" msgid="5863508437783683902">"Күнтізбе"</string> <string name="permgroupdesc_calendar" msgid="3889615280211184106">"күнтізбеге кіру"</string> <string name="permgrouprequest_calendar" msgid="289900767793189421">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> қолданбасына күнтізбеге кіруге рұқсат берілсін бе?"</string> @@ -316,7 +322,10 @@ <string name="permgrouprequest_aural" msgid="6787926123071735620">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> қолданбасына музыка мазмұнына кіруге рұқсат етілсін бе?"</string> <string name="permgrouplab_visual" msgid="6477382108771145134">"Суреттер және бейнелер"</string> <string name="permgroupdesc_visual" msgid="3415827902566663546">"суреттер мен бейнелерге кіру"</string> - <string name="permgrouprequest_visual" msgid="3043752127595243314">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> қолданбасына суреттер мен бейнелерді, тэг енгізілген орындарды пайдалануға рұқсат етілсін бе?"</string> + <!-- no translation found for permgrouprequest_visual (4926581398380334943) --> + <skip /> + <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) --> + <skip /> <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Терезе мазмұнын оқып отыру"</string> <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Ашық тұрған терезе мазмұнын тексеру."</string> <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Explore by Touch функциясын қосу"</string> @@ -509,8 +518,10 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Қолданбаға NFC белгілерімен, карталармен және оқу құралдарымен байланысуға рұқсат береді."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"экран бекітпесін істен шығару"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Қолданбаларға кілтперне және басқа кілтсөзге қатысты қауіпсіздік шараларын өшіру мүмкіндігін береді. Мысалы, телефон кіріс қоңырауларын алғанда кілтпернені өшіреді және қоңырау аяқталғанда қайта қосады."</string> - <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"экранды құлыптау күрделілігін сұрау"</string> - <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Қолданбаға экранды құлыптаудың күрделілік деңгейін (жоғары, орташа, төмен немесе жоқ), соның ішінде ұзақтығы мен түрін анықтауға мүмкіндік береді. Сонымен қатар қолданба пайдаланушыларға құлыпты белгілі бір деңгейге жаңартуды ұсынады. Бірақ бұл ұсыныстарды елемеуге болады. Экран құлпы қарапайым мәтін түрінде сақталмайтынын және құпия сөз қолданбаға белгісіз болатынын ескеріңіз."</string> + <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) --> + <skip /> + <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) --> + <skip /> <string name="permlab_useBiometric" msgid="8837753668509919318">"биометрикалық жабдықты пайдалану"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Аутентификациялау үшін қолданбаға биометрикалық жабдықты пайдалануға рұқсат береді"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"саусақ ізі жабдығын басқару"</string> @@ -565,37 +576,59 @@ <string name="permdesc_manageFace" msgid="8919637120670185330">"Қолданбаға пайдаланатын бет үлгілерін енгізу және жою әдістерін шақыруға мүмкіндік береді."</string> <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"бетті тану жабдығын пайдалану"</string> <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Қолданбаға бетті тану жабдығын қолдануға рұқсат етеді"</string> - <string name="face_acquired_insufficient" msgid="5901287247766106330">"Бет өңделмеді. Әрекетті қайталаңыз."</string> - <string name="face_acquired_too_bright" msgid="610606792381297174">"Бет тым ашық түсті болып шықты. Жарықты азайтыңыз."</string> - <string name="face_acquired_too_dark" msgid="7229162716976778371">"Бет тым күңгірт түсті. Жарық көзін бөгемеңіз."</string> - <string name="face_acquired_too_close" msgid="1980310037427755293">"Датчикті беттен алыстатыңыз."</string> - <string name="face_acquired_too_far" msgid="4494571381828850007">"Датчикті бетке жақындатыңыз."</string> - <string name="face_acquired_too_high" msgid="228411096134808372">"Датчикті жоғары көтеріңіз."</string> - <string name="face_acquired_too_low" msgid="4539774649296349109">"Датчикті төмен қарай жылжытыңыз."</string> - <string name="face_acquired_too_right" msgid="1650292067226118760">"Датчикті оңға қарай жылжытыңыз."</string> - <string name="face_acquired_too_left" msgid="2712489669456176505">"Датчикті солға қарай жылжытыңыз."</string> - <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Датчикке қараңыз."</string> - <string name="face_acquired_not_detected" msgid="5707782294589511391">"Бет анықталмады."</string> - <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Құрылғыны қозғалтпаңыз."</string> + <!-- no translation found for face_acquired_insufficient (2767330364802375742) --> + <skip /> + <!-- no translation found for face_acquired_too_bright (5005650874582450967) --> + <skip /> + <!-- no translation found for face_acquired_too_dark (1966194696381394616) --> + <skip /> + <!-- no translation found for face_acquired_too_close (1401011882624272753) --> + <skip /> + <!-- no translation found for face_acquired_too_far (1210969240069012510) --> + <skip /> + <!-- no translation found for face_acquired_too_high (3362395713403348013) --> + <skip /> + <!-- no translation found for face_acquired_too_low (488983581737550912) --> + <skip /> + <!-- no translation found for face_acquired_too_right (941726879175375970) --> + <skip /> + <!-- no translation found for face_acquired_too_left (5873592047381190672) --> + <skip /> + <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) --> + <skip /> + <!-- no translation found for face_acquired_not_detected (4885504661626728809) --> + <skip /> + <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) --> + <skip /> <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Қайта тіркеліңіз."</string> - <string name="face_acquired_too_different" msgid="5553210341111255124">"Басқа адамның беті анықталды."</string> + <!-- no translation found for face_acquired_too_different (7663983770123789694) --> + <skip /> <string name="face_acquired_too_similar" msgid="1508776858407646460">"Алдыңғысына тым ұқсас, басқаша қалыпта түсіңіз."</string> - <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Камераға тура қараңыз."</string> - <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Камераға тура қараңыз."</string> + <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) --> + <skip /> + <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Басыңызды тік ұстаңыз."</string> - <string name="face_acquired_obscured" msgid="3055077697850272097">"Бетіңізді жаппаңыз."</string> + <!-- no translation found for face_acquired_obscured (5747521031647744553) --> + <skip /> + <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) --> + <skip /> <string-array name="face_acquired_vendor"> </string-array> <string name="face_error_hw_not_available" msgid="6255891785768984615">"Бетті тану жабдығы қолжетімді емес."</string> - <string name="face_error_timeout" msgid="4014326147867150054">"Күту уақыты бітті. Әрекетті қайталаңыз."</string> + <!-- no translation found for face_error_timeout (2605673935810019129) --> + <skip /> <string name="face_error_no_space" msgid="8224993703466381314">"Бетті сақтау мүмкін емес."</string> <string name="face_error_canceled" msgid="283945501061931023">"Бетті танудан бас тартылды."</string> <string name="face_error_user_canceled" msgid="8943921120862164539">"Пайдаланушы бетті тану әрекетінен бас тартты."</string> <string name="face_error_lockout" msgid="3407426963155388504">"Тым көп әрекет жасалды. Кейінірек қайталаңыз."</string> <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Тым көп әрекет жасалды. Бетті тану функциясы өшірілді."</string> - <string name="face_error_unable_to_process" msgid="238761109287767270">"Қайталап көріңіз."</string> - <string name="face_error_not_enrolled" msgid="9166792142679691323">"Ешқандай бет тіркелмеген."</string> - <string name="face_error_hw_not_present" msgid="916085883581450331">"Бұл құрылғыда бетті тану датчигі жоқ."</string> + <!-- no translation found for face_error_unable_to_process (4940944939691171539) --> + <skip /> + <!-- no translation found for face_error_not_enrolled (4245760276260427472) --> + <skip /> + <!-- no translation found for face_error_hw_not_present (5296043240874659926) --> + <skip /> <string name="face_name_template" msgid="7004562145809595384">"<xliff:g id="FACEID">%d</xliff:g> беті"</string> <string-array name="face_error_vendor"> </string-array> @@ -1213,9 +1246,16 @@ <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g> қолданбасын ашу"</string> <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> қолданбасының жұмысы сақталмай жабылады"</string> <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> жад шегінен асты"</string> + <!-- no translation found for dump_heap_ready_notification (1162196579925048701) --> + <skip /> <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Үйінді дамп жиналды. Бөлісу үшін түртіңіз."</string> <string name="dump_heap_title" msgid="5864292264307651673">"Үйінді дамппен бөлісу қажет пе?"</string> - <string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g> процесі <xliff:g id="SIZE">%2$s</xliff:g> процесс жады шегінен асып кетті. Үйінді дамп оның әзірлеушісімен бөлісуге қолжетімді. Абай болыңыз: бұл үйінді дампта бағдарлама кіре алатын кейбір жеке ақпараттарыңыз болуы мүмкін."</string> + <!-- no translation found for dump_heap_text (8546022920319781701) --> + <skip /> + <!-- no translation found for dump_heap_system_text (1205466256312104134) --> + <skip /> + <!-- no translation found for dump_heap_ready_text (6759394977904051000) --> + <skip /> <string name="sendText" msgid="5209874571959469142">"Мәтін үшін әрекет таңдау"</string> <string name="volume_ringtone" msgid="6885421406845734650">"Қоңырау шырылының қаттылығы"</string> <string name="volume_music" msgid="5421651157138628171">"Meдиа дыбысының қаттылығы"</string> @@ -1254,8 +1294,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Барлық желілерді көру үшін түртіңіз"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Қосылу"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Барлық желілер"</string> - <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g> ұсынған Wi‑Fi желісі қолжетімді"</string> - <string name="wifi_suggestion_content" msgid="2658317015552324848">"<xliff:g id="NAME">%s</xliff:g> ұсынған желілерге қосылғыңыз келе ме?"</string> + <!-- no translation found for wifi_suggestion_title (9099832833531486167) --> + <skip /> + <!-- no translation found for wifi_suggestion_content (5883181205841582873) --> + <skip /> <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Иә"</string> <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Жоқ"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi автоматты түрде қосылады"</string> @@ -1267,9 +1309,14 @@ <string name="network_available_sign_in" msgid="1848877297365446605">"Желіге кіру"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> <skip /> - <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi желісінде интернет байланысы жоқ"</string> + <!-- no translation found for wifi_no_internet (5198100389964214865) --> + <skip /> <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Опциялар үшін түртіңіз"</string> <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Жалғанды"</string> + <!-- no translation found for network_partial_connectivity (7774883385494762741) --> + <skip /> + <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) --> + <skip /> <string name="wifi_softap_config_change" msgid="8475911871165857607">"Хотспот параметрлеріне өзгерістер енгізілді"</string> <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Хотспот жолағы өзгертілді."</string> <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Бұл құрылғы тек 5 ГГц жиілікте жұмыс істей алмайды. Бұл жиілік мүмкін болған жағдайда ғана қолданылады."</string> @@ -1355,6 +1402,10 @@ <string name="adb_active_notification_title" msgid="6729044778949189918">"USB түзетуі қосылған"</string> <string name="adb_active_notification_message" msgid="7463062450474107752">"USB арқылы түзетуді өшіру үшін түртіңіз"</string> <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB түзетуін өшіру үшін таңдаңыз."</string> + <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) --> + <skip /> + <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) --> + <skip /> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB портына сұйықтық немесе қоқыс кірді"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB порты автоматты түрде өшірілді. Толығырақ ақпарат алу үшін түртіңіз."</string> <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB портын пайдалана беруге болады"</string> @@ -1906,8 +1957,6 @@ <string name="profile_encrypted_message" msgid="6964994232310195874">"Жұмыс профилінің құлпын ашу үшін түртіңіз"</string> <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> қосылу орындалды"</string> <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Файлдарды көру үшін түртіңіз"</string> - <string name="pin_target" msgid="3052256031352291362">"PIN коды"</string> - <string name="unpin_target" msgid="3556545602439143442">"Босату"</string> <string name="app_info" msgid="6856026610594615344">"Қолданба ақпараты"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="demo_starting_message" msgid="5268556852031489931">"Демо нұсқасы іске қосылуда..."</string> @@ -1998,6 +2047,22 @@ <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Режим туралы хабарландыру"</string> <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Батарея заряды азаюы мүмкін"</string> <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Батарея ұзаққа жетуі үшін, Battery Saver іске қосылды"</string> + <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) --> + <skip /> + <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) --> + <skip /> + <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) --> + <skip /> <string name="mime_type_folder" msgid="7111951698626315204">"Қалта"</string> <string name="mime_type_apk" msgid="5518003630972506900">"Android қолданбасы"</string> <string name="mime_type_generic" msgid="6833871596845900027">"Файл"</string> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index c8d43963fe0b..5c1fe245ebb3 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -141,8 +141,10 @@ <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"ವೈಫೈ ಕರೆ ಮಾಡುವಿಕೆ"</string> <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string> <string name="wifi_calling_off_summary" msgid="8720659586041656098">"ಆಫ್"</string> - <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"ವೈ-ಫೈಗೆ ಆದ್ಯತೆ"</string> - <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"ಮೊಬೈಲ್ಗೆ ಆದ್ಯತೆ"</string> + <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) --> + <skip /> + <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) --> + <skip /> <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"ವೈ-ಫೈ ಮಾತ್ರ"</string> <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ಫಾರ್ವರ್ಡ್ ಮಾಡಲಾಗಿಲ್ಲ"</string> <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> @@ -228,7 +230,8 @@ <string name="global_action_bug_report" msgid="7934010578922304799">"ದೋಷದ ವರದಿ"</string> <string name="global_action_logout" msgid="935179188218826050">"ಸೆಷನ್ ಅಂತ್ಯಗೊಳಿಸಿ"</string> <string name="global_action_screenshot" msgid="8329831278085426283">"ಸ್ಕ್ರೀನ್ಶಾಟ್"</string> - <string name="bugreport_title" msgid="2667494803742548533">"ದೋಷ ವರದಿ ರಚಿಸಿ"</string> + <!-- no translation found for bugreport_title (5981047024855257269) --> + <skip /> <string name="bugreport_message" msgid="398447048750350456">"ನಿಮ್ಮ ಸಾಧನದ ಪ್ರಸ್ತುತ ಸ್ಥಿತಿಯ ಕುರಿತು ಮಾಹಿತಿಯನ್ನು ಸಂಗ್ರಹಿಸಿಕೊಳ್ಳುವುದರ ಜೊತೆ ಇ-ಮೇಲ್ ರೂಪದಲ್ಲಿ ನಿಮಗೆ ರವಾನಿಸುತ್ತದೆ. ಇದು ದೋಷ ವರದಿಯನ್ನು ಪ್ರಾರಂಭಿಸಿದ ಸಮಯದಿಂದ ಅದನ್ನು ಕಳುಹಿಸುವವರೆಗೆ ಸ್ವಲ್ಪ ಸಮಯವನ್ನು ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆ; ದಯವಿಟ್ಟು ತಾಳ್ಮೆಯಿಂದಿರಿ."</string> <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"ಪರಸ್ಪರ ಸಂವಹನ ವರದಿ"</string> <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"ಹೆಚ್ಚಿನ ಸಂದರ್ಭಗಳಲ್ಲಿ ಇದನ್ನು ಬಳಸಿ. ಇದು ವರದಿಯ ಪ್ರಗತಿಯನ್ನು ಟ್ರ್ಯಾಕ್ ಮಾಡಲು, ಸಮಸ್ಯೆ ಕುರಿತು ಹೆಚ್ಚಿನ ವಿವರಗಳನ್ನು ನಮೂದಿಸಲು ಮತ್ತು ಸ್ಕ್ರೀನ್ಶಾಟ್ಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳಲು ಅನುಮತಿಸುತ್ತದೆ. ಇದು ವರದಿ ಮಾಡಲು ಹೆಚ್ಚು ಸಮಯ ತೆಗೆದುಕೊಳ್ಳುವಂತಹ ಕೆಲವು ಕಡಿಮೆ ಬಳಸಲಾದ ವಿಭಾಗಗಳನ್ನು ತ್ಯಜಿಸಬಹುದು."</string> @@ -281,9 +284,12 @@ <string name="permgrouplab_location" msgid="7275582855722310164">"ಸ್ಥಳ"</string> <string name="permgroupdesc_location" msgid="1346617465127855033">"ಈ ಸಾಧನದ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಿ"</string> <string name="permgrouprequest_location" msgid="3788275734953323491">"ಈ ಸಾಧನದ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಲು <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ಗೆ ಅನುಮತಿಸಬೇಕೇ?"</string> - <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"ನೀವು ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಬಳಸುವಾಗ ಈ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಳಕ್ಕೆ ಮಾತ್ರ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿರುತ್ತದೆ."</string> - <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"ಈ ಸಾಧನದ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಲು ಯಾವಾಗಲೂ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ಗೆ ಅನುಮತಿಸಬೇಕೇ?"</string> - <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"ನೀವು ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಬಳಸದಿರುವಾಗಲೂ ಅಪ್ಲಿಕೇಶನ್ ಯಾವಾಗಲೂ ಸ್ಥಳಕ್ಕೆ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿರುತ್ತದೆ."</string> + <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) --> + <skip /> <string name="permgrouplab_calendar" msgid="5863508437783683902">"ಕ್ಯಾಲೆಂಡರ್"</string> <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಪ್ರವೇಶಿಸಲು"</string> <string name="permgrouprequest_calendar" msgid="289900767793189421">"ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಪ್ರವೇಶಿಸಲು <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ಗೆ ಅನುಮತಿಸಬೇಕೇ?"</string> @@ -316,7 +322,10 @@ <string name="permgrouprequest_aural" msgid="6787926123071735620">"ನಿಮ್ಮ ಸಂಗೀತವನ್ನು ಪ್ರವೇಶಿಸಲು <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ಗೆ ಅನುಮತಿಸಬೇಕೇ?"</string> <string name="permgrouplab_visual" msgid="6477382108771145134">"ಫೋಟೋಗಳು ಮತ್ತು ವೀಡಿಯೊಗಳು"</string> <string name="permgroupdesc_visual" msgid="3415827902566663546">"ನಿಮ್ಮ ಫೋಟೋಗಳು & ವೀಡಿಯೊಗಳನ್ನು ಪ್ರವೇಶಿಸಿ"</string> - <string name="permgrouprequest_visual" msgid="3043752127595243314">"ಟ್ಯಾಗ್ ಮಾಡಿದ ಸ್ಥಳಗಳೂ ಸೇರಿದಂತೆ ನಿಮ್ಮ ಫೋಟೋಗಳು ಹಾಗೂ ವೀಡಿಯೊಗಳಿಗೆ ಪ್ರವೇಶ ಪಡೆಯಲು <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ಗೆ ಅನುಮತಿ ನೀಡಬೇಕೇ?"</string> + <!-- no translation found for permgrouprequest_visual (4926581398380334943) --> + <skip /> + <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) --> + <skip /> <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ವಿಂಡೋ ವಿಷಯವನ್ನು ಹಿಂಪಡೆಯುತ್ತದೆ"</string> <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ನೀವು ಬಳಸುತ್ತಿರುವ ವಿಂಡೋದ ವಿಷಯ ಪರೀಕ್ಷಿಸುತ್ತದೆ."</string> <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ಸ್ಪರ್ಶ-ಎಕ್ಸ್ಪ್ಲೋರ್ ಆನ್ ಮಾಡುತ್ತದೆ"</string> @@ -509,8 +518,10 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"ಸಮೀಪದ ಕ್ಷೇತ್ರ ಸಂವಹನ (NFC) ಟ್ಯಾಗ್ಗಳು, ಕಾರ್ಡ್ಗಳು, ಮತ್ತು ಓದುಗರನ್ನು ಅಪ್ಲಿಕೇಶನ್ ಅನುಮತಿಸುತ್ತದೆ."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"ಕೀಲಾಕ್ ಮತ್ತು ಯಾವುದೇ ಸಂಬಂಧಿತ ಭದ್ರತಾ ಪಾಸ್ವರ್ಡ್ ಭದ್ರತೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿ ನೀಡುತ್ತದೆ. ಉದಾಹರಣೆಗೆ, ಒಳಬರುವ ಕರೆಯನ್ನು ಸ್ವೀಕರಿಸುವಾಗ ಕೀಲಾಕ್ ಅನ್ನು ಫೋನ್ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ, ನಂತರ ಕರೆಯು ಅಂತ್ಯಗೊಂಡಾಗ ಕೀಲಾಕ್ ಅನ್ನು ಮರು ಸಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ."</string> - <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಸಂಕೀರ್ಣತೆಯನ್ನು ವಿನಂತಿಸಿ"</string> - <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"ಆ್ಯಪ್ಗೆ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಸಂಕೀರ್ಣತೆ ಮಟ್ಟವನ್ನು ತಿಳಿದುಕೊಳ್ಳಲು ಅನುಮತಿಸುತ್ತದೆ (ಹೆಚ್ಚು, ಮಧ್ಯಮ, ಕಡಿಮೆ ಅಥವಾ ಯಾವುದೂ ಅಲ್ಲ), ಇದು ಉದ್ದದ ಸಂಭವನೀಯ ಶ್ರೇಣಿ ಮತ್ತು ಸ್ಕ್ರೀನ್ ಲಾಕ್ನ ವಿಧವನ್ನು ಸೂಚಿಸುತ್ತದೆ. ಬಳಕೆದಾರರು ನಿರ್ದಿಷ್ಟ ಮಟ್ಟದವರೆಗೆ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಬಹುದು ಎಂಬುದಾಗಿ ಕೂಡ ಆ್ಯಪ್ ಬಳಕೆದಾರರಿಗೆ ಸಲಹೆ ಮಾಡುತ್ತದೆ ಆದರೆ ಬಳಕೆದಾರರು ಮುಕ್ತವಾಗಿ ತಿರಸ್ಕರಿಸಬಹುದು ಮತ್ತು ನ್ಯಾವಿಗೇಟ್ ಮಾಡಬಹುದು. ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ಖಾಲಿಪಠ್ಯದಲ್ಲಿ ಸಂಗ್ರಹಿಸಿಲ್ಲ ಎಂಬುದನ್ನು ಗಮನಿಸಿ, ಇದರಿಂದ ಆ್ಯಪ್ಗೆ ಸರಿಯಾದ ಪಾಸ್ವರ್ಡ್ ಗೊತ್ತಿರುವುದಿಲ್ಲ."</string> + <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) --> + <skip /> + <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) --> + <skip /> <string name="permlab_useBiometric" msgid="8837753668509919318">"ಬಯೋಮೆಟ್ರಿಕ್ ಹಾರ್ಡ್ವೇರ್ ಬಳಸಿ"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"ಪ್ರಮಾಣೀಕರಣಕ್ಕಾಗಿ ಬಯೋಮೆಟ್ರಿಕ್ ಹಾರ್ಡ್ವೇರ್ ಬಳಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"ಬೆರಳಚ್ಚು ಹಾರ್ಡ್ವೇರ್ ನಿರ್ವಹಿಸಿ"</string> @@ -565,37 +576,59 @@ <string name="permdesc_manageFace" msgid="8919637120670185330">"ಬಳಕೆಗೆ ಮುಖದ ಟೆಂಪ್ಲೇಟ್ಗಳನ್ನು ಸೇರಿಸಲು ಮತ್ತು ಅಳಿಸಲು ವಿಧಾನಗಳನ್ನು ಮನವಿ ಮಾಡಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string> <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"ಮುಖ ದೃಢೀಕರಣ ಹಾರ್ಡ್ವೇರ್ ಅನ್ನು ಬಳಸಿ"</string> <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"ಧೃಡೀಕರಣಕ್ಕಾಗಿ ಮುಖದ ಹಾರ್ಡ್ವೇರ್ ಬಳಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string> - <string name="face_acquired_insufficient" msgid="5901287247766106330">"ಮುಖವನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string> - <string name="face_acquired_too_bright" msgid="610606792381297174">"ಮುಖವು ತುಂಬಾ ಪ್ರಕಾಶಮಾನವಾಗಿದೆ. ಕಡಿಮೆ ಲೈಟ್ನಲ್ಲಿ ಪ್ರಯತ್ನಿಸಿ."</string> - <string name="face_acquired_too_dark" msgid="7229162716976778371">"ಮುಖ ತುಂಬಾ ಕಪ್ಪಾಗಿದೆ. ನೇರವಾಗಿ ಬೆಳಕು ಬಿಳುವಂತೆ ಮಾಡಿ."</string> - <string name="face_acquired_too_close" msgid="1980310037427755293">"ಮುಖದಿಂದ ಸೆನ್ಸರ್ ಅನ್ನು ದೂರ ಸರಿಸಿ."</string> - <string name="face_acquired_too_far" msgid="4494571381828850007">"ಸೆನ್ಸರ್ ಅನ್ನು ಮುಖದ ಹತ್ತಿರಕ್ಕೆ ತನ್ನಿ."</string> - <string name="face_acquired_too_high" msgid="228411096134808372">"ಸೆನ್ಸರ್ ಅನ್ನು ಮೇಲಕ್ಕೆ ಸರಿಸಿ."</string> - <string name="face_acquired_too_low" msgid="4539774649296349109">"ಸೆನ್ಸರ್ ಅನ್ನು ಕೆಳಕ್ಕೆ ಸರಿಸಿ."</string> - <string name="face_acquired_too_right" msgid="1650292067226118760">"ಸೆನ್ಸರ್ ಅನ್ನು ಬಲಕ್ಕೆ ಸರಿಸಿ."</string> - <string name="face_acquired_too_left" msgid="2712489669456176505">"ಸೆನ್ಸರ್ ಅನ್ನು ಎಡಕ್ಕೆ ಸರಿಸಿ."</string> - <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"ಸೆನ್ಸರ್ ಅನ್ನು ನೋಡಿ."</string> - <string name="face_acquired_not_detected" msgid="5707782294589511391">"ಯಾವುದೇ ಮುಖ ಪತ್ತೆಯಾಗಿಲ್ಲ."</string> - <string name="face_acquired_too_much_motion" msgid="470381210701463822">"ತುಂಬಾ ಚಲನೆ."</string> + <!-- no translation found for face_acquired_insufficient (2767330364802375742) --> + <skip /> + <!-- no translation found for face_acquired_too_bright (5005650874582450967) --> + <skip /> + <!-- no translation found for face_acquired_too_dark (1966194696381394616) --> + <skip /> + <!-- no translation found for face_acquired_too_close (1401011882624272753) --> + <skip /> + <!-- no translation found for face_acquired_too_far (1210969240069012510) --> + <skip /> + <!-- no translation found for face_acquired_too_high (3362395713403348013) --> + <skip /> + <!-- no translation found for face_acquired_too_low (488983581737550912) --> + <skip /> + <!-- no translation found for face_acquired_too_right (941726879175375970) --> + <skip /> + <!-- no translation found for face_acquired_too_left (5873592047381190672) --> + <skip /> + <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) --> + <skip /> + <!-- no translation found for face_acquired_not_detected (4885504661626728809) --> + <skip /> + <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) --> + <skip /> <string name="face_acquired_recalibrate" msgid="8077949502893707539">"ನಿಮ್ಮ ಮುಖವನ್ನು ಮರುನೋಂದಣಿ ಮಾಡಿ."</string> - <string name="face_acquired_too_different" msgid="5553210341111255124">"ವಿಭಿನ್ನ ಮುಖ ಪತ್ತೆಯಾಗಿದೆ."</string> + <!-- no translation found for face_acquired_too_different (7663983770123789694) --> + <skip /> <string name="face_acquired_too_similar" msgid="1508776858407646460">"ತುಂಬಾ ಸಮಾನ, ನಿಮ್ಮ ಪೋಸ್ ಬದಲಾಯಿಸಿ."</string> - <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"ಕ್ಯಾಮರಾ ಕಡೆ ಹೆಚ್ಚು ನೇರವಾಗಿ ನೋಡಿ."</string> - <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"ಕ್ಯಾಮರಾ ಕಡೆ ಹೆಚ್ಚು ನೇರವಾಗಿ ನೋಡಿ."</string> + <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) --> + <skip /> + <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"ನಿಮ್ಮ ತಲೆಯನ್ನು ವರ್ಟಿಕಲ್ ಆಗಿ ನೇರವಾಗಿಸಿ."</string> - <string name="face_acquired_obscured" msgid="3055077697850272097">"ನಿಮ್ಮ ಮುಖವನ್ನು ಬಹಿರಂಗಪಡಿಸಿ."</string> + <!-- no translation found for face_acquired_obscured (5747521031647744553) --> + <skip /> + <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) --> + <skip /> <string-array name="face_acquired_vendor"> </string-array> <string name="face_error_hw_not_available" msgid="6255891785768984615">"ಮುಖದ ಹಾರ್ಡ್ವೇರ್ ಲಭ್ಯವಿಲ್ಲ."</string> - <string name="face_error_timeout" msgid="4014326147867150054">"ಮುಖ ಸಮಯದ ಅವಧಿಯನ್ನು ತಲುಪಿದೆ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string> + <!-- no translation found for face_error_timeout (2605673935810019129) --> + <skip /> <string name="face_error_no_space" msgid="8224993703466381314">"ಮುಖವನ್ನು ಸಂಗ್ರಹಿಸಲಾಗುವುದಿಲ್ಲ."</string> <string name="face_error_canceled" msgid="283945501061931023">"ಮುಖದ ಕಾರ್ಯಚರಣೆಯನ್ನು ರದ್ದುಗೊಳಿಸಲಾಗಿದೆ."</string> <string name="face_error_user_canceled" msgid="8943921120862164539">"ಮುಖ ದೃಢೀಕರಣವನ್ನು ಬಳಕೆದಾರರ ಮೂಲಕ ರದ್ದುಗೊಳಿಸಲಾಗಿದೆ."</string> <string name="face_error_lockout" msgid="3407426963155388504">"ಹಲವು ಬಾರಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ನಂತರ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string> <string name="face_error_lockout_permanent" msgid="8198354656746088890">"ಹಲವು ಪ್ರಯತ್ನ. ಮುಖದ ದೃಢೀಕರಣ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string> - <string name="face_error_unable_to_process" msgid="238761109287767270">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string> - <string name="face_error_not_enrolled" msgid="9166792142679691323">"ಯಾವುದೇ ಮುಖವನ್ನು ನೋಂದಣಿ ಮಾಡಿಲ್ಲ."</string> - <string name="face_error_hw_not_present" msgid="916085883581450331">"ಈ ಸಾಧನವು ಮುಖ ಪ್ರಮಾಣೀಕರಣ ಸೆನ್ಸರ್ ಅನ್ನು ಹೊಂದಿಲ್ಲ."</string> + <!-- no translation found for face_error_unable_to_process (4940944939691171539) --> + <skip /> + <!-- no translation found for face_error_not_enrolled (4245760276260427472) --> + <skip /> + <!-- no translation found for face_error_hw_not_present (5296043240874659926) --> + <skip /> <string name="face_name_template" msgid="7004562145809595384">"ಮುಖದ <xliff:g id="FACEID">%d</xliff:g>"</string> <string-array name="face_error_vendor"> </string-array> @@ -1213,9 +1246,16 @@ <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g> ಅನ್ನು ತೆರೆಯಿರಿ"</string> <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> ಅನ್ನು ಉಳಿಸದೆಯೇ ಮುಚ್ಚಲಾಗುತ್ತದೆ"</string> <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> ಮೆಮೊರಿ ಮಿತಿಯನ್ನು ಮೀರಿದೆ"</string> + <!-- no translation found for dump_heap_ready_notification (1162196579925048701) --> + <skip /> <string name="dump_heap_notification_detail" msgid="3993078784053054141">"ಹೀಪ್ ಡಂಪ್ ಅನ್ನು ಸಂಗ್ರಹಿಸಲಾಗಿದೆ; ಹಂಚಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="dump_heap_title" msgid="5864292264307651673">"ಹೀಪ್ ಡಂಪ್ ಹಂಚಿಕೊಳ್ಳುವುದೇ?"</string> - <string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g> ಪ್ರಕ್ರಿಯೆಯು <xliff:g id="SIZE">%2$s</xliff:g> ರ ಪ್ರಕ್ರಿಯೆ ಮೆಮೊರಿ ಮಿತಿಯನ್ನು ಮೀರಿದೆ. ನೀವು ಅದರ ಡೆವಲಪರ್ ಜೊತೆ ಹಂಚಿಕೊಳ್ಳಲು ಹೀಪ್ ಡಂಪ್ ಲಭ್ಯವಿದೆ. ಎಚ್ಚರಿಕೆ: ಈ ಹೀಪ್ ಡಂಪ್ ಅಪ್ಲಿಕೇಶನ್ ಪ್ರವೇಶ ಹೊಂದಿರುವ ನಿಮ್ಮ ಯಾವುದೇ ವೈಯಕ್ತಿಕ ಮಾಹಿತಿಯನ್ನು ಹೊಂದಿರಬಹುದು."</string> + <!-- no translation found for dump_heap_text (8546022920319781701) --> + <skip /> + <!-- no translation found for dump_heap_system_text (1205466256312104134) --> + <skip /> + <!-- no translation found for dump_heap_ready_text (6759394977904051000) --> + <skip /> <string name="sendText" msgid="5209874571959469142">"ಪಠ್ಯಕ್ಕೆ ಕ್ರಿಯೆಯನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string> <string name="volume_ringtone" msgid="6885421406845734650">"ರಿಂಗರ್ ವಾಲ್ಯೂಮ್"</string> <string name="volume_music" msgid="5421651157138628171">"ಮೀಡಿಯಾ ವಾಲ್ಯೂಮ್"</string> @@ -1254,8 +1294,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ಎಲ್ಲಾ ನೆಟ್ವರ್ಕ್ಗಳನ್ನು ನೋಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"ಸಂಪರ್ಕಿಸಿ"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"ಎಲ್ಲಾ ನೆಟ್ವರ್ಕ್ಗಳು"</string> - <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g> ಅವರು ಪ್ರಸ್ತಾಪಿಸಿದ ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ ಲಭ್ಯವಿದೆ"</string> - <string name="wifi_suggestion_content" msgid="2658317015552324848">"<xliff:g id="NAME">%s</xliff:g> ಅವರು ಪ್ರಸ್ತಾಪಿಸಿದ ನೆಟ್ವರ್ಕ್ಗಳಿಗೆ ನೀವು ಸಂಪರ್ಕಿಸಲು ಬಯಸುವಿರಾ?"</string> + <!-- no translation found for wifi_suggestion_title (9099832833531486167) --> + <skip /> + <!-- no translation found for wifi_suggestion_content (5883181205841582873) --> + <skip /> <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"ಹೌದು"</string> <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"ಇಲ್ಲ"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"ವೈ‑ಫೈ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಆನ್ ಆಗುತ್ತದೆ"</string> @@ -1267,9 +1309,14 @@ <string name="network_available_sign_in" msgid="1848877297365446605">"ನೆಟ್ವರ್ಕ್ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> <skip /> - <string name="wifi_no_internet" msgid="8938267198124654938">"ವೈ ಫೈ ಯಾವುದೇ ಇಂಟರ್ನೆಟ್ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿಲ್ಲ"</string> + <!-- no translation found for wifi_no_internet (5198100389964214865) --> + <skip /> <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"ಆಯ್ಕೆಗಳಿಗೆ ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"ಸಂಪರ್ಕಿಸಲಾಗಿದೆ"</string> + <!-- no translation found for network_partial_connectivity (7774883385494762741) --> + <skip /> + <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) --> + <skip /> <string name="wifi_softap_config_change" msgid="8475911871165857607">"ನಿಮ್ಮ ಹಾಟ್ಸ್ಪಾಟ್ ಸೆಟ್ಟಿಂಗ್ಗಳಿಗೆ ಬದಲಾವಣೆಗಳು"</string> <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"ನಿಮ್ಮ ಹಾಟ್ಸ್ಪಾಟ್ ಬ್ಯಾಂಡ್ ಬದಲಾಗಿದೆ."</string> <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"ಈ ಸಾಧನವು 5GHz ಗೆ ಮಾತ್ರ ನಿಮ್ಮ ಆದ್ಯತೆಯನ್ನು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ. ಬದಲಿಗೆ, ಈ ಸಾಧನವು 5GHz ಬ್ಯಾಂಡ್ ಅನ್ನು ಲಭ್ಯವಿರುವಾಗ ಬಳಸುತ್ತದೆ."</string> @@ -1352,9 +1399,13 @@ <string name="usb_power_notification_message" msgid="4647527153291917218">"ಸಂಪರ್ಕಗೊಂಡಿರುವ ಸಾಧನವನ್ನು ಚಾರ್ಜ್ ಮಾಡಲಾಗುತ್ತಿದೆ. ಹೆಚ್ಚಿನ ಆಯ್ಕೆಗಳಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ."</string> <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"ಅನ್ಲಾಗ್ ಆಡಿಯೋ ಪರಿಕರ ಪತ್ತೆಯಾಗಿದೆ"</string> <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"ಲಗತ್ತಿಸಲಾದ ಸಾಧನವು ಈ ಫೋನಿನೊಂದಿಗೆ ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ. ಇನ್ನಷ್ಟು ತಿಳಿಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string> - <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ಡೀಬಗಿಂಗ್ ಸಂಪರ್ಕ"</string> + <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ಡೀಬಗಿಂಗ್ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string> <string name="adb_active_notification_message" msgid="7463062450474107752">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು ಆಫ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಆಯ್ಕೆ ಮಾಡಿ."</string> + <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) --> + <skip /> + <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) --> + <skip /> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB ಪೋರ್ಟ್ನಲ್ಲಿ ದ್ರವ ಅಥವಾ ಧೂಳಿನ ಕಣಗಳಿವೆ"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ಪೋರ್ಟ್ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಂಡಿದೆ. ಇನ್ನಷ್ಟು ತಿಳಿಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB ಪೋರ್ಟ್ ಬಳಸಲು ಸುರಕ್ಷಿತವಾಗಿದೆ"</string> @@ -1397,8 +1448,7 @@ <string name="ext_media_init_action" msgid="7952885510091978278">"ಹೊಂದಿಸು"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"ಇಜೆಕ್ಟ್"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"ಎಕ್ಸ್ಪ್ಲೋರ್"</string> - <!-- no translation found for ext_media_seamless_action (6575980560886881233) --> - <skip /> + <string name="ext_media_seamless_action" msgid="6575980560886881233">"ಔಟ್ಪುಟ್ಗೆ ಬದಲಿಸಿ"</string> <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> ಕಾಣೆಯಾಗಿದೆ"</string> <string name="ext_media_missing_message" msgid="4012389235250987930">"ಸಾಧನವನ್ನು ಪುನಃ ಸೇರಿಸಿ"</string> <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> ಸರಿಸಲಾಗುತ್ತಿದೆ"</string> @@ -1907,8 +1957,6 @@ <string name="profile_encrypted_message" msgid="6964994232310195874">"ಕೆಲಸದ ಪ್ರೊಫೈಲ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> ಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string> <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ಫೈಲ್ಗಳನ್ನು ವೀಕ್ಷಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string> - <string name="pin_target" msgid="3052256031352291362">"ಪಿನ್ ಮಾಡು"</string> - <string name="unpin_target" msgid="3556545602439143442">"ಅನ್ಪಿನ್"</string> <string name="app_info" msgid="6856026610594615344">"ಅಪ್ಲಿಕೇಶನ್ ಮಾಹಿತಿ"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="demo_starting_message" msgid="5268556852031489931">"ಡೆಮೋ ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ..."</string> @@ -1999,6 +2047,22 @@ <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"ದೈನಂದಿನ ಸ್ಥಿತಿಯ ಮಾಹಿತಿಯ ಅಧಿಸೂಚನೆ"</string> <string name="dynamic_mode_notification_title" msgid="508815255807182035">"ಚಾರ್ಜ್ಗೆ ಮೊದಲೆ ಬ್ಯಾಟರಿ ಮುಗಿದು ಬಿಡಬಹುದು"</string> <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"ಬ್ಯಾಟರಿ ಅವಧಿ ಹೆಚ್ಚಿಸಲು ಬ್ಯಾಟರಿ ಸೇವರ್ ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string> + <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) --> + <skip /> + <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) --> + <skip /> + <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) --> + <skip /> <string name="mime_type_folder" msgid="7111951698626315204">"ಫೋಲ್ಡರ್"</string> <string name="mime_type_apk" msgid="5518003630972506900">"Android ಆ್ಯಪ್"</string> <string name="mime_type_generic" msgid="6833871596845900027">"ಫೈಲ್"</string> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index 938c53972fa5..e27883234376 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -141,8 +141,10 @@ <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"वायफाय कॉलिंग"</string> <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string> <string name="wifi_calling_off_summary" msgid="8720659586041656098">"बंद"</string> - <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"वाय-फाय अग्रमानांकित"</string> - <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"प्राधान्य दिलेला मोबाइल"</string> + <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) --> + <skip /> + <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) --> + <skip /> <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"केवळ वाय-फाय"</string> <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: अग्रेषित केला नाही"</string> <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> @@ -228,7 +230,8 @@ <string name="global_action_bug_report" msgid="7934010578922304799">"बग रीपोर्ट"</string> <string name="global_action_logout" msgid="935179188218826050">"सेशन समाप्त करा"</string> <string name="global_action_screenshot" msgid="8329831278085426283">"स्क्रीनशॉट"</string> - <string name="bugreport_title" msgid="2667494803742548533">"बग रीपोर्ट घ्या"</string> + <!-- no translation found for bugreport_title (5981047024855257269) --> + <skip /> <string name="bugreport_message" msgid="398447048750350456">"ई-मेल मेसेज म्हणून पाठविण्यासाठी, हे तुमच्या सद्य डिव्हाइस स्थितीविषयी माहिती संकलित करेल. बग रीपोर्ट सुरू करण्यापासून तो पाठविण्यापर्यंत थोडा वेळ लागेल; कृपया धीर धरा."</string> <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"परस्परसंवादी अहवाल"</string> <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"बहुतांश प्रसंगांमध्ये याचा वापर करा. ते तुम्हाला अहवालाच्या प्रगतीचा मागोवा घेण्याची, समस्येविषयी आणखी तपाशील एंटर करण्याची आणि स्क्रीनशॉट घेण्याची अनुमती देते. ते कदाचित अहवाल देण्यासाठी बराच वेळ घेणारे कमी-वापरलेले विभाग वगळू शकते."</string> @@ -281,9 +284,12 @@ <string name="permgrouplab_location" msgid="7275582855722310164">"स्थान"</string> <string name="permgroupdesc_location" msgid="1346617465127855033">"या डिव्हाइसच्या स्थानावर प्रवेश"</string> <string name="permgrouprequest_location" msgid="3788275734953323491">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ला या डिव्हाइसचे स्थान अॅक्सेस करू द्यायचे?"</string> - <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"तुम्ही अॅप वापरत असताना, अॅपला फक्त स्थानाचा अॅक्सेस असेल."</string> - <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"या डिव्हाइसचे स्थान अॅक्सेस करण्याची <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ला नेहेमी अनुमती द्यायची का?"</string> - <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"तुम्ही अॅप वापरत नसलात तरीही, अॅपला स्थानाचा नेहेमी अॅक्सेस असेल."</string> + <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) --> + <skip /> <string name="permgrouplab_calendar" msgid="5863508437783683902">"कॅलेंडर"</string> <string name="permgroupdesc_calendar" msgid="3889615280211184106">"आपल्या कॅलेंडरवर प्रवेश"</string> <string name="permgrouprequest_calendar" msgid="289900767793189421">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ला तुमचे कॅलेंडर अॅक्सेस करू द्यायचे?"</string> @@ -316,7 +322,10 @@ <string name="permgrouprequest_aural" msgid="6787926123071735620">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ला तुमचे संगीत अॅक्सेस करू द्यायचे का?"</string> <string name="permgrouplab_visual" msgid="6477382108771145134">"फोटो आणि व्हिडिओ"</string> <string name="permgroupdesc_visual" msgid="3415827902566663546">"तुमचे फोटो आणि व्हिडिओ अॅक्सेस करा"</string> - <string name="permgrouprequest_visual" msgid="3043752127595243314">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ला टॅग केलेल्या स्थानांसह तुमचे फोटो आणि व्हिडिओ अॅक्सेस करण्याची अनुमती द्यायची का?"</string> + <!-- no translation found for permgrouprequest_visual (4926581398380334943) --> + <skip /> + <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) --> + <skip /> <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"विंडोमधील आशय पुन्हा मिळवा"</string> <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"तुम्ही वापरत असलेल्या विंडोमधील आशय तपासा."</string> <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"स्पर्श करून अन्वेषण चालू करा"</string> @@ -509,8 +518,10 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"फील्ड जवळील कम्युनिकेशन (NFC) टॅग, कार्डे आणि वाचक यांच्यासह संवाद करण्यासाठी अॅपला अनुमती देते."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"तुमचे स्क्रीन लॉक अक्षम करा"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"कीलॉक आणि कोणतीही संबद्ध पासवर्ड सुरक्षितता अक्षम करण्यासाठी अॅप ला अनुमती देते. उदाहरणार्थ, येणारा फोन कॉल प्राप्त करताना फोन कीलॉक अक्षम करतो, नंतर जेव्हा कॉल समाप्त होतो तेव्हा तो कीलॉक पुन्हा-सक्षम करतो."</string> - <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"स्क्रीन लॉक क्लिष्टतेची विनंती करा"</string> - <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"अॅपला स्क्रीन लॉक कितपात क्लिष्ट आहे (खूप, मध्यम, कमी किंवा अजिबात नाही) हे जाणून घेण्याची अनुमती देते, जी वर्णांची साधारण रेंज आणि स्क्रीन लॉकचा प्रकार सूचित करते. अॅप वापरकर्त्यांना असे देखील सुचवू शकते की त्यांनी स्क्रीन लॉक ठराविक पातळीपर्यंत अपडेट करावे पण वापरकर्ते त्याकडे दुर्लक्षत करू शकतात आणि तेथून नेव्हिगेट करू शकता. लक्षात ठेवा की, स्क्रीन लॉक प्लेनटेक्स्टमध्ये स्टोअर केले जात नसल्यामुळे अॅपला नेमका पासवर्ड माहीत नसतो."</string> + <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) --> + <skip /> + <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) --> + <skip /> <string name="permlab_useBiometric" msgid="8837753668509919318">"बायोमेट्रिक हार्डवेअर वापरा"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"ऑथेंटिकेशनसाठी बायोमेट्रिक हार्डवेअरचा वापर करण्याची अॅपला अनुमती देते"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"फिंगरप्रिंट हार्डवेअर व्यवस्थापित करा"</string> @@ -565,37 +576,59 @@ <string name="permdesc_manageFace" msgid="8919637120670185330">"अॅपला वापरासाठी चेहरा टेम्पलेट जोडण्याच्या आणि हटवण्याच्या पद्धती जारी करू देते."</string> <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"चेहरा ऑथेंटिकेशन हार्डवेअर वापरा"</string> <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"अॅपला चेहरा ऑथेंटिकेशनसाठी ऑथेंटिकेशन हार्डवेअर वापरू देते"</string> - <string name="face_acquired_insufficient" msgid="5901287247766106330">"चेहऱ्यावर प्रक्रिया झाली नाही. पुन्हा प्रयत्न करा."</string> - <string name="face_acquired_too_bright" msgid="610606792381297174">"चेहऱ्यावर खूप प्रकाश आहे. कृपया कमी प्रकाशात प्रयत्न करा."</string> - <string name="face_acquired_too_dark" msgid="7229162716976778371">"चेहऱ्यावर खूप अंधार आहे. कृपया प्रकाश स्रोत खुला करा."</string> - <string name="face_acquired_too_close" msgid="1980310037427755293">"कृपया सेन्सर चेहऱ्यापासून आणखी दूर हलवा."</string> - <string name="face_acquired_too_far" msgid="4494571381828850007">"कृपया सेन्सर चेहऱ्याच्या आणखी जवळ आणा."</string> - <string name="face_acquired_too_high" msgid="228411096134808372">"कृपया सेन्सर आणखी वर हलवा."</string> - <string name="face_acquired_too_low" msgid="4539774649296349109">"कृपया सेन्सर आणखी खाली हलवा."</string> - <string name="face_acquired_too_right" msgid="1650292067226118760">"कृपया सेन्सर उजवीकडे हलवा."</string> - <string name="face_acquired_too_left" msgid="2712489669456176505">"कृपया सेन्सर डावीकडे हलवा."</string> - <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"कृपया सेन्सरकडे पहा."</string> - <string name="face_acquired_not_detected" msgid="5707782294589511391">"चेहरा आढळला नाही."</string> - <string name="face_acquired_too_much_motion" msgid="470381210701463822">"डिव्हाइस खूप हलत आहे."</string> + <!-- no translation found for face_acquired_insufficient (2767330364802375742) --> + <skip /> + <!-- no translation found for face_acquired_too_bright (5005650874582450967) --> + <skip /> + <!-- no translation found for face_acquired_too_dark (1966194696381394616) --> + <skip /> + <!-- no translation found for face_acquired_too_close (1401011882624272753) --> + <skip /> + <!-- no translation found for face_acquired_too_far (1210969240069012510) --> + <skip /> + <!-- no translation found for face_acquired_too_high (3362395713403348013) --> + <skip /> + <!-- no translation found for face_acquired_too_low (488983581737550912) --> + <skip /> + <!-- no translation found for face_acquired_too_right (941726879175375970) --> + <skip /> + <!-- no translation found for face_acquired_too_left (5873592047381190672) --> + <skip /> + <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) --> + <skip /> + <!-- no translation found for face_acquired_not_detected (4885504661626728809) --> + <skip /> + <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) --> + <skip /> <string name="face_acquired_recalibrate" msgid="8077949502893707539">"कृपया तुमच्या चेहऱ्याची पुन्हा नोंदणी करा."</string> - <string name="face_acquired_too_different" msgid="5553210341111255124">"वेगळा चेहरा आढळला आहे."</string> + <!-- no translation found for face_acquired_too_different (7663983770123789694) --> + <skip /> <string name="face_acquired_too_similar" msgid="1508776858407646460">"एकाच प्रकारची पोझ देत आहात कृपया तुमची पोझ बदला."</string> - <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"कृपया थेट कॅमेऱ्याच्या दिशेने पाहा."</string> - <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"कृपया थेट कॅमेऱ्याच्या दिशेने पाहा."</string> + <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) --> + <skip /> + <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"कृपया तुमची मान वर करा."</string> - <string name="face_acquired_obscured" msgid="3055077697850272097">"कृपया तुमचा चेहरा दाखवा."</string> + <!-- no translation found for face_acquired_obscured (5747521031647744553) --> + <skip /> + <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) --> + <skip /> <string-array name="face_acquired_vendor"> </string-array> <string name="face_error_hw_not_available" msgid="6255891785768984615">"चेहरा हार्डवेअर उपलब्ध नाही."</string> - <string name="face_error_timeout" msgid="4014326147867150054">"चेहरा टाइमआउट झाला. पुन्हा प्रयत्न करा."</string> + <!-- no translation found for face_error_timeout (2605673935810019129) --> + <skip /> <string name="face_error_no_space" msgid="8224993703466381314">"चेहरा स्टोअर केला जाऊ शकत नाही."</string> <string name="face_error_canceled" msgid="283945501061931023">"चेहरा ऑपरेशन रद्द केले गेले."</string> <string name="face_error_user_canceled" msgid="8943921120862164539">"वापरकर्त्याने चेहरा ऑथेंटिकेशन रद्द केले."</string> <string name="face_error_lockout" msgid="3407426963155388504">"खूप जास्त प्रयत्न केले. नंतर पुन्हा प्रयत्न करा."</string> <string name="face_error_lockout_permanent" msgid="8198354656746088890">"खूप जास्त प्रयत्न केले. चेहरा ऑथेंटिकेशन बंद केले गेले."</string> - <string name="face_error_unable_to_process" msgid="238761109287767270">"पुन्हा प्रयत्न करा."</string> - <string name="face_error_not_enrolled" msgid="9166792142679691323">"चेहरा नोंदवलेला नाही."</string> - <string name="face_error_hw_not_present" msgid="916085883581450331">"या डिव्हाइसमध्ये चेहरा ऑथेंटिकेशन सेन्सर नाही."</string> + <!-- no translation found for face_error_unable_to_process (4940944939691171539) --> + <skip /> + <!-- no translation found for face_error_not_enrolled (4245760276260427472) --> + <skip /> + <!-- no translation found for face_error_hw_not_present (5296043240874659926) --> + <skip /> <string name="face_name_template" msgid="7004562145809595384">"चेहरा <xliff:g id="FACEID">%d</xliff:g>"</string> <string-array name="face_error_vendor"> </string-array> @@ -1164,7 +1197,7 @@ <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> थांबतो"</string> <string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> थांबते"</string> <string name="aerr_restart" msgid="7581308074153624475">"अॅप पुन्हा उघडा"</string> - <string name="aerr_report" msgid="5371800241488400617">"अभिप्राय पाठवा"</string> + <string name="aerr_report" msgid="5371800241488400617">"फीडबॅक पाठवा"</string> <string name="aerr_close" msgid="2991640326563991340">"बंद करा"</string> <string name="aerr_mute" msgid="1974781923723235953">"डिव्हाइस रीस्टार्ट होईपर्यंत म्यूट करा"</string> <string name="aerr_wait" msgid="3199956902437040261">"प्रतीक्षा करा"</string> @@ -1213,9 +1246,16 @@ <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g> उघडा"</string> <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> सेव्ह न करता बंद होईल"</string> <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> ने मेमेरी मर्यादा वाढविली"</string> + <!-- no translation found for dump_heap_ready_notification (1162196579925048701) --> + <skip /> <string name="dump_heap_notification_detail" msgid="3993078784053054141">"हीप डंप गोळा केले. शेअर करण्यासाठी टॅप करा."</string> <string name="dump_heap_title" msgid="5864292264307651673">"हीप डंप शेअर करायचे?"</string> - <string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g> प्रक्रियेने त्याची <xliff:g id="SIZE">%2$s</xliff:g> ची प्रक्रिया मेमरी मर्यादा ओलांडली आहे. त्याच्या विकासकासह शेअर करण्यासाठी तुमच्यासाठी हीप डंप उपलब्ध आहे. सावधगिरी बाळगा: या हीप डंपमध्ये तुमची कोणतीही वैयक्तिक माहिती असू शकते ज्यात अॅप्लिकेशन प्रवेश करू शकतो."</string> + <!-- no translation found for dump_heap_text (8546022920319781701) --> + <skip /> + <!-- no translation found for dump_heap_system_text (1205466256312104134) --> + <skip /> + <!-- no translation found for dump_heap_ready_text (6759394977904051000) --> + <skip /> <string name="sendText" msgid="5209874571959469142">"मजकुरासाठी क्रिया निवडा"</string> <string name="volume_ringtone" msgid="6885421406845734650">"रिंगर व्हॉल्यूम"</string> <string name="volume_music" msgid="5421651157138628171">"मीडिया व्हॉल्यूम"</string> @@ -1254,8 +1294,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"सर्व नेटवर्क पाहण्यासाठी टॅप करा"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"कनेक्ट करा"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"सर्व नेटवर्क"</string> - <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g> ने प्रस्तावित केलेले वाय-फाय नेटवर्क उपलब्ध आहे"</string> - <string name="wifi_suggestion_content" msgid="2658317015552324848">"<xliff:g id="NAME">%s</xliff:g> द्वारे प्रस्तावित नेटवर्कशी कनेक्ट करायचे आहे का?"</string> + <!-- no translation found for wifi_suggestion_title (9099832833531486167) --> + <skip /> + <!-- no translation found for wifi_suggestion_content (5883181205841582873) --> + <skip /> <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"होय"</string> <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"नाही"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"वाय-फाय आपोआप चालू होईल"</string> @@ -1267,9 +1309,14 @@ <string name="network_available_sign_in" msgid="1848877297365446605">"नेटवर्कवर साइन इन करा"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> <skip /> - <string name="wifi_no_internet" msgid="8938267198124654938">"वाय-फाय ला इंटरनेटचा अॅक्सेस नाही"</string> + <!-- no translation found for wifi_no_internet (5198100389964214865) --> + <skip /> <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"पर्यायांसाठी टॅप करा"</string> <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"कनेक्ट केले"</string> + <!-- no translation found for network_partial_connectivity (7774883385494762741) --> + <skip /> + <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) --> + <skip /> <string name="wifi_softap_config_change" msgid="8475911871165857607">"तुमच्या हॉटस्पॉट सेटिंग्जमधील बदल"</string> <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"तुमचा हॉटस्पॉट बँड बदलला आहे."</string> <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"हे डिव्हाइस तुमच्या फक्त ५GHz साठी प्राधान्याला सपोर्ट करत नाही. त्याऐवजी, हे डिव्हाइस ५GHz बँड उपलब्ध असताना वापरेल."</string> @@ -1355,6 +1402,10 @@ <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डीबग करणे कनेक्ट केले"</string> <string name="adb_active_notification_message" msgid="7463062450474107752">"USB डीबगिंग बंद करण्यासाठी टॅप करा"</string> <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB डीबगिंग बंद करण्यासाठी निवडा."</string> + <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) --> + <skip /> + <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) --> + <skip /> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB पोर्ट मध्ये ओलावा किंवा धूळ आहे"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB पोर्ट आपोआप बंद होईल. अधिक जाणून घेण्यासाठी टॅप करा."</string> <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB फोर्ट वापरण्यासाठी सुरक्षित आहे"</string> @@ -1906,8 +1957,6 @@ <string name="profile_encrypted_message" msgid="6964994232310195874">"कार्य प्रोफाईल अनलॉक करण्यासाठी टॅप करा"</string> <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> शी कनेक्ट केलेले"</string> <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"फायली पाहण्यासाठी टॅप करा"</string> - <string name="pin_target" msgid="3052256031352291362">"पिन"</string> - <string name="unpin_target" msgid="3556545602439143442">"अनपिन करा"</string> <string name="app_info" msgid="6856026610594615344">"अॅप माहिती"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="demo_starting_message" msgid="5268556852031489931">"डेमो प्रारंभ करत आहे..."</string> @@ -1998,6 +2047,22 @@ <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"दिनक्रम मोडची माहिती सूचना"</string> <string name="dynamic_mode_notification_title" msgid="508815255807182035">"चार्जिंगची सामान्य पातळी गाठेपर्यंत कदाचित बॅटरी संपू शकते"</string> <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"बॅटरी लाइफ वाढवण्यासाठी बॅटरी सेव्हर सुरू केला आहे"</string> + <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) --> + <skip /> + <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) --> + <skip /> + <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) --> + <skip /> <string name="mime_type_folder" msgid="7111951698626315204">"फोल्डर"</string> <string name="mime_type_apk" msgid="5518003630972506900">"Android अॅप्लिकेशन"</string> <string name="mime_type_generic" msgid="6833871596845900027">"फाइल"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index ecaff4d23ba5..d501cd7be670 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -141,8 +141,10 @@ <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Chamadas Wi-Fi"</string> <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string> <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desativado"</string> - <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Rede Wi-Fi preferida"</string> - <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferência pela rede móvel"</string> + <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) --> + <skip /> + <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) --> + <skip /> <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Apenas Wi-Fi"</string> <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Não reencaminhado"</string> <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> @@ -228,7 +230,8 @@ <string name="global_action_bug_report" msgid="7934010578922304799">"Relatório de erros"</string> <string name="global_action_logout" msgid="935179188218826050">"Terminar sessão"</string> <string name="global_action_screenshot" msgid="8329831278085426283">"Captura de ecrã"</string> - <string name="bugreport_title" msgid="2667494803742548533">"Criar relatório de erros"</string> + <!-- no translation found for bugreport_title (5981047024855257269) --> + <skip /> <string name="bugreport_message" msgid="398447048750350456">"Será recolhida informação sobre o estado atual do seu dispositivo a enviar através de uma mensagem de email. Demorará algum tempo até que o relatório de erro esteja pronto para ser enviado. Aguarde um pouco."</string> <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Relatório interativo"</string> <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Utilize esta opção na maioria das circunstâncias. Permite monitorizar o progresso do relatório, introduzir mais detalhes acerca do problema e tirar capturas de ecrã. Pode omitir algumas secções menos utilizadas que demoram muito tempo a comunicar."</string> @@ -281,9 +284,12 @@ <string name="permgrouplab_location" msgid="7275582855722310164">"Localização"</string> <string name="permgroupdesc_location" msgid="1346617465127855033">"aceder à localização do seu dispositivo"</string> <string name="permgrouprequest_location" msgid="3788275734953323491">"Pretende permitir que a aplicação <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aceda à localização deste dispositivo?"</string> - <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"A aplicação tem acesso à localização apenas quando a estiver a utilizar."</string> - <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Pretende permitir que a aplicação <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aceda sempre à localização deste dispositivo?"</string> - <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"A aplicação terá sempre acesso à localização, mesmo quando não está a utilizá-la."</string> + <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) --> + <skip /> <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendário"</string> <string name="permgroupdesc_calendar" msgid="3889615280211184106">"aceder ao calendário"</string> <string name="permgrouprequest_calendar" msgid="289900767793189421">"Pretende permitir que a aplicação <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aceda ao calendário?"</string> @@ -316,7 +322,10 @@ <string name="permgrouprequest_aural" msgid="6787926123071735620">"Pretende permitir que a aplicação <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aceda à sua música?"</string> <string name="permgrouplab_visual" msgid="6477382108771145134">"Fotos e vídeos"</string> <string name="permgroupdesc_visual" msgid="3415827902566663546">"aceder aos seus vídeos e fotos"</string> - <string name="permgrouprequest_visual" msgid="3043752127595243314">"Pretende permitir que a aplicação <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aceda aos seus vídeos e fotos, incluindo localizações etiquetadas?"</string> + <!-- no translation found for permgrouprequest_visual (4926581398380334943) --> + <skip /> + <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) --> + <skip /> <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Obter conteúdo da janela"</string> <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecionar o conteúdo de uma janela com a qual está a interagir."</string> <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Ativar Explorar Através do Toque"</string> @@ -509,8 +518,10 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Permite que a aplicação comunique com etiquetas, cartões e leitores Near Field Communication (NFC)."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"desativar o bloqueio do ecrã"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permite que a aplicação desative o bloqueio de teclas e qualquer segurança por palavra-passe associada. Por exemplo, o telemóvel desativa o bloqueio de teclas quando recebe uma chamada e reativa o bloqueio de teclas ao terminar a chamada."</string> - <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"solicitar a complexidade do bloqueio de ecrã"</string> - <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Permite que a aplicação aprenda o nível de complexidade do bloqueio de ecrã (elevado, médio, baixo ou nenhum), que indica o intervalo de comprimento e o tipo de bloqueio de ecrã possíveis. A aplicação também pode sugerir aos utilizadores que atualizem o bloqueio de ecrã para um determinado nível, mas estes podem ignorar livremente a sugestão e continuar a navegação. Tenha em atenção que o bloqueio de ecrã não é armazenado em texto simples, pelo que a aplicação desconhece a palavra-passe exata."</string> + <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) --> + <skip /> + <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) --> + <skip /> <string name="permlab_useBiometric" msgid="8837753668509919318">"Utilizar hardware biométrico"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Permite que a aplicação utilize hardware biométrico para autenticação."</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"gerir o hardware de impressão digital"</string> @@ -565,37 +576,59 @@ <string name="permdesc_manageFace" msgid="8919637120670185330">"Permite à aplicação invocar métodos para adicionar e eliminar modelos faciais para uso."</string> <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"utilizar hardware de autenticação facial"</string> <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Permite que a aplicação utilize hardware de autenticação facial para autenticação."</string> - <string name="face_acquired_insufficient" msgid="5901287247766106330">"Não foi possível processar o rosto. Tente de novo."</string> - <string name="face_acquired_too_bright" msgid="610606792381297174">"Rosto demasiado claro. Experimente com menos luz."</string> - <string name="face_acquired_too_dark" msgid="7229162716976778371">"Rosto demasiado escuro. Destape a fonte de luz."</string> - <string name="face_acquired_too_close" msgid="1980310037427755293">"Afaste o sensor do rosto."</string> - <string name="face_acquired_too_far" msgid="4494571381828850007">"Aproxime o sensor do rosto."</string> - <string name="face_acquired_too_high" msgid="228411096134808372">"Mova o sensor para cima."</string> - <string name="face_acquired_too_low" msgid="4539774649296349109">"Mova o sensor para baixo."</string> - <string name="face_acquired_too_right" msgid="1650292067226118760">"Mova o sensor para a direita."</string> - <string name="face_acquired_too_left" msgid="2712489669456176505">"Mova o sensor para a esquerda."</string> - <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Olhe para o sensor."</string> - <string name="face_acquired_not_detected" msgid="5707782294589511391">"Nenhum rosto detetado."</string> - <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Demasiado movimento."</string> + <!-- no translation found for face_acquired_insufficient (2767330364802375742) --> + <skip /> + <!-- no translation found for face_acquired_too_bright (5005650874582450967) --> + <skip /> + <!-- no translation found for face_acquired_too_dark (1966194696381394616) --> + <skip /> + <!-- no translation found for face_acquired_too_close (1401011882624272753) --> + <skip /> + <!-- no translation found for face_acquired_too_far (1210969240069012510) --> + <skip /> + <!-- no translation found for face_acquired_too_high (3362395713403348013) --> + <skip /> + <!-- no translation found for face_acquired_too_low (488983581737550912) --> + <skip /> + <!-- no translation found for face_acquired_too_right (941726879175375970) --> + <skip /> + <!-- no translation found for face_acquired_too_left (5873592047381190672) --> + <skip /> + <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) --> + <skip /> + <!-- no translation found for face_acquired_not_detected (4885504661626728809) --> + <skip /> + <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) --> + <skip /> <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Volte a inscrever o rosto."</string> - <string name="face_acquired_too_different" msgid="5553210341111255124">"Foi detetado um rosto diferente."</string> + <!-- no translation found for face_acquired_too_different (7663983770123789694) --> + <skip /> <string name="face_acquired_too_similar" msgid="1508776858407646460">"Muito parecida, mude de pose."</string> - <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Olhe mais diretamente para a câmara."</string> - <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Olhe mais diretamente para a câmara."</string> + <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) --> + <skip /> + <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Endireite a cabeça na vertical."</string> - <string name="face_acquired_obscured" msgid="3055077697850272097">"Destape o rosto."</string> + <!-- no translation found for face_acquired_obscured (5747521031647744553) --> + <skip /> + <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) --> + <skip /> <string-array name="face_acquired_vendor"> </string-array> <string name="face_error_hw_not_available" msgid="6255891785768984615">"O hardware de rosto não está disponível."</string> - <string name="face_error_timeout" msgid="4014326147867150054">"Limite de tempo de rosto atingido. Tente novamente."</string> + <!-- no translation found for face_error_timeout (2605673935810019129) --> + <skip /> <string name="face_error_no_space" msgid="8224993703466381314">"Não é possível armazenar o rosto."</string> <string name="face_error_canceled" msgid="283945501061931023">"Operação de rosto cancelada."</string> <string name="face_error_user_canceled" msgid="8943921120862164539">"Autenticação facial cancelada pelo utilizador."</string> <string name="face_error_lockout" msgid="3407426963155388504">"Demasiadas tentativas. Tente novamente mais tarde."</string> <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Demasiadas tentativas. Autenticação facial desativada."</string> - <string name="face_error_unable_to_process" msgid="238761109287767270">"Tente novamente."</string> - <string name="face_error_not_enrolled" msgid="9166792142679691323">"Nenhum rosto inscrito."</string> - <string name="face_error_hw_not_present" msgid="916085883581450331">"Este dispositivo não tem sensor de autenticação facial."</string> + <!-- no translation found for face_error_unable_to_process (4940944939691171539) --> + <skip /> + <!-- no translation found for face_error_not_enrolled (4245760276260427472) --> + <skip /> + <!-- no translation found for face_error_hw_not_present (5296043240874659926) --> + <skip /> <string name="face_name_template" msgid="7004562145809595384">"Rosto <xliff:g id="FACEID">%d</xliff:g>"</string> <string-array name="face_error_vendor"> </string-array> @@ -1213,9 +1246,16 @@ <string name="new_app_action" msgid="6694851182870774403">"Abrir a aplicação <xliff:g id="NEW_APP">%1$s</xliff:g>"</string> <string name="new_app_description" msgid="5894852887817332322">"A aplicação <xliff:g id="OLD_APP">%1$s</xliff:g> vai fechar sem guardar."</string> <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> excedeu o limite da memória"</string> + <!-- no translation found for dump_heap_ready_notification (1162196579925048701) --> + <skip /> <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Foi recolhida a captura da área dinâmica para dados. Toque para partilhar."</string> <string name="dump_heap_title" msgid="5864292264307651673">"Pretende partilhar a captura da área dinâmica para dados?"</string> - <string name="dump_heap_text" msgid="4809417337240334941">"O processo <xliff:g id="PROC">%1$s</xliff:g> excedeu o respetivo limite de memória do processo de <xliff:g id="SIZE">%2$s</xliff:g>. Está disponível uma captura da área dinâmica para dados para partilhar com o respetivo programador. Tenha atenção: esta captura da área dinâmica para dados pode conter algumas das suas informações pessoais a que a aplicação tem acesso."</string> + <!-- no translation found for dump_heap_text (8546022920319781701) --> + <skip /> + <!-- no translation found for dump_heap_system_text (1205466256312104134) --> + <skip /> + <!-- no translation found for dump_heap_ready_text (6759394977904051000) --> + <skip /> <string name="sendText" msgid="5209874571959469142">"Escolha uma ação para o texto"</string> <string name="volume_ringtone" msgid="6885421406845734650">"Volume da campainha"</string> <string name="volume_music" msgid="5421651157138628171">"Volume de multimédia"</string> @@ -1254,8 +1294,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toque para ver todas as redes"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Ligar"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Todas as redes"</string> - <string name="wifi_suggestion_title" msgid="8951405130379148709">"Está disponível uma rede Wi-Fi proposta por <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_content" msgid="2658317015552324848">"Pretende estabelecer ligação às redes propostas por <xliff:g id="NAME">%s</xliff:g>?"</string> + <!-- no translation found for wifi_suggestion_title (9099832833531486167) --> + <skip /> + <!-- no translation found for wifi_suggestion_content (5883181205841582873) --> + <skip /> <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Sim"</string> <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Não"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"O Wi‑Fi será ativado automaticamente"</string> @@ -1267,9 +1309,14 @@ <string name="network_available_sign_in" msgid="1848877297365446605">"Início de sessão na rede"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> <skip /> - <string name="wifi_no_internet" msgid="8938267198124654938">"O Wi-Fi não tem acesso à Internet."</string> + <!-- no translation found for wifi_no_internet (5198100389964214865) --> + <skip /> <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Toque para obter mais opções"</string> <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Ligado"</string> + <!-- no translation found for network_partial_connectivity (7774883385494762741) --> + <skip /> + <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) --> + <skip /> <string name="wifi_softap_config_change" msgid="8475911871165857607">"Alterações às definições de zona Wi-Fi"</string> <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"A banda da sua zona Wi-Fi foi alterada."</string> <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Este dispositivo não suporta a sua preferência apenas para 5 GHz. Em alternativa, este dispositivo vai utilizar a banda de 5 GHz quando estiver disponível."</string> @@ -1354,6 +1401,10 @@ <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB ligada"</string> <string name="adb_active_notification_message" msgid="7463062450474107752">"Toque para desativar a depuração USB."</string> <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecione para desativar a depuração por USB."</string> + <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) --> + <skip /> + <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) --> + <skip /> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Líquido ou resíduos na porta USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"A porta USB é automaticamente desativada. Toque para saber mais."</string> <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"É seguro utilizar a porta USB"</string> @@ -1905,8 +1956,6 @@ <string name="profile_encrypted_message" msgid="6964994232310195874">"Toque p/ desb. perfil trabalho"</string> <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Ligado a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string> <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Tocar para ver ficheiros"</string> - <string name="pin_target" msgid="3052256031352291362">"Fixar"</string> - <string name="unpin_target" msgid="3556545602439143442">"Soltar"</string> <string name="app_info" msgid="6856026610594615344">"Info. da aplicação"</string> <string name="negative_duration" msgid="5688706061127375131">"-<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="demo_starting_message" msgid="5268556852031489931">"A iniciar a demonstração…"</string> @@ -1997,6 +2046,22 @@ <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Notificação de informações do Modo rotina"</string> <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Pode ficar sem bateria antes do carregamento habitual"</string> <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Poupança de bateria ativada para prolongar a duração da bateria"</string> + <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) --> + <skip /> + <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) --> + <skip /> + <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) --> + <skip /> <string name="mime_type_folder" msgid="7111951698626315204">"Pasta"</string> <string name="mime_type_apk" msgid="5518003630972506900">"Aplicação para Android"</string> <string name="mime_type_generic" msgid="6833871596845900027">"Ficheiro"</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 31fa1274b063..714f0b40e9b3 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -143,8 +143,10 @@ <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Volanie cez Wi‑Fi"</string> <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string> <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Vypnuté"</string> - <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Preferovať Wi‑Fi"</string> - <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferovať mobilné spojenie"</string> + <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) --> + <skip /> + <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) --> + <skip /> <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Len Wi‑Fi"</string> <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nepresmerované"</string> <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> @@ -232,7 +234,8 @@ <string name="global_action_bug_report" msgid="7934010578922304799">"Hlásenie o chybách"</string> <string name="global_action_logout" msgid="935179188218826050">"Ukončiť reláciu"</string> <string name="global_action_screenshot" msgid="8329831278085426283">"Snímka obrazovky"</string> - <string name="bugreport_title" msgid="2667494803742548533">"Vytvoriť hlásenie chyby"</string> + <!-- no translation found for bugreport_title (5981047024855257269) --> + <skip /> <string name="bugreport_message" msgid="398447048750350456">"Týmto zhromaždíte informácie o aktuálnom stave zariadenia. Informácie je potom možné odoslať e-mailom, chvíľu však potrvá, kým bude hlásenie chyby pripravené na odoslanie. Prosíme vás preto o trpezlivosť."</string> <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktívne nahlásenie"</string> <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Táto možnosť je vhodná pre väčšinu prípadov. Umožňuje sledovať priebeh nahlásenia, zadávať ďalšie podrobnosti o probléme a vytvárať snímky obrazovky. Môžu byť vynechané niektoré menej používané sekcie, ktorých nahlásenie trvá dlho."</string> @@ -287,9 +290,12 @@ <string name="permgrouplab_location" msgid="7275582855722310164">"Poloha"</string> <string name="permgroupdesc_location" msgid="1346617465127855033">"prístup k polohe tohto zariadenia"</string> <string name="permgrouprequest_location" msgid="3788275734953323491">"Povoliť aplikácii <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> prístup k polohe tohto zariadenia?"</string> - <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Aplikácia bude mať prístup k polohe iba vtedy, keď ju budete používať."</string> - <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Chcete vždy povoliť aplikácii <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> prístup k polohe tohto zariadenia?"</string> - <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Aplikácia bude mať vždy prístup k polohe, aj keď ju nebudete používať."</string> + <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) --> + <skip /> <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendár"</string> <string name="permgroupdesc_calendar" msgid="3889615280211184106">"prístup ku kalendáru"</string> <string name="permgrouprequest_calendar" msgid="289900767793189421">"Povoliť aplikácii <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> prístup ku kalendáru?"</string> @@ -322,7 +328,10 @@ <string name="permgrouprequest_aural" msgid="6787926123071735620">"Chcete povoliť aplikácii <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> prístup k hudbe?"</string> <string name="permgrouplab_visual" msgid="6477382108771145134">"Fotky a videá"</string> <string name="permgroupdesc_visual" msgid="3415827902566663546">"prístup k fotkám a videám"</string> - <string name="permgrouprequest_visual" msgid="3043752127595243314">"Chcete povoliť aplikácii <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> prístup k vašim fotkám a videám vrátane označených miest?"</string> + <!-- no translation found for permgrouprequest_visual (4926581398380334943) --> + <skip /> + <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) --> + <skip /> <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Načítať obsah okna"</string> <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Môžete preskúmať obsah okna, s ktorým pracujete."</string> <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Zapnúť funkciu Preskúmanie dotykom"</string> @@ -515,8 +524,10 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Umožňuje aplikácii komunikovať so značkami, kartami a čítačkami s podporou technológie NFC."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"deaktivácia zámky obrazovky"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Umožňuje aplikácii zakázať uzamknutie klávesnice a akékoľvek súvisiace zabezpečenie heslom. Príkladom je zakázanie uzamknutia klávesnice pri prichádzajúcom telefonickom hovore a jeho opätovné povolenie po skončení hovoru."</string> - <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"požadovať zložitosť zámky obrazovky"</string> - <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Umožňuje aplikácii zapamätať si úroveň zložitosti zámky obrazovky (vysoká, stredná, nízka alebo žiadna), ktorá udáva pravdepodobný rozsah dĺžky a typu zámky obrazovky. Aplikácia tiež navrhuje používateľom aktualizáciu zámky obrazovky na určitú úroveň, používatelia sa však môžu na základe vlastného uváženia rozhodnúť tento návrh ignorovať a prejsť inam. Upozorňujeme, že zámka obrazovky nie je uložená vo forme obyčajného textu, takže aplikácia nepozná presné heslo."</string> + <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) --> + <skip /> + <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) --> + <skip /> <string name="permlab_useBiometric" msgid="8837753668509919318">"používať biometrický hardvér"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Umožňuje aplikácii používať na overenie totožnosti biometrický hardvér"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"spravovať hardvér na snímanie odtlačkov prstov"</string> @@ -571,37 +582,59 @@ <string name="permdesc_manageFace" msgid="8919637120670185330">"Umožňuje aplikácii vyvolať metódy, ktoré pridávajú a odstraňujú šablóny tvárí."</string> <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"používanie hardvéru na overenie tváre"</string> <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Umožňuje aplikácii používať na overenie totožnosti hardvér na overenie tváre"</string> - <string name="face_acquired_insufficient" msgid="5901287247766106330">"Tvár sa nepodarilo spracovať. Skúste to znova."</string> - <string name="face_acquired_too_bright" msgid="610606792381297174">"Tvár je príliš svetlá. Skúste to pri nižšom osvetlení."</string> - <string name="face_acquired_too_dark" msgid="7229162716976778371">"Tvár je príliš tmavá. Zvýšte osvetlenie."</string> - <string name="face_acquired_too_close" msgid="1980310037427755293">"Oddiaľte senzor od tváre."</string> - <string name="face_acquired_too_far" msgid="4494571381828850007">"Priblížte senzor k tvári."</string> - <string name="face_acquired_too_high" msgid="228411096134808372">"Pohnite senzor vyššie."</string> - <string name="face_acquired_too_low" msgid="4539774649296349109">"Pohnite senzor nižšie."</string> - <string name="face_acquired_too_right" msgid="1650292067226118760">"Pohnite senzor doprava."</string> - <string name="face_acquired_too_left" msgid="2712489669456176505">"Pohnite senzor doľava."</string> - <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Pozerajte sa na senzor."</string> - <string name="face_acquired_not_detected" msgid="5707782294589511391">"Nebola rozpoznaná žiadna tvár."</string> - <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Priveľa pohybu."</string> + <!-- no translation found for face_acquired_insufficient (2767330364802375742) --> + <skip /> + <!-- no translation found for face_acquired_too_bright (5005650874582450967) --> + <skip /> + <!-- no translation found for face_acquired_too_dark (1966194696381394616) --> + <skip /> + <!-- no translation found for face_acquired_too_close (1401011882624272753) --> + <skip /> + <!-- no translation found for face_acquired_too_far (1210969240069012510) --> + <skip /> + <!-- no translation found for face_acquired_too_high (3362395713403348013) --> + <skip /> + <!-- no translation found for face_acquired_too_low (488983581737550912) --> + <skip /> + <!-- no translation found for face_acquired_too_right (941726879175375970) --> + <skip /> + <!-- no translation found for face_acquired_too_left (5873592047381190672) --> + <skip /> + <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) --> + <skip /> + <!-- no translation found for face_acquired_not_detected (4885504661626728809) --> + <skip /> + <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) --> + <skip /> <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Znova zaregistrujte svoju tvár."</string> - <string name="face_acquired_too_different" msgid="5553210341111255124">"Bola rozpoznaná iná tvár."</string> + <!-- no translation found for face_acquired_too_different (7663983770123789694) --> + <skip /> <string name="face_acquired_too_similar" msgid="1508776858407646460">"Príliš rovnaké, zmeňte postoj."</string> - <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Pozrite sa priamejšie do fotoaparátu."</string> - <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Pozrite sa priamejšie do fotoaparátu."</string> + <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) --> + <skip /> + <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Zvisle vyrovnajte hlavu."</string> - <string name="face_acquired_obscured" msgid="3055077697850272097">"Odkryte svoju tvár."</string> + <!-- no translation found for face_acquired_obscured (5747521031647744553) --> + <skip /> + <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) --> + <skip /> <string-array name="face_acquired_vendor"> </string-array> <string name="face_error_hw_not_available" msgid="6255891785768984615">"Hardvér na snímanie tváre nie je k dispozícii"</string> - <string name="face_error_timeout" msgid="4014326147867150054">"Limit rozpoznania tváre vypršal. Skúste to znova."</string> + <!-- no translation found for face_error_timeout (2605673935810019129) --> + <skip /> <string name="face_error_no_space" msgid="8224993703466381314">"Tvár sa nedá uchovať."</string> <string name="face_error_canceled" msgid="283945501061931023">"Operácia týkajúca sa tváre bola zrušená"</string> <string name="face_error_user_canceled" msgid="8943921120862164539">"Overenie tváre bolo zrušené používateľom."</string> <string name="face_error_lockout" msgid="3407426963155388504">"Príliš veľa pokusov. Skúste to znova neskôr."</string> <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Príliš veľa pokusov. Overenie tváre je zakázané."</string> - <string name="face_error_unable_to_process" msgid="238761109287767270">"Skúste to znova."</string> - <string name="face_error_not_enrolled" msgid="9166792142679691323">"Nemáte zaregistrovanú žiadnu tvár."</string> - <string name="face_error_hw_not_present" msgid="916085883581450331">"Toto zariadenie nemá senzor na overenie tváre."</string> + <!-- no translation found for face_error_unable_to_process (4940944939691171539) --> + <skip /> + <!-- no translation found for face_error_not_enrolled (4245760276260427472) --> + <skip /> + <!-- no translation found for face_error_hw_not_present (5296043240874659926) --> + <skip /> <string name="face_name_template" msgid="7004562145809595384">"Tvár <xliff:g id="FACEID">%d</xliff:g>"</string> <string-array name="face_error_vendor"> </string-array> @@ -1253,9 +1286,16 @@ <string name="new_app_action" msgid="6694851182870774403">"Otvoriť <xliff:g id="NEW_APP">%1$s</xliff:g>"</string> <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> sa zavrie bez uloženia"</string> <string name="dump_heap_notification" msgid="2618183274836056542">"Proces <xliff:g id="PROC">%1$s</xliff:g> prekročil limit pamäte"</string> + <!-- no translation found for dump_heap_ready_notification (1162196579925048701) --> + <skip /> <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Boli zhromaždené zálohy dát. Zdieľajte ich klepnutím."</string> <string name="dump_heap_title" msgid="5864292264307651673">"Chcete zdieľať zálohy údajov?"</string> - <string name="dump_heap_text" msgid="4809417337240334941">"Proces <xliff:g id="PROC">%1$s</xliff:g> prekročil limit <xliff:g id="SIZE">%2$s</xliff:g> pre pamäť procesu. Máte k dispozícii zálohy údajov, ktoré môžete zdieľať s vývojárom. Postupujte opatrne: tieto zálohy údajov nesmú obsahovať žiadne osobné informácie, ku ktorým má táto aplikácia prístup."</string> + <!-- no translation found for dump_heap_text (8546022920319781701) --> + <skip /> + <!-- no translation found for dump_heap_system_text (1205466256312104134) --> + <skip /> + <!-- no translation found for dump_heap_ready_text (6759394977904051000) --> + <skip /> <string name="sendText" msgid="5209874571959469142">"Zvoľte akciu pre text"</string> <string name="volume_ringtone" msgid="6885421406845734650">"Hlasitosť vyzváňania"</string> <string name="volume_music" msgid="5421651157138628171">"Hlasitosť médií"</string> @@ -1298,8 +1338,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Klepnutím zobrazíte všetky siete"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Pripojiť"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Všetky siete"</string> - <string name="wifi_suggestion_title" msgid="8951405130379148709">"K dispozícii je sieť Wi-Fi, ktorú navrhla aplikácia <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_content" msgid="2658317015552324848">"Chcete sa pripájať k sieťam navrhnutým aplikáciou <xliff:g id="NAME">%s</xliff:g>?"</string> + <!-- no translation found for wifi_suggestion_title (9099832833531486167) --> + <skip /> + <!-- no translation found for wifi_suggestion_content (5883181205841582873) --> + <skip /> <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Áno"</string> <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nie"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi sa zapne automaticky"</string> @@ -1311,9 +1353,14 @@ <string name="network_available_sign_in" msgid="1848877297365446605">"Prihlásenie do siete"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> <skip /> - <string name="wifi_no_internet" msgid="8938267198124654938">"Sieť Wi‑Fi nemá prístup k internetu"</string> + <!-- no translation found for wifi_no_internet (5198100389964214865) --> + <skip /> <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Klepnutím získate možnosti"</string> <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Pripojené"</string> + <!-- no translation found for network_partial_connectivity (7774883385494762741) --> + <skip /> + <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) --> + <skip /> <string name="wifi_softap_config_change" msgid="8475911871165857607">"Zmeny nastavení hotspotu"</string> <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Pásmo vášho hotspotu sa zmenilo."</string> <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Toto zariadenie nepodporuje vašu predvoľbu používať iba 5 GHz. Namiesto toho bude pásmo 5 GHz používať vtedy, keď bude k dispozícii."</string> @@ -1398,6 +1445,10 @@ <string name="adb_active_notification_title" msgid="6729044778949189918">"Ladenie cez USB pripojené"</string> <string name="adb_active_notification_message" msgid="7463062450474107752">"Klepnutím vypnite ladenie cez USB"</string> <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Vyberte, ak chcete zakázať ladenie cez USB."</string> + <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) --> + <skip /> + <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) --> + <skip /> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Tekutina alebo nečistoty v porte USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Port USB je automaticky deaktivovaný. Ďalšie informácie zobrazíte klepnutím."</string> <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Port USB môžete bezpečne používať"</string> @@ -1973,8 +2024,6 @@ <string name="profile_encrypted_message" msgid="6964994232310195874">"Profil odomknete klepnutím"</string> <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Pripojené k zariadeniu <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string> <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Klepnutím zobrazíte súbory"</string> - <string name="pin_target" msgid="3052256031352291362">"Pripnúť"</string> - <string name="unpin_target" msgid="3556545602439143442">"Uvoľniť"</string> <string name="app_info" msgid="6856026610594615344">"Info o aplikácii"</string> <string name="negative_duration" msgid="5688706061127375131">"-<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="demo_starting_message" msgid="5268556852031489931">"Spúšťa sa ukážka…"</string> @@ -2067,6 +2116,22 @@ <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Upozornenie s informáciami o rutinnom režime"</string> <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Batéria sa môže vybiť pred obvyklým nabitím"</string> <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Bol aktivovaný šetrič batérie na predĺženie výdrže batérie"</string> + <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) --> + <skip /> + <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) --> + <skip /> + <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) --> + <skip /> <string name="mime_type_folder" msgid="7111951698626315204">"Priečinok"</string> <string name="mime_type_apk" msgid="5518003630972506900">"Aplikácia pre Android"</string> <string name="mime_type_generic" msgid="6833871596845900027">"Súbor"</string> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index 16ea0b7c282b..41f81efc084f 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -141,8 +141,10 @@ <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"வைஃபை அழைப்பு"</string> <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string> <string name="wifi_calling_off_summary" msgid="8720659586041656098">"ஆஃப்"</string> - <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"வைஃபைக்கு முன்னுரிமை"</string> - <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"மொபைல் தரவிற்கு முன்னுரிமை"</string> + <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) --> + <skip /> + <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) --> + <skip /> <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"வைஃபை மட்டும்"</string> <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: பகிரப்படவில்லை"</string> <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> @@ -228,7 +230,8 @@ <string name="global_action_bug_report" msgid="7934010578922304799">"பிழை அறிக்கை"</string> <string name="global_action_logout" msgid="935179188218826050">"அமர்வை முடிக்கிறது"</string> <string name="global_action_screenshot" msgid="8329831278085426283">"ஸ்கிரீன்ஷாட்"</string> - <string name="bugreport_title" msgid="2667494803742548533">"பிழை அறிக்கையை எடு"</string> + <!-- no translation found for bugreport_title (5981047024855257269) --> + <skip /> <string name="bugreport_message" msgid="398447048750350456">"உங்கள் நடப்புச் சாதன நிலையை மின்னஞ்சல் செய்தியாக அனுப்ப, அது குறித்த தகவலை இது சேகரிக்கும். பிழை அறிக்கையைத் தொடங்குவதில் இருந்து, அது அனுப்புவதற்குத் தயாராகும் வரை, இதற்குச் சிறிது நேரம் ஆகும்; பொறுமையாகக் காத்திருக்கவும்."</string> <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"ஊடாடத்தக்க அறிக்கை"</string> <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"பெரும்பாலான சூழ்நிலைகளில் இதைப் பயன்படுத்தவும். இது அறிக்கையின் நிலையைக் கண்காணிக்க, சிக்கலைப் பற்றி மேலும் விவரங்களை உள்ளிட மற்றும் ஸ்கிரீன் ஷாட்டுகளை எடுக்க அனுமதிக்கும். அறிக்கையிட நீண்ட நேரம் எடுக்கக்கூடிய குறைவாகப் பயன்படுத்தப்படும் பிரிவுகள் சிலவற்றை இது தவிர்க்கக்கூடும்."</string> @@ -281,9 +284,12 @@ <string name="permgrouplab_location" msgid="7275582855722310164">"இருப்பிடம்"</string> <string name="permgroupdesc_location" msgid="1346617465127855033">"இந்தச் சாதனத்தின் இருப்பிடத்தை அறிந்து கொள்ள"</string> <string name="permgrouprequest_location" msgid="3788275734953323491">"இந்தச் சாதனத்தின் இருப்பிடத்தை அணுகுவதற்கு <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ஆப்ஸை அனுமதிக்கவா?"</string> - <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"இந்த ஆப்ஸைப் பயன்படுத்தும் சமயத்தில் மட்டுமே, இது உங்கள் இருப்பிடத்தை அணுகும்."</string> - <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"இதன் இருப்பிடத்தை எப்போதுமே <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> அணுக அனுமதிக்கவா?"</string> - <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"இந்த ஆப்ஸைப் பயன்படுத்தாத சமயங்களில் கூட, இது உங்கள் இருப்பிடத்தை அணுகும்."</string> + <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) --> + <skip /> <string name="permgrouplab_calendar" msgid="5863508437783683902">"கேலெண்டர்"</string> <string name="permgroupdesc_calendar" msgid="3889615280211184106">"கேலெண்டரை அணுகலாம்"</string> <string name="permgrouprequest_calendar" msgid="289900767793189421">"கேலெண்டரை அணுகுவதற்கு <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> பயன்பாட்டை அனுமதிக்கவா?"</string> @@ -308,17 +314,17 @@ <string name="permgrouplab_phone" msgid="5229115638567440675">"ஃபோன்"</string> <string name="permgroupdesc_phone" msgid="6234224354060641055">"யாரையும் தொலைபேசியில் அழைக்கலாம்"</string> <string name="permgrouprequest_phone" msgid="9166979577750581037">"மொபைல் அழைப்புகள் செய்யவும், அவற்றை நிர்வகிக்கவும், <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ஆப்ஸை அனுமதிக்கவா?"</string> - <!-- no translation found for permgrouplab_sensors (4838614103153567532) --> - <skip /> + <string name="permgrouplab_sensors" msgid="4838614103153567532">"உடல் சென்சார்கள்"</string> <string name="permgroupdesc_sensors" msgid="7147968539346634043">"உங்கள் உடல் இயக்கம் பற்றி உணர்விகள் கூறும் தகவலைப் பார்க்கலாம்"</string> <string name="permgrouprequest_sensors" msgid="6349806962814556786">"உங்கள் உடலியக்கக் குறிகள் பற்றிய சென்சார் தரவை அணுகுவதற்கு <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> பயன்பாட்டை அனுமதிக்கவா?"</string> <string name="permgrouplab_aural" msgid="965607064083134896">"இசை"</string> <string name="permgroupdesc_aural" msgid="4870189506255958055">"இசையைக் கேட்கலாம்"</string> <string name="permgrouprequest_aural" msgid="6787926123071735620">"இசையை அணுக <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ஆப்ஸை அனுமதிக்கவா?"</string> - <!-- no translation found for permgrouplab_visual (6477382108771145134) --> - <skip /> + <string name="permgrouplab_visual" msgid="6477382108771145134">"படங்கள் & வீடியோக்கள்"</string> <string name="permgroupdesc_visual" msgid="3415827902566663546">"படங்கள் & வீடியோக்களைப் பார்க்கலாம்"</string> - <!-- no translation found for permgrouprequest_visual (3043752127595243314) --> + <!-- no translation found for permgrouprequest_visual (4926581398380334943) --> + <skip /> + <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) --> <skip /> <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"சாளர உள்ளடக்கத்தைப் பெறும்"</string> <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"நீங்கள் பணியாற்றிக் கொண்டிருக்கும் சாளரத்தின் உள்ளடக்கத்தைப் பார்க்கலாம்."</string> @@ -512,8 +518,10 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"குறுகிய இடைவெளி தகவல்பரிமாற்றம் (NFC), குறிகள், கார்டுகள் மற்றும் ரீடர்கள் ஆகியவற்றுடன் தொடர்புகொள்ள, பயன்பாட்டை அனுமதிக்கிறது."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"உங்கள் திரைப் பூட்டை முடக்குதல்"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"விசைப்பூட்டையும், தொடர்புடைய கடவுச்சொல் பாதுகாப்பையும் முடக்கப் பயன்பாட்டை அனுமதிக்கிறது. எடுத்துக்காட்டாக, உள்வரும் மொபைல் அழைப்பைப் பெறும்போது மொபைல் விசைப்பூட்டை முடக்குகிறது, பிறகு அழைப்பு முடிந்தவுடன் விசைப்பூட்டை மீண்டும் இயக்குகிறது."</string> - <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"திரைப் பூட்டு தொடர்பான சிக்கலைத் தீர்க்க அனுமதி கோருதல்"</string> - <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"திரைப் பூட்டு தொடர்பான சிக்கலின் தன்மையைப் பற்றி (அதிகம், நடுத்தரம், குறைவு அல்லது ஏதுமில்லை) அறிந்துகொள்ள ஆப்ஸை அனுமதிக்கிறது. இதன் மூலம் திரைப் பூட்டின் பாதுகாப்பு அளவையும் வகையையும் பற்றி அறிந்துகொள்ள முடிகிறது. மேலும் திரைப் பூட்டு தொடர்பான சிக்கலின் தன்மையைக் குறிப்பிட்ட நிலைக்கு மாற்றிக் கொள்ளலாம் என்பதையும் ஆப்ஸ் பயனர்களுக்குப் பரிந்துரைக்கலாம். ஆனால் தங்கள் விருப்பப்படி அவற்றைப் பயனர்கள் நிராகரிக்கவோ ஏற்கவோ செய்யலாம். கவனத்திற்கு: திரைப் பூட்டு எளிய உரையிலான கடவுச்சொல்லால் சேமிக்கப்படுவதில்லை என்பதால் சரியான கடவுச்சொல்லை ஆப்ஸால் அறிய இயலாது."</string> + <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) --> + <skip /> + <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) --> + <skip /> <string name="permlab_useBiometric" msgid="8837753668509919318">"பயோமெட்ரிக் வன்பொருளைப் பயன்படுத்து"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"பயோமெட்ரிக் வன்பொருளைப் பயன்படுத்தி அங்கீகரிப்பதற்கு, பயன்பாட்டை அனுமதிக்கும்"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"கைரேகை வன்பொருளை நிர்வகி"</string> @@ -568,37 +576,59 @@ <string name="permdesc_manageFace" msgid="8919637120670185330">"உபயோகிப்பதற்காக முக டெம்ப்ளேட்டுகளை சேர்க்கும்/நீக்கும் முறைகளை இயக்க, ஆப்ஸை அனுமதிக்கும்."</string> <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"முக அங்கீகாரத்திற்கான வன்பொருளைப் பயன்படுத்துதல்"</string> <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"அடையாளம் காண்பதற்கு, முக அங்கீகார வன்பொருளைப் பயன்படுத்த ஆப்ஸை அனுமதிக்கிறது"</string> - <string name="face_acquired_insufficient" msgid="5901287247766106330">"அடையாளம் காண முடியவில்லை. மீண்டும் முயலவும்."</string> - <string name="face_acquired_too_bright" msgid="610606792381297174">"முகம் பிரகாசமாக உள்ளது. குறைந்த ஒளியில் முயலவும்."</string> - <string name="face_acquired_too_dark" msgid="7229162716976778371">"முகம் தெரியவில்லை, வெளிச்சமான இடத்தில் முயலவும்."</string> - <string name="face_acquired_too_close" msgid="1980310037427755293">"சென்சாரை முகத்திலிருந்து சற்று தொலைவில் நகர்த்துக."</string> - <string name="face_acquired_too_far" msgid="4494571381828850007">"சென்சாரை முகத்திற்கு அருகில் கொண்டு வரவும்."</string> - <string name="face_acquired_too_high" msgid="228411096134808372">"சென்சாரை மேலே உயர்த்தவும்."</string> - <string name="face_acquired_too_low" msgid="4539774649296349109">"சென்சாரைக் கீழே நகர்த்தவும்."</string> - <string name="face_acquired_too_right" msgid="1650292067226118760">"சென்சாரை வலது புறமாக நகர்த்தவும்."</string> - <string name="face_acquired_too_left" msgid="2712489669456176505">"சென்சாரை இடது புறமாக நகர்த்தவும்."</string> - <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"சென்சாரைப் பார்க்கவும்."</string> - <string name="face_acquired_not_detected" msgid="5707782294589511391">"முகம் தெரியவில்லை."</string> - <string name="face_acquired_too_much_motion" msgid="470381210701463822">"சாதனம் அதிகமாக அசைகிறது."</string> + <!-- no translation found for face_acquired_insufficient (2767330364802375742) --> + <skip /> + <!-- no translation found for face_acquired_too_bright (5005650874582450967) --> + <skip /> + <!-- no translation found for face_acquired_too_dark (1966194696381394616) --> + <skip /> + <!-- no translation found for face_acquired_too_close (1401011882624272753) --> + <skip /> + <!-- no translation found for face_acquired_too_far (1210969240069012510) --> + <skip /> + <!-- no translation found for face_acquired_too_high (3362395713403348013) --> + <skip /> + <!-- no translation found for face_acquired_too_low (488983581737550912) --> + <skip /> + <!-- no translation found for face_acquired_too_right (941726879175375970) --> + <skip /> + <!-- no translation found for face_acquired_too_left (5873592047381190672) --> + <skip /> + <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) --> + <skip /> + <!-- no translation found for face_acquired_not_detected (4885504661626728809) --> + <skip /> + <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) --> + <skip /> <string name="face_acquired_recalibrate" msgid="8077949502893707539">"உங்கள் முகத்தை மீண்டும் பதிவுசெய்யுங்கள்."</string> - <string name="face_acquired_too_different" msgid="5553210341111255124">"வேறு முகம் கண்டறியப்பட்டது."</string> + <!-- no translation found for face_acquired_too_different (7663983770123789694) --> + <skip /> <string name="face_acquired_too_similar" msgid="1508776858407646460">"மீண்டும் அதே போஸ் தருகிறீர்கள், வேறு முயலுங்கள்."</string> - <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"கேமராவை நேரடியாகப் பாருங்கள்."</string> - <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"கேமராவை நேரடியாகப் பாருங்கள்."</string> + <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) --> + <skip /> + <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"உங்கள் தலையை நேராக வைக்கவும்."</string> - <string name="face_acquired_obscured" msgid="3055077697850272097">"முகத்தை மறைக்காதீர்கள்."</string> + <!-- no translation found for face_acquired_obscured (5747521031647744553) --> + <skip /> + <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) --> + <skip /> <string-array name="face_acquired_vendor"> </string-array> <string name="face_error_hw_not_available" msgid="6255891785768984615">"முக அங்கீகாரத்திற்கான வன்பொருள் இல்லை."</string> - <string name="face_error_timeout" msgid="4014326147867150054">"முகப் பதிவிற்கான நேரம் முடிந்தது. மீண்டும் முயல்க."</string> + <!-- no translation found for face_error_timeout (2605673935810019129) --> + <skip /> <string name="face_error_no_space" msgid="8224993703466381314">"முகத்தைச் சேமிக்க இயலாது."</string> <string name="face_error_canceled" msgid="283945501061931023">"முக அங்கீகாரச் செயல்பாடு ரத்துசெய்யப்பட்டது."</string> <string name="face_error_user_canceled" msgid="8943921120862164539">"பயனர், முக அங்கீகாரத்தை ரத்துசெய்தார்."</string> <string name="face_error_lockout" msgid="3407426963155388504">"பலமுறை முயன்றுவிட்டீர்கள். பிறகு முயலவும்."</string> <string name="face_error_lockout_permanent" msgid="8198354656746088890">"பலமுறை தோல்வி. முக அங்கீகாரம் முடக்கப்பட்டது."</string> - <string name="face_error_unable_to_process" msgid="238761109287767270">"மீண்டும் முயலவும்."</string> - <string name="face_error_not_enrolled" msgid="9166792142679691323">"முகம் எதுவும் பதிவு செய்யப்படவில்லை."</string> - <string name="face_error_hw_not_present" msgid="916085883581450331">"இந்தச் சாதனத்தில் முக அங்கீகாரத்திற்கான சென்சார் இல்லை."</string> + <!-- no translation found for face_error_unable_to_process (4940944939691171539) --> + <skip /> + <!-- no translation found for face_error_not_enrolled (4245760276260427472) --> + <skip /> + <!-- no translation found for face_error_hw_not_present (5296043240874659926) --> + <skip /> <string name="face_name_template" msgid="7004562145809595384">"முகம் <xliff:g id="FACEID">%d</xliff:g>"</string> <string-array name="face_error_vendor"> </string-array> @@ -1216,9 +1246,16 @@ <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g> பயன்பாட்டைத் திற"</string> <string name="new_app_description" msgid="5894852887817332322">"சேமிக்கப்படாமலேயே <xliff:g id="OLD_APP">%1$s</xliff:g> மூடப்படும்"</string> <string name="dump_heap_notification" msgid="2618183274836056542">"நினைவக வரம்பை <xliff:g id="PROC">%1$s</xliff:g> மீறியது"</string> + <!-- no translation found for dump_heap_ready_notification (1162196579925048701) --> + <skip /> <string name="dump_heap_notification_detail" msgid="3993078784053054141">"ஹீப் டம்ப் சேகரிக்கப்பட்டது. பகிர, தட்டவும்."</string> <string name="dump_heap_title" msgid="5864292264307651673">"ஹீப் டம்பைப் பகிரவா?"</string> - <string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="SIZE">%2$s</xliff:g> அளவான தனது செயலாக்க நினைவக வரம்பை <xliff:g id="PROC">%1$s</xliff:g> செயலாக்கம் மீறியது. உங்களுக்கான ஹீப் டம்பினை அதன் டெவெலப்பருடன் பகிரலாம். கவனம்: பயன்பாடு அணுகும் விதத்தில், உங்களைப் பற்றிய எந்தத் தனிப்பட்ட தகவலும் இந்த ஹீப் டம்பில் இருக்கலாம் என்பதை நினைவில்கொள்ளவும்."</string> + <!-- no translation found for dump_heap_text (8546022920319781701) --> + <skip /> + <!-- no translation found for dump_heap_system_text (1205466256312104134) --> + <skip /> + <!-- no translation found for dump_heap_ready_text (6759394977904051000) --> + <skip /> <string name="sendText" msgid="5209874571959469142">"உரைக்கான செயலைத் தேர்வுசெய்யவும்"</string> <string name="volume_ringtone" msgid="6885421406845734650">"ரிங்கரின் ஒலியளவு"</string> <string name="volume_music" msgid="5421651157138628171">"மீடியாவின் ஒலியளவு"</string> @@ -1257,8 +1294,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"எல்லா நெட்வொர்க்குகளையும் பார்க்க, தட்டவும்"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"இணை"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"எல்லா நெட்வொர்க்குகளும்"</string> - <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g> பரிந்துரைத்த வைஃபை நெட்வொர்க் கிடைக்கிறது"</string> - <string name="wifi_suggestion_content" msgid="2658317015552324848">"<xliff:g id="NAME">%s</xliff:g> பரிந்துரைத்த நெட்வொர்க்குகளுடன் இணைக்க வேண்டுமா?"</string> + <!-- no translation found for wifi_suggestion_title (9099832833531486167) --> + <skip /> + <!-- no translation found for wifi_suggestion_content (5883181205841582873) --> + <skip /> <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"சரி"</string> <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"வேண்டாம்"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"வைஃபை தானாக ஆன் ஆகும்"</string> @@ -1270,9 +1309,14 @@ <string name="network_available_sign_in" msgid="1848877297365446605">"நெட்வொர்க்கில் உள்நுழையவும்"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> <skip /> - <string name="wifi_no_internet" msgid="8938267198124654938">"வைஃபையில் இண்டர்நெட் அணுகல் இல்லை"</string> + <!-- no translation found for wifi_no_internet (5198100389964214865) --> + <skip /> <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"விருப்பங்களுக்கு, தட்டவும்"</string> <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"இணைக்கப்பட்டது"</string> + <!-- no translation found for network_partial_connectivity (7774883385494762741) --> + <skip /> + <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) --> + <skip /> <string name="wifi_softap_config_change" msgid="8475911871165857607">"உங்கள் ஹாட்ஸ்பாட் அமைப்புகளில் செய்யப்பட்டுள்ள மாற்றங்கள்"</string> <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"உங்கள் ஹாட்ஸ்பாட்டின் அலைவரிசை மாறிவிட்டது."</string> <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"இந்தச் சாதனத்தில், ’5GHz மட்டும்’ எனும் முன்னுரிமைத் தேர்வு ஆதரிக்கப்படவில்லை. எனினும் 5GHz அலைவரிசை கிடைக்கும்போது, சாதனம் அதைப் பயன்படுத்திக்கொள்ளும்."</string> @@ -1358,6 +1402,10 @@ <string name="adb_active_notification_title" msgid="6729044778949189918">"USB பிழைதிருத்தம் இணைக்கப்பட்டது"</string> <string name="adb_active_notification_message" msgid="7463062450474107752">"USB பிழைதிருத்தத்தை ஆஃப் செய்ய, தட்டவும்"</string> <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB பிழைதிருத்தத்தை முடக்க, தேர்ந்தெடுக்கவும்."</string> + <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) --> + <skip /> + <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) --> + <skip /> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB போர்ட்டில் சேதம் உள்ளது"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB போர்ட் தானாகவே முடக்கப்பட்டது மேலும் அறிய, தட்டவும்."</string> <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB போர்ட்டைப் பாதுகாப்பாகப் பயன்படுத்தலாம்"</string> @@ -1909,8 +1957,6 @@ <string name="profile_encrypted_message" msgid="6964994232310195874">"பணிக் கணக்கை திறக்க, தட்டுக"</string> <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> உடன் இணைக்கப்பட்டது"</string> <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"கோப்புகளைப் பார்க்க, தட்டவும்"</string> - <string name="pin_target" msgid="3052256031352291362">"பின் செய்"</string> - <string name="unpin_target" msgid="3556545602439143442">"பின்னை அகற்று"</string> <string name="app_info" msgid="6856026610594615344">"பயன்பாட்டுத் தகவல்"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="demo_starting_message" msgid="5268556852031489931">"டெமோவைத் தொடங்குகிறது…"</string> @@ -2001,6 +2047,22 @@ <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"வழக்கமான பேட்டரி சேமிப்பானுக்கான விவர அறிவிப்பு"</string> <string name="dynamic_mode_notification_title" msgid="508815255807182035">"வழக்கமாகச் சார்ஜ் செய்வதற்கு முன்பே பேட்டரி தீர்ந்துபோகக்கூடும்"</string> <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"பேட்டரி நிலையை நீட்டிக்க பேட்டரி சேமிப்பான் இயக்கப்பட்டுள்ளது"</string> + <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) --> + <skip /> + <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) --> + <skip /> + <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) --> + <skip /> <string name="mime_type_folder" msgid="7111951698626315204">"கோப்புறை"</string> <string name="mime_type_apk" msgid="5518003630972506900">"Android ஆப்ஸ்"</string> <string name="mime_type_generic" msgid="6833871596845900027">"ஃபைல்"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 5f237a7a5a56..f3ae7631acb7 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -141,8 +141,10 @@ <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Gọi qua Wi-Fi"</string> <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string> <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Tắt"</string> - <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Ưu tiên Wi-Fi"</string> - <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Ưu tiên dữ liệu di động"</string> + <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) --> + <skip /> + <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) --> + <skip /> <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Chỉ Wi-Fi"</string> <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Không được chuyển tiếp"</string> <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> @@ -228,7 +230,8 @@ <string name="global_action_bug_report" msgid="7934010578922304799">"Báo cáo lỗi"</string> <string name="global_action_logout" msgid="935179188218826050">"Kết thúc phiên"</string> <string name="global_action_screenshot" msgid="8329831278085426283">"Chụp ảnh màn hình"</string> - <string name="bugreport_title" msgid="2667494803742548533">"Tạo báo cáo lỗi"</string> + <!-- no translation found for bugreport_title (5981047024855257269) --> + <skip /> <string name="bugreport_message" msgid="398447048750350456">"Báo cáo này sẽ thu thập thông tin về tình trạng thiết bị hiện tại của bạn, để gửi dưới dạng thông báo qua email. Sẽ mất một chút thời gian kể từ khi bắt đầu báo cáo lỗi cho tới khi báo cáo sẵn sàng để gửi; xin vui lòng kiên nhẫn."</string> <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Báo cáo tương tác"</string> <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Sử dụng tùy chọn này trong hầu hết các trường hợp. Tùy chọn này cho phép bạn theo dõi tiến trình của báo cáo, nhập thêm thông tin chi tiết về sự cố cũng như chụp ảnh màn hình. Tùy chọn này có thể bỏ qua một số phần ít được sử dụng mà mất nhiều thời gian để báo cáo."</string> @@ -281,9 +284,12 @@ <string name="permgrouplab_location" msgid="7275582855722310164">"Vị trí"</string> <string name="permgroupdesc_location" msgid="1346617465127855033">"truy cập vị trí của thiết bị này"</string> <string name="permgrouprequest_location" msgid="3788275734953323491">"Cho phép <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> truy cập vào vị trí của thiết bị này?"</string> - <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Ứng dụng sẽ chỉ có quyền truy cập vào vị trí khi bạn sử dụng."</string> - <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Luôn cho phép <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> truy cập vị trí thiết bị?"</string> - <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Ứng dụng sẽ luôn có quyền truy cập vào vị trí, ngay cả khi bạn không sử dụng."</string> + <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) --> + <skip /> + <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) --> + <skip /> <string name="permgrouplab_calendar" msgid="5863508437783683902">"Lịch"</string> <string name="permgroupdesc_calendar" msgid="3889615280211184106">"truy cập lịch của bạn"</string> <string name="permgrouprequest_calendar" msgid="289900767793189421">"Cho phép <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> truy cập vào lịch của bạn?"</string> @@ -316,7 +322,10 @@ <string name="permgrouprequest_aural" msgid="6787926123071735620">"Bạn có muốn cho phép <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> sử dụng nhạc không?"</string> <string name="permgrouplab_visual" msgid="6477382108771145134">"Ảnh và video"</string> <string name="permgroupdesc_visual" msgid="3415827902566663546">"sử dụng ảnh và video"</string> - <string name="permgrouprequest_visual" msgid="3043752127595243314">"Cho phép <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> truy cập vào ảnh và video của bạn, bao gồm cả vị trí được gắn thẻ?"</string> + <!-- no translation found for permgrouprequest_visual (4926581398380334943) --> + <skip /> + <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) --> + <skip /> <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Truy xuất nội dung cửa sổ"</string> <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Kiểm tra nội dung của cửa sổ bạn đang tương tác."</string> <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Bật Khám phá bằng cách chạm"</string> @@ -509,8 +518,10 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Cho phép ứng dụng giao tiếp với thẻ Giao tiếp trường gần (NFC), thẻ và trình đọc."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"vô hiệu hóa khóa màn hình của bạn"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Cho phép ứng dụng tắt khóa phím và bất kỳ bảo mật mật khẩu được liên kết nào. Ví dụ: điện thoại tắt khóa phím khi nhận được cuộc gọi đến, sau đó bật lại khóa phím khi cuộc gọi kết thúc."</string> - <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"yêu cầu mức độ phức tạp của khóa màn hình"</string> - <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Cho phép ứng dụng nắm được độ phức tạp của khóa màn hình (cao, trung bình, thấp hoặc không có). Mức độ này cho biết khoảng độ dài và loại khóa màn hình có thể có. Ứng dụng cũng có thể gợi ý người dùng nên cập nhật khóa màn hình lên một mức độ nhất định, nhưng người dùng có thể tùy ý bỏ qua và chuyển sang phần khác. Xin lưu ý rằng khóa màn hình không được lưu trữ dưới dạng văn bản thuần túy, vì vậy ứng dụng sẽ không biết mật khẩu chính xác."</string> + <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) --> + <skip /> + <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) --> + <skip /> <string name="permlab_useBiometric" msgid="8837753668509919318">"sử dụng phần cứng sinh trắc học"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Cho phép ứng dụng dùng phần cứng sinh trắc học để xác thực"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"quản lý phần cứng vân tay"</string> @@ -565,37 +576,59 @@ <string name="permdesc_manageFace" msgid="8919637120670185330">"Cho phép ứng dụng gọi ra các phương pháp để thêm và xóa mẫu khuôn mặt sử dụng."</string> <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"sử dụng phần cứng xác thực khuôn mặt"</string> <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Cho phép ứng dụng sử dụng phần cứng xác thực khuôn mặt để tiến hành xác thực"</string> - <string name="face_acquired_insufficient" msgid="5901287247766106330">"Không thể xử lý khuôn mặt. Vui lòng thử lại."</string> - <string name="face_acquired_too_bright" msgid="610606792381297174">"Khuôn mặt quá sáng. Hãy thử dưới ánh sáng yếu hơn."</string> - <string name="face_acquired_too_dark" msgid="7229162716976778371">"Khuôn mặt quá tối. Hãy tìm nguồn sáng tốt hơn."</string> - <string name="face_acquired_too_close" msgid="1980310037427755293">"Hãy đưa cảm biến ra xa khuôn mặt hơn."</string> - <string name="face_acquired_too_far" msgid="4494571381828850007">"Hãy đưa cảm biến lại gần khuôn mặt hơn."</string> - <string name="face_acquired_too_high" msgid="228411096134808372">"Hãy đưa cảm biến lên cao hơn."</string> - <string name="face_acquired_too_low" msgid="4539774649296349109">"Hãy đưa cảm biến xuống thấp hơn."</string> - <string name="face_acquired_too_right" msgid="1650292067226118760">"Hãy đưa cảm biến sang bên phải."</string> - <string name="face_acquired_too_left" msgid="2712489669456176505">"Hay đưa cảm biến sang bên trái."</string> - <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Hãy nhìn vào cảm biến."</string> - <string name="face_acquired_not_detected" msgid="5707782294589511391">"Không phát hiện được khuôn mặt nào."</string> - <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Thiết bị chuyển động quá nhiều."</string> + <!-- no translation found for face_acquired_insufficient (2767330364802375742) --> + <skip /> + <!-- no translation found for face_acquired_too_bright (5005650874582450967) --> + <skip /> + <!-- no translation found for face_acquired_too_dark (1966194696381394616) --> + <skip /> + <!-- no translation found for face_acquired_too_close (1401011882624272753) --> + <skip /> + <!-- no translation found for face_acquired_too_far (1210969240069012510) --> + <skip /> + <!-- no translation found for face_acquired_too_high (3362395713403348013) --> + <skip /> + <!-- no translation found for face_acquired_too_low (488983581737550912) --> + <skip /> + <!-- no translation found for face_acquired_too_right (941726879175375970) --> + <skip /> + <!-- no translation found for face_acquired_too_left (5873592047381190672) --> + <skip /> + <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) --> + <skip /> + <!-- no translation found for face_acquired_not_detected (4885504661626728809) --> + <skip /> + <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) --> + <skip /> <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Vui lòng đăng ký lại khuôn mặt của bạn."</string> - <string name="face_acquired_too_different" msgid="5553210341111255124">"Đã phát hiện thấy khuôn mặt khác."</string> + <!-- no translation found for face_acquired_too_different (7663983770123789694) --> + <skip /> <string name="face_acquired_too_similar" msgid="1508776858407646460">"Khuôn mặt quá giống nhau, vui lòng đổi tư thế."</string> - <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Vui lòng nhìn thẳng vào máy ảnh."</string> - <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Vui lòng nhìn thẳng vào máy ảnh."</string> + <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) --> + <skip /> + <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Vui lòng giữ thẳng đầu."</string> - <string name="face_acquired_obscured" msgid="3055077697850272097">"Vui lòng không che mặt của bạn."</string> + <!-- no translation found for face_acquired_obscured (5747521031647744553) --> + <skip /> + <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) --> + <skip /> <string-array name="face_acquired_vendor"> </string-array> <string name="face_error_hw_not_available" msgid="6255891785768984615">"Không truy cập được phần cứng nhận dạng khuôn mặt."</string> - <string name="face_error_timeout" msgid="4014326147867150054">"Đã hết thời gian chờ khuôn mặt. Hãy thử lại."</string> + <!-- no translation found for face_error_timeout (2605673935810019129) --> + <skip /> <string name="face_error_no_space" msgid="8224993703466381314">"Không thể lưu khuôn mặt."</string> <string name="face_error_canceled" msgid="283945501061931023">"Đã hủy thao tác dùng khuôn mặt."</string> <string name="face_error_user_canceled" msgid="8943921120862164539">"Người dùng đã hủy thao tác xác thực khuôn mặt."</string> <string name="face_error_lockout" msgid="3407426963155388504">"Bạn đã thử quá nhiều lần. Hãy thử lại sau."</string> <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Đã thử quá nhiều lần. Đã tắt xác thực khuôn mặt."</string> - <string name="face_error_unable_to_process" msgid="238761109287767270">"Hãy thử lại."</string> - <string name="face_error_not_enrolled" msgid="9166792142679691323">"Bạn chưa đăng ký khuôn mặt."</string> - <string name="face_error_hw_not_present" msgid="916085883581450331">"Thiết bị này không có cảm biến xác thực khuôn mặt."</string> + <!-- no translation found for face_error_unable_to_process (4940944939691171539) --> + <skip /> + <!-- no translation found for face_error_not_enrolled (4245760276260427472) --> + <skip /> + <!-- no translation found for face_error_hw_not_present (5296043240874659926) --> + <skip /> <string name="face_name_template" msgid="7004562145809595384">"Khuôn mặt <xliff:g id="FACEID">%d</xliff:g>"</string> <string-array name="face_error_vendor"> </string-array> @@ -1213,9 +1246,16 @@ <string name="new_app_action" msgid="6694851182870774403">"Mở <xliff:g id="NEW_APP">%1$s</xliff:g>"</string> <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> sẽ đóng mà không lưu"</string> <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> đã vượt quá giới hạn bộ nhớ"</string> + <!-- no translation found for dump_heap_ready_notification (1162196579925048701) --> + <skip /> <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Đã thu thập tệp báo lỗi. Hãy nhấn để chia sẻ."</string> <string name="dump_heap_title" msgid="5864292264307651673">"Chia sẻ tệp báo lỗi?"</string> - <string name="dump_heap_text" msgid="4809417337240334941">"Quá trình <xliff:g id="PROC">%1$s</xliff:g> đã vượt quá giới hạn bộ nhớ xử lý <xliff:g id="SIZE">%2$s</xliff:g>. Tệp báo lỗi khả dụng để bạn chia sẻ với nhà phát triển. Hãy cẩn thận: tệp báo lỗi này có thể chứa bất kỳ thông tin cá nhân nào mà ứng dụng có quyền truy cập."</string> + <!-- no translation found for dump_heap_text (8546022920319781701) --> + <skip /> + <!-- no translation found for dump_heap_system_text (1205466256312104134) --> + <skip /> + <!-- no translation found for dump_heap_ready_text (6759394977904051000) --> + <skip /> <string name="sendText" msgid="5209874571959469142">"Chọn một tác vụ cho văn bản"</string> <string name="volume_ringtone" msgid="6885421406845734650">"Âm lượng chuông"</string> <string name="volume_music" msgid="5421651157138628171">"Âm lượng phương tiện"</string> @@ -1254,8 +1294,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Nhấn để xem tất cả các mạng"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Kết nối"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Tất cả các mạng"</string> - <string name="wifi_suggestion_title" msgid="8951405130379148709">"Hiện có thể kết nối với mạng Wi‑Fi do <xliff:g id="NAME">%s</xliff:g> đề xuất"</string> - <string name="wifi_suggestion_content" msgid="2658317015552324848">"Bạn có muốn kết nối với các mạng do <xliff:g id="NAME">%s</xliff:g> đề xuất không?"</string> + <!-- no translation found for wifi_suggestion_title (9099832833531486167) --> + <skip /> + <!-- no translation found for wifi_suggestion_content (5883181205841582873) --> + <skip /> <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Có"</string> <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Không"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi sẽ tự động bật"</string> @@ -1267,9 +1309,14 @@ <string name="network_available_sign_in" msgid="1848877297365446605">"Đăng nhập vào mạng"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> <skip /> - <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi không có quyền truy cập Internet"</string> + <!-- no translation found for wifi_no_internet (5198100389964214865) --> + <skip /> <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Nhấn để biết tùy chọn"</string> <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Đã kết nối"</string> + <!-- no translation found for network_partial_connectivity (7774883385494762741) --> + <skip /> + <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) --> + <skip /> <string name="wifi_softap_config_change" msgid="8475911871165857607">"Những thay đổi trong mục cài đặt điểm phát sóng của bạn"</string> <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Bằng tần của điểm phát sóng đã thay đổi."</string> <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Thiết bị này không hỗ trợ tùy chọn chỉ sử dụng băng tần 5 GHz. Thay vào đó, thiết bị này sẽ sử dụng băng tần 5 GHz khi có thể."</string> @@ -1354,6 +1401,10 @@ <string name="adb_active_notification_title" msgid="6729044778949189918">"Đã kết nối gỡ lỗi USB"</string> <string name="adb_active_notification_message" msgid="7463062450474107752">"Nhấn để tắt tính năng gỡ lỗi USB"</string> <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Chọn để vô hiệu hóa gỡ lỗi USB."</string> + <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) --> + <skip /> + <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) --> + <skip /> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Có chất lỏng hoặc mảnh vỡ trong cổng USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Cổng USB đã tự động tắt. Nhấn để tìm hiểu thêm."</string> <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Có thể sử dụng cổng USB một cách an toàn"</string> @@ -1396,8 +1447,7 @@ <string name="ext_media_init_action" msgid="7952885510091978278">"Thiết lập"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Tháo"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Khám phá"</string> - <!-- no translation found for ext_media_seamless_action (6575980560886881233) --> - <skip /> + <string name="ext_media_seamless_action" msgid="6575980560886881233">"Chuyển đổi đầu ra"</string> <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> bị thiếu"</string> <string name="ext_media_missing_message" msgid="4012389235250987930">"Hãy lắp lại thiết bị"</string> <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Di chuyển <xliff:g id="NAME">%s</xliff:g>"</string> @@ -1906,8 +1956,6 @@ <string name="profile_encrypted_message" msgid="6964994232310195874">"Nhấn để mở khóa hồ sơ công việc"</string> <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Đã kết nối với <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string> <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Nhấn để xem tệp"</string> - <string name="pin_target" msgid="3052256031352291362">"Ghim"</string> - <string name="unpin_target" msgid="3556545602439143442">"Bỏ ghim"</string> <string name="app_info" msgid="6856026610594615344">"Thông tin ứng dụng"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="demo_starting_message" msgid="5268556852031489931">"Đang bắt đầu bản trình diễn..."</string> @@ -1998,6 +2046,22 @@ <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Thông báo cung cấp thông tin về chế độ sạc thông thường"</string> <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Pin có thể hết trước khi sạc bình thường"</string> <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Trình tiết kiệm pin được kích hoạt để kéo dài thời lượng pin"</string> + <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) --> + <skip /> + <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) --> + <skip /> + <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) --> + <skip /> + <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) --> + <skip /> + <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) --> + <skip /> <string name="mime_type_folder" msgid="7111951698626315204">"Thư mục"</string> <string name="mime_type_apk" msgid="5518003630972506900">"Ứng dụng Android"</string> <string name="mime_type_generic" msgid="6833871596845900027">"Tệp"</string> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 71e071c14557..dc0ec03ca7a2 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -58,6 +58,7 @@ <item><xliff:g id="id">@string/status_bar_mobile</xliff:g></item> <item><xliff:g id="id">@string/status_bar_airplane</xliff:g></item> <item><xliff:g id="id">@string/status_bar_battery</xliff:g></item> + <item><xliff:g id="id">@string/status_bar_sensors_off</xliff:g></item> </string-array> <string translatable="false" name="status_bar_rotate">rotate</string> @@ -92,6 +93,7 @@ <string translatable="false" name="status_bar_microphone">microphone</string> <string translatable="false" name="status_bar_camera">camera</string> <string translatable="false" name="status_bar_airplane">airplane</string> + <string translatable="false" name="status_bar_sensors_off">sensors_off</string> <!-- Flag indicating whether the surface flinger has limited alpha compositing functionality in hardware. If set, the window @@ -311,6 +313,15 @@ Settings.Global.NETWORK_AVOID_BAD_WIFI. This is the default value of that setting. --> <integer translatable="false" name="config_networkAvoidBadWifi">1</integer> + <!-- The URL returned by ConnectivityManager#getCaptivePortalServerUrl. The actual returned + value is controlled by Settings.Global.CAPTIVE_PORTAL_HTTP_URL. This is the default value + used if that setting is unset. + This is *NOT* a URL that will always be used by the system network validation to detect + captive portals: NetworkMonitor may use different strategies and will not necessarily use + this URL. NetworkMonitor behaviour should be configured with NetworkStack resource overlays + instead. --> + <string translatable="false" name="config_networkDefaultCaptivePortalServerUrl">http://connectivitycheck.gstatic.com/generate_204</string> + <!-- If the hardware supports specially marking packets that caused a wakeup of the main CPU, set this value to the mark used. --> <integer name="config_networkWakeupPacketMark">0</integer> @@ -914,6 +925,11 @@ case, this can be disabled (set to false). --> <bool name="config_enableCarDockHomeLaunch">true</bool> + <!-- Control whether to force the display of System UI Bars at all times regardless of + System Ui Flags. This can be useful in the Automotive case if there's a requirement for + a UI element to be on screen at all times. --> + <bool name="config_forceShowSystemBars">false</bool> + <!-- HDMI behavior --> <!-- The number of degrees to rotate the display when the device has HDMI connected @@ -3215,6 +3231,12 @@ --> <integer name="config_navBarOpacityMode">0</integer> + <!-- Controls the navigation bar interaction mode: + 0: 3 button mode (back, home, overview buttons) + 1: 2 button mode (back, home buttons + swipe up for overview) + 2: gestures only for back, home and overview --> + <integer name="config_navBarInteractionMode">0</integer> + <!-- Default insets [LEFT/RIGHTxTOP/BOTTOM] from the screen edge for picture-in-picture windows. These values are in DPs and will be converted to pixel sizes internally. --> <string translatable="false" name="config_defaultPictureInPictureScreenEdgeInsets">16x16</string> @@ -3738,9 +3760,6 @@ <!-- Package name for ManagedProvisioning which is responsible for provisioning work profiles. --> <string name="config_managed_provisioning_package" translatable="false">com.android.managedprovisioning</string> - <!-- Whether or not swipe up gesture is enabled by default --> - <bool name="config_swipe_up_gesture_default">false</bool> - <!-- Whether or not swipe up gesture's opt-in setting is available on this device --> <bool name="config_swipe_up_gesture_setting_available">false</bool> diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 7134eed8dde8..023fbaddfb83 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -578,7 +578,6 @@ <dimen name="default_magnifier_horizontal_offset">0dp</dimen> <item type="dimen" format="float" name="default_magnifier_zoom">1.25</item> - <dimen name="chooser_grid_padding">0dp</dimen> <!-- Spacing around the background change frome service to non-service --> <dimen name="chooser_service_spacing">8dp</dimen> @@ -725,4 +724,5 @@ <dimen name="chooser_preview_width">-1px</dimen> <dimen name="resolver_icon_size">42dp</dimen> <dimen name="resolver_badge_size">18dp</dimen> + <dimen name="chooser_target_width">76dp</dimen> </resources> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 24fd3a8718bb..bb473705b416 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -802,7 +802,7 @@ <string name="permgrouprequest_visual">Allow <b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g></b> to access your photos and videos?</string> <!-- Subtitle of the message shown to the user when the apps requests permission to access photos and videos [CHAR LIMIT=150]--> - <string name="permgrouprequestdetail_visual">Locations and other people in your photos and videos can be identified by the app</string> + <string name="permgrouprequestdetail_visual">This includes any locations tagged in your photos and videos</string> <!-- Title for the capability of an accessibility service to retrieve window content. --> <string name="capability_title_canRetrieveWindowContent">Retrieve window content</string> @@ -1584,7 +1584,7 @@ <!-- Error message shown when the face hardware can't be accessed. [CHAR LIMIT=50] --> <string name="face_error_hw_not_available">Face hardware not available.</string> <!-- Error message shown when the face hardware timer has expired and the user needs to restart the operation. [CHAR LIMIT=50] --> - <string name="face_error_timeout">Face time out reached. Try again.</string> + <string name="face_error_timeout">Face timeout reached. Try again.</string> <!-- Error message shown when the face hardware has run out of room for storing faces. [CHAR LIMIT=50] --> <string name="face_error_no_space">Face can\u2019t be stored.</string> <!-- Generic error message shown when the face operation (e.g. enrollment or authentication) is canceled. Generally not shown to the user. [CHAR LIMIT=50] --> @@ -1596,11 +1596,11 @@ <!-- Generic error message shown when the face operation fails because strong authentication is required. [CHAR LIMIT=50] --> <string name="face_error_lockout_permanent">Too many attempts. Facial authentication disabled.</string> <!-- Generic error message shown when the face hardware can't recognize the face. [CHAR LIMIT=50] --> - <string name="face_error_unable_to_process">Try again.</string> + <string name="face_error_unable_to_process">Can\u2019t verify face. Try again.</string> <!-- Generic error message shown when the user has no enrolled face. [CHAR LIMIT=50] --> - <string name="face_error_not_enrolled">No face enrolled.</string> + <string name="face_error_not_enrolled">You haven\u2019t set up face authentication.</string> <!-- Generic error message shown when the app requests face authentication on a device without a sensor. [CHAR LIMIT=60] --> - <string name="face_error_hw_not_present">This device does not have a face authentication sensor.</string> + <string name="face_error_hw_not_present">Face authentication is not supported on this device.</string> <!-- Template to be used to name enrolled faces by default. [CHAR LIMIT=10] --> <string name="face_name_template">Face <xliff:g id="faceId" example="1">%d</xliff:g></string> @@ -3283,18 +3283,36 @@ <string name="dump_heap_notification"><xliff:g id="proc">%1$s</xliff:g> exceeded memory limit</string> + <!-- Notification text to tell the user that a heap dump that they initiated for a process is ready [CHAR LIMIT=NONE] --> + <string name="dump_heap_ready_notification"> + <xliff:g id="proc" example="com.android.example">%1$s</xliff:g> heap dump ready</string> + <!-- Notification details to tell the user that a process has exceeded its memory limit. --> <string name="dump_heap_notification_detail">Heap dump collected. Tap to share.</string> <!-- Title of dialog prompting the user to share a heap dump. --> <string name="dump_heap_title">Share heap dump?</string> - <!-- Text of dialog prompting the user to share a heap dump. --> - <string name="dump_heap_text">The process <xliff:g id="proc">%1$s</xliff:g> has exceeded - its process memory limit of <xliff:g id="size">%2$s</xliff:g>. A heap dump is available + <!-- Text of dialog prompting the user to share a heap dump for an application [CHAR LIMIT=NONE] --> + <string name="dump_heap_text">The + <xliff:g id="proc" example="com.android.example">%1$s</xliff:g> process has exceeded + its memory limit of <xliff:g id="size" example="350MB">%2$s</xliff:g>. A heap dump is available for you to share with its developer. Be careful: this heap dump can contain any of your personal information that the application has access to.</string> + <!-- Text of dialog prompting the user to share a heap dump for a system process [CHAR LIMIT=NONE] --> + <string name="dump_heap_system_text">The + <xliff:g id="proc" example="Android System">%1$s</xliff:g> process has exceeded + its memory limit of <xliff:g id="size" example="350MB">%2$s</xliff:g>. A heap dump is available + for you to share. Be careful: this heap dump can contain any sensitive personal information + that the process has access to.</string> + + <!-- Text of dialog prompting the user to share a heap dump that they initiated [CHAR LIMIT=NONE] --> + <string name="dump_heap_ready_text">A heap dump of + <xliff:g id="proc" example="com.android.example">%1$s</xliff:g>\u2019s process is available + for you to share. Be careful: this heap dump may contain any sensitive personal information + that the process has access to.</string> + <!-- Displayed in the title of the chooser for things to do with text that is to be sent to another application. For example, I can send text through SMS or IM. A dialog with those choices would be shown, @@ -4816,11 +4834,14 @@ <!-- Notification shown when device owner silently deletes a package [CHAR LIMIT=NONE] --> <string name="package_deleted_device_owner">Deleted by your admin</string> + <!-- [CHAR LIMIT=25] String for confirmation button to enable a feature gated by the battery saver warning--> + <string name="confirm_battery_saver">Confirm</string> + <!-- [CHAR_LIMIT=NONE] Battery saver: Feature description, with a "learn more" link. --> - <string name="battery_saver_description_with_learn_more">To extend your battery life, Battery Saver turns off some device features and restricts apps. <annotation id="url">Learn More</annotation></string> + <string name="battery_saver_description_with_learn_more">Battery Saver turns off or restricts background activity, some visual effects \u0026 other high-power features to extend battery life. <annotation id="url">Learn More</annotation></string> <!-- [CHAR_LIMIT=NONE] Battery saver: Feature description, without a "learn more" link. --> - <string name="battery_saver_description">To extend your battery life, Battery Saver turns off some device features and restricts apps.</string> + <string name="battery_saver_description">Battery Saver turns off or restricts background activity, some visual effects \u0026 other high-power features to extend battery life.</string> <!-- [CHAR_LIMIT=NONE] Data saver: Feature description --> <string name="data_saver_description">To help reduce data usage, Data Saver prevents some apps from sending or receiving data in the background. An app you’re currently using can access data, but may do so less frequently. This may mean, for example, that images don’t display until you tap them.</string> @@ -5302,6 +5323,21 @@ <string name="battery_saver_sticky_disabled_notification_title">Battery Saver won\u2019t reactivate until battery low again</string> <!-- Summary of notification letting users know why battery saver didn't turn back on automatically after the device was unplugged [CHAR_LIMIT=NONE] --> <string name="battery_saver_sticky_disabled_notification_summary">Battery has been charged to a sufficient level. Battery Saver won\u2019t reactivate until the battery is low again.</string> + <!-- Title of notification letting users know the battery level at the time the notification was posted [CHAR_LIMIT=80] --> + <string name="battery_saver_charged_notification_title" product="default">Phone <xliff:g id="charge level" example="90%">%1$s</xliff:g> charged</string> + <!-- Title of notification letting users know the battery level at the time the notification was posted [CHAR_LIMIT=80] --> + <string name="battery_saver_charged_notification_title" product="tablet">Tablet <xliff:g id="charge level" example="90%">%1$s</xliff:g> charged</string> + <!-- Title of notification letting users know the battery level at the time the notification was posted [CHAR_LIMIT=80] --> + <string name="battery_saver_charged_notification_title" product="device">Device <xliff:g id="charge level" example="90%">%1$s</xliff:g> charged</string> + <!-- Summary of notification letting users know that battery saver is now off [CHAR_LIMIT=NONE] --> + <string name="battery_saver_off_notification_summary">Battery Saver is off. Features no longer restricted.</string> + <!-- Alternative summary of notification letting users know that battery saver has been turned off. + If it's easy to translate the difference between "Battery Saver turned off. Features no longer restricted." + and "Battery Saver is off. Features no longer restricted." into the target language, + then translate "Battery Saver turned off. Features no longer restricted." + If the translation doesn't make a difference or the difference is hard to capture in the target language, + then translate "Battery Saver is off. Features no longer restricted." instead. [CHAR_LIMIT=NONE] --> + <string name="battery_saver_off_alternative_notification_summary">Battery Saver turned off. Features no longer restricted.</string> <!-- Description of media type: folder or directory that contains additional files. [CHAR LIMIT=32] --> <string name="mime_type_folder">Folder</string> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 764c9c46826f..ae54a6aa4110 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1713,6 +1713,7 @@ <java-symbol type="bool" name="config_enableLockScreenRotation" /> <java-symbol type="bool" name="config_enableLockScreenTranslucentDecor" /> <java-symbol type="bool" name="config_enableTranslucentDecor" /> + <java-symbol type="bool" name="config_forceShowSystemBars" /> <java-symbol type="bool" name="config_lidControlsScreenLock" /> <java-symbol type="bool" name="config_lidControlsSleep" /> <java-symbol type="bool" name="config_lockDayNightMode" /> @@ -2004,6 +2005,7 @@ <java-symbol type="integer" name="config_networkNotifySwitchType" /> <java-symbol type="array" name="config_networkNotifySwitches" /> <java-symbol type="integer" name="config_networkAvoidBadWifi" /> + <java-symbol type="string" name="config_networkDefaultCaptivePortalServerUrl" /> <java-symbol type="integer" name="config_networkWakeupPacketMark" /> <java-symbol type="integer" name="config_networkWakeupPacketMask" /> <java-symbol type="bool" name="config_apfDrop802_3Frames" /> @@ -2114,8 +2116,11 @@ <java-symbol type="string" name="device_storage_monitor_notification_channel" /> <java-symbol type="string" name="dlg_ok" /> <java-symbol type="string" name="dump_heap_notification" /> + <java-symbol type="string" name="dump_heap_ready_notification" /> <java-symbol type="string" name="dump_heap_notification_detail" /> <java-symbol type="string" name="dump_heap_text" /> + <java-symbol type="string" name="dump_heap_ready_text" /> + <java-symbol type="string" name="dump_heap_system_text" /> <java-symbol type="string" name="dump_heap_title" /> <java-symbol type="string" name="factorytest_failed" /> <java-symbol type="string" name="factorytest_no_action" /> @@ -2761,6 +2766,7 @@ <java-symbol type="string" name="chooser_no_direct_share_targets" /> <java-symbol type="drawable" name="chooser_row_layer_list" /> <java-symbol type="dimen" name="chooser_view_spacing" /> + <java-symbol type="dimen" name="chooser_target_width" /> <java-symbol type="dimen" name="chooser_edge_margin_thin" /> <java-symbol type="dimen" name="chooser_edge_margin_normal" /> <java-symbol type="dimen" name="chooser_preview_image_font_size"/> @@ -2778,7 +2784,6 @@ <java-symbol type="layout" name="chooser_row" /> <java-symbol type="layout" name="chooser_row_direct_share" /> - <java-symbol type="id" name="target_badge" /> <java-symbol type="bool" name="config_supportDoubleTapWake" /> <java-symbol type="drawable" name="ic_perm_device_info" /> <java-symbol type="string" name="config_radio_access_family" /> @@ -2831,6 +2836,7 @@ <java-symbol type="string" name="config_packagedKeyboardName" /> <java-symbol type="bool" name="config_forceWindowDrawsStatusBarBackground" /> <java-symbol type="integer" name="config_navBarOpacityMode" /> + <java-symbol type="integer" name="config_navBarInteractionMode" /> <java-symbol type="color" name="system_bar_background_semi_transparent" /> <!-- EditText suggestion popup. --> @@ -2924,6 +2930,7 @@ <java-symbol type="string" name="status_bar_vpn" /> <java-symbol type="string" name="status_bar_microphone" /> <java-symbol type="string" name="status_bar_camera" /> + <java-symbol type="string" name="status_bar_sensors_off" /> <!-- Locale picker --> <java-symbol type="id" name="locale_search_menu" /> @@ -3508,7 +3515,6 @@ <java-symbol type="string" name="shortcut_restore_signature_mismatch" /> <java-symbol type="string" name="shortcut_restore_unknown_issue" /> - <java-symbol type="bool" name="config_swipe_up_gesture_default" /> <java-symbol type="bool" name="config_swipe_up_gesture_setting_available" /> <!-- From media projection --> @@ -3647,6 +3653,9 @@ <java-symbol type="string" name="battery_saver_notification_channel_name" /> <java-symbol type="string" name="battery_saver_sticky_disabled_notification_title" /> <java-symbol type="string" name="battery_saver_sticky_disabled_notification_summary" /> + <java-symbol type="string" name="battery_saver_charged_notification_title" /> + <java-symbol type="string" name="battery_saver_off_notification_summary" /> + <java-symbol type="string" name="battery_saver_off_alternative_notification_summary" /> <java-symbol type="string" name="dynamic_mode_notification_channel_name" /> <java-symbol type="string" name="dynamic_mode_notification_title" /> <java-symbol type="string" name="dynamic_mode_notification_summary" /> diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index 6fb4744f6a77..8fc6a9694586 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -129,7 +129,7 @@ public class SettingsBackupTest { Settings.Global.AUTOFILL_LOGGING_LEVEL, Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE, Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS, - Settings.Global.AUTOMATIC_POWER_SAVER_MODE, + Settings.Global.AUTOMATIC_POWER_SAVE_MODE, Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, Settings.Global.BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST, Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY, @@ -623,7 +623,6 @@ public class SettingsBackupTest { Settings.Secure.DEFAULT_INPUT_METHOD, Settings.Secure.DEVICE_PAIRED, Settings.Secure.DIALER_DEFAULT_APPLICATION, - Settings.Secure.DISABLE_AIRPLANE_MODE_AFTER_SP_DISABLED, Settings.Secure.DISABLED_PRINT_SERVICES, Settings.Secure.DISABLED_SYSTEM_INPUT_METHODS, Settings.Secure.DISPLAY_DENSITY_FORCED, @@ -647,8 +646,6 @@ public class SettingsBackupTest { Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT, // Candidate? Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, Settings.Secure.LOCK_TO_APP_EXIT_LOCKED, - Settings.Secure.MAINTAIN_AIRPLANE_MODE_AFTER_SP_DISABLED, - Settings.Secure.MAINTAIN_LOCATION_AFTER_SP_DISABLED, Settings.Secure.MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, Settings.Secure.MULTI_PRESS_TIMEOUT, Settings.Secure.NFC_PAYMENT_FOREGROUND, @@ -662,7 +659,6 @@ public class SettingsBackupTest { Settings.Secure.PARENTAL_CONTROL_LAST_UPDATE, Settings.Secure.PAYMENT_SERVICE_SEARCH_URI, Settings.Secure.PRINT_SERVICE_SEARCH_URI, - Settings.Secure.REENABLE_LOCATION_AFTER_SP_DISABLED, Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT, // Candidate? Settings.Secure.SEARCH_GLOBAL_SEARCH_ACTIVITY, Settings.Secure.SEARCH_MAX_RESULTS_PER_SOURCE, @@ -686,7 +682,6 @@ public class SettingsBackupTest { Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE, Settings.Secure.SELECTED_SPELL_CHECKER, // Intentionally removed in Q Settings.Secure.SELECTED_SPELL_CHECKER_SUBTYPE, // Intentionally removed in Q - Settings.Secure.SENSOR_PRIVACY_SENSOR_STATE, Settings.Secure.SETTINGS_CLASSNAME, Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, // candidate? Settings.Secure.SHOW_ROTATION_SUGGESTIONS, diff --git a/core/tests/coretests/src/android/view/textclassifier/intent/LegacyIntentClassificationFactoryTest.java b/core/tests/coretests/src/android/view/textclassifier/intent/LegacyIntentClassificationFactoryTest.java index 72d1ab1c9d0c..e1ccd7523eba 100644 --- a/core/tests/coretests/src/android/view/textclassifier/intent/LegacyIntentClassificationFactoryTest.java +++ b/core/tests/coretests/src/android/view/textclassifier/intent/LegacyIntentClassificationFactoryTest.java @@ -64,7 +64,9 @@ public class LegacyIntentClassificationFactoryTest { null, null, null, - null); + null, + 0, + 0); List<LabeledIntent> intents = mLegacyIntentClassificationFactory.create( InstrumentationRegistry.getContext(), @@ -98,7 +100,9 @@ public class LegacyIntentClassificationFactoryTest { null, null, null, - null); + null, + 0, + 0); List<LabeledIntent> intents = mLegacyIntentClassificationFactory.create( InstrumentationRegistry.getContext(), diff --git a/core/tests/coretests/src/android/view/textclassifier/intent/TemplateClassificationIntentFactoryTest.java b/core/tests/coretests/src/android/view/textclassifier/intent/TemplateClassificationIntentFactoryTest.java index ccf8607b84d9..2e97e638ba57 100644 --- a/core/tests/coretests/src/android/view/textclassifier/intent/TemplateClassificationIntentFactoryTest.java +++ b/core/tests/coretests/src/android/view/textclassifier/intent/TemplateClassificationIntentFactoryTest.java @@ -82,7 +82,9 @@ public class TemplateClassificationIntentFactoryTest { null, null, null, - createRemoteActionTemplates()); + createRemoteActionTemplates(), + 0, + 0); List<LabeledIntent> intents = mTemplateClassificationIntentFactory.create( @@ -121,7 +123,9 @@ public class TemplateClassificationIntentFactoryTest { null, null, null, - createRemoteActionTemplates()); + createRemoteActionTemplates(), + 0, + 0); List<LabeledIntent> intents = mTemplateClassificationIntentFactory.create( @@ -156,7 +160,9 @@ public class TemplateClassificationIntentFactoryTest { null, null, null, - null); + null, + 0, + 0); mTemplateClassificationIntentFactory.create( InstrumentationRegistry.getContext(), @@ -189,7 +195,9 @@ public class TemplateClassificationIntentFactoryTest { null, null, null, - new RemoteActionTemplate[0]); + new RemoteActionTemplate[0], + 0, + 0); mTemplateClassificationIntentFactory.create( InstrumentationRegistry.getContext(), diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java index 185fa0750ff1..8c2375eaaf4c 100644 --- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java +++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java @@ -599,7 +599,7 @@ public class ChooserActivityTest { mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); - verify(mockLogger, Mockito.times(2)).write(logMakerCaptor.capture()); + verify(mockLogger, Mockito.times(3)).write(logMakerCaptor.capture()); // First invocation is from onCreate assertThat(logMakerCaptor.getAllValues().get(1).getCategory(), is(MetricsEvent.ACTION_SHARE_WITH_PREVIEW)); @@ -629,7 +629,7 @@ public class ChooserActivityTest { ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class); mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); - verify(mockLogger, Mockito.times(2)).write(logMakerCaptor.capture()); + verify(mockLogger, Mockito.times(3)).write(logMakerCaptor.capture()); // First invocation is from onCreate assertThat(logMakerCaptor.getAllValues().get(1).getCategory(), is(MetricsEvent.ACTION_SHARE_WITH_PREVIEW)); diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index 94f69b8905d6..afb50714a93d 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -112,7 +112,6 @@ applications that come with the platform <permission name="android.permission.MANAGE_USERS"/> <permission name="android.permission.UPDATE_APP_OPS_STATS"/> <permission name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME"/> - <permission name="android.permission.CLEAR_APP_USER_DATA"/> <permission name="android.permission.PACKAGE_USAGE_STATS"/> </privapp-permissions> @@ -124,6 +123,7 @@ applications that come with the platform <permission name="android.permission.UPDATE_APP_OPS_STATS"/> <permission name="android.permission.REQUEST_INCIDENT_REPORT_APPROVAL"/> <permission name="android.permission.APPROVE_INCIDENT_REPORTS"/> + <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE" /> </privapp-permissions> <privapp-permissions package="com.android.phone"> @@ -308,6 +308,8 @@ applications that come with the platform <permission name="android.permission.STATUS_BAR_SERVICE"/> <permission name="android.permission.REQUEST_INCIDENT_REPORT_APPROVAL"/> <permission name="android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS"/> + <permission name="android.permission.SET_WALLPAPER" /> + <permission name="android.permission.SET_WALLPAPER_COMPONENT" /> </privapp-permissions> <privapp-permissions package="com.android.statementservice"> @@ -330,9 +332,9 @@ applications that come with the platform <permission name="android.permission.CONTROL_VPN"/> </privapp-permissions> - <privapp-permissions package="com.android.dynandroid"> + <privapp-permissions package="com.android.dynsystem"> <permission name="android.permission.REBOOT"/> - <permission name="android.permission.MANAGE_DYNAMIC_ANDROID"/> + <permission name="android.permission.MANAGE_DYNAMIC_SYSTEM"/> </privapp-permissions> </permissions> diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java index 346c7ab970dd..c48546103a6f 100644 --- a/graphics/java/android/graphics/Paint.java +++ b/graphics/java/android/graphics/Paint.java @@ -229,7 +229,8 @@ public class Paint { public static final int VERTICAL_TEXT_FLAG = 0x1000; // These flags are always set on a new/reset paint, even if flags 0 is passed. - static final int HIDDEN_DEFAULT_PAINT_FLAGS = DEV_KERN_TEXT_FLAG | EMBEDDED_BITMAP_TEXT_FLAG; + static final int HIDDEN_DEFAULT_PAINT_FLAGS = DEV_KERN_TEXT_FLAG | EMBEDDED_BITMAP_TEXT_FLAG + | FILTER_BITMAP_FLAG; /** * Font hinter option that disables font hinting. diff --git a/graphics/java/android/graphics/text/MeasuredText.java b/graphics/java/android/graphics/text/MeasuredText.java index 9db7533044e2..b6d8fa19fca8 100644 --- a/graphics/java/android/graphics/text/MeasuredText.java +++ b/graphics/java/android/graphics/text/MeasuredText.java @@ -42,7 +42,7 @@ import libcore.util.NativeAllocationRegistry; * String text = "Hello, Android."; * MeasuredText mt = new MeasuredText.Builder(text.toCharArray()) * .appendStyleRun(paint, 7, false) // Use paint for "Hello, " - * .appendStyleRun(bigPaint, 8, false) // Use bigPaint for "Hello, " + * .appendStyleRun(bigPaint, 8, false) // Use bigPaint for "Android." * .build(); * </code> * </pre> diff --git a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp index fe2d41ef630b..ceab407cb939 100644 --- a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp +++ b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp @@ -65,7 +65,6 @@ void VkFunctorDrawHandler::draw(const GrBackendDrawableInfo& info) { VkFunctorDrawParams params{ .width = mImageInfo.width(), .height = mImageInfo.height(), - .is_layer = false, // TODO(boliu): Populate is_layer. .color_space_ptr = mImageInfo.colorSpace(), .clip_left = mClip.fLeft, .clip_top = mClip.fTop, diff --git a/libs/hwui/private/hwui/DrawVkInfo.h b/libs/hwui/private/hwui/DrawVkInfo.h index fb55f5ca4c93..4ae0f5a0a2e5 100644 --- a/libs/hwui/private/hwui/DrawVkInfo.h +++ b/libs/hwui/private/hwui/DrawVkInfo.h @@ -42,9 +42,6 @@ struct VkFunctorDrawParams { int width; int height; - // Input: is the render target a FBO - bool is_layer; - // Input: current transform matrix float transform[16]; diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp index 9916da5d9f10..b8ebf3bb0ca9 100644 --- a/libs/hwui/renderthread/VulkanManager.cpp +++ b/libs/hwui/renderthread/VulkanManager.cpp @@ -439,34 +439,47 @@ Frame VulkanManager::dequeueNextBuffer(VulkanSurface* surface) { LOG_ALWAYS_FATAL_IF(!bufferInfo->dequeued); if (bufferInfo->dequeue_fence != -1) { - int fence_clone = dup(bufferInfo->dequeue_fence); - if (fence_clone == -1) { - ALOGE("dup(fence) failed, stalling until signalled: %s (%d)", strerror(errno), errno); - sync_wait(bufferInfo->dequeue_fence, -1 /* forever */); - } else { - VkSemaphoreCreateInfo semaphoreInfo; - semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - semaphoreInfo.pNext = nullptr; - semaphoreInfo.flags = 0; - VkSemaphore semaphore; - VkResult err = mCreateSemaphore(mDevice, &semaphoreInfo, nullptr, &semaphore); - LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err, "Failed to create import semaphore, err: %d", - err); - - VkImportSemaphoreFdInfoKHR importInfo; - importInfo.sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR; - importInfo.pNext = nullptr; - importInfo.semaphore = semaphore; - importInfo.flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT; - importInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; - importInfo.fd = fence_clone; - - err = mImportSemaphoreFdKHR(mDevice, &importInfo); - LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err, "Failed to import semaphore, err: %d", err); - - GrBackendSemaphore backendSemaphore; - backendSemaphore.initVulkan(semaphore); - bufferInfo->skSurface->wait(1, &backendSemaphore); + struct sync_file_info* finfo = sync_file_info(bufferInfo->dequeue_fence); + bool isSignalPending = false; + if (finfo != NULL) { + isSignalPending = finfo->status != 1; + sync_file_info_free(finfo); + } + if (isSignalPending) { + int fence_clone = dup(bufferInfo->dequeue_fence); + if (fence_clone == -1) { + ALOGE("dup(fence) failed, stalling until signalled: %s (%d)", strerror(errno), + errno); + sync_wait(bufferInfo->dequeue_fence, -1 /* forever */); + } else { + VkSemaphoreCreateInfo semaphoreInfo; + semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + semaphoreInfo.pNext = nullptr; + semaphoreInfo.flags = 0; + VkSemaphore semaphore; + VkResult err = mCreateSemaphore(mDevice, &semaphoreInfo, nullptr, &semaphore); + LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err, "Failed to create import semaphore, err: %d", + err); + + VkImportSemaphoreFdInfoKHR importInfo; + importInfo.sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR; + importInfo.pNext = nullptr; + importInfo.semaphore = semaphore; + importInfo.flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT; + importInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; + importInfo.fd = fence_clone; + + err = mImportSemaphoreFdKHR(mDevice, &importInfo); + LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err, "Failed to import semaphore, err: %d", err); + + GrBackendSemaphore backendSemaphore; + backendSemaphore.initVulkan(semaphore); + bufferInfo->skSurface->wait(1, &backendSemaphore); + // The following flush blocks the GPU immediately instead of waiting for other + // drawing ops. It seems dequeue_fence is not respected otherwise. + //TODO: remove the flush after finding why backendSemaphore is not working. + bufferInfo->skSurface->flush(); + } } } diff --git a/libs/hwui/renderthread/VulkanSurface.cpp b/libs/hwui/renderthread/VulkanSurface.cpp index c03c3a896e26..a98eb322cfc7 100644 --- a/libs/hwui/renderthread/VulkanSurface.cpp +++ b/libs/hwui/renderthread/VulkanSurface.cpp @@ -256,11 +256,44 @@ VulkanSurface* VulkanSurface::Create(ANativeWindow* window, ColorMode colorMode, vkPixelFormat = VK_FORMAT_R16G16B16A16_SFLOAT; } - uint64_t producerUsage = - AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER | AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE; - uint64_t consumerUsage; - native_window_get_consumer_usage(window, &consumerUsage); - windowInfo.windowUsageFlags = consumerUsage | producerUsage; + if (nullptr != vkManager.mGetPhysicalDeviceImageFormatProperties2) { + VkPhysicalDeviceExternalImageFormatInfo externalImageFormatInfo; + externalImageFormatInfo.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO; + externalImageFormatInfo.pNext = nullptr; + externalImageFormatInfo.handleType = + VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID; + + VkPhysicalDeviceImageFormatInfo2 imageFormatInfo; + imageFormatInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2; + imageFormatInfo.pNext = &externalImageFormatInfo; + imageFormatInfo.format = vkPixelFormat; + imageFormatInfo.type = VK_IMAGE_TYPE_2D; + imageFormatInfo.tiling = VK_IMAGE_TILING_OPTIMAL; + imageFormatInfo.usage = usageFlags; + imageFormatInfo.flags = 0; + + VkAndroidHardwareBufferUsageANDROID hwbUsage; + hwbUsage.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID; + hwbUsage.pNext = nullptr; + + VkImageFormatProperties2 imgFormProps; + imgFormProps.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2; + imgFormProps.pNext = &hwbUsage; + + res = vkManager.mGetPhysicalDeviceImageFormatProperties2(vkManager.mPhysicalDevice, + &imageFormatInfo, &imgFormProps); + if (VK_SUCCESS != res) { + ALOGE("Failed to query GetPhysicalDeviceImageFormatProperties2"); + return nullptr; + } + + windowInfo.windowUsageFlags = hwbUsage.androidHardwareBufferUsage; + + } else { + ALOGE("VulkanSurface::Create() vkmGetPhysicalDeviceImageFormatProperties2 is missing"); + return nullptr; + } /* * Now we attempt to modify the window! diff --git a/location/java/android/location/GnssClock.java b/location/java/android/location/GnssClock.java index 8507c8344b6c..538406180367 100644 --- a/location/java/android/location/GnssClock.java +++ b/location/java/android/location/GnssClock.java @@ -16,6 +16,8 @@ package android.location; +import android.annotation.FloatRange; +import android.annotation.IntRange; import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; @@ -36,6 +38,8 @@ public final class GnssClock implements Parcelable { private static final int HAS_BIAS_UNCERTAINTY = (1<<4); private static final int HAS_DRIFT = (1<<5); private static final int HAS_DRIFT_UNCERTAINTY = (1<<6); + private static final int HAS_ELAPSED_REALTIME_NANOS = (1 << 7); + private static final int HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS = (1 << 8); // End enumerations in sync with gps.h @@ -49,6 +53,8 @@ public final class GnssClock implements Parcelable { private double mDriftNanosPerSecond; private double mDriftUncertaintyNanosPerSecond; private int mHardwareClockDiscontinuityCount; + private long mElapsedRealtimeNanos; + private long mElapsedRealtimeUncertaintyNanos; /** * @hide @@ -74,6 +80,8 @@ public final class GnssClock implements Parcelable { mDriftNanosPerSecond = clock.mDriftNanosPerSecond; mDriftUncertaintyNanosPerSecond = clock.mDriftUncertaintyNanosPerSecond; mHardwareClockDiscontinuityCount = clock.mHardwareClockDiscontinuityCount; + mElapsedRealtimeNanos = clock.mElapsedRealtimeNanos; + mElapsedRealtimeUncertaintyNanos = clock.mElapsedRealtimeUncertaintyNanos; } /** @@ -167,6 +175,7 @@ public final class GnssClock implements Parcelable { * <p>This value is often effectively zero (it is the reference clock by which all other times * and time uncertainties are measured), and thus this field may often be 0, or not provided. */ + @FloatRange(from = 0.0f) public double getTimeUncertaintyNanos() { return mTimeUncertaintyNanos; } @@ -176,7 +185,7 @@ public final class GnssClock implements Parcelable { * @hide */ @TestApi - public void setTimeUncertaintyNanos(double timeUncertaintyNanos) { + public void setTimeUncertaintyNanos(@FloatRange(from = 0.0f) double timeUncertaintyNanos) { setFlag(HAS_TIME_UNCERTAINTY); mTimeUncertaintyNanos = timeUncertaintyNanos; } @@ -297,6 +306,7 @@ public final class GnssClock implements Parcelable { * * <p>The value is only available if {@link #hasBiasUncertaintyNanos()} is {@code true}. */ + @FloatRange(from = 0.0f) public double getBiasUncertaintyNanos() { return mBiasUncertaintyNanos; } @@ -306,7 +316,7 @@ public final class GnssClock implements Parcelable { * @hide */ @TestApi - public void setBiasUncertaintyNanos(double biasUncertaintyNanos) { + public void setBiasUncertaintyNanos(@FloatRange(from = 0.0f) double biasUncertaintyNanos) { setFlag(HAS_BIAS_UNCERTAINTY); mBiasUncertaintyNanos = biasUncertaintyNanos; } @@ -379,6 +389,7 @@ public final class GnssClock implements Parcelable { * <p>The value is only available if {@link #hasDriftUncertaintyNanosPerSecond()} is * {@code true}. */ + @FloatRange(from = 0.0f) public double getDriftUncertaintyNanosPerSecond() { return mDriftUncertaintyNanosPerSecond; } @@ -388,7 +399,8 @@ public final class GnssClock implements Parcelable { * @hide */ @TestApi - public void setDriftUncertaintyNanosPerSecond(double driftUncertaintyNanosPerSecond) { + public void setDriftUncertaintyNanosPerSecond( + @FloatRange(from = 0.0f) double driftUncertaintyNanosPerSecond) { setFlag(HAS_DRIFT_UNCERTAINTY); mDriftUncertaintyNanosPerSecond = driftUncertaintyNanosPerSecond; } @@ -404,6 +416,90 @@ public final class GnssClock implements Parcelable { } /** + * Returns {@code true} if {@link #getElapsedRealtimeNanos()} is available, {@code false} + * otherwise. + */ + public boolean hasElapsedRealtimeNanos() { + return isFlagSet(HAS_ELAPSED_REALTIME_NANOS); + } + + /** + * Returns the elapsed real-time of this clock since system boot, in nanoseconds. + * + * <p>The value is only available if {@link #hasElapsedRealtimeNanos()} is + * {@code true}. + */ + public long getElapsedRealtimeNanos() { + return mElapsedRealtimeNanos; + } + + /** + * Sets the elapsed real-time of this clock since system boot, in nanoseconds. + * @hide + */ + @TestApi + public void setElapsedRealtimeNanos(long elapsedRealtimeNanos) { + setFlag(HAS_ELAPSED_REALTIME_NANOS); + mElapsedRealtimeNanos = elapsedRealtimeNanos; + } + + /** + * Resets the elapsed real-time of this clock since system boot, in nanoseconds. + * @hide + */ + @TestApi + public void resetElapsedRealtimeNanos() { + resetFlag(HAS_ELAPSED_REALTIME_NANOS); + mElapsedRealtimeNanos = 0; + } + + /** + * Returns {@code true} if {@link #getElapsedRealtimeUncertaintyNanos()} is available, {@code + * false} otherwise. + */ + public boolean hasElapsedRealtimeUncertaintyNanos() { + return isFlagSet(HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS); + } + + /** + * Gets the estimate of the relative precision of the alignment of the + * {@link #getElapsedRealtimeNanos()} timestamp, with the reported measurements in + * nanoseconds (68% confidence). + * + * <p>The value is only available if {@link #hasElapsedRealtimeUncertaintyNanos()} is + * {@code true}. + */ + @IntRange(from = 0) + public long getElapsedRealtimeUncertaintyNanos() { + return mElapsedRealtimeUncertaintyNanos; + } + + /** + * Sets the estimate of the relative precision of the alignment of the + * {@link #getElapsedRealtimeNanos()} timestamp, with the reported measurements in + * nanoseconds (68% confidence). + * @hide + */ + @TestApi + public void setElapsedRealtimeUncertaintyNanos( + @IntRange(from = 0) long elapsedRealtimeUncertaintyNanos) { + setFlag(HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS); + mElapsedRealtimeUncertaintyNanos = elapsedRealtimeUncertaintyNanos; + } + + /** + * Resets the estimate of the relative precision of the alignment of the + * {@link #getElapsedRealtimeNanos()} timestamp, with the reported measurements in + * nanoseconds (68% confidence). + * @hide + */ + @TestApi + public void resetElapsedRealtimeUncertaintyNanos() { + resetFlag(HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS); + mElapsedRealtimeUncertaintyNanos = Long.MAX_VALUE; + } + + /** * Gets count of hardware clock discontinuities. * * <p>When this value stays the same, vs. a value in a previously reported {@link GnssClock}, it @@ -446,6 +542,8 @@ public final class GnssClock implements Parcelable { gpsClock.mDriftNanosPerSecond = parcel.readDouble(); gpsClock.mDriftUncertaintyNanosPerSecond = parcel.readDouble(); gpsClock.mHardwareClockDiscontinuityCount = parcel.readInt(); + gpsClock.mElapsedRealtimeNanos = parcel.readLong(); + gpsClock.mElapsedRealtimeUncertaintyNanos = parcel.readLong(); return gpsClock; } @@ -468,6 +566,8 @@ public final class GnssClock implements Parcelable { parcel.writeDouble(mDriftNanosPerSecond); parcel.writeDouble(mDriftUncertaintyNanosPerSecond); parcel.writeInt(mHardwareClockDiscontinuityCount); + parcel.writeLong(mElapsedRealtimeNanos); + parcel.writeLong(mElapsedRealtimeUncertaintyNanos); } @Override @@ -514,6 +614,16 @@ public final class GnssClock implements Parcelable { "HardwareClockDiscontinuityCount", mHardwareClockDiscontinuityCount)); + builder.append(String.format( + format, + "ElapsedRealtimeNanos", + hasElapsedRealtimeNanos() ? mElapsedRealtimeNanos : null)); + + builder.append(String.format( + format, + "ElapsedRealtimeUncertaintyNanos", + hasElapsedRealtimeUncertaintyNanos() ? mElapsedRealtimeUncertaintyNanos : null)); + return builder.toString(); } @@ -528,6 +638,8 @@ public final class GnssClock implements Parcelable { resetDriftNanosPerSecond(); resetDriftUncertaintyNanosPerSecond(); setHardwareClockDiscontinuityCount(Integer.MIN_VALUE); + resetElapsedRealtimeNanos(); + resetElapsedRealtimeUncertaintyNanos(); } private void setFlag(int flag) { diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java index e5fd0d342e9d..b4be21987cf7 100644 --- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java +++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java @@ -238,6 +238,8 @@ public class GpsNetInitiatedHandler { * window after the end of that call. * 3. If the device is in a emergency callback state, this is provided by querying * TelephonyManager. + * 4. If the user has recently sent an Emergency SMS and telephony reports that it is in + * emergency SMS mode, this is provided by querying TelephonyManager. * @return true if is considered in user initiated emergency mode for NI purposes */ public boolean getInEmergency() { @@ -246,7 +248,9 @@ public class GpsNetInitiatedHandler { && ((SystemClock.elapsedRealtime() - mCallEndElapsedRealtimeMillis) < mEmergencyExtensionMillis); boolean isInEmergencyCallback = mTelephonyManager.getEmergencyCallbackMode(); - return mIsInEmergencyCall || isInEmergencyCallback || isInEmergencyExtension; + boolean isInEmergencySmsMode = mTelephonyManager.isInEmergencySmsMode(); + return mIsInEmergencyCall || isInEmergencyCallback || isInEmergencyExtension + || isInEmergencySmsMode; } public void setEmergencyExtensionSeconds(int emergencyExtensionSeconds) { diff --git a/media/Android.bp b/media/Android.bp index 86dc509501a4..34801813ee87 100644 --- a/media/Android.bp +++ b/media/Android.bp @@ -90,7 +90,6 @@ filegroup { "apex/java/android/media/DataSourceDesc.java", "apex/java/android/media/UriDataSourceDesc.java", "apex/java/android/media/FileDataSourceDesc.java", - "apex/java/android/media/CallbackDataSourceDesc.java", "apex/java/android/media/Media2Utils.java", "apex/java/android/media/MediaPlayer2Utils.java", "apex/java/android/media/MediaPlayer2.java", @@ -98,6 +97,7 @@ filegroup { "apex/java/android/media/Media2HTTPConnection.java", "apex/java/android/media/RoutingDelegate.java", "apex/java/android/media/BufferingParams.java", + "apex/java/android/media/ProxyDataSourceCallback.java", ], } diff --git a/media/apex/java/android/media/CallbackDataSourceDesc.java b/media/apex/java/android/media/CallbackDataSourceDesc.java deleted file mode 100644 index d9db62e99126..000000000000 --- a/media/apex/java/android/media/CallbackDataSourceDesc.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2018 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.TestApi; - -/** - * Structure of data source descriptor for sources using callback. - * - * Used by {@link MediaPlayer2#setDataSource}, {@link MediaPlayer2#setNextDataSource} and - * {@link MediaPlayer2#setNextDataSources} to set data source for playback. - * - * <p>Users should use {@link Builder} to create {@link CallbackDataSourceDesc}. - * @hide - */ -@TestApi -public class CallbackDataSourceDesc extends DataSourceDesc { - private DataSourceCallback mDataSourceCallback; - - CallbackDataSourceDesc(String mediaId, long startPositionMs, long endPositionMs, - DataSourceCallback dataSourceCallback) { - super(mediaId, startPositionMs, endPositionMs); - mDataSourceCallback = dataSourceCallback; - } - - /** - * Return the DataSourceCallback of this data source. - * @return the DataSourceCallback of this data source - */ - public @NonNull DataSourceCallback getDataSourceCallback() { - return mDataSourceCallback; - } -} diff --git a/media/apex/java/android/media/DataSourceCallback.java b/media/apex/java/android/media/DataSourceCallback.java index 6515bd6a2c09..c297ecda249c 100644 --- a/media/apex/java/android/media/DataSourceCallback.java +++ b/media/apex/java/android/media/DataSourceCallback.java @@ -32,8 +32,12 @@ import java.io.IOException; * you don't need to do your own synchronization unless you're modifying the * DataSourceCallback from another thread while it's being used by the framework.</p> * + * @hide */ public abstract class DataSourceCallback implements Closeable { + + public static final int END_OF_STREAM = -1; + /** * Called to request data from the given position. * @@ -49,7 +53,7 @@ public abstract class DataSourceCallback implements Closeable { * @param offset the offset within buffer to read the data into. * @param size the number of bytes to read. * @throws IOException on fatal errors. - * @return the number of bytes read, or -1 if end of stream is reached. + * @return the number of bytes read, or {@link #END_OF_STREAM} if end of stream is reached. */ public abstract int readAt(long position, @NonNull byte[] buffer, int offset, int size) throws IOException; diff --git a/media/apex/java/android/media/DataSourceDesc.java b/media/apex/java/android/media/DataSourceDesc.java index be80c2255844..d00ff2a70955 100644 --- a/media/apex/java/android/media/DataSourceDesc.java +++ b/media/apex/java/android/media/DataSourceDesc.java @@ -125,7 +125,6 @@ public class DataSourceDesc { private static final int SOURCE_TYPE_UNKNOWN = 0; private static final int SOURCE_TYPE_URI = 1; private static final int SOURCE_TYPE_FILE = 2; - private static final int SOURCE_TYPE_CALLBACK = 3; private int mSourceType = SOURCE_TYPE_UNKNOWN; private String mMediaId; @@ -142,9 +141,6 @@ public class DataSourceDesc { private long mOffset = 0; private long mLength = FileDataSourceDesc.FD_LENGTH_UNKNOWN; - // For CallbackDataSourceDesc - private DataSourceCallback mDataSourceCallback; - /** * Constructs a new BuilderBase with the defaults. */ @@ -173,9 +169,6 @@ public class DataSourceDesc { mUri = ((UriDataSourceDesc) dsd).getUri(); mHeader = ((UriDataSourceDesc) dsd).getHeaders(); mCookies = ((UriDataSourceDesc) dsd).getCookies(); - } else if (dsd instanceof CallbackDataSourceDesc) { - mSourceType = SOURCE_TYPE_CALLBACK; - mDataSourceCallback = ((CallbackDataSourceDesc) dsd).getDataSourceCallback(); } else { throw new IllegalStateException("Unknown source type:" + mSourceType); } @@ -204,9 +197,6 @@ public class DataSourceDesc { } else if (mSourceType == SOURCE_TYPE_URI) { desc = new UriDataSourceDesc( mMediaId, mStartPositionMs, mEndPositionMs, mUri, mHeader, mCookies); - } else if (mSourceType == SOURCE_TYPE_CALLBACK) { - desc = new CallbackDataSourceDesc( - mMediaId, mStartPositionMs, mEndPositionMs, mDataSourceCallback); } else { throw new IllegalStateException("Unknown source type:" + mSourceType); } @@ -326,7 +316,7 @@ public class DataSourceDesc { /** * Sets the data source (ParcelFileDescriptor) to use. The ParcelFileDescriptor must be - * seekable (N.B. a LocalSocket is not seekable). When the {@link FileDataSourceDesc} + * seekable (N.B. a LocalSocket is not seekable). When the {@link DataSourceDesc} * created by this builder is passed to {@link MediaPlayer2} via * {@link MediaPlayer2#setDataSource}, * {@link MediaPlayer2#setNextDataSource} or @@ -347,7 +337,7 @@ public class DataSourceDesc { /** * Sets the data source (ParcelFileDescriptor) to use. The ParcelFileDescriptor must be - * seekable (N.B. a LocalSocket is not seekable). When the {@link FileDataSourceDesc} + * seekable (N.B. a LocalSocket is not seekable). When the {@link DataSourceDesc} * created by this builder is passed to {@link MediaPlayer2} via * {@link MediaPlayer2#setDataSource}, * {@link MediaPlayer2#setNextDataSource} or @@ -367,7 +357,9 @@ public class DataSourceDesc { public Builder setDataSource( @NonNull ParcelFileDescriptor pfd, long offset, long length) { setSourceType(SOURCE_TYPE_FILE); - Media2Utils.checkArgument(pfd != null, "pfd cannot be null."); + if (pfd == null) { + throw new NullPointerException("pfd cannot be null."); + } if (offset < 0) { offset = 0; } @@ -380,20 +372,6 @@ public class DataSourceDesc { return this; } - /** - * Sets the data source (DataSourceCallback) to use. - * - * @param dscb the DataSourceCallback for the media to play - * @return the same Builder instance. - * @throws NullPointerException if dscb is null. - */ - public @NonNull Builder setDataSource(@NonNull DataSourceCallback dscb) { - setSourceType(SOURCE_TYPE_CALLBACK); - Media2Utils.checkArgument(dscb != null, "data source cannot be null."); - mDataSourceCallback = dscb; - return this; - } - private void setSourceType(int type) { if (mSourceType != SOURCE_TYPE_UNKNOWN) { throw new IllegalStateException("Source is already set. type=" + mSourceType); diff --git a/media/apex/java/android/media/MediaController2.java b/media/apex/java/android/media/MediaController2.java index 2743a34d3f55..1e8438ec9fe8 100644 --- a/media/apex/java/android/media/MediaController2.java +++ b/media/apex/java/android/media/MediaController2.java @@ -22,8 +22,8 @@ import static android.media.MediaConstants.KEY_PID; import static android.media.MediaConstants.KEY_PLAYBACK_ACTIVE; import static android.media.MediaConstants.KEY_SESSION2LINK; import static android.media.MediaConstants.KEY_TOKEN_EXTRAS; -import static android.media.Session2Command.RESULT_ERROR_UNKNOWN_ERROR; -import static android.media.Session2Command.RESULT_INFO_SKIPPED; +import static android.media.Session2Command.Result.RESULT_ERROR_UNKNOWN_ERROR; +import static android.media.Session2Command.Result.RESULT_INFO_SKIPPED; import static android.media.Session2Token.TYPE_SESSION; import android.annotation.NonNull; @@ -329,7 +329,7 @@ public class MediaController2 implements AutoCloseable { MediaController2.this, command, args); if (resultReceiver != null) { if (result == null) { - resultReceiver.send(Session2Command.RESULT_INFO_SKIPPED, null); + resultReceiver.send(RESULT_INFO_SKIPPED, null); } else { resultReceiver.send(result.getResultCode(), result.getResultData()); } diff --git a/media/apex/java/android/media/MediaPlayer2.java b/media/apex/java/android/media/MediaPlayer2.java index 68a46ed5b8b8..19bb2586af35 100644 --- a/media/apex/java/android/media/MediaPlayer2.java +++ b/media/apex/java/android/media/MediaPlayer2.java @@ -878,22 +878,27 @@ public class MediaPlayer2 implements AutoCloseable, AudioRouting { throws IOException { Media2Utils.checkArgument(dsd != null, "the DataSourceDesc cannot be null"); - if (dsd instanceof CallbackDataSourceDesc) { - CallbackDataSourceDesc cbDSD = (CallbackDataSourceDesc) dsd; - handleDataSource(isCurrent, - srcId, - cbDSD.getDataSourceCallback(), - cbDSD.getStartPosition(), - cbDSD.getEndPosition()); - } else if (dsd instanceof FileDataSourceDesc) { + if (dsd instanceof FileDataSourceDesc) { FileDataSourceDesc fileDSD = (FileDataSourceDesc) dsd; - handleDataSource(isCurrent, - srcId, - fileDSD.getParcelFileDescriptor(), - fileDSD.getOffset(), - fileDSD.getLength(), - fileDSD.getStartPosition(), - fileDSD.getEndPosition()); + ParcelFileDescriptor pfd = fileDSD.getParcelFileDescriptor(); + if (pfd.getStatSize() == -1) { + // Underlying pipeline doesn't understand '-1' size. Create a wrapper for + // translation. + // TODO: Make native code handle '-1' size. + handleDataSource(isCurrent, + srcId, + new ProxyDataSourceCallback(pfd), + fileDSD.getStartPosition(), + fileDSD.getEndPosition()); + } else { + handleDataSource(isCurrent, + srcId, + pfd, + fileDSD.getOffset(), + fileDSD.getLength(), + fileDSD.getStartPosition(), + fileDSD.getEndPosition()); + } } else if (dsd instanceof UriDataSourceDesc) { UriDataSourceDesc uriDSD = (UriDataSourceDesc) dsd; handleDataSource(isCurrent, @@ -1963,6 +1968,17 @@ public class MediaPlayer2 implements AutoCloseable, AudioRouting { private native byte[] native_invoke(byte[] request); /** + * @hide + */ + @IntDef(flag = false, prefix = "MEDIA_TRACK_TYPE", value = { + TrackInfo.MEDIA_TRACK_TYPE_VIDEO, + TrackInfo.MEDIA_TRACK_TYPE_AUDIO, + TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE + }) + @Retention(RetentionPolicy.SOURCE) + public @interface TrackType {} + + /** * Class for MediaPlayer2 to return each audio/video/subtitle track's metadata. * * @see MediaPlayer2#getTrackInfo @@ -2009,10 +2025,11 @@ public class MediaPlayer2 implements AutoCloseable, AudioRouting { public static final int MEDIA_TRACK_TYPE_SUBTITLE = 4; public static final int MEDIA_TRACK_TYPE_METADATA = 5; + final int mId; final int mTrackType; final MediaFormat mFormat; - static TrackInfo create(Iterator<Value> in) { + static TrackInfo create(int idx, Iterator<Value> in) { int trackType = in.next().getInt32Value(); // TODO: build the full MediaFormat; currently we are using createSubtitleFormat // even for audio/video tracks, meaning we only set the mime and language. @@ -2025,11 +2042,12 @@ public class MediaPlayer2 implements AutoCloseable, AudioRouting { format.setInteger(MediaFormat.KEY_IS_DEFAULT, in.next().getInt32Value()); format.setInteger(MediaFormat.KEY_IS_FORCED_SUBTITLE, in.next().getInt32Value()); } - return new TrackInfo(trackType, format); + return new TrackInfo(idx, trackType, format); } /** @hide */ - TrackInfo(int type, MediaFormat format) { + TrackInfo(int id, int type, MediaFormat format) { + mId = id; mTrackType = type; mFormat = format; } @@ -2116,7 +2134,7 @@ public class MediaPlayer2 implements AutoCloseable, AudioRouting { } TrackInfo[] trackInfo = new TrackInfo[size]; for (int i = 0; i < size; ++i) { - trackInfo[i] = TrackInfo.create(in); + trackInfo[i] = TrackInfo.create(i, in); } return trackInfo; } @@ -2124,54 +2142,56 @@ public class MediaPlayer2 implements AutoCloseable, AudioRouting { /** * Returns the index of the audio, video, or subtitle track currently selected for playback. * The return value is an index into the array returned by {@link #getTrackInfo}, and can - * be used in calls to {@link #selectTrack(int)} or {@link #deselectTrack(int)}. + * be used in calls to {@link #selectTrack(TrackInfo)} or {@link #deselectTrack(TrackInfo)}. * Same as {@link #getSelectedTrack(DataSourceDesc, int)} with * {@code dsd = getCurrentDataSource()}. * * @param trackType should be one of {@link TrackInfo#MEDIA_TRACK_TYPE_VIDEO}, * {@link TrackInfo#MEDIA_TRACK_TYPE_AUDIO}, or * {@link TrackInfo#MEDIA_TRACK_TYPE_SUBTITLE} - * @return index of the audio, video, or subtitle track currently selected for playback; - * a negative integer is returned when there is no selected track for {@code trackType} or + * @return metadata corresponding to the audio, video, or subtitle track currently selected for + * playback; {@code null} is returned when there is no selected track for {@code trackType} or * when {@code trackType} is not one of audio, video, or subtitle. * @throws IllegalStateException if called after {@link #close()} * @throws NullPointerException if current data source is null * * @see #getTrackInfo() - * @see #selectTrack(int) - * @see #deselectTrack(int) + * @see #selectTrack(TrackInfo) + * @see #deselectTrack(TrackInfo) */ - public int getSelectedTrack(int trackType) { + @Nullable + public TrackInfo getSelectedTrack(@TrackType int trackType) { return getSelectedTrack(getCurrentDataSource(), trackType); } /** * Returns the index of the audio, video, or subtitle track currently selected for playback. * The return value is an index into the array returned by {@link #getTrackInfo}, and can - * be used in calls to {@link #selectTrack(DataSourceDesc, int)} or - * {@link #deselectTrack(DataSourceDesc, int)}. + * be used in calls to {@link #selectTrack(DataSourceDesc, TrackInfo)} or + * {@link #deselectTrack(DataSourceDesc, TrackInfo)}. * * @param dsd the descriptor of data source of which you want to get selected track * @param trackType should be one of {@link TrackInfo#MEDIA_TRACK_TYPE_VIDEO}, * {@link TrackInfo#MEDIA_TRACK_TYPE_AUDIO}, or * {@link TrackInfo#MEDIA_TRACK_TYPE_SUBTITLE} - * @return index of the audio, video, or subtitle track currently selected for playback; - * a negative integer is returned when there is no selected track for {@code trackType} or + * @return metadata corresponding to the audio, video, or subtitle track currently selected for + * playback; {@code null} is returned when there is no selected track for {@code trackType} or * when {@code trackType} is not one of audio, video, or subtitle. * @throws IllegalStateException if called after {@link #close()} * @throws NullPointerException if dsd is null * * @see #getTrackInfo(DataSourceDesc) - * @see #selectTrack(DataSourceDesc, int) - * @see #deselectTrack(DataSourceDesc, int) + * @see #selectTrack(DataSourceDesc, TrackInfo) + * @see #deselectTrack(DataSourceDesc, TrackInfo) */ - public int getSelectedTrack(@NonNull DataSourceDesc dsd, int trackType) { + @Nullable + public TrackInfo getSelectedTrack(@NonNull DataSourceDesc dsd, @TrackType int trackType) { if (dsd == null) { throw new NullPointerException("non-null dsd is expected"); } SourceInfo sourceInfo = getSourceInfo(dsd); if (sourceInfo == null) { - return -1; + return null; } PlayerMessage request = PlayerMessage.newBuilder() @@ -2181,26 +2201,30 @@ public class MediaPlayer2 implements AutoCloseable, AudioRouting { .build(); PlayerMessage response = invoke(request); if (response == null) { - return -1; + return null; } - return response.getValues(0).getInt32Value(); + // TODO: return full TrackInfo data from native player instead of index + final int idx = response.getValues(0).getInt32Value(); + final List<TrackInfo> trackInfos = getTrackInfo(dsd); + return trackInfos.isEmpty() ? null : trackInfos.get(idx); } /** * Selects a track of current data source. - * Same as {@link #selectTrack(DataSourceDesc, int)} with + * Same as {@link #selectTrack(DataSourceDesc, TrackInfo)} with * {@code dsd = getCurrentDataSource()}. * - * @param index the index of the track to be selected. The valid range of the index - * is 0..total number of track - 1. The total number of tracks as well as the type of - * each individual track can be found by calling {@link #getTrackInfo()} method. + * @param trackInfo metadata corresponding to the track to be selected. A {@code trackInfo} + * object can be obtained from {@link #getTrackInfo()}. * @return a token which can be used to cancel the operation later with {@link #cancelCommand}. * + * This is an asynchronous call. + * * @see MediaPlayer2#getTrackInfo() */ - // This is an asynchronous call. - public @NonNull Object selectTrack(int index) { - return selectTrack(getCurrentDataSource(), index); + @NonNull + public Object selectTrack(@NonNull TrackInfo trackInfo) { + return selectTrack(getCurrentDataSource(), trackInfo); } /** @@ -2225,38 +2249,40 @@ public class MediaPlayer2 implements AutoCloseable, AudioRouting { * in that an audio track can only be selected in the <em>Prepared</em> state. * </p> * @param dsd the descriptor of data source of which you want to select track - * @param index the index of the track to be selected. The valid range of the index - * is 0..total number of track - 1. The total number of tracks as well as the type of - * each individual track can be found by calling {@link #getTrackInfo(DataSourceDesc)} method. + * @param trackInfo metadata corresponding to the track to be selected. A {@code trackInfo} + * object can be obtained from {@link #getTrackInfo()}. * @return a token which can be used to cancel the operation later with {@link #cancelCommand}. * + * This is an asynchronous call. + * * @see MediaPlayer2#getTrackInfo(DataSourceDesc) */ - // This is an asynchronous call. - public @NonNull Object selectTrack(@NonNull DataSourceDesc dsd, int index) { + @NonNull + public Object selectTrack(@NonNull DataSourceDesc dsd, @NonNull TrackInfo trackInfo) { return addTask(new Task(CALL_COMPLETED_SELECT_TRACK, false) { @Override void process() { - selectOrDeselectTrack(dsd, index, true /* select */); + selectOrDeselectTrack(dsd, trackInfo.mId, true /* select */); } }); } /** * Deselect a track of current data source. - * Same as {@link #deselectTrack(DataSourceDesc, int)} with + * Same as {@link #deselectTrack(DataSourceDesc, TrackInfo)} with * {@code dsd = getCurrentDataSource()}. * - * @param index the index of the track to be deselected. The valid range of the index - * is 0..total number of tracks - 1. The total number of tracks as well as the type of - * each individual track can be found by calling {@link #getTrackInfo()} method. + * @param trackInfo metadata corresponding to the track to be selected. A {@code trackInfo} + * object can be obtained from {@link #getTrackInfo()}. * @return a token which can be used to cancel the operation later with {@link #cancelCommand}. * + * This is an asynchronous call. + * * @see MediaPlayer2#getTrackInfo() */ - // This is an asynchronous call. - public @NonNull Object deselectTrack(int index) { - return deselectTrack(getCurrentDataSource(), index); + @NonNull + public Object deselectTrack(@NonNull TrackInfo trackInfo) { + return deselectTrack(getCurrentDataSource(), trackInfo); } /** @@ -2267,19 +2293,20 @@ public class MediaPlayer2 implements AutoCloseable, AudioRouting { * selected before, it throws an exception. * </p> * @param dsd the descriptor of data source of which you want to deselect track - * @param index the index of the track to be deselected. The valid range of the index - * is 0..total number of tracks - 1. The total number of tracks as well as the type of - * each individual track can be found by calling {@link #getTrackInfo} method. + * @param trackInfo metadata corresponding to the track to be selected. A {@code trackInfo} + * object can be obtained from {@link #getTrackInfo()}. * @return a token which can be used to cancel the operation later with {@link #cancelCommand}. * + * This is an asynchronous call. + * * @see MediaPlayer2#getTrackInfo(DataSourceDesc) */ - // This is an asynchronous call. - public @NonNull Object deselectTrack(@NonNull DataSourceDesc dsd, int index) { + @NonNull + public Object deselectTrack(@NonNull DataSourceDesc dsd, @NonNull TrackInfo trackInfo) { return addTask(new Task(CALL_COMPLETED_DESELECT_TRACK, false) { @Override void process() { - selectOrDeselectTrack(dsd, index, false /* select */); + selectOrDeselectTrack(dsd, trackInfo.mId, false /* select */); } }); } @@ -2640,11 +2667,13 @@ public class MediaPlayer2 implements AutoCloseable, AudioRouting { return; } Iterator<Value> in = playerMsg.getValuesList().iterator(); - SubtitleData data = new SubtitleData( - in.next().getInt32Value(), // trackIndex - in.next().getInt64Value(), // startTimeUs - in.next().getInt64Value(), // durationUs - in.next().getBytesValue().toByteArray()); // data + final int trackIndex = in.next().getInt32Value(); + TrackInfo trackInfo = getTrackInfo(dsd).get(trackIndex); + final long startTimeUs = in.next().getInt64Value(); + final long durationTimeUs = in.next().getInt64Value(); + final byte[] subData = in.next().getBytesValue().toByteArray(); + SubtitleData data = new SubtitleData(trackInfo, + startTimeUs, durationTimeUs, subData); sendEvent(new EventNotifier() { @Override public void notify(EventCallback callback) { @@ -2765,6 +2794,74 @@ public class MediaPlayer2 implements AutoCloseable, AudioRouting { } /** + * Class encapsulating subtitle data, as received through the + * {@link EventCallback#onSubtitleData} interface. + * <p> + * A {@link SubtitleData} object includes: + * <ul> + * <li> track metadadta in a {@link TrackInfo} object</li> + * <li> the start time (in microseconds) of the data</li> + * <li> the duration (in microseconds) of the data</li> + * <li> the actual data.</li> + * </ul> + * The data is stored in a byte-array, and is encoded in one of the supported in-band + * subtitle formats. The subtitle encoding is determined by the MIME type of the + * {@link TrackInfo} of the subtitle track, one of + * {@link MediaFormat#MIMETYPE_TEXT_CEA_608}, {@link MediaFormat#MIMETYPE_TEXT_CEA_708}, + * {@link MediaFormat#MIMETYPE_TEXT_VTT}. + */ + public static final class SubtitleData { + + private TrackInfo mTrackInfo; + private long mStartTimeUs; + private long mDurationUs; + private byte[] mData; + + private SubtitleData(TrackInfo trackInfo, long startTimeUs, long durationUs, byte[] data) { + mTrackInfo = trackInfo; + mStartTimeUs = startTimeUs; + mDurationUs = durationUs; + mData = (data != null ? data : new byte[0]); + } + + /** + * @return metadata of track which contains this subtitle data + */ + @NonNull + public TrackInfo getTrackInfo() { + return mTrackInfo; + } + + /** + * @return media time at which the subtitle should start to be displayed in microseconds + */ + public long getStartTimeUs() { + return mStartTimeUs; + } + + /** + * @return the duration in microsecond during which the subtitle should be displayed + */ + public long getDurationUs() { + return mDurationUs; + } + + /** + * Returns the encoded data for the subtitle content. + * Encoding format depends on the subtitle type, refer to + * <a href="https://en.wikipedia.org/wiki/CEA-708">CEA 708</a>, + * <a href="https://en.wikipedia.org/wiki/EIA-608">CEA/EIA 608</a> and + * <a href="https://www.w3.org/TR/webvtt1/">WebVTT</a>, defined by the MIME type + * of the subtitle track. + * @return the encoded subtitle data + */ + @NonNull + public byte[] getData() { + return mData; + } + } + + /** * Interface definition for callbacks to be invoked when the player has the corresponding * events. */ @@ -3439,10 +3536,18 @@ public class MediaPlayer2 implements AutoCloseable, AudioRouting { /** * Mutable builder to create a {@link MediaPlayer2.DrmPreparationInfo} object. + * + * {@link Builder#Builder(UUID) UUID} must not be null; {@link #setKeyType keyType} + * must be one of {@link MediaDrm#KEY_TYPE_STREAMING} or {@link MediaDrm#KEY_TYPE_OFFLINE}. + * <p> + * When {@link #setKeyType keyType} is {@link MediaDrm#KEY_TYPE_STREAMING}, + * {@link #setInitData(byte[]) initData} and {@link #setMimeType(String) mimeType} + * must not be null; When {@link #setKeyType keyType} is {@link MediaDrm#KEY_TYPE_OFFLINE}, + * {@link #setKeySetId(byte[]) keySetId} must not be null. */ public static final class Builder { - private UUID mUUID; + private final UUID mUUID; private byte[] mKeySetId; private byte[] mInitData; private String mMimeType; @@ -3450,15 +3555,11 @@ public class MediaPlayer2 implements AutoCloseable, AudioRouting { private Map<String, String> mOptionalParameters; /** - * Set UUID of the crypto scheme selected to decrypt content. An UUID can be retrieved - * from the source listening to {@link MediaPlayer2.DrmEventCallback#onDrmInfo}. - * - * @param uuid of selected crypto scheme - * @return this + * @param uuid UUID of the crypto scheme selected to decrypt content. An UUID can be + * retrieved from the source listening to {@link DrmEventCallback#onDrmInfo}. */ - public @NonNull Builder setUuid(@NonNull UUID uuid) { + public Builder(@NonNull UUID uuid) { this.mUUID = uuid; - return this; } /** @@ -3531,12 +3632,16 @@ public class MediaPlayer2 implements AutoCloseable, AudioRouting { } /** - * @return an immutable {@link MediaPlayer2.DrmPreparationInfo} representing the - * settings of this builder + * @return an immutable {@link DrmPreparationInfo} based on settings of this builder */ - public @NonNull MediaPlayer2.DrmPreparationInfo build() { - return new MediaPlayer2.DrmPreparationInfo(mUUID, mKeySetId, mInitData, mMimeType, - mKeyType, mOptionalParameters); + @NonNull + public DrmPreparationInfo build() { + final DrmPreparationInfo info = new DrmPreparationInfo(mUUID, mKeySetId, mInitData, + mMimeType, mKeyType, mOptionalParameters); + if (!info.isValid()) { + throw new IllegalArgumentException("invalid DrmPreparationInfo"); + } + return info; } } @@ -3572,13 +3677,61 @@ public class MediaPlayer2 implements AutoCloseable, AudioRouting { } return false; } + + /** + * @return UUID of the crypto scheme selected to decrypt content. + */ + @NonNull + public UUID getUuid() { + return mUUID; + } + + /** + * @return identifier of the persisted offline key. + */ + @Nullable + public byte[] getKeySetId() { + return mKeySetId; + } + + /** + * @return container-specific DRM initialization data. + */ + @Nullable + public byte[] getInitData() { + return mInitData; + } + + /** + * @return mime type of the content + */ + @Nullable + public String getMimeType() { + return mMimeType; + } + + /** + * @return type of the key request. + */ + @MediaPlayer2.MediaDrmKeyType + public int getKeyType() { + return mKeyType; + } + + /** + * @return optional parameters to be included in the {@link MediaDrm.KeyRequest}. + */ + @Nullable + public Map<String, String> getOptionalParameters() { + return mOptionalParameters; + } } /** * Interface definition for callbacks to be invoked when the player has the corresponding * DRM events. */ - public static class DrmEventCallback { + public static abstract class DrmEventCallback { /** * Called to indicate DRM info is available. Return a {@link DrmPreparationInfo} object that @@ -3591,10 +3744,9 @@ public class MediaPlayer2 implements AutoCloseable, AudioRouting { * @return a {@link DrmPreparationInfo} object to initialize DRM playback, or null to skip * DRM initialization */ - public @Nullable DrmPreparationInfo onDrmInfo(@NonNull MediaPlayer2 mp, - @NonNull DataSourceDesc dsd, @NonNull DrmInfo drmInfo) { - return null; - } + @Nullable + public abstract DrmPreparationInfo onDrmInfo(@NonNull MediaPlayer2 mp, + @NonNull DataSourceDesc dsd, @NonNull DrmInfo drmInfo); /** * Called to give the app the opportunity to configure DRM before the session is created. @@ -3629,10 +3781,9 @@ public class MediaPlayer2 implements AutoCloseable, AudioRouting { * throwing an {@link RuntimeException} from this callback would trigger an * {@link EventCallback#onError}. */ - public @NonNull byte[] onDrmKeyRequest(@NonNull MediaPlayer2 mp, - @NonNull DataSourceDesc dsd, @NonNull MediaDrm.KeyRequest request) { - return new byte[0]; - } + @NonNull + public abstract byte[] onDrmKeyRequest(@NonNull MediaPlayer2 mp, + @NonNull DataSourceDesc dsd, @NonNull MediaDrm.KeyRequest request); /** * Called to notify the client that {@code mp} is ready to decrypt DRM protected data source @@ -3657,10 +3808,11 @@ public class MediaPlayer2 implements AutoCloseable, AudioRouting { /** * Registers the callback to be invoked for various DRM events. * + * This is a synchronous call. + * * @param eventCallback the callback that will be run * @param executor the executor through which the callback should be invoked */ - // This is a synchronous call. public void setDrmEventCallback(@NonNull @CallbackExecutor Executor executor, @NonNull DrmEventCallback eventCallback) { if (eventCallback == null) { @@ -3677,8 +3829,9 @@ public class MediaPlayer2 implements AutoCloseable, AudioRouting { /** * Clear the {@link DrmEventCallback}. + * + * This is a synchronous call. */ - // This is a synchronous call. public void clearDrmEventCallback() { synchronized (mDrmEventCallbackLock) { mDrmEventCallback = null; diff --git a/media/apex/java/android/media/MediaPlayer2Utils.java b/media/apex/java/android/media/MediaPlayer2Utils.java index c6dee22813a0..ac34260f9bcf 100644 --- a/media/apex/java/android/media/MediaPlayer2Utils.java +++ b/media/apex/java/android/media/MediaPlayer2Utils.java @@ -36,6 +36,8 @@ public class MediaPlayer2Utils { .setSampleRate(sampleRate) .setChannelMask(channelMask) .build(); - return AudioManager.isOffloadedPlaybackSupported(format); + //TODO MP2 needs to pass AudioAttributes for this query, instead of using default attr + return AudioManager.isOffloadedPlaybackSupported(format, + (new AudioAttributes.Builder()).build()); } } diff --git a/media/apex/java/android/media/MediaSession2.java b/media/apex/java/android/media/MediaSession2.java index d63de098ecee..a900d8745006 100644 --- a/media/apex/java/android/media/MediaSession2.java +++ b/media/apex/java/android/media/MediaSession2.java @@ -22,8 +22,8 @@ import static android.media.MediaConstants.KEY_PID; import static android.media.MediaConstants.KEY_PLAYBACK_ACTIVE; import static android.media.MediaConstants.KEY_SESSION2LINK; import static android.media.MediaConstants.KEY_TOKEN_EXTRAS; -import static android.media.Session2Command.RESULT_ERROR_UNKNOWN_ERROR; -import static android.media.Session2Command.RESULT_INFO_SKIPPED; +import static android.media.Session2Command.Result.RESULT_ERROR_UNKNOWN_ERROR; +import static android.media.Session2Command.Result.RESULT_INFO_SKIPPED; import static android.media.Session2Token.TYPE_SESSION; import android.annotation.NonNull; @@ -415,7 +415,7 @@ public class MediaSession2 implements AutoCloseable { MediaSession2.this, controllerInfo, command, args); if (resultReceiver != null) { if (result == null) { - resultReceiver.send(Session2Command.RESULT_INFO_SKIPPED, null); + resultReceiver.send(RESULT_INFO_SKIPPED, null); } else { resultReceiver.send(result.getResultCode(), result.getResultData()); } diff --git a/media/apex/java/android/media/ProxyDataSourceCallback.java b/media/apex/java/android/media/ProxyDataSourceCallback.java new file mode 100644 index 000000000000..14d3ce87f03d --- /dev/null +++ b/media/apex/java/android/media/ProxyDataSourceCallback.java @@ -0,0 +1,68 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.media; + +import android.os.ParcelFileDescriptor; +import android.system.ErrnoException; +import android.system.Os; +import android.system.OsConstants; +import android.util.Log; + +import java.io.FileDescriptor; +import java.io.IOException; + +/** + * A DataSourceCallback that is backed by a ParcelFileDescriptor. + */ +class ProxyDataSourceCallback extends DataSourceCallback { + private static final String TAG = "TestDataSourceCallback"; + + ParcelFileDescriptor mPFD; + FileDescriptor mFD; + + ProxyDataSourceCallback(ParcelFileDescriptor pfd) throws IOException { + mPFD = pfd.dup(); + mFD = mPFD.getFileDescriptor(); + } + + @Override + public synchronized int readAt(long position, byte[] buffer, int offset, int size) + throws IOException { + try { + Os.lseek(mFD, position, OsConstants.SEEK_SET); + int ret = Os.read(mFD, buffer, offset, size); + return (ret == 0) ? END_OF_STREAM : ret; + } catch (ErrnoException e) { + throw new IOException(e); + } + } + + @Override + public synchronized long getSize() throws IOException { + return mPFD.getStatSize(); + } + + @Override + public synchronized void close() { + try { + mPFD.close(); + } catch (IOException e) { + Log.e(TAG, "Failed to close the PFD.", e); + } + } +} + diff --git a/media/apex/java/android/media/Session2Command.java b/media/apex/java/android/media/Session2Command.java index 6822ea56b5e8..7f73dc123063 100644 --- a/media/apex/java/android/media/Session2Command.java +++ b/media/apex/java/android/media/Session2Command.java @@ -48,22 +48,6 @@ public final class Session2Command implements Parcelable { */ public static final int COMMAND_CODE_CUSTOM = 0; - /** - * Result code representing that the command is skipped or canceled. For an example, a seek - * command can be skipped if it is followed by another seek command. - */ - public static final int RESULT_INFO_SKIPPED = 1; - - /** - * Result code representing that the command is successfully completed. - */ - public static final int RESULT_SUCCESS = 0; - - /** - * Result code represents that call is ended with an unknown error. - */ - public static final int RESULT_ERROR_UNKNOWN_ERROR = -1; - public static final @android.annotation.NonNull Parcelable.Creator<Session2Command> CREATOR = new Parcelable.Creator<Session2Command>() { @Override @@ -185,6 +169,22 @@ public final class Session2Command implements Parcelable { private final Bundle mResultData; /** + * Result code representing that the command is skipped or canceled. For an example, a seek + * command can be skipped if it is followed by another seek command. + */ + public static final int RESULT_INFO_SKIPPED = 1; + + /** + * Result code representing that the command is successfully completed. + */ + public static final int RESULT_SUCCESS = 0; + + /** + * Result code represents that call is ended with an unknown error. + */ + public static final int RESULT_ERROR_UNKNOWN_ERROR = -1; + + /** * Constructor of {@link Result}. * * @param resultCode result code diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index f9080a70206e..7cb5e00e7684 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -44,6 +44,7 @@ import android.media.session.MediaController; import android.media.session.MediaSession; import android.media.session.MediaSessionLegacyHelper; import android.media.session.MediaSessionManager; +import android.net.Uri; import android.os.Binder; import android.os.Build; import android.os.Handler; @@ -1488,13 +1489,18 @@ public class AudioManager { * it does not indicate whether the resources necessary for the offloaded playback are * available at that instant. * @param format the audio format (codec, sample rate, channels) being checked. + * @param attributes the {@link AudioAttributes} to be used for playback * @return true if the given audio format can be offloaded. */ - public static boolean isOffloadedPlaybackSupported(@NonNull AudioFormat format) { + public static boolean isOffloadedPlaybackSupported(@NonNull AudioFormat format, + @NonNull AudioAttributes attributes) { if (format == null) { - throw new IllegalArgumentException("Illegal null AudioFormat"); + throw new NullPointerException("Illegal null AudioFormat"); } - return AudioSystem.isOffloadSupported(format); + if (attributes == null) { + throw new NullPointerException("Illegal null AudioAttributes"); + } + return AudioSystem.isOffloadSupported(format, attributes); } //==================================================================== @@ -3307,7 +3313,8 @@ public class AudioManager { try { MediaProjection projection = policy.getMediaProjection(); String regId = service.registerAudioPolicy(policy.getConfig(), policy.cb(), - policy.hasFocusListener(), policy.isFocusPolicy(), policy.isVolumeController(), + policy.hasFocusListener(), policy.isFocusPolicy(), policy.isTestFocusPolicy(), + policy.isVolumeController(), projection == null ? null : projection.getProjection()); if (regId == null) { return ERROR; @@ -5441,6 +5448,20 @@ public class AudioManager { sAudioAudioVolumeGroupChangedHandler.unregisterListener(callback); } + /** + * Return if an asset contains haptic channels or not. + * @param uri the {@link Uri} of the asset. + * @return true if the assert contains haptic channels. + * @hide + */ + public static boolean hasHapticChannels(Uri uri) { + try { + return getService().hasHapticChannels(uri); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + //--------------------------------------------------------- // Inner classes //-------------------- diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java index 8051236680aa..a7760a80974d 100644 --- a/media/java/android/media/AudioRecord.java +++ b/media/java/android/media/AudioRecord.java @@ -1798,8 +1798,8 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, * * @return true if sucessful. */ - public boolean setMicrophoneDirection(@DirectionMode int direction) { - return native_set_microphone_direction(direction) == AudioSystem.SUCCESS; + public boolean setPreferredMicrophoneDirection(@DirectionMode int direction) { + return native_set_preferred_microphone_direction(direction) == AudioSystem.SUCCESS; } /** @@ -1810,10 +1810,11 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, * though 0 (no zoom) to 1 (maximum zoom). * @return true if sucessful. */ - public boolean setMicrophoneFieldDimension(@FloatRange(from = -1.0, to = 1.0) float zoom) { + public boolean setPreferredMicrophoneFieldDimension( + @FloatRange(from = -1.0, to = 1.0) float zoom) { Preconditions.checkArgument( zoom >= -1 && zoom <= 1, "Argument must fall between -1 & 1 (inclusive)"); - return native_set_microphone_field_dimension(zoom) == AudioSystem.SUCCESS; + return native_set_preferred_microphone_field_dimension(zoom) == AudioSystem.SUCCESS; } //--------------------------------------------------------- @@ -1969,8 +1970,8 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, private native int native_getPortId(); - private native int native_set_microphone_direction(int direction); - private native int native_set_microphone_field_dimension(float zoom); + private native int native_set_preferred_microphone_direction(int direction); + private native int native_set_preferred_microphone_field_dimension(float zoom); //--------------------------------------------------------- // Utility methods diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index a976d707f5cb..ad255fe3d5a2 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -1022,13 +1022,14 @@ public class AudioSystem public static native float getStreamVolumeDB(int stream, int index, int device); - static boolean isOffloadSupported(@NonNull AudioFormat format) { + static boolean isOffloadSupported(@NonNull AudioFormat format, @NonNull AudioAttributes attr) { return native_is_offload_supported(format.getEncoding(), format.getSampleRate(), - format.getChannelMask(), format.getChannelIndexMask()); + format.getChannelMask(), format.getChannelIndexMask(), + attr.getVolumeControlStream()); } private static native boolean native_is_offload_supported(int encoding, int sampleRate, - int channelMask, int channelIndexMask); + int channelMask, int channelIndexMask, int streamType); public static native int getMicrophones(ArrayList<MicrophoneInfo> microphonesInfo); diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index 41e059bba92d..325e227e6f93 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -914,8 +914,9 @@ public class AudioTrack extends PlayerBase /** * Sets whether this track will play through the offloaded audio path. * When set to true, at build time, the audio format will be checked against - * {@link AudioManager#isOffloadedPlaybackSupported(AudioFormat)} to verify the audio format - * used by this track is supported on the device's offload path (if any). + * {@link AudioManager#isOffloadedPlaybackSupported(AudioFormat,AudioAttributes)} + * to verify the audio format used by this track is supported on the device's offload + * path (if any). * <br>Offload is only supported for media audio streams, and therefore requires that * the usage be {@link AudioAttributes#USAGE_MEDIA}. * @param offload true to require the offload path for playback. @@ -979,7 +980,7 @@ public class AudioTrack extends PlayerBase throw new UnsupportedOperationException( "Cannot create AudioTrack, offload requires USAGE_MEDIA"); } - if (!AudioSystem.isOffloadSupported(mFormat)) { + if (!AudioSystem.isOffloadSupported(mFormat, mAttributes)) { throw new UnsupportedOperationException( "Cannot create AudioTrack, offload format not supported"); } @@ -3177,7 +3178,8 @@ public class AudioTrack extends PlayerBase * Registers a callback for the notification of stream events. * This callback can only be registered for instances operating in offloaded mode * (see {@link AudioTrack.Builder#setOffloadedPlayback(boolean)} and - * {@link AudioManager#isOffloadedPlaybackSupported(AudioFormat)} for more details). + * {@link AudioManager#isOffloadedPlaybackSupported(AudioFormat,AudioAttributes)} for + * more details). * @param executor {@link Executor} to handle the callbacks. * @param eventCallback the callback to receive the stream event notifications. */ diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index c29f355181f4..980cb0459821 100644 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -37,6 +37,7 @@ import android.media.audiopolicy.AudioProductStrategies; import android.media.audiopolicy.AudioVolumeGroups; import android.media.audiopolicy.IAudioPolicyCallback; import android.media.projection.IMediaProjection; +import android.net.Uri; /** * {@hide} @@ -195,6 +196,7 @@ interface IAudioService { String registerAudioPolicy(in AudioPolicyConfig policyConfig, in IAudioPolicyCallback pcb, boolean hasFocusListener, boolean isFocusPolicy, + boolean isTestFocusPolicy, boolean isVolumeController, in IMediaProjection projection); oneway void unregisterAudioPolicyAsync(in IAudioPolicyCallback pcb); @@ -250,6 +252,8 @@ interface IAudioService { int removeUidDeviceAffinity(in IAudioPolicyCallback pcb, in int uid); + boolean hasHapticChannels(in Uri uri); + // WARNING: read warning at top of file, new methods that need to be used by native // code via IAudioManager.h need to be added to the top section. } diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java index aeb77cfddbbd..a08aec3ed20c 100644 --- a/media/java/android/media/MediaDrm.java +++ b/media/java/android/media/MediaDrm.java @@ -304,6 +304,11 @@ public final class MediaDrm implements AutoCloseable { } /** + * The SessionException has an unknown error code. + */ + public static final int ERROR_UNKNOWN = 0; + + /** * This indicates that apps using MediaDrm sessions are * temporarily exceeding the capacity of available crypto * resources. The app should retry the operation later. @@ -547,6 +552,13 @@ public final class MediaDrm implements AutoCloseable { */ public static final int STATUS_INTERNAL_ERROR = 4; + /** + * The key is not yet usable to decrypt media because the start + * time is in the future. The key will become usable when + * its start time is reached. + */ + public static final int STATUS_USABLE_IN_FUTURE = 5; + /** @hide */ @IntDef({ STATUS_USABLE, @@ -554,6 +566,7 @@ public final class MediaDrm implements AutoCloseable { STATUS_OUTPUT_NOT_ALLOWED, STATUS_PENDING, STATUS_INTERNAL_ERROR, + STATUS_USABLE_IN_FUTURE, }) @Retention(RetentionPolicy.SOURCE) public @interface KeyStatusCode {} diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java index 8686c5905af7..a22c8d0a8457 100644 --- a/media/java/android/media/MediaFormat.java +++ b/media/java/android/media/MediaFormat.java @@ -874,6 +874,12 @@ public final class MediaFormat { */ public static final String KEY_IS_FORCED_SUBTITLE = "is-forced-subtitle"; + /** + * A key describing the number of haptic channels in an audio format. + * The associated value is an integer. + */ + public static final String KEY_HAPTIC_CHANNEL_COUNT = "haptic-channel-count"; + /** @hide */ public static final String KEY_IS_TIMED_TEXT = "is-timed-text"; diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java index e7b4752701fb..575a0bb03f7b 100644 --- a/media/java/android/media/MediaRecorder.java +++ b/media/java/android/media/MediaRecorder.java @@ -1537,8 +1537,8 @@ public class MediaRecorder implements AudioRouting, * @param direction Direction constant. * @return true if sucessful. */ - public boolean setMicrophoneDirection(@DirectionMode int direction) { - return native_setMicrophoneDirection(direction) == 0; + public boolean setPreferredMicrophoneDirection(@DirectionMode int direction) { + return native_setPreferredMicrophoneDirection(direction) == 0; } /** @@ -1549,14 +1549,15 @@ public class MediaRecorder implements AudioRouting, * though 0 (no zoom) to 1 (maximum zoom). * @return true if sucessful. */ - public boolean setMicrophoneFieldDimension(@FloatRange(from = -1.0, to = 1.0) float zoom) { + public boolean setPreferredMicrophoneFieldDimension( + @FloatRange(from = -1.0, to = 1.0) float zoom) { Preconditions.checkArgument( zoom >= -1 && zoom <= 1, "Argument must fall between -1 & 1 (inclusive)"); - return native_setMicrophoneFieldDimension(zoom) == 0; + return native_setPreferredMicrophoneFieldDimension(zoom) == 0; } - private native int native_setMicrophoneDirection(int direction); - private native int native_setMicrophoneFieldDimension(float zoom); + private native int native_setPreferredMicrophoneDirection(int direction); + private native int native_setPreferredMicrophoneFieldDimension(float zoom); //-------------------------------------------------------------------------- // Implementation of AudioRecordingMonitor interface diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java index 30719fd8c750..771628cf7b1e 100644 --- a/media/java/android/media/MediaScanner.java +++ b/media/java/android/media/MediaScanner.java @@ -116,7 +116,14 @@ import java.util.concurrent.atomic.AtomicBoolean; * The MediaScanner class is not thread-safe, so it should only be used in a single threaded manner. * * {@hide} + * + * @deprecated this media scanner has served faithfully for many years, but it's + * become tedious to test and maintain, mainly due to the way it + * weaves obscurely between managed and native code. It's been + * replaced by {@code ModernMediaScanner} in the + * {@code MediaProvider} package. */ +@Deprecated public class MediaScanner implements AutoCloseable { static { System.loadLibrary("media_jni"); diff --git a/media/java/android/media/MicrophoneDirection.java b/media/java/android/media/MicrophoneDirection.java index 2382da54801c..e4eec446b7bc 100644 --- a/media/java/android/media/MicrophoneDirection.java +++ b/media/java/android/media/MicrophoneDirection.java @@ -32,13 +32,21 @@ public interface MicrophoneDirection { */ int MIC_DIRECTION_UNSPECIFIED = 0; /** - * Optimize capture for audio coming from the screen-side of the device. + * Optimize capture for audio coming from the side of the device facing the user. + * In the typical case, a device with a single screen, screen-side camera/microphone and + * non-screen-side camera/microphone, this will be the screen side (as in a "selfie"). + * For a different device geometry, it is the side for which the expectation is to be + * facing the user. */ - int MIC_DIRECTION_FRONT = 1; + int MIC_DIRECTION_TOWARDS_USER = 1; /** - * Optimize capture for audio coming from the side of the device opposite the screen. + * Optimize capture for audio coming from the side of the device pointing away from the user. + * In the typical case, a device with a single screen, screen-side camera/microphone and + * non-screen-side camera/microphone, this will be the non-screen side. + * For a different device geometry, it is the side for which the expectation is to be + * facing away from the user. This is the "taking a video of something else" case. */ - int MIC_DIRECTION_BACK = 2; + int MIC_DIRECTION_AWAY_FROM_USER = 2; /** * Optimize capture for audio coming from an off-device microphone. */ @@ -47,8 +55,8 @@ public interface MicrophoneDirection { /** @hide */ /*public*/ @IntDef({ MIC_DIRECTION_UNSPECIFIED, - MIC_DIRECTION_FRONT, - MIC_DIRECTION_BACK, + MIC_DIRECTION_TOWARDS_USER, + MIC_DIRECTION_AWAY_FROM_USER, MIC_DIRECTION_EXTERNAL }) @Retention(RetentionPolicy.SOURCE) @@ -58,18 +66,23 @@ public interface MicrophoneDirection { * which side of the device to optimize capture from. Typically used in conjunction with * the camera capturing video. * + * Usage would include specifying the audio capture to follow camera being used to capture + * video. * @param direction Direction constant. * @return true if sucessful. */ - boolean setMicrophoneDirection(@DirectionMode int direction); + boolean setPreferredMicrophoneDirection(@DirectionMode int direction); /** * Specifies the zoom factor (i.e. the field dimension) for the selected microphone * (for processing). The selected microphone is determined by the use-case for the stream. * + * Usage would include specifying the audio focus to follow the zoom specified for the camera + * being used to capture video. + * * @param zoom the desired field dimension of microphone capture. Range is from -1 (wide angle), * though 0 (no zoom) to 1 (maximum zoom). * @return true if sucessful. */ - boolean setMicrophoneFieldDimension(@FloatRange(from = -1.0, to = 1.0) float zoom); + boolean setPreferredMicrophoneFieldDimension(@FloatRange(from = -1.0, to = 1.0) float zoom); } diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java index 9a609236aa30..e0e657bb4474 100644 --- a/media/java/android/media/RingtoneManager.java +++ b/media/java/android/media/RingtoneManager.java @@ -1098,6 +1098,28 @@ public class RingtoneManager { } /** + * Returns if the {@link Ringtone} at the given position in the + * {@link Cursor} contains haptic channels. + * + * @param position The position (in the {@link Cursor}) of the ringtone. + * @return true if the ringtone contains haptic channels. + */ + public boolean hasHapticChannels(int position) { + return hasHapticChannels(getRingtoneUri(position)); + } + + /** + * Returns if the {@link Ringtone} from a given sound URI contains + * haptic channels or not. + * + * @param ringtoneUri The {@link Uri} of a sound or ringtone. + * @return true if the ringtone contains haptic channels. + */ + public static boolean hasHapticChannels(@NonNull Uri ringtoneUri) { + return AudioManager.hasHapticChannels(ringtoneUri); + } + + /** * Creates a {@link android.media.MediaScannerConnection} to scan a ringtone file and add its * information to the internal database. * diff --git a/media/java/android/media/audiopolicy/AudioPolicy.java b/media/java/android/media/audiopolicy/AudioPolicy.java index 978583e99971..00f601388164 100644 --- a/media/java/android/media/audiopolicy/AudioPolicy.java +++ b/media/java/android/media/audiopolicy/AudioPolicy.java @@ -75,6 +75,7 @@ public class AudioPolicy { private String mRegistrationId; private AudioPolicyStatusListener mStatusListener; private boolean mIsFocusPolicy; + private boolean mIsTestFocusPolicy; /** * The list of AudioTrack instances created to inject audio into the associated mixes @@ -121,6 +122,10 @@ public class AudioPolicy { /** @hide */ public boolean isFocusPolicy() { return mIsFocusPolicy; } /** @hide */ + public boolean isTestFocusPolicy() { + return mIsTestFocusPolicy; + } + /** @hide */ public boolean isVolumeController() { return mVolCb != null; } /** @hide */ public @Nullable MediaProjection getMediaProjection() { @@ -128,10 +133,11 @@ public class AudioPolicy { } /** - * The parameter is guaranteed non-null through the Builder + * The parameters are guaranteed non-null through the Builder */ private AudioPolicy(AudioPolicyConfig config, Context context, Looper looper, - AudioPolicyFocusListener fl, AudioPolicyStatusListener sl, boolean isFocusPolicy, + AudioPolicyFocusListener fl, AudioPolicyStatusListener sl, + boolean isFocusPolicy, boolean isTestFocusPolicy, AudioPolicyVolumeCallback vc, @Nullable MediaProjection projection) { mConfig = config; mStatus = POLICY_STATUS_UNREGISTERED; @@ -148,6 +154,7 @@ public class AudioPolicy { mFocusListener = fl; mStatusListener = sl; mIsFocusPolicy = isFocusPolicy; + mIsTestFocusPolicy = isTestFocusPolicy; mVolCb = vc; mProjection = projection; } @@ -163,6 +170,7 @@ public class AudioPolicy { private AudioPolicyFocusListener mFocusListener; private AudioPolicyStatusListener mStatusListener; private boolean mIsFocusPolicy = false; + private boolean mIsTestFocusPolicy = false; private AudioPolicyVolumeCallback mVolCb; private MediaProjection mProjection; @@ -181,6 +189,7 @@ public class AudioPolicy { * @return the same Builder instance. * @throws IllegalArgumentException */ + @NonNull public Builder addMix(@NonNull AudioMix mix) throws IllegalArgumentException { if (mix == null) { throw new IllegalArgumentException("Illegal null AudioMix argument"); @@ -195,6 +204,7 @@ public class AudioPolicy { * @return the same Builder instance. * @throws IllegalArgumentException */ + @NonNull public Builder setLooper(@NonNull Looper looper) throws IllegalArgumentException { if (looper == null) { throw new IllegalArgumentException("Illegal null Looper argument"); @@ -220,12 +230,28 @@ public class AudioPolicy { * @param enforce true if the policy will govern audio focus decisions. * @return the same Builder instance. */ + @NonNull public Builder setIsAudioFocusPolicy(boolean isFocusPolicy) { mIsFocusPolicy = isFocusPolicy; return this; } /** + * Test method to declare whether this audio focus policy is for test purposes only. + * Having a test policy registered will disable the current focus policy and replace it + * with this test policy. When unregistered, the previous focus policy will be restored. + * <p>A value of <code>true</code> will be ignored if the AudioPolicy is not also + * focus policy. + * @param isTestFocusPolicy true if the focus policy to register is for testing purposes. + * @return the same Builder instance + */ + @NonNull + public Builder setIsTestFocusPolicy(boolean isTestFocusPolicy) { + mIsTestFocusPolicy = isTestFocusPolicy; + return this; + } + + /** * Sets the audio policy status listener. * @param l a {@link AudioPolicy.AudioPolicyStatusListener} */ @@ -240,6 +266,7 @@ public class AudioPolicy { * @param vc * @return the same Builder instance. */ + @NonNull public Builder setAudioPolicyVolumeCallback(@NonNull AudioPolicyVolumeCallback vc) { if (vc == null) { throw new IllegalArgumentException("Invalid null volume callback"); @@ -256,6 +283,7 @@ public class AudioPolicy { * * @hide */ + @NonNull public Builder setMediaProjection(@NonNull MediaProjection projection) { if (projection == null) { throw new IllegalArgumentException("Invalid null volume callback"); @@ -273,6 +301,7 @@ public class AudioPolicy { * {@link AudioPolicy.AudioPolicyStatusListener} but the policy was configured * as an audio focus policy with {@link #setIsAudioFocusPolicy(boolean)}. */ + @NonNull public AudioPolicy build() { if (mStatusListener != null) { // the AudioPolicy status listener includes updates on each mix activity state @@ -285,7 +314,8 @@ public class AudioPolicy { + "an AudioPolicyFocusListener"); } return new AudioPolicy(new AudioPolicyConfig(mMixes), mContext, mLooper, - mFocusListener, mStatusListener, mIsFocusPolicy, mVolCb, mProjection); + mFocusListener, mStatusListener, mIsFocusPolicy, mIsTestFocusPolicy, + mVolCb, mProjection); } } diff --git a/media/java/android/media/projection/OWNERS b/media/java/android/media/projection/OWNERS new file mode 100644 index 000000000000..7e7335d68d3b --- /dev/null +++ b/media/java/android/media/projection/OWNERS @@ -0,0 +1 @@ +michaelwr@google.com diff --git a/media/java/android/media/session/ISessionCallback.aidl b/media/java/android/media/session/ISessionCallback.aidl index cd33c044d142..0add1b417c4f 100644 --- a/media/java/android/media/session/ISessionCallback.aidl +++ b/media/java/android/media/session/ISessionCallback.aidl @@ -26,48 +26,48 @@ import android.os.ResultReceiver; * @hide */ oneway interface ISessionCallback { - void notifyCommand(String packageName, int pid, int uid, in ControllerCallbackLink caller, + void onCommand(String packageName, int pid, int uid, in ControllerCallbackLink caller, String command, in Bundle args, in ResultReceiver cb); - void notifyMediaButton(String packageName, int pid, int uid, in Intent mediaButtonIntent, + void onMediaButton(String packageName, int pid, int uid, in Intent mediaButtonIntent, int sequenceNumber, in ResultReceiver cb); - void notifyMediaButtonFromController(String packageName, int pid, int uid, + void onMediaButtonFromController(String packageName, int pid, int uid, in ControllerCallbackLink caller, in Intent mediaButtonIntent); - // These callbacks are for the TransportPerformer - void notifyPrepare(String packageName, int pid, int uid, in ControllerCallbackLink caller); - void notifyPrepareFromMediaId(String packageName, int pid, int uid, + // These callbacks are for the TransportControls + void onPrepare(String packageName, int pid, int uid, in ControllerCallbackLink caller); + void onPrepareFromMediaId(String packageName, int pid, int uid, in ControllerCallbackLink caller, String mediaId, in Bundle extras); - void notifyPrepareFromSearch(String packageName, int pid, int uid, + void onPrepareFromSearch(String packageName, int pid, int uid, in ControllerCallbackLink caller, String query, in Bundle extras); - void notifyPrepareFromUri(String packageName, int pid, int uid, + void onPrepareFromUri(String packageName, int pid, int uid, in ControllerCallbackLink caller, in Uri uri, in Bundle extras); - void notifyPlay(String packageName, int pid, int uid, in ControllerCallbackLink caller); - void notifyPlayFromMediaId(String packageName, int pid, int uid, + void onPlay(String packageName, int pid, int uid, in ControllerCallbackLink caller); + void onPlayFromMediaId(String packageName, int pid, int uid, in ControllerCallbackLink caller, String mediaId, in Bundle extras); - void notifyPlayFromSearch(String packageName, int pid, int uid, + void onPlayFromSearch(String packageName, int pid, int uid, in ControllerCallbackLink caller, String query, in Bundle extras); - void notifyPlayFromUri(String packageName, int pid, int uid, in ControllerCallbackLink caller, + void onPlayFromUri(String packageName, int pid, int uid, in ControllerCallbackLink caller, in Uri uri, in Bundle extras); - void notifySkipToTrack(String packageName, int pid, int uid, in ControllerCallbackLink caller, + void onSkipToTrack(String packageName, int pid, int uid, in ControllerCallbackLink caller, long id); - void notifyPause(String packageName, int pid, int uid, in ControllerCallbackLink caller); - void notifyStop(String packageName, int pid, int uid, in ControllerCallbackLink caller); - void notifyNext(String packageName, int pid, int uid, in ControllerCallbackLink caller); - void notifyPrevious(String packageName, int pid, int uid, in ControllerCallbackLink caller); - void notifyFastForward(String packageName, int pid, int uid, in ControllerCallbackLink caller); - void notifyRewind(String packageName, int pid, int uid, in ControllerCallbackLink caller); - void notifySeekTo(String packageName, int pid, int uid, in ControllerCallbackLink caller, + void onPause(String packageName, int pid, int uid, in ControllerCallbackLink caller); + void onStop(String packageName, int pid, int uid, in ControllerCallbackLink caller); + void onNext(String packageName, int pid, int uid, in ControllerCallbackLink caller); + void onPrevious(String packageName, int pid, int uid, in ControllerCallbackLink caller); + void onFastForward(String packageName, int pid, int uid, in ControllerCallbackLink caller); + void onRewind(String packageName, int pid, int uid, in ControllerCallbackLink caller); + void onSeekTo(String packageName, int pid, int uid, in ControllerCallbackLink caller, long pos); - void notifyRate(String packageName, int pid, int uid, in ControllerCallbackLink caller, + void onRate(String packageName, int pid, int uid, in ControllerCallbackLink caller, in Rating rating); - void notifySetPlaybackSpeed(String packageName, int pid, int uid, + void onSetPlaybackSpeed(String packageName, int pid, int uid, in ControllerCallbackLink caller, float speed); - void notifyCustomAction(String packageName, int pid, int uid, in ControllerCallbackLink caller, + void onCustomAction(String packageName, int pid, int uid, in ControllerCallbackLink caller, String action, in Bundle args); // These callbacks are for volume handling - void notifyAdjustVolume(String packageName, int pid, int uid, in ControllerCallbackLink caller, + void onAdjustVolume(String packageName, int pid, int uid, in ControllerCallbackLink caller, int direction); - void notifySetVolumeTo(String packageName, int pid, int uid, + void onSetVolumeTo(String packageName, int pid, int uid, in ControllerCallbackLink caller, int value); } diff --git a/media/java/android/media/session/ISessionManager.aidl b/media/java/android/media/session/ISessionManager.aidl index 023484764a52..e073a4e2f6c8 100644 --- a/media/java/android/media/session/ISessionManager.aidl +++ b/media/java/android/media/session/ISessionManager.aidl @@ -23,9 +23,9 @@ import android.media.session.ICallback; import android.media.session.IOnMediaKeyListener; import android.media.session.IOnVolumeKeyLongPressListener; import android.media.session.ISession; +import android.media.session.ISessionCallback; import android.media.session.ISession2TokensListener; import android.media.session.MediaSession; -import android.media.session.SessionCallbackLink; import android.os.Bundle; import android.view.KeyEvent; @@ -34,7 +34,7 @@ import android.view.KeyEvent; * @hide */ interface ISessionManager { - ISession createSession(String packageName, in SessionCallbackLink sessionCb, String tag, + ISession createSession(String packageName, in ISessionCallback sessionCb, String tag, in Bundle sessionInfo, int userId); void notifySession2Created(in Session2Token sessionToken); List<MediaSession.Token> getSessions(in ComponentName compName, int userId); diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java index cbc6c9d6e451..aa61a01310c9 100644 --- a/media/java/android/media/session/MediaSession.java +++ b/media/java/android/media/session/MediaSession.java @@ -27,12 +27,15 @@ import android.content.Intent; import android.media.AudioAttributes; import android.media.MediaDescription; import android.media.MediaMetadata; +import android.media.MediaParceledListSlice; import android.media.Rating; import android.media.VolumeProvider; import android.media.session.MediaSessionManager.RemoteUserInfo; import android.net.Uri; import android.os.Bundle; import android.os.Handler; +import android.os.Looper; +import android.os.Message; import android.os.Parcel; import android.os.Parcelable; import android.os.Process; @@ -40,9 +43,14 @@ import android.os.RemoteException; import android.os.ResultReceiver; import android.service.media.MediaBrowserService; import android.text.TextUtils; +import android.util.Log; +import android.util.Pair; +import android.view.KeyEvent; +import android.view.ViewConfiguration; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.lang.ref.WeakReference; import java.util.List; import java.util.Objects; @@ -116,12 +124,21 @@ public final class MediaSession { FLAG_EXCLUSIVE_GLOBAL_PRIORITY }) public @interface SessionFlags { } - private final MediaSessionEngine mImpl; + private final Object mLock = new Object(); private final int mMaxBitmapSize; + private final Token mSessionToken; + private final MediaController mController; + private final ISession mBinder; + private final CallbackStub mCbStub; + // Do not change the name of mCallback. Support lib accesses this by using reflection. @UnsupportedAppUsage - private Object mCallback; + private CallbackMessageHandler mCallback; + private VolumeProvider mVolumeProvider; + private PlaybackState mPlaybackState; + + private boolean mActive = false; /** * Creates a new session. The session will automatically be registered with @@ -160,14 +177,15 @@ public final class MediaSession { if (TextUtils.isEmpty(tag)) { throw new IllegalArgumentException("tag cannot be null or empty"); } + mMaxBitmapSize = context.getResources().getDimensionPixelSize( + com.android.internal.R.dimen.config_mediaMetadataBitmapMaxSize); + mCbStub = new CallbackStub(this); MediaSessionManager manager = (MediaSessionManager) context .getSystemService(Context.MEDIA_SESSION_SERVICE); try { - SessionCallbackLink cbLink = new SessionCallbackLink(context); - ISession binder = manager.createSession(cbLink, tag, sessionInfo); - mImpl = new MediaSessionEngine(context, binder, cbLink); - mMaxBitmapSize = context.getResources().getDimensionPixelSize( - com.android.internal.R.dimen.config_mediaMetadataBitmapMaxSize); + mBinder = manager.createSession(mCbStub, tag, sessionInfo); + mSessionToken = new Token(mBinder.getController()); + mController = new MediaController(context, mSessionToken); } catch (RemoteException e) { throw new RuntimeException("Remote error creating session.", e); } @@ -183,8 +201,7 @@ public final class MediaSession { * @param callback The callback object */ public void setCallback(@Nullable Callback callback) { - mCallback = callback == null ? null : new Object(); - mImpl.setCallback(callback); + setCallback(callback, null); } /** @@ -197,8 +214,24 @@ public final class MediaSession { * @param handler The handler that events should be posted on. */ public void setCallback(@Nullable Callback callback, @Nullable Handler handler) { - mCallback = callback == null ? null : new Object(); - mImpl.setCallback(callback, handler); + synchronized (mLock) { + if (mCallback != null) { + // We're updating the callback, clear the session from the old one. + mCallback.mCallback.mSession = null; + mCallback.removeCallbacksAndMessages(null); + } + if (callback == null) { + mCallback = null; + return; + } + if (handler == null) { + handler = new Handler(); + } + callback.mSession = this; + CallbackMessageHandler msgHandler = new CallbackMessageHandler(handler.getLooper(), + callback); + mCallback = msgHandler; + } } /** @@ -209,7 +242,11 @@ public final class MediaSession { * @param pi The intent to launch to show UI for this Session. */ public void setSessionActivity(@Nullable PendingIntent pi) { - mImpl.setSessionActivity(pi); + try { + mBinder.setLaunchPendingIntent(pi); + } catch (RemoteException e) { + Log.wtf(TAG, "Failure in setLaunchPendingIntent.", e); + } } /** @@ -221,7 +258,11 @@ public final class MediaSession { * @param mbr The {@link PendingIntent} to send the media button event to. */ public void setMediaButtonReceiver(@Nullable PendingIntent mbr) { - mImpl.setMediaButtonReceiver(mbr); + try { + mBinder.setMediaButtonReceiver(mbr); + } catch (RemoteException e) { + Log.wtf(TAG, "Failure in setMediaButtonReceiver.", e); + } } /** @@ -230,7 +271,11 @@ public final class MediaSession { * @param flags The flags to set for this session. */ public void setFlags(@SessionFlags int flags) { - mImpl.setFlags(flags); + try { + mBinder.setFlags(flags); + } catch (RemoteException e) { + Log.wtf(TAG, "Failure in setFlags.", e); + } } /** @@ -245,7 +290,14 @@ public final class MediaSession { * @param attributes The {@link AudioAttributes} for this session's audio. */ public void setPlaybackToLocal(AudioAttributes attributes) { - mImpl.setPlaybackToLocal(attributes); + if (attributes == null) { + throw new IllegalArgumentException("Attributes cannot be null for local playback."); + } + try { + mBinder.setPlaybackToLocal(attributes); + } catch (RemoteException e) { + Log.wtf(TAG, "Failure in setPlaybackToLocal.", e); + } } /** @@ -260,7 +312,26 @@ public final class MediaSession { * not be null. */ public void setPlaybackToRemote(@NonNull VolumeProvider volumeProvider) { - mImpl.setPlaybackToRemote(volumeProvider); + if (volumeProvider == null) { + throw new IllegalArgumentException("volumeProvider may not be null!"); + } + synchronized (mLock) { + mVolumeProvider = volumeProvider; + } + volumeProvider.setCallback(new VolumeProvider.Callback() { + @Override + public void onVolumeChanged(VolumeProvider volumeProvider) { + notifyRemoteVolumeChanged(volumeProvider); + } + }); + + try { + mBinder.setPlaybackToRemote(volumeProvider.getVolumeControl(), + volumeProvider.getMaxVolume()); + mBinder.setCurrentVolume(volumeProvider.getCurrentVolume()); + } catch (RemoteException e) { + Log.wtf(TAG, "Failure in setPlaybackToRemote.", e); + } } /** @@ -272,7 +343,15 @@ public final class MediaSession { * @param active Whether this session is active or not. */ public void setActive(boolean active) { - mImpl.setActive(active); + if (mActive == active) { + return; + } + try { + mBinder.setActive(active); + mActive = active; + } catch (RemoteException e) { + Log.wtf(TAG, "Failure in setActive.", e); + } } /** @@ -281,7 +360,7 @@ public final class MediaSession { * @return True if the session is active, false otherwise. */ public boolean isActive() { - return mImpl.isActive(); + return mActive; } /** @@ -293,7 +372,14 @@ public final class MediaSession { * @param extras Any extras included with the event */ public void sendSessionEvent(@NonNull String event, @Nullable Bundle extras) { - mImpl.sendSessionEvent(event, extras); + if (TextUtils.isEmpty(event)) { + throw new IllegalArgumentException("event cannot be null or empty"); + } + try { + mBinder.sendEvent(event, extras); + } catch (RemoteException e) { + Log.wtf(TAG, "Error sending event", e); + } } /** @@ -302,7 +388,11 @@ public final class MediaSession { * but it must be released if your activity or service is being destroyed. */ public void release() { - mImpl.close(); + try { + mBinder.destroySession(); + } catch (RemoteException e) { + Log.wtf(TAG, "Error releasing session: ", e); + } } /** @@ -314,7 +404,7 @@ public final class MediaSession { * session */ public @NonNull Token getSessionToken() { - return mImpl.getSessionToken(); + return mSessionToken; } /** @@ -324,7 +414,7 @@ public final class MediaSession { * @return A controller for this session. */ public @NonNull MediaController getController() { - return mImpl.getController(); + return mController; } /** @@ -333,7 +423,12 @@ public final class MediaSession { * @param state The current state of playback */ public void setPlaybackState(@Nullable PlaybackState state) { - mImpl.setPlaybackState(state); + mPlaybackState = state; + try { + mBinder.setPlaybackState(state); + } catch (RemoteException e) { + Log.wtf(TAG, "Dead object in setPlaybackState.", e); + } } /** @@ -345,10 +440,24 @@ public final class MediaSession { * @see android.media.MediaMetadata.Builder#putBitmap */ public void setMetadata(@Nullable MediaMetadata metadata) { + long duration = -1; + int fields = 0; + MediaDescription description = null; if (metadata != null) { - metadata = new MediaMetadata.Builder(metadata, mMaxBitmapSize).build(); + metadata = (new MediaMetadata.Builder(metadata, mMaxBitmapSize)).build(); + if (metadata.containsKey(MediaMetadata.METADATA_KEY_DURATION)) { + duration = metadata.getLong(MediaMetadata.METADATA_KEY_DURATION); + } + fields = metadata.size(); + description = metadata.getDescription(); + } + String metadataDescription = "size=" + fields + ", description=" + description; + + try { + mBinder.setMetadata(metadata, duration, metadataDescription); + } catch (RemoteException e) { + Log.wtf(TAG, "Dead object in setPlaybackState.", e); } - mImpl.setMetadata(metadata); } /** @@ -363,7 +472,11 @@ public final class MediaSession { * @param queue A list of items in the play queue. */ public void setQueue(@Nullable List<QueueItem> queue) { - mImpl.setQueue(queue); + try { + mBinder.setQueue(queue == null ? null : new MediaParceledListSlice(queue)); + } catch (RemoteException e) { + Log.wtf("Dead object in setQueue.", e); + } } /** @@ -374,7 +487,11 @@ public final class MediaSession { * @param title The title of the play queue. */ public void setQueueTitle(@Nullable CharSequence title) { - mImpl.setQueueTitle(title); + try { + mBinder.setQueueTitle(title); + } catch (RemoteException e) { + Log.wtf("Dead object in setQueueTitle.", e); + } } /** @@ -391,7 +508,11 @@ public final class MediaSession { * </ul> */ public void setRatingType(@Rating.Style int type) { - mImpl.setRatingType(type); + try { + mBinder.setRatingType(type); + } catch (RemoteException e) { + Log.e(TAG, "Error in setRatingType.", e); + } } /** @@ -402,7 +523,11 @@ public final class MediaSession { * @param extras The extras associated with the {@link MediaSession}. */ public void setExtras(@Nullable Bundle extras) { - mImpl.setExtras(extras); + try { + mBinder.setExtras(extras); + } catch (RemoteException e) { + Log.wtf("Dead object in setExtras.", e); + } } /** @@ -414,7 +539,31 @@ public final class MediaSession { * @see MediaSessionManager#isTrustedForMediaControl(RemoteUserInfo) */ public final @NonNull RemoteUserInfo getCurrentControllerInfo() { - return mImpl.getCurrentControllerInfo(); + if (mCallback == null || mCallback.mCurrentControllerInfo == null) { + throw new IllegalStateException( + "This should be called inside of MediaSession.Callback methods"); + } + return mCallback.mCurrentControllerInfo; + } + + /** + * Notify the system that the remote volume changed. + * + * @param provider The provider that is handling volume changes. + * @hide + */ + public void notifyRemoteVolumeChanged(VolumeProvider provider) { + synchronized (mLock) { + if (provider == null || provider != mVolumeProvider) { + Log.w(TAG, "Received update from stale volume provider"); + return; + } + } + try { + mBinder.setCurrentVolume(provider.getCurrentVolume()); + } catch (RemoteException e) { + Log.e(TAG, "Error in notifyVolumeChanged", e); + } } /** @@ -426,7 +575,10 @@ public final class MediaSession { */ @UnsupportedAppUsage public String getCallingPackage() { - return mImpl.getCallingPackage(); + if (mCallback != null && mCallback.mCurrentControllerInfo != null) { + return mCallback.mCurrentControllerInfo.getPackageName(); + } + return null; } /** @@ -435,7 +587,130 @@ public final class MediaSession { * @hide */ public static boolean isActiveState(int state) { - return MediaSessionEngine.isActiveState(state); + switch (state) { + case PlaybackState.STATE_FAST_FORWARDING: + case PlaybackState.STATE_REWINDING: + case PlaybackState.STATE_SKIPPING_TO_PREVIOUS: + case PlaybackState.STATE_SKIPPING_TO_NEXT: + case PlaybackState.STATE_BUFFERING: + case PlaybackState.STATE_CONNECTING: + case PlaybackState.STATE_PLAYING: + return true; + } + return false; + } + + void dispatchPrepare(RemoteUserInfo caller) { + postToCallback(caller, CallbackMessageHandler.MSG_PREPARE, null, null); + } + + void dispatchPrepareFromMediaId(RemoteUserInfo caller, String mediaId, Bundle extras) { + postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_MEDIA_ID, mediaId, extras); + } + + void dispatchPrepareFromSearch(RemoteUserInfo caller, String query, Bundle extras) { + postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_SEARCH, query, extras); + } + + void dispatchPrepareFromUri(RemoteUserInfo caller, Uri uri, Bundle extras) { + postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_URI, uri, extras); + } + + void dispatchPlay(RemoteUserInfo caller) { + postToCallback(caller, CallbackMessageHandler.MSG_PLAY, null, null); + } + + void dispatchPlayFromMediaId(RemoteUserInfo caller, String mediaId, Bundle extras) { + postToCallback(caller, CallbackMessageHandler.MSG_PLAY_MEDIA_ID, mediaId, extras); + } + + void dispatchPlayFromSearch(RemoteUserInfo caller, String query, Bundle extras) { + postToCallback(caller, CallbackMessageHandler.MSG_PLAY_SEARCH, query, extras); + } + + void dispatchPlayFromUri(RemoteUserInfo caller, Uri uri, Bundle extras) { + postToCallback(caller, CallbackMessageHandler.MSG_PLAY_URI, uri, extras); + } + + void dispatchSkipToItem(RemoteUserInfo caller, long id) { + postToCallback(caller, CallbackMessageHandler.MSG_SKIP_TO_ITEM, id, null); + } + + void dispatchPause(RemoteUserInfo caller) { + postToCallback(caller, CallbackMessageHandler.MSG_PAUSE, null, null); + } + + void dispatchStop(RemoteUserInfo caller) { + postToCallback(caller, CallbackMessageHandler.MSG_STOP, null, null); + } + + void dispatchNext(RemoteUserInfo caller) { + postToCallback(caller, CallbackMessageHandler.MSG_NEXT, null, null); + } + + void dispatchPrevious(RemoteUserInfo caller) { + postToCallback(caller, CallbackMessageHandler.MSG_PREVIOUS, null, null); + } + + void dispatchFastForward(RemoteUserInfo caller) { + postToCallback(caller, CallbackMessageHandler.MSG_FAST_FORWARD, null, null); + } + + void dispatchRewind(RemoteUserInfo caller) { + postToCallback(caller, CallbackMessageHandler.MSG_REWIND, null, null); + } + + void dispatchSeekTo(RemoteUserInfo caller, long pos) { + postToCallback(caller, CallbackMessageHandler.MSG_SEEK_TO, pos, null); + } + + void dispatchRate(RemoteUserInfo caller, Rating rating) { + postToCallback(caller, CallbackMessageHandler.MSG_RATE, rating, null); + } + + void dispatchSetPlaybackSpeed(RemoteUserInfo caller, float speed) { + postToCallback(caller, CallbackMessageHandler.MSG_SET_PLAYBACK_SPEED, speed, null); + } + + void dispatchCustomAction(RemoteUserInfo caller, String action, Bundle args) { + postToCallback(caller, CallbackMessageHandler.MSG_CUSTOM_ACTION, action, args); + } + + void dispatchMediaButton(RemoteUserInfo caller, Intent mediaButtonIntent) { + postToCallback(caller, CallbackMessageHandler.MSG_MEDIA_BUTTON, mediaButtonIntent, null); + } + + void dispatchMediaButtonDelayed(RemoteUserInfo info, Intent mediaButtonIntent, + long delay) { + postToCallbackDelayed(info, CallbackMessageHandler.MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT, + mediaButtonIntent, null, delay); + } + + void dispatchAdjustVolume(RemoteUserInfo caller, int direction) { + postToCallback(caller, CallbackMessageHandler.MSG_ADJUST_VOLUME, direction, null); + } + + void dispatchSetVolumeTo(RemoteUserInfo caller, int volume) { + postToCallback(caller, CallbackMessageHandler.MSG_SET_VOLUME, volume, null); + } + + void dispatchCommand(RemoteUserInfo caller, String command, Bundle args, + ResultReceiver resultCb) { + Command cmd = new Command(command, args, resultCb); + postToCallback(caller, CallbackMessageHandler.MSG_COMMAND, cmd, null); + } + + void postToCallback(RemoteUserInfo caller, int what, Object obj, Bundle data) { + postToCallbackDelayed(caller, what, obj, data, 0); + } + + void postToCallbackDelayed(RemoteUserInfo caller, int what, Object obj, Bundle data, + long delay) { + synchronized (mLock) { + if (mCallback != null) { + mCallback.post(caller, what, obj, data, delay); + } + } } /** @@ -534,7 +809,9 @@ public final class MediaSession { */ public abstract static class Callback { - MediaSessionEngine.MediaButtonEventDelegate mMediaButtonEventDelegate; + private MediaSession mSession; + private CallbackMessageHandler mHandler; + private boolean mMediaPlayPauseKeyPending; public Callback() { } @@ -566,12 +843,110 @@ public final class MediaSession { * @return True if the event was handled, false otherwise. */ public boolean onMediaButtonEvent(@NonNull Intent mediaButtonIntent) { - if (mMediaButtonEventDelegate != null) { - return mMediaButtonEventDelegate.onMediaButtonIntent(mediaButtonIntent); + if (mSession != null && mHandler != null + && Intent.ACTION_MEDIA_BUTTON.equals(mediaButtonIntent.getAction())) { + KeyEvent ke = mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); + if (ke != null && ke.getAction() == KeyEvent.ACTION_DOWN) { + PlaybackState state = mSession.mPlaybackState; + long validActions = state == null ? 0 : state.getActions(); + switch (ke.getKeyCode()) { + case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: + case KeyEvent.KEYCODE_HEADSETHOOK: + if (ke.getRepeatCount() > 0) { + // Consider long-press as a single tap. + handleMediaPlayPauseKeySingleTapIfPending(); + } else if (mMediaPlayPauseKeyPending) { + // Consider double tap as the next. + mHandler.removeMessages(CallbackMessageHandler + .MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT); + mMediaPlayPauseKeyPending = false; + if ((validActions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0) { + onSkipToNext(); + } + } else { + mMediaPlayPauseKeyPending = true; + mSession.dispatchMediaButtonDelayed( + mSession.getCurrentControllerInfo(), + mediaButtonIntent, ViewConfiguration.getDoubleTapTimeout()); + } + return true; + default: + // If another key is pressed within double tap timeout, consider the + // pending play/pause as a single tap to handle media keys in order. + handleMediaPlayPauseKeySingleTapIfPending(); + break; + } + + switch (ke.getKeyCode()) { + case KeyEvent.KEYCODE_MEDIA_PLAY: + if ((validActions & PlaybackState.ACTION_PLAY) != 0) { + onPlay(); + return true; + } + break; + case KeyEvent.KEYCODE_MEDIA_PAUSE: + if ((validActions & PlaybackState.ACTION_PAUSE) != 0) { + onPause(); + return true; + } + break; + case KeyEvent.KEYCODE_MEDIA_NEXT: + if ((validActions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0) { + onSkipToNext(); + return true; + } + break; + case KeyEvent.KEYCODE_MEDIA_PREVIOUS: + if ((validActions & PlaybackState.ACTION_SKIP_TO_PREVIOUS) != 0) { + onSkipToPrevious(); + return true; + } + break; + case KeyEvent.KEYCODE_MEDIA_STOP: + if ((validActions & PlaybackState.ACTION_STOP) != 0) { + onStop(); + return true; + } + break; + case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: + if ((validActions & PlaybackState.ACTION_FAST_FORWARD) != 0) { + onFastForward(); + return true; + } + break; + case KeyEvent.KEYCODE_MEDIA_REWIND: + if ((validActions & PlaybackState.ACTION_REWIND) != 0) { + onRewind(); + return true; + } + break; + } + } } return false; } + private void handleMediaPlayPauseKeySingleTapIfPending() { + if (!mMediaPlayPauseKeyPending) { + return; + } + mMediaPlayPauseKeyPending = false; + mHandler.removeMessages(CallbackMessageHandler.MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT); + PlaybackState state = mSession.mPlaybackState; + long validActions = state == null ? 0 : state.getActions(); + boolean isPlaying = state != null + && state.getState() == PlaybackState.STATE_PLAYING; + boolean canPlay = (validActions & (PlaybackState.ACTION_PLAY_PAUSE + | PlaybackState.ACTION_PLAY)) != 0; + boolean canPause = (validActions & (PlaybackState.ACTION_PLAY_PAUSE + | PlaybackState.ACTION_PAUSE)) != 0; + if (isPlaying && canPause) { + onPause(); + } else if (!isPlaying && canPlay) { + onPlay(); + } + } + /** * Override to handle requests to prepare playback. During the preparation, a session should * not hold audio focus in order to allow other sessions play seamlessly. The state of @@ -727,13 +1102,259 @@ public final class MediaSession { */ public void onCustomAction(@NonNull String action, @Nullable Bundle extras) { } + } + + /** + * @hide + */ + public static class CallbackStub extends ISessionCallback.Stub { + private WeakReference<MediaSession> mMediaSession; + + public CallbackStub(MediaSession session) { + mMediaSession = new WeakReference<>(session); + } - /** - * @hide - */ - public void onSetMediaButtonEventDelegate( - @NonNull MediaSessionEngine.MediaButtonEventDelegate delegate) { - mMediaButtonEventDelegate = delegate; + private static RemoteUserInfo createRemoteUserInfo(String packageName, int pid, int uid) { + return new RemoteUserInfo(packageName, pid, uid); + } + + @Override + public void onCommand(String packageName, int pid, int uid, + ControllerCallbackLink caller, String command, Bundle args, ResultReceiver cb) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchCommand(createRemoteUserInfo(packageName, pid, uid), + command, args, cb); + } + } + + @Override + public void onMediaButton(String packageName, int pid, int uid, Intent mediaButtonIntent, + int sequenceNumber, ResultReceiver cb) { + MediaSession session = mMediaSession.get(); + try { + if (session != null) { + session.dispatchMediaButton(createRemoteUserInfo(packageName, pid, uid), + mediaButtonIntent); + } + } finally { + if (cb != null) { + cb.send(sequenceNumber, null); + } + } + } + + @Override + public void onMediaButtonFromController(String packageName, int pid, int uid, + ControllerCallbackLink caller, Intent mediaButtonIntent) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchMediaButton(createRemoteUserInfo(packageName, pid, uid), + mediaButtonIntent); + } + } + + @Override + public void onPrepare(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchPrepare(createRemoteUserInfo(packageName, pid, uid)); + } + } + + @Override + public void onPrepareFromMediaId(String packageName, int pid, int uid, + ControllerCallbackLink caller, String mediaId, + Bundle extras) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchPrepareFromMediaId( + createRemoteUserInfo(packageName, pid, uid), mediaId, extras); + } + } + + @Override + public void onPrepareFromSearch(String packageName, int pid, int uid, + ControllerCallbackLink caller, String query, + Bundle extras) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchPrepareFromSearch( + createRemoteUserInfo(packageName, pid, uid), query, extras); + } + } + + @Override + public void onPrepareFromUri(String packageName, int pid, int uid, + ControllerCallbackLink caller, Uri uri, Bundle extras) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchPrepareFromUri(createRemoteUserInfo(packageName, pid, uid), + uri, extras); + } + } + + @Override + public void onPlay(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchPlay(createRemoteUserInfo(packageName, pid, uid)); + } + } + + @Override + public void onPlayFromMediaId(String packageName, int pid, int uid, + ControllerCallbackLink caller, String mediaId, + Bundle extras) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchPlayFromMediaId(createRemoteUserInfo(packageName, pid, uid), + mediaId, extras); + } + } + + @Override + public void onPlayFromSearch(String packageName, int pid, int uid, + ControllerCallbackLink caller, String query, + Bundle extras) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchPlayFromSearch(createRemoteUserInfo(packageName, pid, uid), + query, extras); + } + } + + @Override + public void onPlayFromUri(String packageName, int pid, int uid, + ControllerCallbackLink caller, Uri uri, Bundle extras) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchPlayFromUri(createRemoteUserInfo(packageName, pid, uid), + uri, extras); + } + } + + @Override + public void onSkipToTrack(String packageName, int pid, int uid, + ControllerCallbackLink caller, long id) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchSkipToItem(createRemoteUserInfo(packageName, pid, uid), id); + } + } + + @Override + public void onPause(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchPause(createRemoteUserInfo(packageName, pid, uid)); + } + } + + @Override + public void onStop(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchStop(createRemoteUserInfo(packageName, pid, uid)); + } + } + + @Override + public void onNext(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchNext(createRemoteUserInfo(packageName, pid, uid)); + } + } + + @Override + public void onPrevious(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchPrevious(createRemoteUserInfo(packageName, pid, uid)); + } + } + + @Override + public void onFastForward(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchFastForward(createRemoteUserInfo(packageName, pid, uid)); + } + } + + @Override + public void onRewind(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchRewind(createRemoteUserInfo(packageName, pid, uid)); + } + } + + @Override + public void onSeekTo(String packageName, int pid, int uid, + ControllerCallbackLink caller, long pos) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchSeekTo(createRemoteUserInfo(packageName, pid, uid), pos); + } + } + + @Override + public void onRate(String packageName, int pid, int uid, ControllerCallbackLink caller, + Rating rating) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchRate(createRemoteUserInfo(packageName, pid, uid), rating); + } + } + + @Override + public void onSetPlaybackSpeed(String packageName, int pid, int uid, + ControllerCallbackLink caller, float speed) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchSetPlaybackSpeed( + createRemoteUserInfo(packageName, pid, uid), speed); + } + } + + @Override + public void onCustomAction(String packageName, int pid, int uid, + ControllerCallbackLink caller, String action, Bundle args) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchCustomAction(createRemoteUserInfo(packageName, pid, uid), + action, args); + } + } + + @Override + public void onAdjustVolume(String packageName, int pid, int uid, + ControllerCallbackLink caller, int direction) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchAdjustVolume(createRemoteUserInfo(packageName, pid, uid), + direction); + } + } + + @Override + public void onSetVolumeTo(String packageName, int pid, int uid, + ControllerCallbackLink caller, int value) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchSetVolumeTo(createRemoteUserInfo(packageName, pid, uid), + value); + } } } @@ -747,7 +1368,7 @@ public final class MediaSession { */ public static final int UNKNOWN_ID = -1; - private final MediaSessionEngine.QueueItem mImpl; + private final MediaDescription mDescription; @UnsupportedAppUsage private final long mId; @@ -759,32 +1380,39 @@ public final class MediaSession { * play queue and cannot be {@link #UNKNOWN_ID}. */ public QueueItem(MediaDescription description, long id) { - mImpl = new MediaSessionEngine.QueueItem(description, id); + if (description == null) { + throw new IllegalArgumentException("Description cannot be null."); + } + if (id == UNKNOWN_ID) { + throw new IllegalArgumentException("Id cannot be QueueItem.UNKNOWN_ID"); + } + mDescription = description; mId = id; } private QueueItem(Parcel in) { - mImpl = new MediaSessionEngine.QueueItem(in); - mId = mImpl.getQueueId(); + mDescription = MediaDescription.CREATOR.createFromParcel(in); + mId = in.readLong(); } /** * Get the description for this item. */ public MediaDescription getDescription() { - return mImpl.getDescription(); + return mDescription; } /** * Get the queue id for this item. */ public long getQueueId() { - return mImpl.getQueueId(); + return mId; } @Override public void writeToParcel(Parcel dest, int flags) { - mImpl.writeToParcel(dest, flags); + mDescription.writeToParcel(dest, flags); + dest.writeLong(mId); } @Override @@ -795,20 +1423,21 @@ public final class MediaSession { public static final @android.annotation.NonNull Creator<MediaSession.QueueItem> CREATOR = new Creator<MediaSession.QueueItem>() { - @Override - public MediaSession.QueueItem createFromParcel(Parcel p) { - return new MediaSession.QueueItem(p); - } + @Override + public MediaSession.QueueItem createFromParcel(Parcel p) { + return new MediaSession.QueueItem(p); + } - @Override - public MediaSession.QueueItem[] newArray(int size) { - return new MediaSession.QueueItem[size]; - } - }; + @Override + public MediaSession.QueueItem[] newArray(int size) { + return new MediaSession.QueueItem[size]; + } + }; @Override public String toString() { - return mImpl.toString(); + return "MediaSession.QueueItem {" + "Description=" + mDescription + ", Id=" + mId + + " }"; } @Override @@ -821,7 +1450,171 @@ public final class MediaSession { return false; } - return mImpl.equals(((QueueItem) o).mImpl); + final QueueItem item = (QueueItem) o; + if (mId != item.mId) { + return false; + } + + if (!Objects.equals(mDescription, item.mDescription)) { + return false; + } + + return true; + } + } + + private static final class Command { + public final String command; + public final Bundle extras; + public final ResultReceiver stub; + + Command(String command, Bundle extras, ResultReceiver stub) { + this.command = command; + this.extras = extras; + this.stub = stub; + } + } + + private class CallbackMessageHandler extends Handler { + private static final int MSG_COMMAND = 1; + private static final int MSG_MEDIA_BUTTON = 2; + private static final int MSG_PREPARE = 3; + private static final int MSG_PREPARE_MEDIA_ID = 4; + private static final int MSG_PREPARE_SEARCH = 5; + private static final int MSG_PREPARE_URI = 6; + private static final int MSG_PLAY = 7; + private static final int MSG_PLAY_MEDIA_ID = 8; + private static final int MSG_PLAY_SEARCH = 9; + private static final int MSG_PLAY_URI = 10; + private static final int MSG_SKIP_TO_ITEM = 11; + private static final int MSG_PAUSE = 12; + private static final int MSG_STOP = 13; + private static final int MSG_NEXT = 14; + private static final int MSG_PREVIOUS = 15; + private static final int MSG_FAST_FORWARD = 16; + private static final int MSG_REWIND = 17; + private static final int MSG_SEEK_TO = 18; + private static final int MSG_RATE = 19; + private static final int MSG_SET_PLAYBACK_SPEED = 20; + private static final int MSG_CUSTOM_ACTION = 21; + private static final int MSG_ADJUST_VOLUME = 22; + private static final int MSG_SET_VOLUME = 23; + private static final int MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT = 24; + + private MediaSession.Callback mCallback; + private RemoteUserInfo mCurrentControllerInfo; + + CallbackMessageHandler(Looper looper, MediaSession.Callback callback) { + super(looper); + mCallback = callback; + mCallback.mHandler = this; + } + + void post(RemoteUserInfo caller, int what, Object obj, Bundle data, long delayMs) { + Pair<RemoteUserInfo, Object> objWithCaller = Pair.create(caller, obj); + Message msg = obtainMessage(what, objWithCaller); + msg.setAsynchronous(true); + msg.setData(data); + if (delayMs > 0) { + sendMessageDelayed(msg, delayMs); + } else { + sendMessage(msg); + } + } + + @Override + public void handleMessage(Message msg) { + mCurrentControllerInfo = ((Pair<RemoteUserInfo, Object>) msg.obj).first; + + VolumeProvider vp; + Object obj = ((Pair<RemoteUserInfo, Object>) msg.obj).second; + + switch (msg.what) { + case MSG_COMMAND: + Command cmd = (Command) obj; + mCallback.onCommand(cmd.command, cmd.extras, cmd.stub); + break; + case MSG_MEDIA_BUTTON: + mCallback.onMediaButtonEvent((Intent) obj); + break; + case MSG_PREPARE: + mCallback.onPrepare(); + break; + case MSG_PREPARE_MEDIA_ID: + mCallback.onPrepareFromMediaId((String) obj, msg.getData()); + break; + case MSG_PREPARE_SEARCH: + mCallback.onPrepareFromSearch((String) obj, msg.getData()); + break; + case MSG_PREPARE_URI: + mCallback.onPrepareFromUri((Uri) obj, msg.getData()); + break; + case MSG_PLAY: + mCallback.onPlay(); + break; + case MSG_PLAY_MEDIA_ID: + mCallback.onPlayFromMediaId((String) obj, msg.getData()); + break; + case MSG_PLAY_SEARCH: + mCallback.onPlayFromSearch((String) obj, msg.getData()); + break; + case MSG_PLAY_URI: + mCallback.onPlayFromUri((Uri) obj, msg.getData()); + break; + case MSG_SKIP_TO_ITEM: + mCallback.onSkipToQueueItem((Long) obj); + break; + case MSG_PAUSE: + mCallback.onPause(); + break; + case MSG_STOP: + mCallback.onStop(); + break; + case MSG_NEXT: + mCallback.onSkipToNext(); + break; + case MSG_PREVIOUS: + mCallback.onSkipToPrevious(); + break; + case MSG_FAST_FORWARD: + mCallback.onFastForward(); + break; + case MSG_REWIND: + mCallback.onRewind(); + break; + case MSG_SEEK_TO: + mCallback.onSeekTo((Long) obj); + break; + case MSG_RATE: + mCallback.onSetRating((Rating) obj); + break; + case MSG_SET_PLAYBACK_SPEED: + mCallback.onSetPlaybackSpeed((Float) obj); + break; + case MSG_CUSTOM_ACTION: + mCallback.onCustomAction((String) obj, msg.getData()); + break; + case MSG_ADJUST_VOLUME: + synchronized (mLock) { + vp = mVolumeProvider; + } + if (vp != null) { + vp.onAdjustVolume((int) obj); + } + break; + case MSG_SET_VOLUME: + synchronized (mLock) { + vp = mVolumeProvider; + } + if (vp != null) { + vp.onSetVolumeTo((int) obj); + } + break; + case MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT: + mCallback.handleMediaPlayPauseKeySingleTapIfPending(); + break; + } + mCurrentControllerInfo = null; } } } diff --git a/media/java/android/media/session/MediaSessionEngine.java b/media/java/android/media/session/MediaSessionEngine.java deleted file mode 100644 index 7c5243ac31cd..000000000000 --- a/media/java/android/media/session/MediaSessionEngine.java +++ /dev/null @@ -1,1236 +0,0 @@ -/* - * Copyright 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.media.session; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.app.Activity; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.media.AudioAttributes; -import android.media.MediaDescription; -import android.media.MediaMetadata; -import android.media.MediaParceledListSlice; -import android.media.Rating; -import android.media.VolumeProvider; -import android.media.session.MediaSessionManager.RemoteUserInfo; -import android.net.Uri; -import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.os.Parcel; -import android.os.RemoteException; -import android.os.ResultReceiver; -import android.service.media.MediaBrowserService; -import android.text.TextUtils; -import android.util.Log; -import android.util.Pair; -import android.view.KeyEvent; -import android.view.ViewConfiguration; - -import java.util.List; -import java.util.Objects; - -/** - * @hide - */ -public final class MediaSessionEngine implements AutoCloseable { - private static final String TAG = "MediaSession"; - - private final Object mLock = new Object(); - - private final MediaSession.Token mSessionToken; - private final MediaController mController; - private final ISession mBinder; - - private CallbackMessageHandler mCallbackHandler; - private VolumeProvider mVolumeProvider; - private PlaybackState mPlaybackState; - - private boolean mActive = false; - - /** - * Creates a new session. The session will automatically be registered with - * the system but will not be published until {@link #setActive(boolean) - * setActive(true)} is called. You must call {@link #close()} when - * finished with the session. - * - * @param context The context to use to create the session. - * @param binder A session binder - */ - public MediaSessionEngine(@NonNull Context context, @NonNull ISession binder, - @NonNull SessionCallbackLink cbLink) throws RemoteException { - mBinder = binder; - - cbLink.setSessionEngine(this); - mSessionToken = new MediaSession.Token(mBinder.getController()); - mController = new MediaController(context, mSessionToken); - } - - /** - * Set the callback to receive updates for the MediaSession. This includes - * media button events and transport controls. The caller's thread will be - * used to post updates. - * <p> - * Set the callback to null to stop receiving updates. - * - * @param callback The callback object - */ - public void setCallback(@Nullable MediaSession.Callback callback) { - setCallback(callback, new Handler()); - } - - /** - * Set the callback to receive updates for the MediaSession. This includes - * media button events and transport controls. - * <p> - * Set the callback to null to stop receiving updates. - * - * @param callback The callback to receive updates on. - * @param handler The handler that events should be posted on. - */ - public void setCallback(@Nullable MediaSession.Callback callback, @NonNull Handler handler) { - setCallbackInternal(callback == null ? null : new CallbackWrapper(callback), handler); - } - - private void setCallbackInternal(CallbackWrapper callback, Handler handler) { - synchronized (mLock) { - if (mCallbackHandler != null) { - // We're updating the callback, clear the session from the old one. - mCallbackHandler.mCallbackWrapper.mSessionImpl = null; - mCallbackHandler.removeCallbacksAndMessages(null); - } - if (callback == null) { - mCallbackHandler = null; - return; - } - callback.mSessionImpl = this; - CallbackMessageHandler msgHandler = new CallbackMessageHandler(handler.getLooper(), - callback); - mCallbackHandler = msgHandler; - } - } - - /** - * Set an intent for launching UI for this Session. This can be used as a - * quick link to an ongoing media screen. The intent should be for an - * activity that may be started using {@link Activity#startActivity(Intent)}. - * - * @param pi The intent to launch to show UI for this Session. - */ - public void setSessionActivity(@Nullable PendingIntent pi) { - try { - mBinder.setLaunchPendingIntent(pi); - } catch (RemoteException e) { - Log.wtf(TAG, "Failure in setLaunchPendingIntent.", e); - } - } - - /** - * Set a pending intent for your media button receiver to allow restarting - * playback after the session has been stopped. If your app is started in - * this way an {@link Intent#ACTION_MEDIA_BUTTON} intent will be sent via - * the pending intent. - * - * @param mbr The {@link PendingIntent} to send the media button event to. - */ - public void setMediaButtonReceiver(@Nullable PendingIntent mbr) { - try { - mBinder.setMediaButtonReceiver(mbr); - } catch (RemoteException e) { - Log.wtf(TAG, "Failure in setMediaButtonReceiver.", e); - } - } - - /** - * Set any flags for the session. - * - * @param flags The flags to set for this session. - */ - public void setFlags(int flags) { - try { - mBinder.setFlags(flags); - } catch (RemoteException e) { - Log.wtf(TAG, "Failure in setFlags.", e); - } - } - - /** - * Set the attributes for this session's audio. This will affect the - * system's volume handling for this session. If - * {@link #setPlaybackToRemote} was previously called it will stop receiving - * volume commands and the system will begin sending volume changes to the - * appropriate stream. - * <p> - * By default sessions use attributes for media. - * - * @param attributes The {@link AudioAttributes} for this session's audio. - */ - public void setPlaybackToLocal(AudioAttributes attributes) { - if (attributes == null) { - throw new IllegalArgumentException("Attributes cannot be null for local playback."); - } - try { - mBinder.setPlaybackToLocal(attributes); - } catch (RemoteException e) { - Log.wtf(TAG, "Failure in setPlaybackToLocal.", e); - } - } - - /** - * Configure this session to use remote volume handling. This must be called - * to receive volume button events, otherwise the system will adjust the - * appropriate stream volume for this session. If - * {@link #setPlaybackToLocal} was previously called the system will stop - * handling volume changes for this session and pass them to the volume - * provider instead. - * - * @param volumeProvider The provider that will handle volume changes. May - * not be null. - */ - public void setPlaybackToRemote(@NonNull VolumeProvider volumeProvider) { - if (volumeProvider == null) { - throw new IllegalArgumentException("volumeProvider may not be null!"); - } - synchronized (mLock) { - mVolumeProvider = volumeProvider; - } - volumeProvider.setCallback(new VolumeProvider.Callback() { - @Override - public void onVolumeChanged(VolumeProvider volumeProvider) { - notifyRemoteVolumeChanged(volumeProvider); - } - }); - - try { - mBinder.setPlaybackToRemote(volumeProvider.getVolumeControl(), - volumeProvider.getMaxVolume()); - mBinder.setCurrentVolume(volumeProvider.getCurrentVolume()); - } catch (RemoteException e) { - Log.wtf(TAG, "Failure in setPlaybackToRemote.", e); - } - } - - /** - * Set if this session is currently active and ready to receive commands. If - * set to false your session's controller may not be discoverable. You must - * set the session to active before it can start receiving media button - * events or transport commands. - * - * @param active Whether this session is active or not. - */ - public void setActive(boolean active) { - if (mActive == active) { - return; - } - try { - mBinder.setActive(active); - mActive = active; - } catch (RemoteException e) { - Log.wtf(TAG, "Failure in setActive.", e); - } - } - - /** - * Get the current active state of this session. - * - * @return True if the session is active, false otherwise. - */ - public boolean isActive() { - return mActive; - } - - /** - * Send a proprietary event to all MediaControllers listening to this - * Session. It's up to the Controller/Session owner to determine the meaning - * of any events. - * - * @param event The name of the event to send - * @param extras Any extras included with the event - */ - public void sendSessionEvent(@NonNull String event, @Nullable Bundle extras) { - if (TextUtils.isEmpty(event)) { - throw new IllegalArgumentException("event cannot be null or empty"); - } - try { - mBinder.sendEvent(event, extras); - } catch (RemoteException e) { - Log.wtf(TAG, "Error sending event", e); - } - } - - /** - * This must be called when an app has finished performing playback. If - * playback is expected to start again shortly the session can be left open, - * but it must be released if your activity or service is being destroyed. - */ - public void close() { - try { - mBinder.destroySession(); - } catch (RemoteException e) { - Log.wtf(TAG, "Error releasing session: ", e); - } - } - - /** - * Retrieve a token object that can be used by apps to create a - * {@link MediaController} for interacting with this session. The owner of - * the session is responsible for deciding how to distribute these tokens. - * - * @return A token that can be used to create a MediaController for this - * session - */ - public @NonNull MediaSession.Token getSessionToken() { - return mSessionToken; - } - - /** - * Get a controller for this session. This is a convenience method to avoid - * having to cache your own controller in process. - * - * @return A controller for this session. - */ - public @NonNull MediaController getController() { - return mController; - } - - /** - * Update the current playback state. - * - * @param state The current state of playback - */ - public void setPlaybackState(@Nullable PlaybackState state) { - mPlaybackState = state; - try { - mBinder.setPlaybackState(state); - } catch (RemoteException e) { - Log.wtf(TAG, "Dead object in setPlaybackState.", e); - } - } - - /** - * Update the current metadata. New metadata can be created using - * {@link android.media.MediaMetadata.Builder}. This operation may take time proportional to - * the size of the bitmap to replace large bitmaps with a scaled down copy. - * - * @param metadata The new metadata - * @see android.media.MediaMetadata.Builder#putBitmap - */ - public void setMetadata(@Nullable MediaMetadata metadata) { - long duration = -1; - int fields = 0; - MediaDescription description = null; - if (metadata != null) { - if (metadata.containsKey(MediaMetadata.METADATA_KEY_DURATION)) { - duration = metadata.getLong(MediaMetadata.METADATA_KEY_DURATION); - } - fields = metadata.size(); - description = metadata.getDescription(); - } - String metadataDescription = "size=" + fields + ", description=" + description; - - try { - mBinder.setMetadata(metadata, duration, metadataDescription); - } catch (RemoteException e) { - Log.wtf(TAG, "Dead object in setPlaybackState.", e); - } - } - - /** - * Update the list of items in the play queue. It is an ordered list and - * should contain the current item, and previous or upcoming items if they - * exist. Specify null if there is no current play queue. - * <p> - * The queue should be of reasonable size. If the play queue is unbounded - * within your app, it is better to send a reasonable amount in a sliding - * window instead. - * - * @param queue A list of items in the play queue. - */ - public void setQueue(@Nullable List<MediaSession.QueueItem> queue) { - try { - mBinder.setQueue(queue == null ? null : new MediaParceledListSlice(queue)); - } catch (RemoteException e) { - Log.wtf("Dead object in setQueue.", e); - } - } - - /** - * Set the title of the play queue. The UI should display this title along - * with the play queue itself. - * e.g. "Play Queue", "Now Playing", or an album name. - * - * @param title The title of the play queue. - */ - public void setQueueTitle(@Nullable CharSequence title) { - try { - mBinder.setQueueTitle(title); - } catch (RemoteException e) { - Log.wtf("Dead object in setQueueTitle.", e); - } - } - - /** - * Set the style of rating used by this session. Apps trying to set the - * rating should use this style. Must be one of the following: - * <ul> - * <li>{@link Rating#RATING_NONE}</li> - * <li>{@link Rating#RATING_3_STARS}</li> - * <li>{@link Rating#RATING_4_STARS}</li> - * <li>{@link Rating#RATING_5_STARS}</li> - * <li>{@link Rating#RATING_HEART}</li> - * <li>{@link Rating#RATING_PERCENTAGE}</li> - * <li>{@link Rating#RATING_THUMB_UP_DOWN}</li> - * </ul> - */ - public void setRatingType(int type) { - try { - mBinder.setRatingType(type); - } catch (RemoteException e) { - Log.e(TAG, "Error in setRatingType.", e); - } - } - - /** - * Set some extras that can be associated with the {@link MediaSession}. No assumptions should - * be made as to how a {@link MediaController} will handle these extras. - * Keys should be fully qualified (e.g. com.example.MY_EXTRA) to avoid conflicts. - * - * @param extras The extras associated with the {@link MediaSession}. - */ - public void setExtras(@Nullable Bundle extras) { - try { - mBinder.setExtras(extras); - } catch (RemoteException e) { - Log.wtf("Dead object in setExtras.", e); - } - } - - /** - * Gets the controller information who sent the current request. - * <p> - * Note: This is only valid while in a request callback, such as - * {@link MediaSession.Callback#onPlay}. - * - * @throws IllegalStateException If this method is called outside of - * {@link MediaSession.Callback} methods. - * @see MediaSessionManager#isTrustedForMediaControl(RemoteUserInfo) - */ - public @NonNull RemoteUserInfo getCurrentControllerInfo() { - if (mCallbackHandler == null || mCallbackHandler.mCurrentControllerInfo == null) { - throw new IllegalStateException( - "This should be called inside of MediaSession.Callback methods"); - } - return mCallbackHandler.mCurrentControllerInfo; - } - - /** - * Returns the name of the package that sent the last media button, transport control, or - * command from controllers and the system. This is only valid while in a request callback, such - * as {@link MediaSession.Callback#onPlay}. - */ - public String getCallingPackage() { - if (mCallbackHandler != null && mCallbackHandler.mCurrentControllerInfo != null) { - return mCallbackHandler.mCurrentControllerInfo.getPackageName(); - } - return null; - } - - - /** - * Notify the system that the remote volume changed. - * - * @param provider The provider that is handling volume changes. - */ - private void notifyRemoteVolumeChanged(VolumeProvider provider) { - synchronized (mLock) { - if (provider == null || provider != mVolumeProvider) { - Log.w(TAG, "Received update from stale volume provider"); - return; - } - } - try { - mBinder.setCurrentVolume(provider.getCurrentVolume()); - } catch (RemoteException e) { - Log.e(TAG, "Error in notifyVolumeChanged", e); - } - } - - void dispatchPrepare(RemoteUserInfo caller) { - postToCallback(caller, CallbackMessageHandler.MSG_PREPARE, null, null); - } - - void dispatchPrepareFromMediaId(RemoteUserInfo caller, String mediaId, Bundle extras) { - postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_MEDIA_ID, mediaId, extras); - } - - void dispatchPrepareFromSearch(RemoteUserInfo caller, String query, Bundle extras) { - postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_SEARCH, query, extras); - } - - void dispatchPrepareFromUri(RemoteUserInfo caller, Uri uri, Bundle extras) { - postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_URI, uri, extras); - } - - void dispatchPlay(RemoteUserInfo caller) { - postToCallback(caller, CallbackMessageHandler.MSG_PLAY, null, null); - } - - void dispatchPlayFromMediaId(RemoteUserInfo caller, String mediaId, Bundle extras) { - postToCallback(caller, CallbackMessageHandler.MSG_PLAY_MEDIA_ID, mediaId, extras); - } - - void dispatchPlayFromSearch(RemoteUserInfo caller, String query, Bundle extras) { - postToCallback(caller, CallbackMessageHandler.MSG_PLAY_SEARCH, query, extras); - } - - void dispatchPlayFromUri(RemoteUserInfo caller, Uri uri, Bundle extras) { - postToCallback(caller, CallbackMessageHandler.MSG_PLAY_URI, uri, extras); - } - - void dispatchSkipToItem(RemoteUserInfo caller, long id) { - postToCallback(caller, CallbackMessageHandler.MSG_SKIP_TO_ITEM, id, null); - } - - void dispatchPause(RemoteUserInfo caller) { - postToCallback(caller, CallbackMessageHandler.MSG_PAUSE, null, null); - } - - void dispatchStop(RemoteUserInfo caller) { - postToCallback(caller, CallbackMessageHandler.MSG_STOP, null, null); - } - - void dispatchNext(RemoteUserInfo caller) { - postToCallback(caller, CallbackMessageHandler.MSG_NEXT, null, null); - } - - void dispatchPrevious(RemoteUserInfo caller) { - postToCallback(caller, CallbackMessageHandler.MSG_PREVIOUS, null, null); - } - - void dispatchFastForward(RemoteUserInfo caller) { - postToCallback(caller, CallbackMessageHandler.MSG_FAST_FORWARD, null, null); - } - - void dispatchRewind(RemoteUserInfo caller) { - postToCallback(caller, CallbackMessageHandler.MSG_REWIND, null, null); - } - - void dispatchSeekTo(RemoteUserInfo caller, long pos) { - postToCallback(caller, CallbackMessageHandler.MSG_SEEK_TO, pos, null); - } - - void dispatchRate(RemoteUserInfo caller, Rating rating) { - postToCallback(caller, CallbackMessageHandler.MSG_RATE, rating, null); - } - - void dispatchSetPlaybackSpeed(RemoteUserInfo caller, float speed) { - postToCallback(caller, CallbackMessageHandler.MSG_SET_PLAYBACK_SPEED, speed, null); - } - - void dispatchCustomAction(RemoteUserInfo caller, String action, Bundle args) { - postToCallback(caller, CallbackMessageHandler.MSG_CUSTOM_ACTION, action, args); - } - - void dispatchMediaButton(RemoteUserInfo caller, Intent mediaButtonIntent) { - postToCallback(caller, CallbackMessageHandler.MSG_MEDIA_BUTTON, mediaButtonIntent, null); - } - - void dispatchMediaButtonDelayed(RemoteUserInfo info, Intent mediaButtonIntent, - long delay) { - postToCallbackDelayed(info, CallbackMessageHandler.MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT, - mediaButtonIntent, null, delay); - } - - void dispatchAdjustVolume(RemoteUserInfo caller, int direction) { - postToCallback(caller, CallbackMessageHandler.MSG_ADJUST_VOLUME, direction, null); - } - - void dispatchSetVolumeTo(RemoteUserInfo caller, int volume) { - postToCallback(caller, CallbackMessageHandler.MSG_SET_VOLUME, volume, null); - } - - void dispatchCommand(RemoteUserInfo caller, String command, Bundle args, - ResultReceiver resultCb) { - Command cmd = new Command(command, args, resultCb); - postToCallback(caller, CallbackMessageHandler.MSG_COMMAND, cmd, null); - } - - private void postToCallback(RemoteUserInfo caller, int what, Object obj, Bundle data) { - postToCallbackDelayed(caller, what, obj, data, 0); - } - - private void postToCallbackDelayed(RemoteUserInfo caller, int what, Object obj, Bundle data, - long delay) { - synchronized (mLock) { - if (mCallbackHandler != null) { - mCallbackHandler.post(caller, what, obj, data, delay); - } - } - } - - /** - * Return true if this is considered an active playback state. - */ - public static boolean isActiveState(int state) { - switch (state) { - case PlaybackState.STATE_FAST_FORWARDING: - case PlaybackState.STATE_REWINDING: - case PlaybackState.STATE_SKIPPING_TO_PREVIOUS: - case PlaybackState.STATE_SKIPPING_TO_NEXT: - case PlaybackState.STATE_BUFFERING: - case PlaybackState.STATE_CONNECTING: - case PlaybackState.STATE_PLAYING: - return true; - } - return false; - } - - /** - * Interface for handling MediaButtoneEvent - */ - public interface MediaButtonEventDelegate { - /** - * Called when a media button is pressed and this session has the - * highest priority or a controller sends a media button event to the - * session. - * - * @param mediaButtonIntent an intent containing the KeyEvent as an extra - * @return True if the event was handled, false otherwise. - */ - boolean onMediaButtonIntent(Intent mediaButtonIntent); - } - - /** - * Receives media buttons, transport controls, and commands from controllers - * and the system. A callback may be set using {@link #setCallback}. - * @hide - */ - public static class CallbackWrapper implements MediaButtonEventDelegate { - - private final MediaSession.Callback mCallback; - - @SuppressWarnings("WeakerAccess") /* synthetic access */ - MediaSessionEngine mSessionImpl; - @SuppressWarnings("WeakerAccess") /* synthetic access */ - CallbackMessageHandler mHandler; - private boolean mMediaPlayPauseKeyPending; - - public CallbackWrapper(MediaSession.Callback callback) { - mCallback = callback; - if (mCallback != null) { - mCallback.onSetMediaButtonEventDelegate(this); - } - } - - /** - * Called when a controller has sent a command to this session. - * The owner of the session may handle custom commands but is not - * required to. - * - * @param command The command name. - * @param args Optional parameters for the command, may be null. - * @param cb A result receiver to which a result may be sent by the command, may be null. - */ - public void onCommand(@NonNull String command, @Nullable Bundle args, - @Nullable ResultReceiver cb) { - if (mCallback != null) { - mCallback.onCommand(command, args, cb); - } - } - - /** - * Called when a media button is pressed and this session has the - * highest priority or a controller sends a media button event to the - * session. The default behavior will call the relevant method if the - * action for it was set. - * <p> - * The intent will be of type {@link Intent#ACTION_MEDIA_BUTTON} with a - * KeyEvent in {@link Intent#EXTRA_KEY_EVENT} - * - * @param mediaButtonIntent an intent containing the KeyEvent as an - * extra - * @return True if the event was handled, false otherwise. - */ - public boolean onMediaButtonEvent(@NonNull Intent mediaButtonIntent) { - return mCallback == null ? false : mCallback.onMediaButtonEvent(mediaButtonIntent); - } - - private void handleMediaPlayPauseKeySingleTapIfPending() { - if (!mMediaPlayPauseKeyPending) { - return; - } - mMediaPlayPauseKeyPending = false; - mHandler.removeMessages(CallbackMessageHandler.MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT); - PlaybackState state = mSessionImpl.mPlaybackState; - long validActions = state == null ? 0 : state.getActions(); - boolean isPlaying = state != null - && state.getState() == PlaybackState.STATE_PLAYING; - boolean canPlay = (validActions & (PlaybackState.ACTION_PLAY_PAUSE - | PlaybackState.ACTION_PLAY)) != 0; - boolean canPause = (validActions & (PlaybackState.ACTION_PLAY_PAUSE - | PlaybackState.ACTION_PAUSE)) != 0; - if (isPlaying && canPause) { - onPause(); - } else if (!isPlaying && canPlay) { - onPlay(); - } - } - - /** - * Override to handle requests to prepare playback. During the preparation, a session should - * not hold audio focus in order to allow other sessions play seamlessly. The state of - * playback should be updated to {@link PlaybackState#STATE_PAUSED} after the preparation is - * done. - */ - public void onPrepare() { - if (mCallback != null) { - mCallback.onPrepare(); - } - } - - /** - * Override to handle requests to prepare for playing a specific mediaId that was provided - * by your app's {@link MediaBrowserService}. During the preparation, a session should not - * hold audio focus in order to allow other sessions play seamlessly. The state of playback - * should be updated to {@link PlaybackState#STATE_PAUSED} after the preparation is done. - * The playback of the prepared content should start in the implementation of - * {@link #onPlay}. Override {@link #onPlayFromMediaId} to handle requests for starting - * playback without preparation. - */ - public void onPrepareFromMediaId(String mediaId, Bundle extras) { - if (mCallback != null) { - mCallback.onPrepareFromMediaId(mediaId, extras); - } - } - - /** - * Override to handle requests to prepare playback from a search query. An empty query - * indicates that the app may prepare any music. The implementation should attempt to make a - * smart choice about what to play. During the preparation, a session should not hold audio - * focus in order to allow other sessions play seamlessly. The state of playback should be - * updated to {@link PlaybackState#STATE_PAUSED} after the preparation is done. The playback - * of the prepared content should start in the implementation of {@link #onPlay}. Override - * {@link #onPlayFromSearch} to handle requests for starting playback without preparation. - */ - public void onPrepareFromSearch(String query, Bundle extras) { - if (mCallback != null) { - mCallback.onPrepareFromSearch(query, extras); - } - } - - /** - * Override to handle requests to prepare a specific media item represented by a URI. - * During the preparation, a session should not hold audio focus in order to allow - * other sessions play seamlessly. The state of playback should be updated to - * {@link PlaybackState#STATE_PAUSED} after the preparation is done. - * The playback of the prepared content should start in the implementation of - * {@link #onPlay}. Override {@link #onPlayFromUri} to handle requests - * for starting playback without preparation. - */ - public void onPrepareFromUri(Uri uri, Bundle extras) { - if (mCallback != null) { - mCallback.onPrepareFromUri(uri, extras); - } - } - - /** - * Override to handle requests to begin playback. - */ - public void onPlay() { - if (mCallback != null) { - mCallback.onPlay(); - } - } - - /** - * Override to handle requests to begin playback from a search query. An - * empty query indicates that the app may play any music. The - * implementation should attempt to make a smart choice about what to - * play. - */ - public void onPlayFromSearch(String query, Bundle extras) { - if (mCallback != null) { - mCallback.onPlayFromSearch(query, extras); - } - } - - /** - * Override to handle requests to play a specific mediaId that was - * provided by your app's {@link MediaBrowserService}. - */ - public void onPlayFromMediaId(String mediaId, Bundle extras) { - if (mCallback != null) { - mCallback.onPlayFromMediaId(mediaId, extras); - } - } - - /** - * Override to handle requests to play a specific media item represented by a URI. - */ - public void onPlayFromUri(Uri uri, Bundle extras) { - if (mCallback != null) { - mCallback.onPlayFromUri(uri, extras); - } - } - - /** - * Override to handle requests to play an item with a given id from the - * play queue. - */ - public void onSkipToQueueItem(long id) { - if (mCallback != null) { - mCallback.onSkipToQueueItem(id); - } - } - - /** - * Override to handle requests to pause playback. - */ - public void onPause() { - if (mCallback != null) { - mCallback.onPause(); - } - } - - /** - * Override to handle requests to skip to the next media item. - */ - public void onSkipToNext() { - if (mCallback != null) { - mCallback.onSkipToNext(); - } - } - - /** - * Override to handle requests to skip to the previous media item. - */ - public void onSkipToPrevious() { - if (mCallback != null) { - mCallback.onSkipToPrevious(); - } - } - - /** - * Override to handle requests to fast forward. - */ - public void onFastForward() { - if (mCallback != null) { - mCallback.onFastForward(); - } - } - - /** - * Override to handle requests to rewind. - */ - public void onRewind() { - if (mCallback != null) { - mCallback.onRewind(); - } - } - - /** - * Override to handle requests to stop playback. - */ - public void onStop() { - if (mCallback != null) { - mCallback.onStop(); - } - } - - /** - * Override to handle requests to seek to a specific position in ms. - * - * @param pos New position to move to, in milliseconds. - */ - public void onSeekTo(long pos) { - if (mCallback != null) { - mCallback.onSeekTo(pos); - } - } - - /** - * Override to handle the item being rated. - * - * @param rating - */ - public void onSetRating(@NonNull Rating rating) { - if (mCallback != null) { - mCallback.onSetRating(rating); - } - } - - /** - * Override to handle the playback speed change. - * - * @param speed the playback speed - */ - public void onSetPlaybackSpeed(float speed) { - if (mCallback != null) { - mCallback.onSetPlaybackSpeed(speed); - } - } - - /** - * Called when a {@link MediaController} wants a {@link PlaybackState.CustomAction} to be - * performed. - * - * @param action The action that was originally sent in the - * {@link PlaybackState.CustomAction}. - * @param extras Optional extras specified by the {@link MediaController}. - */ - public void onCustomAction(@NonNull String action, @Nullable Bundle extras) { - if (mCallback != null) { - mCallback.onCustomAction(action, extras); - } - } - - @Override - public boolean onMediaButtonIntent(Intent mediaButtonIntent) { - if (mSessionImpl != null && mHandler != null - && Intent.ACTION_MEDIA_BUTTON.equals(mediaButtonIntent.getAction())) { - KeyEvent ke = mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); - if (ke != null && ke.getAction() == KeyEvent.ACTION_DOWN) { - PlaybackState state = mSessionImpl.mPlaybackState; - long validActions = state == null ? 0 : state.getActions(); - switch (ke.getKeyCode()) { - case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: - case KeyEvent.KEYCODE_HEADSETHOOK: - if (ke.getRepeatCount() > 0) { - // Consider long-press as a single tap. - handleMediaPlayPauseKeySingleTapIfPending(); - } else if (mMediaPlayPauseKeyPending) { - // Consider double tap as the next. - mHandler.removeMessages(CallbackMessageHandler - .MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT); - mMediaPlayPauseKeyPending = false; - if ((validActions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0) { - onSkipToNext(); - } - } else { - mMediaPlayPauseKeyPending = true; - mSessionImpl.dispatchMediaButtonDelayed( - mSessionImpl.getCurrentControllerInfo(), - mediaButtonIntent, ViewConfiguration.getDoubleTapTimeout()); - } - return true; - default: - // If another key is pressed within double tap timeout, consider the - // pending play/pause as a single tap to handle media keys in order. - handleMediaPlayPauseKeySingleTapIfPending(); - break; - } - - switch (ke.getKeyCode()) { - case KeyEvent.KEYCODE_MEDIA_PLAY: - if ((validActions & PlaybackState.ACTION_PLAY) != 0) { - onPlay(); - return true; - } - break; - case KeyEvent.KEYCODE_MEDIA_PAUSE: - if ((validActions & PlaybackState.ACTION_PAUSE) != 0) { - onPause(); - return true; - } - break; - case KeyEvent.KEYCODE_MEDIA_NEXT: - if ((validActions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0) { - onSkipToNext(); - return true; - } - break; - case KeyEvent.KEYCODE_MEDIA_PREVIOUS: - if ((validActions & PlaybackState.ACTION_SKIP_TO_PREVIOUS) != 0) { - onSkipToPrevious(); - return true; - } - break; - case KeyEvent.KEYCODE_MEDIA_STOP: - if ((validActions & PlaybackState.ACTION_STOP) != 0) { - onStop(); - return true; - } - break; - case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: - if ((validActions & PlaybackState.ACTION_FAST_FORWARD) != 0) { - onFastForward(); - return true; - } - break; - case KeyEvent.KEYCODE_MEDIA_REWIND: - if ((validActions & PlaybackState.ACTION_REWIND) != 0) { - onRewind(); - return true; - } - break; - } - } - } - return false; - } - } - - /** - * A single item that is part of the play queue. It contains a description - * of the item and its id in the queue. - */ - public static final class QueueItem { - /** - * This id is reserved. No items can be explicitly assigned this id. - */ - public static final int UNKNOWN_ID = -1; - - private final MediaDescription mDescription; - private final long mId; - - /** - * Create a new {@link MediaSession.QueueItem}. - * - * @param description The {@link MediaDescription} for this item. - * @param id An identifier for this item. It must be unique within the - * play queue and cannot be {@link #UNKNOWN_ID}. - */ - public QueueItem(MediaDescription description, long id) { - if (description == null) { - throw new IllegalArgumentException("Description cannot be null."); - } - if (id == UNKNOWN_ID) { - throw new IllegalArgumentException("Id cannot be QueueItem.UNKNOWN_ID"); - } - mDescription = description; - mId = id; - } - - public QueueItem(Parcel in) { - mDescription = MediaDescription.CREATOR.createFromParcel(in); - mId = in.readLong(); - } - - /** - * Get the description for this item. - */ - public MediaDescription getDescription() { - return mDescription; - } - - /** - * Get the queue id for this item. - */ - public long getQueueId() { - return mId; - } - - /** - * Flatten this object in to a Parcel. - * - * @param dest The Parcel in which the object should be written. - * @param flags Additional flags about how the object should be written. - */ - public void writeToParcel(Parcel dest, int flags) { - mDescription.writeToParcel(dest, flags); - dest.writeLong(mId); - } - - @Override - public String toString() { - return "MediaSession.QueueItem {" + "Description=" + mDescription + ", Id=" + mId - + " }"; - } - - @Override - public boolean equals(Object o) { - if (o == null) { - return false; - } - - if (!(o instanceof QueueItem)) { - return false; - } - - final QueueItem item = (QueueItem) o; - if (mId != item.mId) { - return false; - } - - if (!Objects.equals(mDescription, item.mDescription)) { - return false; - } - - return true; - } - } - - private static final class Command { - public final String command; - public final Bundle extras; - public final ResultReceiver stub; - - Command(String command, Bundle extras, ResultReceiver stub) { - this.command = command; - this.extras = extras; - this.stub = stub; - } - } - - private class CallbackMessageHandler extends Handler { - private static final int MSG_COMMAND = 1; - private static final int MSG_MEDIA_BUTTON = 2; - private static final int MSG_PREPARE = 3; - private static final int MSG_PREPARE_MEDIA_ID = 4; - private static final int MSG_PREPARE_SEARCH = 5; - private static final int MSG_PREPARE_URI = 6; - private static final int MSG_PLAY = 7; - private static final int MSG_PLAY_MEDIA_ID = 8; - private static final int MSG_PLAY_SEARCH = 9; - private static final int MSG_PLAY_URI = 10; - private static final int MSG_SKIP_TO_ITEM = 11; - private static final int MSG_PAUSE = 12; - private static final int MSG_STOP = 13; - private static final int MSG_NEXT = 14; - private static final int MSG_PREVIOUS = 15; - private static final int MSG_FAST_FORWARD = 16; - private static final int MSG_REWIND = 17; - private static final int MSG_SEEK_TO = 18; - private static final int MSG_RATE = 19; - private static final int MSG_SET_PLAYBACK_SPEED = 20; - private static final int MSG_CUSTOM_ACTION = 21; - private static final int MSG_ADJUST_VOLUME = 22; - private static final int MSG_SET_VOLUME = 23; - private static final int MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT = 24; - - @SuppressWarnings("WeakerAccess") /* synthetic access */ - CallbackWrapper mCallbackWrapper; - @SuppressWarnings("WeakerAccess") /* synthetic access */ - RemoteUserInfo mCurrentControllerInfo; - - CallbackMessageHandler(Looper looper, CallbackWrapper callbackWrapper) { - super(looper); - mCallbackWrapper = callbackWrapper; - mCallbackWrapper.mHandler = this; - } - - void post(RemoteUserInfo caller, int what, Object obj, Bundle data, long delayMs) { - Pair<RemoteUserInfo, Object> objWithCaller = Pair.create(caller, obj); - Message msg = obtainMessage(what, objWithCaller); - msg.setAsynchronous(true); - msg.setData(data); - if (delayMs > 0) { - sendMessageDelayed(msg, delayMs); - } else { - sendMessage(msg); - } - } - - @Override - public void handleMessage(Message msg) { - mCurrentControllerInfo = ((Pair<RemoteUserInfo, Object>) msg.obj).first; - - VolumeProvider vp; - Object obj = ((Pair<RemoteUserInfo, Object>) msg.obj).second; - - switch (msg.what) { - case MSG_COMMAND: - Command cmd = (Command) obj; - mCallbackWrapper.onCommand(cmd.command, cmd.extras, cmd.stub); - break; - case MSG_MEDIA_BUTTON: - mCallbackWrapper.onMediaButtonEvent((Intent) obj); - break; - case MSG_PREPARE: - mCallbackWrapper.onPrepare(); - break; - case MSG_PREPARE_MEDIA_ID: - mCallbackWrapper.onPrepareFromMediaId((String) obj, msg.getData()); - break; - case MSG_PREPARE_SEARCH: - mCallbackWrapper.onPrepareFromSearch((String) obj, msg.getData()); - break; - case MSG_PREPARE_URI: - mCallbackWrapper.onPrepareFromUri((Uri) obj, msg.getData()); - break; - case MSG_PLAY: - mCallbackWrapper.onPlay(); - break; - case MSG_PLAY_MEDIA_ID: - mCallbackWrapper.onPlayFromMediaId((String) obj, msg.getData()); - break; - case MSG_PLAY_SEARCH: - mCallbackWrapper.onPlayFromSearch((String) obj, msg.getData()); - break; - case MSG_PLAY_URI: - mCallbackWrapper.onPlayFromUri((Uri) obj, msg.getData()); - break; - case MSG_SKIP_TO_ITEM: - mCallbackWrapper.onSkipToQueueItem((Long) obj); - break; - case MSG_PAUSE: - mCallbackWrapper.onPause(); - break; - case MSG_STOP: - mCallbackWrapper.onStop(); - break; - case MSG_NEXT: - mCallbackWrapper.onSkipToNext(); - break; - case MSG_PREVIOUS: - mCallbackWrapper.onSkipToPrevious(); - break; - case MSG_FAST_FORWARD: - mCallbackWrapper.onFastForward(); - break; - case MSG_REWIND: - mCallbackWrapper.onRewind(); - break; - case MSG_SEEK_TO: - mCallbackWrapper.onSeekTo((Long) obj); - break; - case MSG_RATE: - mCallbackWrapper.onSetRating((Rating) obj); - break; - case MSG_SET_PLAYBACK_SPEED: - mCallbackWrapper.onSetPlaybackSpeed((Float) obj); - break; - case MSG_CUSTOM_ACTION: - mCallbackWrapper.onCustomAction((String) obj, msg.getData()); - break; - case MSG_ADJUST_VOLUME: - synchronized (mLock) { - vp = mVolumeProvider; - } - if (vp != null) { - vp.onAdjustVolume((int) obj); - } - break; - case MSG_SET_VOLUME: - synchronized (mLock) { - vp = mVolumeProvider; - } - if (vp != null) { - vp.onSetVolumeTo((int) obj); - } - break; - case MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT: - mCallbackWrapper.handleMediaPlayPauseKeySingleTapIfPending(); - break; - } - mCurrentControllerInfo = null; - } - } -} diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java index 7ca5c9398394..51e3a4dc8c4b 100644 --- a/media/java/android/media/session/MediaSessionManager.java +++ b/media/java/android/media/session/MediaSessionManager.java @@ -107,7 +107,7 @@ public final class MediaSessionManager { * @hide */ @NonNull - public ISession createSession(@NonNull SessionCallbackLink cbStub, @NonNull String tag, + public ISession createSession(@NonNull MediaSession.CallbackStub cbStub, @NonNull String tag, @Nullable Bundle sessionInfo) { try { return mService.createSession(mContext.getPackageName(), cbStub, tag, sessionInfo, diff --git a/media/java/android/media/session/SessionCallbackLink.java b/media/java/android/media/session/SessionCallbackLink.java deleted file mode 100644 index 6ffdc2bace18..000000000000 --- a/media/java/android/media/session/SessionCallbackLink.java +++ /dev/null @@ -1,969 +0,0 @@ -/* - * Copyright 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.media.session; - -import android.Manifest; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.RequiresPermission; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.media.Rating; -import android.media.session.MediaSessionManager.RemoteUserInfo; -import android.net.Uri; -import android.os.Binder; -import android.os.Bundle; -import android.os.IBinder; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.Process; -import android.os.RemoteException; -import android.os.ResultReceiver; - -import java.lang.ref.WeakReference; - -/** - * Handles incoming commands to {@link MediaSession.Callback}. - * @hide - */ -public final class SessionCallbackLink implements Parcelable { - final Context mContext; - final ISessionCallback mISessionCallback; - - /** - * Constructor for stub (Callee) - * @hide - */ - public SessionCallbackLink(@NonNull Context context) { - mContext = context; - mISessionCallback = new CallbackStub(); - } - - /** - * Constructor for interface (Caller) - */ - public SessionCallbackLink(IBinder binder) { - mContext = null; - mISessionCallback = ISessionCallback.Stub.asInterface(binder); - } - - /** - * Set {@link MediaSessionEngine} which will be used by {@link CallbackStub}. - */ - void setSessionEngine(@Nullable MediaSessionEngine sessionImpl) { - if (mISessionCallback instanceof CallbackStub) { - ((CallbackStub) mISessionCallback).mSessionImpl = new WeakReference<>(sessionImpl); - } - } - - /** - * Notify session that a controller sends a command. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param command the name of the command - * @param args the arguments included with the command - * @param cb the result receiver for getting the result of the command - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyCommand(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, @NonNull String command, - @Nullable Bundle args, @Nullable ResultReceiver cb) { - try { - mISessionCallback.notifyCommand(packageName, pid, uid, caller, command, args, cb); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that the android system sends a media button event. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param mediaButtonIntent the media button intent - * @param sequenceNumber the sequence number of this call - * @param cb the result receiver for getting the result of the command - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyMediaButton(@NonNull String packageName, int pid, int uid, - @NonNull Intent mediaButtonIntent, int sequenceNumber, - @Nullable ResultReceiver cb) { - try { - mISessionCallback.notifyMediaButton(packageName, pid, uid, mediaButtonIntent, - sequenceNumber, cb); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller sends a media button event. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param mediaButtonIntent the media button intent - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyMediaButtonFromController(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, @NonNull Intent mediaButtonIntent) { - try { - mISessionCallback.notifyMediaButtonFromController(packageName, pid, uid, caller, - mediaButtonIntent); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests preparing media. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyPrepare(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller) { - try { - mISessionCallback.notifyPrepare(packageName, pid, uid, caller); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests preparing media from given media ID. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param mediaId the ID of the media - * @param extras the extras included with this request. - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyPrepareFromMediaId(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, @NonNull String mediaId, - @Nullable Bundle extras) { - try { - mISessionCallback.notifyPrepareFromMediaId(packageName, pid, uid, caller, mediaId, - extras); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests preparing media from given search query. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param query the search query - * @param extras the extras included with this request. - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyPrepareFromSearch(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, @NonNull String query, - @Nullable Bundle extras) { - try { - mISessionCallback.notifyPrepareFromSearch(packageName, pid, uid, caller, query, extras); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests preparing media from given uri. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param uri the uri of the media - * @param extras the extras included with this request. - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyPrepareFromUri(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, @NonNull Uri uri, @Nullable Bundle extras) { - try { - mISessionCallback.notifyPrepareFromUri(packageName, pid, uid, caller, uri, extras); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests playing media. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyPlay(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller) { - try { - mISessionCallback.notifyPlay(packageName, pid, uid, caller); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests playing media from given media ID. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param mediaId the ID of the media - * @param extras the extras included with this request. - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyPlayFromMediaId(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, @NonNull String mediaId, - @Nullable Bundle extras) { - try { - mISessionCallback.notifyPlayFromMediaId(packageName, pid, uid, caller, mediaId, extras); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests playing media from given search query. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param query the search query - * @param extras the extras included with this request. - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyPlayFromSearch(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, @NonNull String query, - @Nullable Bundle extras) { - try { - mISessionCallback.notifyPlayFromSearch(packageName, pid, uid, caller, query, extras); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests playing media from given uri. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param uri the uri of the media - * @param extras the extras included with this request. - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyPlayFromUri(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, @NonNull Uri uri, @Nullable Bundle extras) { - try { - mISessionCallback.notifyPlayFromUri(packageName, pid, uid, caller, uri, extras); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests skipping to the queue item with given ID. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param id the queue id of the item - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifySkipToTrack(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, long id) { - try { - mISessionCallback.notifySkipToTrack(packageName, pid, uid, caller, id); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests pausing media. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyPause(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller) { - try { - mISessionCallback.notifyPause(packageName, pid, uid, caller); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests stopping media. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyStop(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller) { - try { - mISessionCallback.notifyStop(packageName, pid, uid, caller); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests skipping to the next queue item. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyNext(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller) { - try { - mISessionCallback.notifyNext(packageName, pid, uid, caller); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests skipping to the previous queue item. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyPrevious(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller) { - try { - mISessionCallback.notifyPrevious(packageName, pid, uid, caller); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests fast-forwarding. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyFastForward(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller) { - try { - mISessionCallback.notifyFastForward(packageName, pid, uid, caller); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests rewinding. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyRewind(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller) { - try { - mISessionCallback.notifyRewind(packageName, pid, uid, caller); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests seeking to the specific position. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param pos the position to move to, in milliseconds - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifySeekTo(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, long pos) { - try { - mISessionCallback.notifySeekTo(packageName, pid, uid, caller, pos); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests rating of the current media. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param rating the rating of the current media - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyRate(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, @NonNull Rating rating) { - try { - mISessionCallback.notifyRate(packageName, pid, uid, caller, rating); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests changing playback speed. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param speed the playback speed - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifySetPlaybackSpeed(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, float speed) { - try { - mISessionCallback.notifySetPlaybackSpeed(packageName, pid, uid, caller, speed); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller sends a custom action. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param action the name of the action - * @param args the arguments included with this action - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyCustomAction(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, @NonNull String action, @Nullable Bundle args) { - try { - mISessionCallback.notifyCustomAction(packageName, pid, uid, caller, action, args); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests adjusting volume. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param direction the direction of the volume change. - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyAdjustVolume(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, int direction) { - try { - mISessionCallback.notifyAdjustVolume(packageName, pid, uid, caller, direction); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests setting volume. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param value the volume value to set - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifySetVolumeTo(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, int value) { - try { - mISessionCallback.notifySetVolumeTo(packageName, pid, uid, caller, value); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** Gets the binder */ - @NonNull - public IBinder getBinder() { - return mISessionCallback.asBinder(); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeStrongBinder(mISessionCallback.asBinder()); - } - - public static final @android.annotation.NonNull Parcelable.Creator<SessionCallbackLink> CREATOR = - new Parcelable.Creator<SessionCallbackLink>() { - @Override - public SessionCallbackLink createFromParcel(Parcel in) { - return new SessionCallbackLink(in.readStrongBinder()); - } - - @Override - public SessionCallbackLink[] newArray(int size) { - return new SessionCallbackLink[size]; - } - }; - - private class CallbackStub extends ISessionCallback.Stub { - private WeakReference<MediaSessionEngine> mSessionImpl; - - private RemoteUserInfo createRemoteUserInfo(String packageName, int pid, int uid) { - return new RemoteUserInfo(packageName, pid, uid); - } - - @Override - public void notifyCommand(String packageName, int pid, int uid, - ControllerCallbackLink caller, String command, Bundle args, ResultReceiver cb) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchCommand(createRemoteUserInfo(packageName, pid, uid), - command, args, cb); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyMediaButton(String packageName, int pid, int uid, - Intent mediaButtonIntent, int sequenceNumber, ResultReceiver cb) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchMediaButton( - createRemoteUserInfo(packageName, pid, uid), mediaButtonIntent); - } - } finally { - if (cb != null) { - cb.send(sequenceNumber, null); - } - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyMediaButtonFromController(String packageName, int pid, int uid, - ControllerCallbackLink caller, Intent mediaButtonIntent) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchMediaButton(createRemoteUserInfo(packageName, pid, uid), - mediaButtonIntent); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyPrepare(String packageName, int pid, int uid, - ControllerCallbackLink caller) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchPrepare(createRemoteUserInfo(packageName, pid, uid)); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyPrepareFromMediaId(String packageName, int pid, int uid, - ControllerCallbackLink caller, String mediaId, Bundle extras) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchPrepareFromMediaId( - createRemoteUserInfo(packageName, pid, uid), mediaId, extras); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyPrepareFromSearch(String packageName, int pid, int uid, - ControllerCallbackLink caller, String query, Bundle extras) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchPrepareFromSearch( - createRemoteUserInfo(packageName, pid, uid), query, extras); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyPrepareFromUri(String packageName, int pid, int uid, - ControllerCallbackLink caller, Uri uri, Bundle extras) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchPrepareFromUri( - createRemoteUserInfo(packageName, pid, uid), uri, extras); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyPlay(String packageName, int pid, int uid, - ControllerCallbackLink caller) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchPlay(createRemoteUserInfo(packageName, pid, uid)); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyPlayFromMediaId(String packageName, int pid, int uid, - ControllerCallbackLink caller, String mediaId, Bundle extras) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchPlayFromMediaId( - createRemoteUserInfo(packageName, pid, uid), mediaId, extras); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyPlayFromSearch(String packageName, int pid, int uid, - ControllerCallbackLink caller, String query, Bundle extras) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchPlayFromSearch( - createRemoteUserInfo(packageName, pid, uid), query, extras); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyPlayFromUri(String packageName, int pid, int uid, - ControllerCallbackLink caller, Uri uri, Bundle extras) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchPlayFromUri( - createRemoteUserInfo(packageName, pid, uid), uri, extras); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifySkipToTrack(String packageName, int pid, int uid, - ControllerCallbackLink caller, long id) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchSkipToItem( - createRemoteUserInfo(packageName, pid, uid), id); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyPause(String packageName, int pid, int uid, - ControllerCallbackLink caller) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchPause(createRemoteUserInfo(packageName, pid, uid)); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyStop(String packageName, int pid, int uid, - ControllerCallbackLink caller) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchStop(createRemoteUserInfo(packageName, pid, uid)); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyNext(String packageName, int pid, int uid, - ControllerCallbackLink caller) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchNext(createRemoteUserInfo(packageName, pid, uid)); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyPrevious(String packageName, int pid, int uid, - ControllerCallbackLink caller) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchPrevious(createRemoteUserInfo(packageName, pid, uid)); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyFastForward(String packageName, int pid, int uid, - ControllerCallbackLink caller) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchFastForward( - createRemoteUserInfo(packageName, pid, uid)); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyRewind(String packageName, int pid, int uid, - ControllerCallbackLink caller) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchRewind(createRemoteUserInfo(packageName, pid, uid)); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifySeekTo(String packageName, int pid, int uid, - ControllerCallbackLink caller, long pos) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchSeekTo( - createRemoteUserInfo(packageName, pid, uid), pos); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyRate(String packageName, int pid, int uid, ControllerCallbackLink caller, - Rating rating) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchRate( - createRemoteUserInfo(packageName, pid, uid), rating); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifySetPlaybackSpeed(String packageName, int pid, int uid, - ControllerCallbackLink caller, float speed) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchSetPlaybackSpeed( - createRemoteUserInfo(packageName, pid, uid), speed); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyCustomAction(String packageName, int pid, int uid, - ControllerCallbackLink caller, String action, Bundle args) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchCustomAction( - createRemoteUserInfo(packageName, pid, uid), action, args); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyAdjustVolume(String packageName, int pid, int uid, - ControllerCallbackLink caller, int direction) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchAdjustVolume( - createRemoteUserInfo(packageName, pid, uid), direction); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifySetVolumeTo(String packageName, int pid, int uid, - ControllerCallbackLink caller, int value) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchSetVolumeTo( - createRemoteUserInfo(packageName, pid, uid), value); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - private void ensureMediaControlPermission() { - // Check if it's system server or has MEDIA_CONTENT_CONTROL. - // Note that system server doesn't have MEDIA_CONTENT_CONTROL, so we need extra - // check here. - if (getCallingUid() == Process.SYSTEM_UID || mContext.checkCallingPermission( - android.Manifest.permission.MEDIA_CONTENT_CONTROL) - == PackageManager.PERMISSION_GRANTED) { - return; - } - throw new SecurityException("Must hold the MEDIA_CONTENT_CONTROL permission."); - } - } -} diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java index dc2d17753b1d..6361fd81d2af 100755 --- a/media/java/android/mtp/MtpDatabase.java +++ b/media/java/android/mtp/MtpDatabase.java @@ -25,16 +25,13 @@ import android.content.IntentFilter; import android.content.SharedPreferences; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; -import android.media.MediaScanner; import android.net.Uri; import android.os.BatteryManager; import android.os.RemoteException; import android.os.SystemProperties; import android.os.storage.StorageVolume; import android.provider.MediaStore; -import android.provider.MediaStore.Audio; import android.provider.MediaStore.Files; -import android.provider.MediaStore.MediaColumns; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; @@ -42,6 +39,8 @@ import android.util.Log; import android.view.Display; import android.view.WindowManager; +import com.android.internal.annotations.VisibleForNative; + import dalvik.system.CloseGuard; import com.google.android.collect.Sets; @@ -72,7 +71,6 @@ public class MtpDatabase implements AutoCloseable { private final ContentProviderClient mMediaProvider; private final String mVolumeName; private final Uri mObjectsUri; - private final MediaScanner mMediaScanner; private final AtomicBoolean mClosed = new AtomicBoolean(); private final CloseGuard mCloseGuard = CloseGuard.get(); @@ -159,7 +157,6 @@ public class MtpDatabase implements AutoCloseable { MtpConstants.PROPERTY_TRACK, MtpConstants.PROPERTY_ORIGINAL_RELEASE_DATE, MtpConstants.PROPERTY_DURATION, - MtpConstants.PROPERTY_GENRE, MtpConstants.PROPERTY_COMPOSER, MtpConstants.PROPERTY_AUDIO_WAVE_CODEC, MtpConstants.PROPERTY_BITRATE_TYPE, @@ -187,6 +184,7 @@ public class MtpDatabase implements AutoCloseable { MtpConstants.DEVICE_PROPERTY_PERCEIVED_DEVICE_TYPE, }; + @VisibleForNative private int[] getSupportedObjectProperties(int format) { switch (format) { case MtpConstants.FORMAT_MP3: @@ -214,14 +212,41 @@ public class MtpDatabase implements AutoCloseable { } } + public static Uri getObjectPropertiesUri(int format, String volumeName) { + switch (format) { + case MtpConstants.FORMAT_MP3: + case MtpConstants.FORMAT_WAV: + case MtpConstants.FORMAT_WMA: + case MtpConstants.FORMAT_OGG: + case MtpConstants.FORMAT_AAC: + return MediaStore.Audio.Media.getContentUri(volumeName); + case MtpConstants.FORMAT_MPEG: + case MtpConstants.FORMAT_3GP_CONTAINER: + case MtpConstants.FORMAT_WMV: + return MediaStore.Video.Media.getContentUri(volumeName); + case MtpConstants.FORMAT_EXIF_JPEG: + case MtpConstants.FORMAT_GIF: + case MtpConstants.FORMAT_PNG: + case MtpConstants.FORMAT_BMP: + case MtpConstants.FORMAT_DNG: + case MtpConstants.FORMAT_HEIF: + return MediaStore.Images.Media.getContentUri(volumeName); + default: + return MediaStore.Files.getContentUri(volumeName); + } + } + + @VisibleForNative private int[] getSupportedDeviceProperties() { return DEVICE_PROPERTIES; } + @VisibleForNative private int[] getSupportedPlaybackFormats() { return PLAYBACK_FORMATS; } + @VisibleForNative private int[] getSupportedCaptureFormats() { // no capture formats yet return null; @@ -254,7 +279,6 @@ public class MtpDatabase implements AutoCloseable { .acquireContentProviderClient(MediaStore.AUTHORITY); mVolumeName = volumeName; mObjectsUri = Files.getMtpObjectsUri(volumeName); - mMediaScanner = new MediaScanner(context, mVolumeName); mManager = new MtpStorageManager(new MtpStorageManager.MtpNotifier() { @Override public void sendObjectAdded(int id) { @@ -304,7 +328,6 @@ public class MtpDatabase implements AutoCloseable { mManager.close(); mCloseGuard.close(); if (mClosed.compareAndSet(false, true)) { - mMediaScanner.close(); if (mMediaProvider != null) { mMediaProvider.close(); } @@ -380,6 +403,7 @@ public class MtpDatabase implements AutoCloseable { } } + @VisibleForNative private int beginSendObject(String path, int format, int parent, int storageId) { MtpStorageManager.MtpObject parentObj = parent == 0 ? mManager.getStorageRoot(storageId) : mManager.getObject(parent); @@ -391,6 +415,7 @@ public class MtpDatabase implements AutoCloseable { return mManager.beginSendObject(parentObj, objPath.getFileName().toString(), format); } + @VisibleForNative private void endSendObject(int handle, boolean succeeded) { MtpStorageManager.MtpObject obj = mManager.getObject(handle); if (obj == null || !mManager.endSendObject(obj, succeeded)) { @@ -399,69 +424,16 @@ public class MtpDatabase implements AutoCloseable { } // Add the new file to MediaProvider if (succeeded) { - String path = obj.getPath().toString(); - int format = obj.getFormat(); - // Get parent info from MediaProvider, since the id is different from MTP's - ContentValues values = new ContentValues(); - values.put(Files.FileColumns.DATA, path); - values.put(Files.FileColumns.FORMAT, format); - values.put(Files.FileColumns.SIZE, obj.getSize()); - values.put(Files.FileColumns.DATE_MODIFIED, obj.getModifiedTime()); - try { - if (obj.getParent().isRoot()) { - values.put(Files.FileColumns.PARENT, 0); - } else { - int parentId = findInMedia(obj.getParent().getPath()); - if (parentId != -1) { - values.put(Files.FileColumns.PARENT, parentId); - } else { - // The parent isn't in MediaProvider. Don't add the new file. - return; - } - } - - Uri uri = mMediaProvider.insert(mObjectsUri, values); - if (uri != null) { - rescanFile(path, Integer.parseInt(uri.getPathSegments().get(2)), format); - } - } catch (RemoteException e) { - Log.e(TAG, "RemoteException in beginSendObject", e); - } + MediaStore.scanFile(mContext, obj.getPath().toFile()); } } + @VisibleForNative private void rescanFile(String path, int handle, int format) { - // handle abstract playlists separately - // they do not exist in the file system so don't use the media scanner here - if (format == MtpConstants.FORMAT_ABSTRACT_AV_PLAYLIST) { - // extract name from path - String name = path; - int lastSlash = name.lastIndexOf('/'); - if (lastSlash >= 0) { - name = name.substring(lastSlash + 1); - } - // strip trailing ".pla" from the name - if (name.endsWith(".pla")) { - name = name.substring(0, name.length() - 4); - } - - ContentValues values = new ContentValues(1); - values.put(Audio.Playlists.DATA, path); - values.put(Audio.Playlists.NAME, name); - values.put(Files.FileColumns.FORMAT, format); - values.put(Files.FileColumns.DATE_MODIFIED, System.currentTimeMillis() / 1000); - values.put(MediaColumns.MEDIA_SCANNER_NEW_OBJECT_ID, handle); - try { - mMediaProvider.insert( - Audio.Playlists.EXTERNAL_CONTENT_URI, values); - } catch (RemoteException e) { - Log.e(TAG, "RemoteException in endSendObject", e); - } - } else { - mMediaScanner.scanMtpFile(path, handle, format); - } + MediaStore.scanFile(mContext, new File(path)); } + @VisibleForNative private int[] getObjectList(int storageID, int format, int parent) { List<MtpStorageManager.MtpObject> objs = mManager.getObjects(parent, format, storageID); @@ -475,6 +447,7 @@ public class MtpDatabase implements AutoCloseable { return ret; } + @VisibleForNative private int getNumObjects(int storageID, int format, int parent) { List<MtpStorageManager.MtpObject> objs = mManager.getObjects(parent, format, storageID); @@ -484,6 +457,7 @@ public class MtpDatabase implements AutoCloseable { return objs.size(); } + @VisibleForNative private MtpPropertyList getObjectPropertyList(int handle, int format, int property, int groupCode, int depth) { // FIXME - implement group support @@ -551,16 +525,16 @@ public class MtpDatabase implements AutoCloseable { // format should be the same between get & put propertyGroup = mPropertyGroupsByFormat.get(format); if (propertyGroup == null) { - int[] propertyList = getSupportedObjectProperties(format); + final int[] propertyList = getSupportedObjectProperties(format); propertyGroup = new MtpPropertyGroup(mMediaProvider, mVolumeName, propertyList); mPropertyGroupsByFormat.put(format, propertyGroup); } } else { // Get this property value - final int[] propertyList = new int[]{property}; propertyGroup = mPropertyGroupsByProperty.get(property); if (propertyGroup == null) { + final int[] propertyList = new int[]{property}; propertyGroup = new MtpPropertyGroup(mMediaProvider, mVolumeName, propertyList); mPropertyGroupsByProperty.put(property, propertyGroup); @@ -616,28 +590,19 @@ public class MtpDatabase implements AutoCloseable { if (obj.isDir()) { // for directories, check if renamed from something hidden to something non-hidden if (oldPath.getFileName().startsWith(".") && !newPath.startsWith(".")) { - // directory was unhidden - try { - mMediaProvider.call(MediaStore.UNHIDE_CALL, newPath.toString(), null); - } catch (RemoteException e) { - Log.e(TAG, "failed to unhide/rescan for " + newPath); - } + MediaStore.scanFile(mContext, newPath.toFile()); } } else { // for files, check if renamed from .nomedia to something else if (oldPath.getFileName().toString().toLowerCase(Locale.US).equals(NO_MEDIA) && !newPath.getFileName().toString().toLowerCase(Locale.US).equals(NO_MEDIA)) { - try { - mMediaProvider.call(MediaStore.UNHIDE_CALL, - oldPath.getParent().toString(), null); - } catch (RemoteException e) { - Log.e(TAG, "failed to unhide/rescan for " + newPath); - } + MediaStore.scanFile(mContext, newPath.getParent().toFile()); } } return MtpConstants.RESPONSE_OK; } + @VisibleForNative private int beginMoveObject(int handle, int newParent, int newStorage) { MtpStorageManager.MtpObject obj = mManager.getObject(handle); MtpStorageManager.MtpObject parent = newParent == 0 ? @@ -649,6 +614,7 @@ public class MtpDatabase implements AutoCloseable { return allowed ? MtpConstants.RESPONSE_OK : MtpConstants.RESPONSE_GENERAL_ERROR; } + @VisibleForNative private void endMoveObject(int oldParent, int newParent, int oldStorage, int newStorage, int objId, boolean success) { MtpStorageManager.MtpObject oldParentObj = oldParent == 0 ? @@ -698,20 +664,14 @@ public class MtpDatabase implements AutoCloseable { mMediaProvider.update(mObjectsUri, values, PATH_WHERE, whereArgs); } else { // Old parent doesn't exist - add the object - values.put(Files.FileColumns.FORMAT, obj.getFormat()); - values.put(Files.FileColumns.SIZE, obj.getSize()); - values.put(Files.FileColumns.DATE_MODIFIED, obj.getModifiedTime()); - Uri uri = mMediaProvider.insert(mObjectsUri, values); - if (uri != null) { - rescanFile(path.toString(), - Integer.parseInt(uri.getPathSegments().get(2)), obj.getFormat()); - } + MediaStore.scanFile(mContext, path.toFile()); } } catch (RemoteException e) { Log.e(TAG, "RemoteException in mMediaProvider.update", e); } } + @VisibleForNative private int beginCopyObject(int handle, int newParent, int newStorage) { MtpStorageManager.MtpObject obj = mManager.getObject(handle); MtpStorageManager.MtpObject parent = newParent == 0 ? @@ -721,6 +681,7 @@ public class MtpDatabase implements AutoCloseable { return mManager.beginCopyObject(obj, parent); } + @VisibleForNative private void endCopyObject(int handle, boolean success) { MtpStorageManager.MtpObject obj = mManager.getObject(handle); if (obj == null || !mManager.endCopyObject(obj, success)) { @@ -730,39 +691,10 @@ public class MtpDatabase implements AutoCloseable { if (!success) { return; } - String path = obj.getPath().toString(); - int format = obj.getFormat(); - // Get parent info from MediaProvider, since the id is different from MTP's - ContentValues values = new ContentValues(); - values.put(Files.FileColumns.DATA, path); - values.put(Files.FileColumns.FORMAT, format); - values.put(Files.FileColumns.SIZE, obj.getSize()); - values.put(Files.FileColumns.DATE_MODIFIED, obj.getModifiedTime()); - try { - if (obj.getParent().isRoot()) { - values.put(Files.FileColumns.PARENT, 0); - } else { - int parentId = findInMedia(obj.getParent().getPath()); - if (parentId != -1) { - values.put(Files.FileColumns.PARENT, parentId); - } else { - // The parent isn't in MediaProvider. Don't add the new file. - return; - } - } - if (obj.isDir()) { - mMediaScanner.scanDirectories(new String[]{path}); - } else { - Uri uri = mMediaProvider.insert(mObjectsUri, values); - if (uri != null) { - rescanFile(path, Integer.parseInt(uri.getPathSegments().get(2)), format); - } - } - } catch (RemoteException e) { - Log.e(TAG, "RemoteException in beginSendObject", e); - } + MediaStore.scanFile(mContext, obj.getPath().toFile()); } + @VisibleForNative private int setObjectProperty(int handle, int property, long intValue, String stringValue) { switch (property) { @@ -774,6 +706,7 @@ public class MtpDatabase implements AutoCloseable { } } + @VisibleForNative private int getDeviceProperty(int property, long[] outIntValue, char[] outStringValue) { switch (property) { case MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: @@ -809,6 +742,7 @@ public class MtpDatabase implements AutoCloseable { } } + @VisibleForNative private int setDeviceProperty(int property, long intValue, String stringValue) { switch (property) { case MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: @@ -823,6 +757,7 @@ public class MtpDatabase implements AutoCloseable { return MtpConstants.RESPONSE_DEVICE_PROP_NOT_SUPPORTED; } + @VisibleForNative private boolean getObjectInfo(int handle, int[] outStorageFormatParent, char[] outName, long[] outCreatedModified) { MtpStorageManager.MtpObject obj = mManager.getObject(handle); @@ -842,6 +777,7 @@ public class MtpDatabase implements AutoCloseable { return true; } + @VisibleForNative private int getObjectFilePath(int handle, char[] outFilePath, long[] outFileLengthFormat) { MtpStorageManager.MtpObject obj = mManager.getObject(handle); if (obj == null) { @@ -866,6 +802,7 @@ public class MtpDatabase implements AutoCloseable { return obj.getFormat(); } + @VisibleForNative private int beginDeleteObject(int handle) { MtpStorageManager.MtpObject obj = mManager.getObject(handle); if (obj == null) { @@ -877,6 +814,7 @@ public class MtpDatabase implements AutoCloseable { return MtpConstants.RESPONSE_OK; } + @VisibleForNative private void endDeleteObject(int handle, boolean success) { MtpStorageManager.MtpObject obj = mManager.getObject(handle); if (obj == null) { @@ -922,12 +860,7 @@ public class MtpDatabase implements AutoCloseable { String[] whereArgs = new String[]{path.toString()}; if (mMediaProvider.delete(mObjectsUri, PATH_WHERE, whereArgs) > 0) { if (!isDir && path.toString().toLowerCase(Locale.US).endsWith(NO_MEDIA)) { - try { - String parentPath = path.getParent().toString(); - mMediaProvider.call(MediaStore.UNHIDE_CALL, parentPath, null); - } catch (RemoteException e) { - Log.e(TAG, "failed to unhide/rescan for " + path); - } + MediaStore.scanFile(mContext, path.getParent().toFile()); } } else { Log.i(TAG, "Mediaprovider didn't delete " + path); @@ -937,6 +870,7 @@ public class MtpDatabase implements AutoCloseable { } } + @VisibleForNative private int[] getObjectReferences(int handle) { MtpStorageManager.MtpObject obj = mManager.getObject(handle); if (obj == null) @@ -972,6 +906,7 @@ public class MtpDatabase implements AutoCloseable { return null; } + @VisibleForNative private int setObjectReferences(int handle, int[] references) { MtpStorageManager.MtpObject obj = mManager.getObject(handle); if (obj == null) @@ -1004,7 +939,7 @@ public class MtpDatabase implements AutoCloseable { return MtpConstants.RESPONSE_GENERAL_ERROR; } - // used by the JNI code + @VisibleForNative private long mNativeContext; private native final void native_setup(); diff --git a/media/java/android/mtp/MtpPropertyGroup.java b/media/java/android/mtp/MtpPropertyGroup.java index 77d0f34f1ad6..6d5be8ef6985 100644 --- a/media/java/android/mtp/MtpPropertyGroup.java +++ b/media/java/android/mtp/MtpPropertyGroup.java @@ -48,7 +48,6 @@ class MtpPropertyGroup { private final ContentProviderClient mProvider; private final String mVolumeName; - private final Uri mUri; // list of all properties in this group private final Property[] mProperties; @@ -62,7 +61,6 @@ class MtpPropertyGroup { public MtpPropertyGroup(ContentProviderClient provider, String volumeName, int[] properties) { mProvider = provider; mVolumeName = volumeName; - mUri = Files.getMtpObjectsUri(volumeName); int count = properties.length; ArrayList<String> columns = new ArrayList<>(count); @@ -139,10 +137,6 @@ class MtpPropertyGroup { column = Audio.AudioColumns.ALBUM_ARTIST; type = MtpConstants.TYPE_STR; break; - case MtpConstants.PROPERTY_GENRE: - // genre requires a special query - type = MtpConstants.TYPE_STR; - break; case MtpConstants.PROPERTY_COMPOSER: column = Audio.AudioColumns.COMPOSER; type = MtpConstants.TYPE_STR; @@ -176,46 +170,6 @@ class MtpPropertyGroup { } } - private String queryAudio(String path, String column) { - Cursor c = null; - try { - c = mProvider.query(Audio.Media.getContentUri(mVolumeName), - new String [] { column }, - PATH_WHERE, new String[] {path}, null, null); - if (c != null && c.moveToNext()) { - return c.getString(0); - } else { - return ""; - } - } catch (Exception e) { - return ""; - } finally { - if (c != null) { - c.close(); - } - } - } - - private String queryGenre(String path) { - Cursor c = null; - try { - c = mProvider.query(Audio.Genres.getContentUri(mVolumeName), - new String [] { Audio.GenresColumns.NAME }, - PATH_WHERE, new String[] {path}, null, null); - if (c != null && c.moveToNext()) { - return c.getString(0); - } else { - return ""; - } - } catch (Exception e) { - return ""; - } finally { - if (c != null) { - c.close(); - } - } - } - /** * Gets the values of the properties represented by this property group for the given * object and adds them to the given property list. @@ -229,12 +183,16 @@ class MtpPropertyGroup { if (property.column != -1 && c == null) { try { // Look up the entry in MediaProvider only if one of those properties is needed. - c = mProvider.query(mUri, mColumns, + final Uri uri = MtpDatabase.getObjectPropertiesUri(object.getFormat(), + mVolumeName); + c = mProvider.query(uri, mColumns, PATH_WHERE, new String[] {path}, null, null); if (c != null && !c.moveToNext()) { c.close(); c = null; } + } catch (IllegalArgumentException e) { + return MtpConstants.RESPONSE_INVALID_OBJECT_PROP_CODE; } catch (RemoteException e) { Log.e(TAG, "Mediaprovider lookup failed"); } @@ -290,20 +248,6 @@ class MtpPropertyGroup { list.append(id, property.code, MtpConstants.TYPE_UINT16, track % 1000); break; - case MtpConstants.PROPERTY_ARTIST: - list.append(id, property.code, - queryAudio(path, Audio.AudioColumns.ARTIST)); - break; - case MtpConstants.PROPERTY_ALBUM_NAME: - list.append(id, property.code, - queryAudio(path, Audio.AudioColumns.ALBUM)); - break; - case MtpConstants.PROPERTY_GENRE: - String genre = queryGenre(path); - if (genre != null) { - list.append(id, property.code, genre); - } - break; case MtpConstants.PROPERTY_AUDIO_WAVE_CODEC: case MtpConstants.PROPERTY_AUDIO_BITRATE: case MtpConstants.PROPERTY_SAMPLE_RATE: diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp index d7ab854d63ba..f412161f418a 100644 --- a/media/jni/android_media_MediaDrm.cpp +++ b/media/jni/android_media_MediaDrm.cpp @@ -149,6 +149,7 @@ struct SessionExceptionFields { }; struct SessionExceptionErrorCodes { + jint kErrorUnknown; jint kResourceContention; } gSessionExceptionErrorCodes; @@ -888,6 +889,8 @@ static void android_media_MediaDrm_native_init(JNIEnv *env) { gFields.sessionException.classId = static_cast<jclass>(env->NewGlobalRef(clazz)); GET_FIELD_ID(gFields.sessionException.errorCode, clazz, "mErrorCode", "I"); + GET_STATIC_FIELD_ID(field, clazz, "ERROR_UNKNOWN", "I"); + gSessionExceptionErrorCodes.kErrorUnknown = env->GetStaticIntField(clazz, field); GET_STATIC_FIELD_ID(field, clazz, "ERROR_RESOURCE_CONTENTION", "I"); gSessionExceptionErrorCodes.kResourceContention = env->GetStaticIntField(clazz, field); } diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp index 3ec0903472bc..24fff0635238 100644 --- a/media/jni/android_media_MediaRecorder.cpp +++ b/media/jni/android_media_MediaRecorder.cpp @@ -760,9 +760,9 @@ android_media_MediaRecord_getActiveMicrophones(JNIEnv *env, return jStatus; } -static jint android_media_MediaRecord_setMicrophoneDirection( +static jint android_media_MediaRecord_setPreferredMicrophoneDirection( JNIEnv *env, jobject thiz, jint direction) { - ALOGV("setMicrophoneDirection(%d)", direction); + ALOGV("setPreferredMicrophoneDirection(%d)", direction); sp<MediaRecorder> mr = getMediaRecorder(env, thiz); if (mr == NULL) { jniThrowException(env, "java/lang/IllegalStateException", NULL); @@ -771,7 +771,7 @@ static jint android_media_MediaRecord_setMicrophoneDirection( jint jStatus = AUDIO_JAVA_SUCCESS; status_t status = - mr->setMicrophoneDirection(static_cast<audio_microphone_direction_t>(direction)); + mr->setPreferredMicrophoneDirection(static_cast<audio_microphone_direction_t>(direction)); if (status != NO_ERROR) { jStatus = nativeToJavaStatus(status); } @@ -779,9 +779,9 @@ static jint android_media_MediaRecord_setMicrophoneDirection( return jStatus; } -static jint android_media_MediaRecord_setMicrophoneFieldDimension( +static jint android_media_MediaRecord_setPreferredMicrophoneFieldDimension( JNIEnv *env, jobject thiz, jfloat zoom) { - ALOGV("setMicrophoneFieldDimension(%f)", zoom); + ALOGV("setPreferredMicrophoneFieldDimension(%f)", zoom); sp<MediaRecorder> mr = getMediaRecorder(env, thiz); if (mr == NULL) { jniThrowException(env, "java/lang/IllegalStateException", NULL); @@ -789,7 +789,7 @@ static jint android_media_MediaRecord_setMicrophoneFieldDimension( } jint jStatus = AUDIO_JAVA_SUCCESS; - status_t status = mr->setMicrophoneFieldDimension(zoom); + status_t status = mr->setPreferredMicrophoneFieldDimension(zoom); if (status != NO_ERROR) { jStatus = nativeToJavaStatus(status); } @@ -850,8 +850,10 @@ static const JNINativeMethod gMethods[] = { {"native_getActiveMicrophones", "(Ljava/util/ArrayList;)I", (void *)android_media_MediaRecord_getActiveMicrophones}, {"native_getPortId", "()I", (void *)android_media_MediaRecord_getPortId}, - {"native_setMicrophoneDirection", "(I)I", (void *)android_media_MediaRecord_setMicrophoneDirection}, - {"native_setMicrophoneFieldDimension", "(F)I", (void *)android_media_MediaRecord_setMicrophoneFieldDimension}, + {"native_setPreferredMicrophoneDirection", "(I)I", + (void *)android_media_MediaRecord_setPreferredMicrophoneDirection}, + {"native_setPreferredMicrophoneFieldDimension", "(F)I", + (void *)android_media_MediaRecord_setPreferredMicrophoneFieldDimension}, }; // This function only registers the native methods, and is called from diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestResultPrinter.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestResultPrinter.java index 2492109abb96..ed2eebf88665 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestResultPrinter.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestResultPrinter.java @@ -40,14 +40,14 @@ public class CameraTestResultPrinter { private Instrumentation mInst = null; private boolean mWriteToFile = true; - public CameraTestResultPrinter(Instrumentation instrumentation, boolean writeToFile) { mInst = instrumentation; mWriteToFile = writeToFile; // Create a log directory if not exists. File baseDir = new File(RESULT_DIR); - if (!baseDir.exists() && !baseDir.mkdirs()) { + baseDir.mkdirs(); + if (!baseDir.isDirectory()) { throw new IllegalStateException("Couldn't create directory for logs: " + baseDir); } Log.v(TAG, String.format("Saving test results under: %s", baseDir.getAbsolutePath())); diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt index e1dc40636ca5..1f2480ba0b47 100644 --- a/native/android/libandroid.map.txt +++ b/native/android/libandroid.map.txt @@ -148,6 +148,7 @@ LIBANDROID { AHardwareBuffer_getNativeHandle; # introduced=26 AHardwareBuffer_isSupported; # introduced=29 AHardwareBuffer_lock; # introduced=26 + AHardwareBuffer_lockAndGetInfo; # introduced=29 AHardwareBuffer_lockPlanes; # introduced=29 AHardwareBuffer_recvHandleFromUnixSocket; # introduced=26 AHardwareBuffer_release; # introduced=26 diff --git a/native/webview/plat_support/draw_fn.h b/native/webview/plat_support/draw_fn.h index 5b3e496be81a..42cad43af8fc 100644 --- a/native/webview/plat_support/draw_fn.h +++ b/native/webview/plat_support/draw_fn.h @@ -44,23 +44,8 @@ struct AwDrawFn_DrawGLParams { int width; int height; - // Input: is the View rendered into an independent layer. - // If false, the surface is likely to hold to the full screen contents, with - // the scissor box set by the caller to the actual View location and size. - // Also the transformation matrix will contain at least a translation to the - // position of the View to render, plus any other transformations required as - // part of any ongoing View animation. View translucency (alpha) is ignored, - // although the framework will set is_layer to true for non-opaque cases. - // Can be requested via the View.setLayerType(View.LAYER_TYPE_NONE, ...) - // Android API method. - // - // If true, the surface is dedicated to the View and should have its size. - // The viewport and scissor box are set by the caller to the whole surface. - // Animation transformations are handled by the caller and not reflected in - // the provided transformation matrix. Translucency works normally. - // Can be requested via the View.setLayerType(View.LAYER_TYPE_HARDWARE, ...) - // Android API method. - bool is_layer; + // Used to be is_layer. + bool deprecated_0; // Input: current transformation matrix in surface pixels. // Uses the column-based OpenGL matrix format. @@ -102,8 +87,7 @@ struct AwDrawFn_DrawVkParams { int width; int height; - // Input: is the render target a FBO - bool is_layer; + bool deprecated_0; // Input: current transform matrix float transform[16]; diff --git a/native/webview/plat_support/draw_functor.cpp b/native/webview/plat_support/draw_functor.cpp index e43a60c3f396..7cce61b87d12 100644 --- a/native/webview/plat_support/draw_functor.cpp +++ b/native/webview/plat_support/draw_functor.cpp @@ -65,7 +65,7 @@ void draw_gl(int functor, void* data, .clip_bottom = draw_gl_params.clipBottom, .width = draw_gl_params.width, .height = draw_gl_params.height, - .is_layer = draw_gl_params.isLayer, + .deprecated_0 = false, .transfer_function_g = gabcdef[0], .transfer_function_a = gabcdef[1], .transfer_function_b = gabcdef[2], @@ -126,7 +126,7 @@ void drawVk(int functor, void* data, const uirenderer::VkFunctorDrawParams& draw .version = kAwDrawFnVersion, .width = draw_vk_params.width, .height = draw_vk_params.height, - .is_layer = draw_vk_params.is_layer, + .deprecated_0 = false, .secondary_command_buffer = draw_vk_params.secondary_command_buffer, .color_attachment_index = draw_vk_params.color_attachment_index, .compatible_render_pass = draw_vk_params.compatible_render_pass, diff --git a/packages/DynamicAndroidInstallationService/Android.mk b/packages/DynamicSystemInstallationService/Android.mk index 13d96ac3906e..16aca1bd07c5 100644 --- a/packages/DynamicAndroidInstallationService/Android.mk +++ b/packages/DynamicSystemInstallationService/Android.mk @@ -8,7 +8,7 @@ LOCAL_RESOURCE_DIR := $(addprefix $(LOCAL_PATH)/, res) LOCAL_USE_AAPT2 := true -LOCAL_PACKAGE_NAME := DynamicAndroidInstallationService +LOCAL_PACKAGE_NAME := DynamicSystemInstallationService LOCAL_CERTIFICATE := platform LOCAL_PRIVILEGED_MODULE := true LOCAL_PRIVATE_PLATFORM_APIS := true diff --git a/packages/DynamicAndroidInstallationService/AndroidManifest.xml b/packages/DynamicSystemInstallationService/AndroidManifest.xml index 32acad4d5ab0..291111713977 100644 --- a/packages/DynamicAndroidInstallationService/AndroidManifest.xml +++ b/packages/DynamicSystemInstallationService/AndroidManifest.xml @@ -1,10 +1,10 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.dynandroid" + package="com.android.dynsystem" android:sharedUserId="android.uid.system"> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.INTERNET" /> - <uses-permission android:name="android.permission.MANAGE_DYNAMIC_ANDROID" /> + <uses-permission android:name="android.permission.MANAGE_DYNAMIC_SYSTEM" /> <uses-permission android:name="android.permission.REBOOT" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> @@ -13,24 +13,24 @@ android:label="@string/app_name"> <service - android:name=".DynamicAndroidInstallationService" + android:name=".DynamicSystemInstallationService" android:enabled="true" android:exported="true" - android:permission="android.permission.MANAGE_DYNAMIC_ANDROID" - android:process=":dynandroid"> + android:permission="android.permission.MANAGE_DYNAMIC_SYSTEM" + android:process=":dynsystem"> <intent-filter> - <action android:name="android.content.action.NOTIFY_IF_IN_USE" /> + <action android:name="android.os.image.action.NOTIFY_IF_IN_USE" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </service> <activity android:name=".VerificationActivity" android:exported="true" - android:permission="android.permission.MANAGE_DYNAMIC_ANDROID" + android:permission="android.permission.MANAGE_DYNAMIC_SYSTEM" android:theme="@android:style/Theme.Material.Light.Dialog.NoActionBar" - android:process=":dynandroid"> + android:process=":dynsystem"> <intent-filter> - <action android:name="android.content.action.START_INSTALL" /> + <action android:name="android.os.image.action.START_INSTALL" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> diff --git a/packages/DynamicAndroidInstallationService/MODULE_LICENSE_APACHE2 b/packages/DynamicSystemInstallationService/MODULE_LICENSE_APACHE2 index e69de29bb2d1..e69de29bb2d1 100644 --- a/packages/DynamicAndroidInstallationService/MODULE_LICENSE_APACHE2 +++ b/packages/DynamicSystemInstallationService/MODULE_LICENSE_APACHE2 diff --git a/packages/DynamicAndroidInstallationService/NOTICE b/packages/DynamicSystemInstallationService/NOTICE index c5b1efa7aac7..c5b1efa7aac7 100644 --- a/packages/DynamicAndroidInstallationService/NOTICE +++ b/packages/DynamicSystemInstallationService/NOTICE diff --git a/packages/DynamicAndroidInstallationService/res/drawable/ic_system_update_googblue_24dp.xml b/packages/DynamicSystemInstallationService/res/drawable/ic_system_update_googblue_24dp.xml index acf1567ab7fe..acf1567ab7fe 100644 --- a/packages/DynamicAndroidInstallationService/res/drawable/ic_system_update_googblue_24dp.xml +++ b/packages/DynamicSystemInstallationService/res/drawable/ic_system_update_googblue_24dp.xml diff --git a/packages/DynamicAndroidInstallationService/res/values/strings.xml b/packages/DynamicSystemInstallationService/res/values/strings.xml index 03c7c28c7036..a72e4e2c1b74 100644 --- a/packages/DynamicAndroidInstallationService/res/values/strings.xml +++ b/packages/DynamicSystemInstallationService/res/values/strings.xml @@ -12,14 +12,14 @@ <!-- password page description [CHAR LIMIT=128] --> <string name="keyguard_description">Please enter your password and continue to AndroidOnTap installation</string> - <!-- Displayed on notification: DynAndroid installation is completed [CHAR LIMIT=128] --> + <!-- Displayed on notification: AndroidOnTap installation is completed [CHAR LIMIT=128] --> <string name="notification_install_completed">New system is ready, you can reboot into it or discard it.</string> - <!-- Displayed on notification: DynAndroid installation is in progress [CHAR LIMIT=128] --> + <!-- Displayed on notification: AndroidOnTap installation is in progress [CHAR LIMIT=128] --> <string name="notification_install_inprogress">Installation is in progress.</string> - <!-- Displayed on notification: DynAndroid installation is in progress [CHAR LIMIT=128] --> + <!-- Displayed on notification: AndroidOnTap installation is in progress [CHAR LIMIT=128] --> <string name="notification_install_failed">Installation Failed.</string> <!-- Displayed on notification: We are running in AndroidOnTap [CHAR LIMIT=128] --> - <string name="notification_dynandroid_in_use">We are running in AndroidOnTap.</string> + <string name="notification_dynsystem_in_use">We are running in AndroidOnTap.</string> <!-- Action on notification: Cancel installation [CHAR LIMIT=16] --> <string name="notification_action_cancel">Cancel</string> @@ -28,11 +28,11 @@ <!-- Action on notification: Uninstall AndroidOnTap [CHAR LIMIT=16] --> <string name="notification_action_uninstall">Uninstall</string> <!-- Action on notification: Reboot to AndroidOnTap [CHAR LIMIT=16] --> - <string name="notification_action_reboot_to_dynandroid">Reboot</string> + <string name="notification_action_reboot_to_dynsystem">Reboot</string> - <!-- Toast when installed DynamicAndroid is discarded [CHAR LIMIT=64] --> - <string name="toast_dynandroid_discarded">Installed AndroidOnTap is discarded.</string> - <!-- Toast when we fail to launch into DynamicAndroid [CHAR LIMIT=64] --> - <string name="toast_failed_to_reboot_to_dynandroid">Failed to reboot into AndroidOnTap.</string> + <!-- Toast when installed AndroidOnTap is discarded [CHAR LIMIT=64] --> + <string name="toast_dynsystem_discarded">Installed AndroidOnTap is discarded.</string> + <!-- Toast when we fail to launch into AndroidOnTap [CHAR LIMIT=64] --> + <string name="toast_failed_to_reboot_to_dynsystem">Failed to reboot into AndroidOnTap.</string> </resources> diff --git a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/BootCompletedReceiver.java b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/BootCompletedReceiver.java index dd1be897b2ea..38576ee47283 100644 --- a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/BootCompletedReceiver.java +++ b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/BootCompletedReceiver.java @@ -14,20 +14,20 @@ * limitations under the License. */ -package com.android.dynandroid; +package com.android.dynsystem; import android.content.BroadcastReceiver; import android.content.Context; -import android.content.DynamicAndroidClient; import android.content.Intent; import android.os.UserHandle; +import android.os.image.DynamicSystemClient; import android.util.Log; /** * A BoardcastReceiver waiting for ACTION_BOOT_COMPLETED and ask * the service to display a notification if we are currently running - * in DynamicAndroid. + * in DynamicSystem. */ public class BootCompletedReceiver extends BroadcastReceiver { @@ -41,9 +41,9 @@ public class BootCompletedReceiver extends BroadcastReceiver { if (Intent.ACTION_BOOT_COMPLETED.equals(action)) { Intent startServiceIntent = new Intent( - context, DynamicAndroidInstallationService.class); + context, DynamicSystemInstallationService.class); - startServiceIntent.setAction(DynamicAndroidClient.ACTION_NOTIFY_IF_IN_USE); + startServiceIntent.setAction(DynamicSystemClient.ACTION_NOTIFY_IF_IN_USE); context.startServiceAsUser(startServiceIntent, UserHandle.SYSTEM); } } diff --git a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/DynamicAndroidInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/DynamicSystemInstallationService.java index d942babf78a6..df2c57181904 100644 --- a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/DynamicAndroidInstallationService.java +++ b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/DynamicSystemInstallationService.java @@ -14,28 +14,28 @@ * limitations under the License. */ -package com.android.dynandroid; - -import static android.content.DynamicAndroidClient.ACTION_NOTIFY_IF_IN_USE; -import static android.content.DynamicAndroidClient.ACTION_START_INSTALL; -import static android.content.DynamicAndroidClient.CAUSE_ERROR_EXCEPTION; -import static android.content.DynamicAndroidClient.CAUSE_ERROR_INVALID_URL; -import static android.content.DynamicAndroidClient.CAUSE_ERROR_IO; -import static android.content.DynamicAndroidClient.CAUSE_INSTALL_CANCELLED; -import static android.content.DynamicAndroidClient.CAUSE_INSTALL_COMPLETED; -import static android.content.DynamicAndroidClient.CAUSE_NOT_SPECIFIED; -import static android.content.DynamicAndroidClient.STATUS_IN_PROGRESS; -import static android.content.DynamicAndroidClient.STATUS_IN_USE; -import static android.content.DynamicAndroidClient.STATUS_NOT_STARTED; -import static android.content.DynamicAndroidClient.STATUS_READY; +package com.android.dynsystem; + import static android.os.AsyncTask.Status.FINISHED; import static android.os.AsyncTask.Status.PENDING; import static android.os.AsyncTask.Status.RUNNING; - -import static com.android.dynandroid.InstallationAsyncTask.RESULT_ERROR_EXCEPTION; -import static com.android.dynandroid.InstallationAsyncTask.RESULT_ERROR_INVALID_URL; -import static com.android.dynandroid.InstallationAsyncTask.RESULT_ERROR_IO; -import static com.android.dynandroid.InstallationAsyncTask.RESULT_OK; +import static android.os.image.DynamicSystemClient.ACTION_NOTIFY_IF_IN_USE; +import static android.os.image.DynamicSystemClient.ACTION_START_INSTALL; +import static android.os.image.DynamicSystemClient.CAUSE_ERROR_EXCEPTION; +import static android.os.image.DynamicSystemClient.CAUSE_ERROR_INVALID_URL; +import static android.os.image.DynamicSystemClient.CAUSE_ERROR_IO; +import static android.os.image.DynamicSystemClient.CAUSE_INSTALL_CANCELLED; +import static android.os.image.DynamicSystemClient.CAUSE_INSTALL_COMPLETED; +import static android.os.image.DynamicSystemClient.CAUSE_NOT_SPECIFIED; +import static android.os.image.DynamicSystemClient.STATUS_IN_PROGRESS; +import static android.os.image.DynamicSystemClient.STATUS_IN_USE; +import static android.os.image.DynamicSystemClient.STATUS_NOT_STARTED; +import static android.os.image.DynamicSystemClient.STATUS_READY; + +import static com.android.dynsystem.InstallationAsyncTask.RESULT_ERROR_EXCEPTION; +import static com.android.dynsystem.InstallationAsyncTask.RESULT_ERROR_INVALID_URL; +import static com.android.dynsystem.InstallationAsyncTask.RESULT_ERROR_IO; +import static com.android.dynsystem.InstallationAsyncTask.RESULT_OK; import android.app.Notification; import android.app.NotificationChannel; @@ -43,16 +43,16 @@ import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Context; -import android.content.DynamicAndroidClient; import android.content.Intent; import android.os.Bundle; -import android.os.DynamicAndroidManager; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.Messenger; import android.os.PowerManager; import android.os.RemoteException; +import android.os.image.DynamicSystemClient; +import android.os.image.DynamicSystemManager; import android.util.Log; import android.widget.Toast; @@ -60,31 +60,31 @@ import java.lang.ref.WeakReference; import java.util.ArrayList; /** - * This class is the service in charge of DynamicAndroid installation. + * This class is the service in charge of DynamicSystem installation. * It also posts status to notification bar and wait for user's * cancel and confirm commnands. */ -public class DynamicAndroidInstallationService extends Service +public class DynamicSystemInstallationService extends Service implements InstallationAsyncTask.InstallStatusListener { - private static final String TAG = "DynAndroidInstallationService"; + private static final String TAG = "DynSystemInstallationService"; /* * Intent actions */ private static final String ACTION_CANCEL_INSTALL = - "com.android.dynandroid.ACTION_CANCEL_INSTALL"; + "com.android.dynsystem.ACTION_CANCEL_INSTALL"; private static final String ACTION_DISCARD_INSTALL = - "com.android.dynandroid.ACTION_DISCARD_INSTALL"; - private static final String ACTION_REBOOT_TO_DYN_ANDROID = - "com.android.dynandroid.ACTION_REBOOT_TO_DYN_ANDROID"; + "com.android.dynsystem.ACTION_DISCARD_INSTALL"; + private static final String ACTION_REBOOT_TO_DYN_SYSTEM = + "com.android.dynsystem.ACTION_REBOOT_TO_DYN_SYSTEM"; private static final String ACTION_REBOOT_TO_NORMAL = - "com.android.dynandroid.ACTION_REBOOT_TO_NORMAL"; + "com.android.dynsystem.ACTION_REBOOT_TO_NORMAL"; /* * For notification */ - private static final String NOTIFICATION_CHANNEL_ID = "com.android.dynandroid"; + private static final String NOTIFICATION_CHANNEL_ID = "com.android.dynsystem"; private static final int NOTIFICATION_ID = 1; /* @@ -97,15 +97,15 @@ public class DynamicAndroidInstallationService extends Service final Messenger mMessenger = new Messenger(new IncomingHandler(this)); static class IncomingHandler extends Handler { - private final WeakReference<DynamicAndroidInstallationService> mWeakService; + private final WeakReference<DynamicSystemInstallationService> mWeakService; - IncomingHandler(DynamicAndroidInstallationService service) { + IncomingHandler(DynamicSystemInstallationService service) { mWeakService = new WeakReference<>(service); } @Override public void handleMessage(Message msg) { - DynamicAndroidInstallationService service = mWeakService.get(); + DynamicSystemInstallationService service = mWeakService.get(); if (service != null) { service.handleMessage(msg); @@ -113,7 +113,7 @@ public class DynamicAndroidInstallationService extends Service } } - private DynamicAndroidManager mDynAndroid; + private DynamicSystemManager mDynSystem; private NotificationManager mNM; private long mSystemSize; @@ -130,7 +130,7 @@ public class DynamicAndroidInstallationService extends Service prepareNotification(); - mDynAndroid = (DynamicAndroidManager) getSystemService(Context.DYNAMIC_ANDROID_SERVICE); + mDynSystem = (DynamicSystemManager) getSystemService(Context.DYNAMIC_SYSTEM_SERVICE); } @Override @@ -156,8 +156,8 @@ public class DynamicAndroidInstallationService extends Service executeCancelCommand(); } else if (ACTION_DISCARD_INSTALL.equals(action)) { executeDiscardCommand(); - } else if (ACTION_REBOOT_TO_DYN_ANDROID.equals(action)) { - executeRebootToDynAndroidCommand(); + } else if (ACTION_REBOOT_TO_DYN_SYSTEM.equals(action)) { + executeRebootToDynSystemCommand(); } else if (ACTION_REBOOT_TO_NORMAL.equals(action)) { executeRebootToNormalCommand(); } else if (ACTION_NOTIFY_IF_IN_USE.equals(action)) { @@ -215,17 +215,17 @@ public class DynamicAndroidInstallationService extends Service return; } - if (isInDynamicAndroid()) { - Log.e(TAG, "We are already running in DynamicAndroid"); + if (isInDynamicSystem()) { + Log.e(TAG, "We are already running in DynamicSystem"); return; } - String url = intent.getStringExtra(DynamicAndroidClient.KEY_SYSTEM_URL); - mSystemSize = intent.getLongExtra(DynamicAndroidClient.KEY_SYSTEM_SIZE, 0); - mUserdataSize = intent.getLongExtra(DynamicAndroidClient.KEY_USERDATA_SIZE, 0); + String url = intent.getStringExtra(DynamicSystemClient.KEY_SYSTEM_URL); + mSystemSize = intent.getLongExtra(DynamicSystemClient.KEY_SYSTEM_SIZE, 0); + mUserdataSize = intent.getLongExtra(DynamicSystemClient.KEY_USERDATA_SIZE, 0); mInstallTask = new InstallationAsyncTask( - url, mSystemSize, mUserdataSize, mDynAndroid, this); + url, mSystemSize, mUserdataSize, mDynSystem, this); mInstallTask.execute(); @@ -251,7 +251,7 @@ public class DynamicAndroidInstallationService extends Service } private void executeDiscardCommand() { - if (isInDynamicAndroid()) { + if (isInDynamicSystem()) { Log.e(TAG, "We are now running in AOT, please reboot to normal system first"); return; } @@ -262,16 +262,16 @@ public class DynamicAndroidInstallationService extends Service } Toast.makeText(this, - getString(R.string.toast_dynandroid_discarded), + getString(R.string.toast_dynsystem_discarded), Toast.LENGTH_LONG).show(); resetTaskAndStop(); postStatus(STATUS_NOT_STARTED, CAUSE_INSTALL_CANCELLED); - mDynAndroid.remove(); + mDynSystem.remove(); } - private void executeRebootToDynAndroidCommand() { + private void executeRebootToDynSystemCommand() { if (mInstallTask == null || mInstallTask.getStatus() != FINISHED) { Log.e(TAG, "Trying to reboot to AOT while there is no complete installation"); return; @@ -282,10 +282,10 @@ public class DynamicAndroidInstallationService extends Service mNM.cancel(NOTIFICATION_ID); Toast.makeText(this, - getString(R.string.toast_failed_to_reboot_to_dynandroid), + getString(R.string.toast_failed_to_reboot_to_dynsystem), Toast.LENGTH_LONG).show(); - mDynAndroid.remove(); + mDynSystem.remove(); return; } @@ -293,12 +293,12 @@ public class DynamicAndroidInstallationService extends Service PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); if (powerManager != null) { - powerManager.reboot("dynandroid"); + powerManager.reboot("dynsystem"); } } private void executeRebootToNormalCommand() { - if (!isInDynamicAndroid()) { + if (!isInDynamicSystem()) { Log.e(TAG, "It's already running in normal system."); return; } @@ -346,7 +346,7 @@ public class DynamicAndroidInstallationService extends Service } private PendingIntent createPendingIntent(String action) { - Intent intent = new Intent(this, DynamicAndroidInstallationService.class); + Intent intent = new Intent(this, DynamicSystemInstallationService.class); intent.setAction(action); return PendingIntent.getService(this, 0, intent, 0); } @@ -375,8 +375,8 @@ public class DynamicAndroidInstallationService extends Service builder.setContentText(getString(R.string.notification_install_completed)); builder.addAction(new Notification.Action.Builder( - null, getString(R.string.notification_action_reboot_to_dynandroid), - createPendingIntent(ACTION_REBOOT_TO_DYN_ANDROID)).build()); + null, getString(R.string.notification_action_reboot_to_dynsystem), + createPendingIntent(ACTION_REBOOT_TO_DYN_SYSTEM)).build()); builder.addAction(new Notification.Action.Builder( null, getString(R.string.notification_action_discard), @@ -385,7 +385,7 @@ public class DynamicAndroidInstallationService extends Service break; case STATUS_IN_USE: - builder.setContentText(getString(R.string.notification_dynandroid_in_use)); + builder.setContentText(getString(R.string.notification_dynsystem_in_use)); builder.addAction(new Notification.Action.Builder( null, getString(R.string.notification_action_uninstall), @@ -409,7 +409,7 @@ public class DynamicAndroidInstallationService extends Service } private boolean verifyRequest(Intent intent) { - String url = intent.getStringExtra(DynamicAndroidClient.KEY_SYSTEM_URL); + String url = intent.getStringExtra(DynamicSystemClient.KEY_SYSTEM_URL); return VerificationActivity.isVerified(url); } @@ -443,16 +443,16 @@ public class DynamicAndroidInstallationService extends Service private void notifyOneClient(Messenger client, int status, int cause) throws RemoteException { Bundle bundle = new Bundle(); - bundle.putLong(DynamicAndroidClient.KEY_INSTALLED_SIZE, mInstalledSize); + bundle.putLong(DynamicSystemClient.KEY_INSTALLED_SIZE, mInstalledSize); client.send(Message.obtain(null, - DynamicAndroidClient.MSG_POST_STATUS, status, cause, bundle)); + DynamicSystemClient.MSG_POST_STATUS, status, cause, bundle)); } private int getStatus() { - if (isInDynamicAndroid()) { + if (isInDynamicSystem()) { return STATUS_IN_USE; - } else if (isDynamicAndroidInstalled()) { + } else if (isDynamicSystemInstalled()) { return STATUS_READY; } else if (mInstallTask == null) { return STATUS_NOT_STARTED; @@ -479,17 +479,17 @@ public class DynamicAndroidInstallationService extends Service } } - private boolean isInDynamicAndroid() { - return mDynAndroid.isInUse(); + private boolean isInDynamicSystem() { + return mDynSystem.isInUse(); } - private boolean isDynamicAndroidInstalled() { - return mDynAndroid.isInstalled(); + private boolean isDynamicSystemInstalled() { + return mDynSystem.isInstalled(); } void handleMessage(Message msg) { switch (msg.what) { - case DynamicAndroidClient.MSG_REGISTER_LISTENER: + case DynamicSystemClient.MSG_REGISTER_LISTENER: try { Messenger client = msg.replyTo; @@ -505,7 +505,7 @@ public class DynamicAndroidInstallationService extends Service } break; - case DynamicAndroidClient.MSG_UNREGISTER_LISTENER: + case DynamicSystemClient.MSG_UNREGISTER_LISTENER: mClients.remove(msg.replyTo); break; default: diff --git a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java index 03fc7739fcce..052fc0a109b3 100644 --- a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java +++ b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package com.android.dynandroid; +package com.android.dynsystem; import android.gsi.GsiProgress; import android.os.AsyncTask; -import android.os.DynamicAndroidManager; +import android.os.image.DynamicSystemManager; import android.util.Log; import android.webkit.URLUtil; @@ -60,9 +60,9 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Integer> { private final String mUrl; private final long mSystemSize; private final long mUserdataSize; - private final DynamicAndroidManager mDynamicAndroid; + private final DynamicSystemManager mDynSystem; private final InstallStatusListener mListener; - private DynamicAndroidManager.Session mInstallationSession; + private DynamicSystemManager.Session mInstallationSession; private int mResult = NO_RESULT; @@ -70,11 +70,11 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Integer> { InstallationAsyncTask(String url, long systemSize, long userdataSize, - DynamicAndroidManager dynAndroid, InstallStatusListener listener) { + DynamicSystemManager dynSystem, InstallStatusListener listener) { mUrl = url; mSystemSize = systemSize; mUserdataSize = userdataSize; - mDynamicAndroid = dynAndroid; + mDynSystem = dynSystem; mListener = listener; } @@ -98,7 +98,7 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Integer> { Thread thread = new Thread(() -> { mInstallationSession = - mDynamicAndroid.startInstallation(mSystemSize, mUserdataSize); + mDynSystem.startInstallation(mSystemSize, mUserdataSize); }); @@ -106,12 +106,12 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Integer> { while (thread.isAlive()) { if (isCancelled()) { - boolean aborted = mDynamicAndroid.abort(); - Log.d(TAG, "Called DynamicAndroidManager.abort(), result = " + aborted); + boolean aborted = mDynSystem.abort(); + Log.d(TAG, "Called DynamicSystemManager.abort(), result = " + aborted); return RESULT_OK; } - GsiProgress progress = mDynamicAndroid.getInstallationProgress(); + GsiProgress progress = mDynSystem.getInstallationProgress(); installedSize = progress.bytes_processed; if (installedSize > reportedInstalledSize + minStepToReport) { @@ -146,7 +146,7 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Integer> { ? bytes : Arrays.copyOf(bytes, numBytesRead); if (!mInstallationSession.write(writeBuffer)) { - throw new IOException("Failed write() to DynamicAndroid"); + throw new IOException("Failed write() to DynamicSystem"); } installedSize += numBytesRead; diff --git a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/VerificationActivity.java b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/VerificationActivity.java index c18c4fe689c9..f05930f8ec07 100644 --- a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/VerificationActivity.java +++ b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/VerificationActivity.java @@ -14,19 +14,19 @@ * limitations under the License. */ -package com.android.dynandroid; +package com.android.dynsystem; -import static android.content.DynamicAndroidClient.KEY_SYSTEM_SIZE; -import static android.content.DynamicAndroidClient.KEY_SYSTEM_URL; -import static android.content.DynamicAndroidClient.KEY_USERDATA_SIZE; +import static android.os.image.DynamicSystemClient.KEY_SYSTEM_SIZE; +import static android.os.image.DynamicSystemClient.KEY_SYSTEM_URL; +import static android.os.image.DynamicSystemClient.KEY_USERDATA_SIZE; import android.app.Activity; import android.app.KeyguardManager; import android.content.Context; -import android.content.DynamicAndroidClient; import android.content.Intent; import android.os.Bundle; import android.os.UserHandle; +import android.os.image.DynamicSystemClient; import android.util.Log; @@ -88,8 +88,8 @@ public class VerificationActivity extends Activity { sVerifiedUrl = url; // start service - Intent intent = new Intent(this, DynamicAndroidInstallationService.class); - intent.setAction(DynamicAndroidClient.ACTION_START_INSTALL); + Intent intent = new Intent(this, DynamicSystemInstallationService.class); + intent.setAction(DynamicSystemClient.ACTION_START_INSTALL); intent.putExtra(KEY_SYSTEM_URL, url); intent.putExtra(KEY_SYSTEM_SIZE, systemSize); intent.putExtra(KEY_USERDATA_SIZE, userdataSize); diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/AssistantTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/AssistantTest.java index 459cd407a586..ee29bc594801 100644 --- a/packages/ExtServices/tests/src/android/ext/services/notification/AssistantTest.java +++ b/packages/ExtServices/tests/src/android/ext/services/notification/AssistantTest.java @@ -182,7 +182,7 @@ public class AssistantTest extends ServiceTestCase<Assistant> { mAssistant.setFakeRanking(generateRanking(sbn, P1C1)); mAssistant.onNotificationPosted(sbn, mock(RankingMap.class)); - verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any()); + verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any()); } @Test @@ -195,7 +195,7 @@ public class AssistantTest extends ServiceTestCase<Assistant> { mAssistant.onNotificationPosted(sbn, mock(RankingMap.class)); ArgumentCaptor<Adjustment> captor = ArgumentCaptor.forClass(Adjustment.class); - verify(mNoMan, times(1)).applyAdjustmentFromAssistant(any(), captor.capture()); + verify(mNoMan, times(1)).applyEnqueuedAdjustmentFromAssistant(any(), captor.capture()); assertEquals(sbn.getKey(), captor.getValue().getKey()); assertEquals(Ranking.USER_SENTIMENT_NEGATIVE, captor.getValue().getSignals().getInt(Adjustment.KEY_USER_SENTIMENT)); @@ -210,7 +210,7 @@ public class AssistantTest extends ServiceTestCase<Assistant> { mAssistant.setFakeRanking(generateRanking(sbn, P1C3)); mAssistant.onNotificationPosted(sbn, mock(RankingMap.class)); - verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any()); + verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any()); } @Test @@ -230,7 +230,7 @@ public class AssistantTest extends ServiceTestCase<Assistant> { mAssistant.onNotificationPosted(sbn, mock(RankingMap.class)); ArgumentCaptor<Adjustment> captor = ArgumentCaptor.forClass(Adjustment.class); - verify(mNoMan, times(1)).applyAdjustmentFromAssistant(any(), captor.capture()); + verify(mNoMan, times(1)).applyEnqueuedAdjustmentFromAssistant(any(), captor.capture()); assertEquals(sbn.getKey(), captor.getValue().getKey()); assertEquals(Ranking.USER_SENTIMENT_NEGATIVE, captor.getValue().getSignals().getInt(Adjustment.KEY_USER_SENTIMENT)); @@ -253,7 +253,7 @@ public class AssistantTest extends ServiceTestCase<Assistant> { sbn = generateSbn(PKG1, UID1, P1C1, "new one!", "group"); mAssistant.onNotificationPosted(sbn, mock(RankingMap.class)); - verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any()); + verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any()); } @Test @@ -272,7 +272,7 @@ public class AssistantTest extends ServiceTestCase<Assistant> { sbn = generateSbn(PKG1, UID1, P1C1, "new one!", null); mAssistant.onNotificationPosted(sbn, mock(RankingMap.class)); - verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any()); + verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any()); } @Test @@ -291,7 +291,7 @@ public class AssistantTest extends ServiceTestCase<Assistant> { sbn = generateSbn(PKG1, UID1, P1C1, "new one!", null); mAssistant.onNotificationPosted(sbn, mock(RankingMap.class)); - verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any()); + verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any()); } @Test @@ -310,7 +310,7 @@ public class AssistantTest extends ServiceTestCase<Assistant> { sbn = generateSbn(PKG1, UID1, P1C1, "new one!", null); mAssistant.onNotificationPosted(sbn, mock(RankingMap.class)); - verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any()); + verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any()); } @Test @@ -322,7 +322,7 @@ public class AssistantTest extends ServiceTestCase<Assistant> { mAssistant.setFakeRanking(generateRanking(sbn, P2C1)); mAssistant.onNotificationPosted(sbn, mock(RankingMap.class)); - verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any()); + verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any()); } @Test @@ -334,7 +334,7 @@ public class AssistantTest extends ServiceTestCase<Assistant> { mAssistant.setFakeRanking(generateRanking(sbn, P1C2)); mAssistant.onNotificationPosted(sbn, mock(RankingMap.class)); - verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any()); + verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any()); } @Test diff --git a/packages/NetworkStack/Android.bp b/packages/NetworkStack/Android.bp index 8872147b65ed..52534a8fbae7 100644 --- a/packages/NetworkStack/Android.bp +++ b/packages/NetworkStack/Android.bp @@ -14,11 +14,16 @@ // limitations under the License. // +java_defaults { + name: "NetworkStackCommon", + sdk_version: "system_current", + min_sdk_version: "28", +} + // Library including the network stack, used to compile both variants of the network stack android_library { name: "NetworkStackBase", - sdk_version: "system_current", - min_sdk_version: "28", + defaults: ["NetworkStackCommon"], srcs: [ "src/**/*.java", ":framework-networkstack-shared-srcs", @@ -29,38 +34,37 @@ android_library { "netd_aidl_interface-java", "networkstack-aidl-interfaces-java", "datastallprotosnano", + "networkstackprotosnano", ], manifest: "AndroidManifestBase.xml", } -// Non-updatable in-process network stack for devices not using the module -android_app { - name: "InProcessNetworkStack", - sdk_version: "system_current", - min_sdk_version: "28", - certificate: "platform", +java_defaults { + name: "NetworkStackAppCommon", + defaults: ["NetworkStackCommon"], privileged: true, static_libs: [ "NetworkStackBase", ], + // Resources already included in NetworkStackBase + resource_dirs: [], jarjar_rules: "jarjar-rules-shared.txt", // The permission configuration *must* be included to ensure security of the device required: ["NetworkStackPermissionStub"], +} + +// Non-updatable network stack running in the system server process for devices not using the module +android_app { + name: "InProcessNetworkStack", + defaults: ["NetworkStackAppCommon"], + certificate: "platform", manifest: "AndroidManifest_InProcess.xml", } // Updatable network stack packaged as an application android_app { name: "NetworkStack", - sdk_version: "system_current", - min_sdk_version: "28", + defaults: ["NetworkStackAppCommon"], certificate: "networkstack", - privileged: true, - static_libs: [ - "NetworkStackBase" - ], - jarjar_rules: "jarjar-rules-shared.txt", - // The permission configuration *must* be included to ensure security of the device - required: ["NetworkStackPermissionStub"], manifest: "AndroidManifest.xml", } diff --git a/packages/NetworkStack/AndroidManifest.xml b/packages/NetworkStack/AndroidManifest.xml index a90db11df016..b0a7923d65f4 100644 --- a/packages/NetworkStack/AndroidManifest.xml +++ b/packages/NetworkStack/AndroidManifest.xml @@ -19,6 +19,7 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.networkstack" android:sharedUserId="android.uid.networkstack"> + <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" /> <!-- Signature permission defined in NetworkStackStub --> <uses-permission android:name="android.permission.MAINLINE_NETWORK_STACK" /> <application> @@ -28,4 +29,4 @@ </intent-filter> </service> </application> -</manifest>
\ No newline at end of file +</manifest> diff --git a/packages/NetworkStack/AndroidManifestBase.xml b/packages/NetworkStack/AndroidManifestBase.xml index 621d30c31f98..f69e4b2bb795 100644 --- a/packages/NetworkStack/AndroidManifestBase.xml +++ b/packages/NetworkStack/AndroidManifestBase.xml @@ -20,7 +20,6 @@ package="com.android.networkstack" android:versionCode="11" android:versionName="Q-initial"> - <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> diff --git a/packages/NetworkStack/AndroidManifest_InProcess.xml b/packages/NetworkStack/AndroidManifest_InProcess.xml index 48fcecd2f06d..275cd02a6cc0 100644 --- a/packages/NetworkStack/AndroidManifest_InProcess.xml +++ b/packages/NetworkStack/AndroidManifest_InProcess.xml @@ -20,6 +20,7 @@ package="com.android.networkstack.inprocess" android:sharedUserId="android.uid.system" android:process="system"> + <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" /> <application> <service android:name="com.android.server.NetworkStackService" android:process="system"> <intent-filter> @@ -27,4 +28,4 @@ </intent-filter> </service> </application> -</manifest>
\ No newline at end of file +</manifest> diff --git a/packages/NetworkStack/res/values/config.xml b/packages/NetworkStack/res/values/config.xml new file mode 100644 index 000000000000..52425e57ba3a --- /dev/null +++ b/packages/NetworkStack/res/values/config.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <!-- Captive portal http url --> + <string name="config_captive_portal_http_url" translatable="false">http://connectivitycheck.gstatic.com/generate_204</string> +</resources>
\ No newline at end of file diff --git a/packages/NetworkStack/src/android/net/ip/IpClient.java b/packages/NetworkStack/src/android/net/ip/IpClient.java index 61dc966076a8..346ac68407de 100644 --- a/packages/NetworkStack/src/android/net/ip/IpClient.java +++ b/packages/NetworkStack/src/android/net/ip/IpClient.java @@ -897,7 +897,7 @@ public class IpClient extends StateMachine { // accompanying code in IpReachabilityMonitor) is unreachable. final boolean ignoreIPv6ProvisioningLoss = mConfiguration != null && mConfiguration.mUsingMultinetworkPolicyTracker - && mCm.getAvoidBadWifi(); + && mCm.shouldAvoidBadWifi(); // Additionally: // diff --git a/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java b/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java index e73cba626f15..3aa6933fe8f2 100644 --- a/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java +++ b/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java @@ -332,7 +332,7 @@ public class IpReachabilityMonitor { } private boolean avoidingBadLinks() { - return !mUsingMultinetworkPolicyTracker || mCm.getAvoidBadWifi(); + return !mUsingMultinetworkPolicyTracker || mCm.shouldAvoidBadWifi(); } public void probeAll() { diff --git a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java index 73b203c3df49..f3476ed1566f 100644 --- a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java +++ b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java @@ -83,6 +83,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.RingBufferIndices; import com.android.internal.util.State; import com.android.internal.util.StateMachine; +import com.android.networkstack.R; import java.io.IOException; import java.net.HttpURLConnection; @@ -1710,9 +1711,15 @@ public class NetworkMonitor extends StateMachine { /** * Get the captive portal server HTTP URL that is configured on the device. + * + * NetworkMonitor does not use {@link ConnectivityManager#getCaptivePortalServerUrl()} as + * it has its own updatable strategies to detect captive portals. The framework only advises + * on one URL that can be used, while NetworkMonitor may implement more complex logic. */ public String getCaptivePortalServerHttpUrl(Context context) { - return NetworkMonitorUtils.getCaptivePortalServerHttpUrl(context); + final String defaultUrl = + context.getResources().getString(R.string.config_captive_portal_http_url); + return NetworkMonitorUtils.getCaptivePortalServerHttpUrl(context, defaultUrl); } /** diff --git a/packages/PackageInstaller/AndroidManifest.xml b/packages/PackageInstaller/AndroidManifest.xml index a69b41258974..62535b635e44 100644 --- a/packages/PackageInstaller/AndroidManifest.xml +++ b/packages/PackageInstaller/AndroidManifest.xml @@ -15,7 +15,6 @@ <uses-permission android:name="android.permission.MANAGE_APP_OPS_MODES" /> <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" /> <uses-permission android:name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME" /> - <uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" /> <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" /> <uses-permission android:name="com.google.android.permission.INSTALL_WEARABLE_PACKAGES" /> diff --git a/packages/PackageInstaller/res/layout/uninstall_content_view.xml b/packages/PackageInstaller/res/layout/uninstall_content_view.xml index 2f8966c0461b..5666c0e44e0b 100644 --- a/packages/PackageInstaller/res/layout/uninstall_content_view.xml +++ b/packages/PackageInstaller/res/layout/uninstall_content_view.xml @@ -36,16 +36,6 @@ style="@android:style/TextAppearance.Material.Subhead" /> <CheckBox - android:id="@+id/clearContributedFiles" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="8dp" - android:layout_marginStart="-8dp" - android:paddingLeft="8sp" - android:visibility="gone" - style="@android:style/TextAppearance.Material.Subhead" /> - - <CheckBox android:id="@+id/keepData" android:layout_width="wrap_content" android:layout_height="wrap_content" diff --git a/packages/PackageInstaller/res/values-ar/strings.xml b/packages/PackageInstaller/res/values-ar/strings.xml index edbd1782092c..389639cbd665 100644 --- a/packages/PackageInstaller/res/values-ar/strings.xml +++ b/packages/PackageInstaller/res/values-ar/strings.xml @@ -58,7 +58,6 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"هل تريد إزالة هذا التطبيق للمستخدم <xliff:g id="USERNAME">%1$s</xliff:g>؟"</string> <string name="uninstall_update_text" msgid="863648314632448705">"هل تريد استبدال هذا التطبيق بإصدار المصنع؟ ستتم إزالة جميع البيانات."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"هل تريد استبدال هذا التطبيق بإصدار المصنع؟ ستتم إزالة جميع البيانات. وسيؤثر هذا في جميع مستخدمي هذا الجهاز، بما في ذلك من لديهم ملفات شخصية للعمل."</string> - <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"إزالة <xliff:g id="SIZE">%1$s</xliff:g> من ملفات الوسائط المرتبطة أيضًا."</string> <string name="uninstall_keep_data" msgid="7002379587465487550">"الاحتفاظ بالحجم <xliff:g id="SIZE">%1$s</xliff:g> من بيانات التطبيق."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"عمليات إلغاء التثبيت الجارية"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"عمليات إلغاء التثبيت غير الناجحة"</string> diff --git a/packages/PackageInstaller/res/values-ca/strings.xml b/packages/PackageInstaller/res/values-ca/strings.xml index 6c081619f03c..1490d4841272 100644 --- a/packages/PackageInstaller/res/values-ca/strings.xml +++ b/packages/PackageInstaller/res/values-ca/strings.xml @@ -58,7 +58,6 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Vols desinstal·lar aquesta aplicació per a l\'usuari <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Vols substituir aquesta aplicació per la versió de fàbrica? Se suprimiran totes les dades."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Vols substituir aquesta aplicació per la versió de fàbrica? Se suprimiran totes les dades. Això afectarà tots els usuaris d\'aquest dispositiu, inclosos els que tinguin un perfil professional."</string> - <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Suprimeix també <xliff:g id="SIZE">%1$s</xliff:g> de fitxers multimèdia associats."</string> <string name="uninstall_keep_data" msgid="7002379587465487550">"Conserva <xliff:g id="SIZE">%1$s</xliff:g> de dades de l\'aplicació."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Desinstal·lacions en curs"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Desinstal·lacions fallides"</string> diff --git a/packages/PackageInstaller/res/values-de/strings.xml b/packages/PackageInstaller/res/values-de/strings.xml index 4ad9b7387898..3958b7491464 100644 --- a/packages/PackageInstaller/res/values-de/strings.xml +++ b/packages/PackageInstaller/res/values-de/strings.xml @@ -58,7 +58,6 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Möchtest du diese App für den Nutzer <xliff:g id="USERNAME">%1$s</xliff:g> deinstallieren?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Diese App durch die Werksversion ersetzen? Alle Daten werden entfernt."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Diese App durch die Werksversion ersetzen? Alle Daten werden entfernt. Dies betrifft alle Nutzer des Geräts, einschließlich Arbeitsprofilen."</string> - <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Auch <xliff:g id="SIZE">%1$s</xliff:g> der verknüpften Mediendateien entfernen."</string> <string name="uninstall_keep_data" msgid="7002379587465487550">"<xliff:g id="SIZE">%1$s</xliff:g> an App-Daten behalten."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Laufende Deinstallationen"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Fehlgeschlagene Deinstallationen"</string> diff --git a/packages/PackageInstaller/res/values-es/strings.xml b/packages/PackageInstaller/res/values-es/strings.xml index 72351d6f494e..592aa7429d76 100644 --- a/packages/PackageInstaller/res/values-es/strings.xml +++ b/packages/PackageInstaller/res/values-es/strings.xml @@ -58,7 +58,6 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"¿Quieres desinstalar esta aplicación para el usuario <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"¿Quieres sustituir esta aplicación con la versión de fábrica? Ten en cuenta que se borrarán todos los datos."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"¿Quieres sustituir esta aplicación con la versión de fábrica? Ten en cuenta que se borrarán todos los datos. Esto afecta a todos los usuarios del dispositivo, incluidos los que tienen perfiles de trabajo."</string> - <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Eliminar también <xliff:g id="SIZE">%1$s</xliff:g> de archivos multimedia asociados."</string> <string name="uninstall_keep_data" msgid="7002379587465487550">"Mantener <xliff:g id="SIZE">%1$s</xliff:g> de datos de aplicaciones."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Desinstalaciones en curso"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Desinstalaciones fallidas"</string> diff --git a/packages/PackageInstaller/res/values-eu/strings.xml b/packages/PackageInstaller/res/values-eu/strings.xml index 30a366592fb4..9c23097b7f23 100644 --- a/packages/PackageInstaller/res/values-eu/strings.xml +++ b/packages/PackageInstaller/res/values-eu/strings.xml @@ -58,8 +58,7 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"<xliff:g id="USERNAME">%1$s</xliff:g> erabiltzaileari desinstalatu nahi diozu aplikazioa?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Aplikazio hau jatorrizko bertsioarekin ordeztu nahi duzu? Datu guztiak ezabatuko dira."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Aplikazio hau jatorrizko bertsioarekin ordeztu nahi duzu? Datu guztiak ezabatuko dira. Gailuaren erabiltzaile guztiengan izango du eragina, laneko profilak dituztenak barne."</string> - <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Halaber, kendu erlazionatutako multimedia-fitxategiak (<xliff:g id="SIZE">%1$s</xliff:g>)."</string> - <string name="uninstall_keep_data" msgid="7002379587465487550">"Mantendu aplikazio-datuen <xliff:g id="SIZE">%1$s</xliff:g>."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Mantendu aplikazioetako datuen <xliff:g id="SIZE">%1$s</xliff:g>."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Abian diren desinstalatze-eragiketak"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Desinstalatu ezin izan direnak"</string> <string name="uninstalling" msgid="8709566347688966845">"Desinstalatzen…"</string> diff --git a/packages/PackageInstaller/res/values-fr-rCA/strings.xml b/packages/PackageInstaller/res/values-fr-rCA/strings.xml index 78c04b3eb164..df550435dc4e 100644 --- a/packages/PackageInstaller/res/values-fr-rCA/strings.xml +++ b/packages/PackageInstaller/res/values-fr-rCA/strings.xml @@ -58,7 +58,6 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Voulez-vous désinstaller cette application pour l\'utilisateur <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Remplacer cette application par la version d\'usine? Toutes les données seront supprimées."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Remplacer cette application par la version d\'usine? Toutes les données seront supprimées. Cela touchera tous les utilisateurs de cet appareil, y compris ceux qui utilisent un profil professionnel."</string> - <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Aussi supprimer <xliff:g id="SIZE">%1$s</xliff:g> de fichiers médias connexes."</string> <string name="uninstall_keep_data" msgid="7002379587465487550">"Garder <xliff:g id="SIZE">%1$s</xliff:g> de données d\'application."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Désinstallations en cours…"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Désinstallations échouées"</string> diff --git a/packages/PackageInstaller/res/values-fr/strings.xml b/packages/PackageInstaller/res/values-fr/strings.xml index 7d69edf335e5..c90cc6d4a224 100644 --- a/packages/PackageInstaller/res/values-fr/strings.xml +++ b/packages/PackageInstaller/res/values-fr/strings.xml @@ -58,7 +58,6 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Voulez-vous désinstaller cette application pour l\'utilisateur <xliff:g id="USERNAME">%1$s</xliff:g> ?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Remplacer cette application par la version d\'usine ? Toutes les données seront supprimées."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Remplacer cette application par la version d\'usine ? Toutes les données seront supprimées. Tous les utilisateurs de cet appareil seront affectés, y compris ceux qui ont un profil professionnel."</string> - <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Supprimer également <xliff:g id="SIZE">%1$s</xliff:g> de fichiers multimédias associés."</string> <string name="uninstall_keep_data" msgid="7002379587465487550">"Conserver <xliff:g id="SIZE">%1$s</xliff:g> de données d\'application."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Désinstallations en cours"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Échec des désinstallations"</string> diff --git a/packages/PackageInstaller/res/values-hy/strings.xml b/packages/PackageInstaller/res/values-hy/strings.xml index da1bf3cd16cb..c7418f944a5c 100644 --- a/packages/PackageInstaller/res/values-hy/strings.xml +++ b/packages/PackageInstaller/res/values-hy/strings.xml @@ -58,7 +58,6 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Ապատեղադրե՞լ այս հավելվածը <xliff:g id="USERNAME">%1$s</xliff:g> օգտատիրոջ համար:"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Փոխարինե՞լ այս հավելվածը գործարանային տարբերակով: Բոլոր տվյալները կհեռացվեն:"</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Փոխարինե՞լ այս հավելվածը գործարանային տարբերակով: Բոլոր տվյալները կհեռացվեն: Դա վերաբերում է այս սարքի բոլոր օգտատերերին, այդ թվում նաև աշխատանքային պրոֆիլներ ունեցողներին:"</string> - <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Նաև հեռացնել առնչվող մեդիա ֆայլերը (<xliff:g id="SIZE">%1$s</xliff:g>)"</string> <string name="uninstall_keep_data" msgid="7002379587465487550">"Չհեռացնել հավելվածների տվյալները (<xliff:g id="SIZE">%1$s</xliff:g>):"</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Ընթացիկ ապատեղադրումներ"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Ձախողված ապատեղադրումներ"</string> diff --git a/packages/PackageInstaller/res/values-kk/strings.xml b/packages/PackageInstaller/res/values-kk/strings.xml index cecc482c8a27..8253d5eb253d 100644 --- a/packages/PackageInstaller/res/values-kk/strings.xml +++ b/packages/PackageInstaller/res/values-kk/strings.xml @@ -58,7 +58,6 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"<xliff:g id="USERNAME">%1$s</xliff:g> үшін осы қолданба жойылсын ба?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Осы қолданбаны зауыттық нұсқамен ауыстыру керек пе? Барлық деректер жойылады."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Осы қолданбаны зауыттық нұсқамен ауыстыру керек пе? Барлық деректер жойылады. Бұл осы құрылғының барлық пайдаланушыларына, соның ішінде жұмыс профильдері бар пайдаланушыларға әсер етеді."</string> - <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Байланыстырылған <xliff:g id="SIZE">%1$s</xliff:g> медиа файлдар да өшірілсін."</string> <string name="uninstall_keep_data" msgid="7002379587465487550">"Қолданба деректерін (<xliff:g id="SIZE">%1$s</xliff:g>) сақтау."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Орындалып жатқан жою процестері"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Сәтсіз жою әрекеттері"</string> diff --git a/packages/PackageInstaller/res/values-kn/strings.xml b/packages/PackageInstaller/res/values-kn/strings.xml index d78d3687f7a9..fdefb4c36462 100644 --- a/packages/PackageInstaller/res/values-kn/strings.xml +++ b/packages/PackageInstaller/res/values-kn/strings.xml @@ -58,7 +58,6 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"<xliff:g id="USERNAME">%1$s</xliff:g> ಬಳಕೆದಾರರಿಗೆ ಈ ಆ್ಯಪ್ ಅನ್ನು ಅನ್ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲು ನೀವು ಬಯಸುವಿರಾ?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"ಈ ಆ್ಯಪ್ ಬದಲಿಗೆ ಫ್ಯಾಕ್ಟರಿ ಆವೃತ್ತಿಯನ್ನು ಬದಲಾಯಿಸುವುದೇ? ಎಲ್ಲಾ ಡೇಟಾ ತೆಗೆದುಹಾಕಲಾಗುತ್ತದೆ."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"ಈ ಆ್ಯಪ್ ಬದಲಿಗೆ ಫ್ಯಾಕ್ಟರಿ ಆವೃತ್ತಿಯನ್ನು ಬದಲಾಯಿಸುವುದೇ? ಎಲ್ಲಾ ಡೇಟಾ ತೆಗೆದುಹಾಕಲಾಗುತ್ತದೆ. ಕೆಲಸದ ಪ್ರೊಫೈಲ್ಗಳನ್ನು ಹೊಂದಿರುವವುಗಳನ್ನು ಒಳಗೊಂಡಂತೆ ಈ ಸಾಧನದ ಎಲ್ಲಾ ಬಳಕೆದಾರರಿಗೆ ಇದು ಪರಿಣಾಮ ಬೀರುತ್ತದೆ."</string> - <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"ಸಂಯೋಜಿತ ಮಾಧ್ಯಮ ಫೈಲ್ಗಳ <xliff:g id="SIZE">%1$s</xliff:g> ಗಾತ್ರವನ್ನು ಕೂಡ ತೆಗೆದುಹಾಕಿ"</string> <string name="uninstall_keep_data" msgid="7002379587465487550">"ಆ್ಯಪ್ ಡೇಟಾದಲ್ಲಿ <xliff:g id="SIZE">%1$s</xliff:g> ಇರಿಸಿಕೊಳ್ಳಿ."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"ಚಾಲನೆಯಲ್ಲಿರುವ ಅನ್ಇನ್ಸ್ಟಾಲ್ಗಳು"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"ವಿಫಲಗೊಂಡ ಅನ್ಇನ್ಸ್ಟಾಲ್ಗಳು"</string> diff --git a/packages/PackageInstaller/res/values-mr/strings.xml b/packages/PackageInstaller/res/values-mr/strings.xml index 4deab35c4b3e..200c99381bcd 100644 --- a/packages/PackageInstaller/res/values-mr/strings.xml +++ b/packages/PackageInstaller/res/values-mr/strings.xml @@ -58,7 +58,6 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"तुम्हाला <xliff:g id="USERNAME">%1$s</xliff:g> वापरकर्त्यासाठी हे अॅप अनइंस्टॉल करायचे आहे का?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"फॅक्टरी आवृत्तीसह हे अॅप बदलायचे का? सर्व डेटा काढला जाईल."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"फॅक्टरी आवृत्तीसह हे अॅप बदलायचे? सर्व डेटा काढला जाईल. हे कार्य प्रोफाइल असलेल्यांसह या डिव्हाइसच्या सर्व वापरकर्त्यांना प्रभावित करते."</string> - <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"<xliff:g id="SIZE">%1$s</xliff:g> आकाराच्या संबंधित मीडिया फायलीदेखील काढा."</string> <string name="uninstall_keep_data" msgid="7002379587465487550">"ॲप डेटा पैकी <xliff:g id="SIZE">%1$s</xliff:g> ठेवा."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"अनइंस्टॉल रन होत आहेत"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"अनइंस्टॉल करता आले नाही"</string> diff --git a/packages/PackageInstaller/res/values-pt-rPT/strings.xml b/packages/PackageInstaller/res/values-pt-rPT/strings.xml index 903db3e3ddd2..252e903e9a17 100644 --- a/packages/PackageInstaller/res/values-pt-rPT/strings.xml +++ b/packages/PackageInstaller/res/values-pt-rPT/strings.xml @@ -58,7 +58,6 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Pretende desinstalar esta aplicação para o utilizador <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Pretende substituir esta aplicação pela versão de fábrica? Todos os dados são removidos."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Pretende substituir esta aplicação pela versão de fábrica? Todos os dados são removidos. Esta ação afeta todos os utilizadores deste dispositivo, incluindo os que têm perfis de trabalho."</string> - <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Remover também <xliff:g id="SIZE">%1$s</xliff:g> de ficheiros multimédia associados."</string> <string name="uninstall_keep_data" msgid="7002379587465487550">"Manter <xliff:g id="SIZE">%1$s</xliff:g> de dados da aplicação."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Desinstalações em execução"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Desinstalações com falha"</string> diff --git a/packages/PackageInstaller/res/values-sk/strings.xml b/packages/PackageInstaller/res/values-sk/strings.xml index 509dac5ed0b2..2fbecf58f140 100644 --- a/packages/PackageInstaller/res/values-sk/strings.xml +++ b/packages/PackageInstaller/res/values-sk/strings.xml @@ -58,7 +58,6 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Chcete túto aplikáciu odinštalovať pre používateľa <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Nahradiť túto aplikáciu výrobnou verziou? Všetky údaje sa odstránia."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Nahradiť túto aplikáciu výrobnou verziou? Všetky údaje sa odstránia. Ovplyvní to všetkých používateľov tohto zariadenia vrátane tých s pracovnými profilmi."</string> - <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Odstrániť tiež <xliff:g id="SIZE">%1$s</xliff:g> prepojených súborov médií."</string> <string name="uninstall_keep_data" msgid="7002379587465487550">"Zachovať nasledujúcu veľkosť dát aplikácie: <xliff:g id="SIZE">%1$s</xliff:g>."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Prebiehajúce odinštalovania"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Neúspešné odinštalácie"</string> diff --git a/packages/PackageInstaller/res/values-ta/strings.xml b/packages/PackageInstaller/res/values-ta/strings.xml index b69ce166f86d..afa2e9c33bd3 100644 --- a/packages/PackageInstaller/res/values-ta/strings.xml +++ b/packages/PackageInstaller/res/values-ta/strings.xml @@ -58,7 +58,6 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"<xliff:g id="USERNAME">%1$s</xliff:g> என்ற பயனருக்கு இந்த ஆப்ஸை நிறுவல் நீக்க விரும்புகிறீர்களா?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"ஆரம்பநிலைப் பதிப்புக்கு இந்த ஆப்ஸை மாற்றியமைக்கவா? அனைத்துத் தரவும் அகற்றப்படும்."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"ஆரம்பநிலைப் பதிப்புக்கு இந்த ஆப்ஸை மாற்றியமைக்கவா? அனைத்துத் தரவும் அகற்றப்படும். பணிக் கணக்குகளுடன் உள்ளவர்கள் உட்பட இந்தச் சாதனத்தின் அனைத்துப் பயனர்களையும் இது பாதிக்கும்."</string> - <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"இதனுடன் தொடர்புடைய <xliff:g id="SIZE">%1$s</xliff:g> மீடியா ஃபைல்களையும் அகற்று."</string> <string name="uninstall_keep_data" msgid="7002379587465487550">"<xliff:g id="SIZE">%1$s</xliff:g> ஆப்ஸ் தரவை வைத்திரு."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"இயக்கத்திலுள்ள நிறுவல் நீக்கங்கள்"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"தோல்வியுற்ற நிறுவல் நீக்கங்கள்"</string> diff --git a/packages/PackageInstaller/res/values-vi/strings.xml b/packages/PackageInstaller/res/values-vi/strings.xml index 84c02e2da658..7dd5cd9f0c5a 100644 --- a/packages/PackageInstaller/res/values-vi/strings.xml +++ b/packages/PackageInstaller/res/values-vi/strings.xml @@ -58,7 +58,6 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Bạn có muốn gỡ cài đặt ứng dụng này cho người dùng <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Thay thế ứng dụng này bằng phiên bản gốc? Tất cả dữ liệu sẽ bị xóa."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Thay thế ứng dụng này bằng phiên bản gốc? Tất cả dữ liệu sẽ bị xóa. Điều này ảnh hưởng đến tất cả người dùng thiết bị này, bao gồm cả những người có hồ sơ công việc."</string> - <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Đồng thời xóa <xliff:g id="SIZE">%1$s</xliff:g> tệp đa phương tiện liên kết."</string> <string name="uninstall_keep_data" msgid="7002379587465487550">"Giữ lại <xliff:g id="SIZE">%1$s</xliff:g> dữ liệu ứng dụng."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Các quá trình gỡ cài đặt đang chạy"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Gỡ cài đặt không thành công"</string> diff --git a/packages/PackageInstaller/res/values/strings.xml b/packages/PackageInstaller/res/values/strings.xml index a05a219b917b..797656ef62f4 100644 --- a/packages/PackageInstaller/res/values/strings.xml +++ b/packages/PackageInstaller/res/values/strings.xml @@ -119,8 +119,6 @@ <string name="uninstall_update_text">Replace this app with the factory version? All data will be removed.</string> <!-- [CHAR LIMIT=none] --> <string name="uninstall_update_text_multiuser">Replace this app with the factory version? All data will be removed. This affects all users of this device, including those with work profiles.</string> - <!-- Label of a checkbox that allows to remove the files contributed by app during uninstall [CHAR LIMIT=none] --> - <string name="uninstall_remove_contributed_files">Also remove <xliff:g id="size" example="1.5MB">%1$s</xliff:g> of associated media files.</string> <!-- Label of a checkbox that allows to keep the data (e.g. files, settings) of the app on uninstall [CHAR LIMIT=none] --> <string name="uninstall_keep_data">Keep <xliff:g id="size" example="1.5MB">%1$s</xliff:g> of app data.</string> diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallUninstalling.java b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallUninstalling.java index 63d8c5a82519..c4dceb4fe079 100644 --- a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallUninstalling.java +++ b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallUninstalling.java @@ -50,8 +50,6 @@ public class UninstallUninstalling extends Activity implements "com.android.packageinstaller.ACTION_UNINSTALL_COMMIT"; static final String EXTRA_APP_LABEL = "com.android.packageinstaller.extra.APP_LABEL"; - static final String EXTRA_CLEAR_CONTRIBUTED_FILES = - "com.android.packageinstaller.extra.CLEAR_CONTRIBUTED_FILES"; static final String EXTRA_KEEP_DATA = "com.android.packageinstaller.extra.KEEP_DATA"; private int mUninstallId; @@ -75,8 +73,6 @@ public class UninstallUninstalling extends Activity implements if (savedInstanceState == null) { boolean allUsers = getIntent().getBooleanExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, false); - boolean clearContributedFiles = getIntent().getBooleanExtra( - EXTRA_CLEAR_CONTRIBUTED_FILES, false); boolean keepData = getIntent().getBooleanExtra(EXTRA_KEEP_DATA, false); UserHandle user = getIntent().getParcelableExtra(Intent.EXTRA_USER); @@ -102,7 +98,6 @@ public class UninstallUninstalling extends Activity implements broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT); int flags = allUsers ? PackageManager.DELETE_ALL_USERS : 0; - flags |= clearContributedFiles ? PackageManager.DELETE_CONTRIBUTED_MEDIA : 0; flags |= keepData ? PackageManager.DELETE_KEEP_DATA : 0; try { diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java index 54194491d140..be778e92787e 100755 --- a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java +++ b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java @@ -285,7 +285,7 @@ public class UninstallerActivity extends Activity { fragment.show(ft, "dialog"); } - public void startUninstallProgress(boolean clearContributedFiles, boolean keepData) { + public void startUninstallProgress(boolean keepData) { boolean returnResult = getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false); CharSequence label = mDialogInfo.appInfo.loadSafeLabel(getPackageManager()); @@ -310,8 +310,6 @@ public class UninstallerActivity extends Activity { newIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, mDialogInfo.allUsers); newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO, mDialogInfo.appInfo); newIntent.putExtra(UninstallUninstalling.EXTRA_APP_LABEL, label); - newIntent.putExtra(UninstallUninstalling.EXTRA_CLEAR_CONTRIBUTED_FILES, - clearContributedFiles); newIntent.putExtra(UninstallUninstalling.EXTRA_KEEP_DATA, keepData); newIntent.putExtra(PackageInstaller.EXTRA_CALLBACK, mDialogInfo.callback); @@ -362,7 +360,6 @@ public class UninstallerActivity extends Activity { Log.i(TAG, "Uninstalling extras=" + broadcastIntent.getExtras()); int flags = mDialogInfo.allUsers ? PackageManager.DELETE_ALL_USERS : 0; - flags |= clearContributedFiles ? PackageManager.DELETE_CONTRIBUTED_MEDIA : 0; flags |= keepData ? PackageManager.DELETE_KEEP_DATA : 0; ActivityThread.getPackageManager().getPackageInstaller().uninstall( diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java index 499da758739e..0a37cc6cb6ca 100644 --- a/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java +++ b/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java @@ -36,7 +36,6 @@ import android.os.UserHandle; import android.os.UserManager; import android.os.storage.StorageManager; import android.os.storage.StorageVolume; -import android.provider.MediaStore; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -54,57 +53,9 @@ public class UninstallAlertDialogFragment extends DialogFragment implements DialogInterface.OnClickListener { private static final String LOG_TAG = UninstallAlertDialogFragment.class.getSimpleName(); - private @Nullable CheckBox mClearContributedFiles; private @Nullable CheckBox mKeepData; /** - * Get number of bytes of the files contributed by the package. - * - * @param pkg The package that might have contributed files. - * @param user The user the package belongs to. - * - * @return The number of bytes. - */ - private long getContributedMediaSizeForUser(@NonNull String pkg, @NonNull UserHandle user) { - try { - return MediaStore.getContributedMediaSize(getContext(), pkg, user); - } catch (IOException e) { - Log.e(LOG_TAG, "Cannot determine amount of contributes files for " + pkg - + " (user " + user + ")", e); - return 0; - } - } - - /** - * Get number of bytes of the files contributed by the package. - * - * @param pkg The package that might have contributed files. - * @param user The user the package belongs to or {@code null} if files of all users should be - * counted. - * - * @return The number of bytes. - */ - private long getContributedMediaSize(@NonNull String pkg, @Nullable UserHandle user) { - UserManager userManager = getContext().getSystemService(UserManager.class); - - long contributedFileSize = 0; - - if (user == null) { - List<UserInfo> users = userManager.getUsers(); - - int numUsers = users.size(); - for (int i = 0; i < numUsers; i++) { - contributedFileSize += getContributedMediaSizeForUser(pkg, - UserHandle.of(users.get(i).id)); - } - } else { - contributedFileSize = getContributedMediaSizeForUser(pkg, user); - } - - return contributedFileSize; - } - - /** * Get number of bytes of the app data of the package. * * @param pkg The package that might have app data. @@ -212,8 +163,6 @@ public class UninstallAlertDialogFragment extends DialogFragment implements dialogBuilder.setNegativeButton(android.R.string.cancel, this); String pkg = dialogInfo.appInfo.packageName; - long contributedFileSize = getContributedMediaSize(pkg, - dialogInfo.allUsers ? null : dialogInfo.user); boolean suggestToKeepAppData; try { @@ -230,28 +179,17 @@ public class UninstallAlertDialogFragment extends DialogFragment implements appDataSize = getAppDataSize(pkg, dialogInfo.allUsers ? null : dialogInfo.user); } - if (contributedFileSize == 0 && appDataSize == 0) { + if (appDataSize == 0) { dialogBuilder.setMessage(messageBuilder.toString()); } else { LayoutInflater inflater = getContext().getSystemService(LayoutInflater.class); ViewGroup content = (ViewGroup) inflater.inflate(R.layout.uninstall_content_view, null); ((TextView) content.requireViewById(R.id.message)).setText(messageBuilder.toString()); - - if (contributedFileSize != 0) { - mClearContributedFiles = content.requireViewById(R.id.clearContributedFiles); - mClearContributedFiles.setVisibility(View.VISIBLE); - mClearContributedFiles.setText( - getString(R.string.uninstall_remove_contributed_files, - formatFileSize(getContext(), contributedFileSize))); - } - - if (appDataSize != 0) { - mKeepData = content.requireViewById(R.id.keepData); - mKeepData.setVisibility(View.VISIBLE); - mKeepData.setText(getString(R.string.uninstall_keep_data, - formatFileSize(getContext(), appDataSize))); - } + mKeepData = content.requireViewById(R.id.keepData); + mKeepData.setVisibility(View.VISIBLE); + mKeepData.setText(getString(R.string.uninstall_keep_data, + formatFileSize(getContext(), appDataSize))); dialogBuilder.setView(content); } @@ -263,7 +201,6 @@ public class UninstallAlertDialogFragment extends DialogFragment implements public void onClick(DialogInterface dialog, int which) { if (which == Dialog.BUTTON_POSITIVE) { ((UninstallerActivity) getActivity()).startUninstallProgress( - mClearContributedFiles != null && mClearContributedFiles.isChecked(), mKeepData != null && mKeepData.isChecked()); } else { ((UninstallerActivity) getActivity()).dispatchAborted(); diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAlertFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAlertFragment.java index ac5fd76f5bda..21d25f5b030f 100644 --- a/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAlertFragment.java +++ b/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAlertFragment.java @@ -99,7 +99,7 @@ public class UninstallAlertFragment extends GuidedStepFragment { public void onGuidedActionClicked(GuidedAction action) { if (isAdded()) { if (action.getId() == GuidedAction.ACTION_ID_OK) { - ((UninstallerActivity) getActivity()).startUninstallProgress(false, false); + ((UninstallerActivity) getActivity()).startUninstallProgress(false); getActivity().finish(); } else { ((UninstallerActivity) getActivity()).dispatchAborted(); diff --git a/packages/PrintSpooler/res/values-sk/strings.xml b/packages/PrintSpooler/res/values-sk/strings.xml index 184f4d83f056..6fe9004d2e91 100644 --- a/packages/PrintSpooler/res/values-sk/strings.xml +++ b/packages/PrintSpooler/res/values-sk/strings.xml @@ -27,7 +27,7 @@ <string name="label_duplex" msgid="5370037254347072243">"Obojstranné"</string> <string name="label_orientation" msgid="2853142581990496477">"Orientácia"</string> <string name="label_pages" msgid="7768589729282182230">"Strany"</string> - <string name="destination_default_text" msgid="5422708056807065710">"Výber tlačiarne"</string> + <string name="destination_default_text" msgid="5422708056807065710">"Vyberte tlačiareň"</string> <string name="template_all_pages" msgid="3322235982020148762">"Všetky: <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string> <string name="template_page_range" msgid="428638530038286328">"Rozsah: <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string> <string name="pages_range_example" msgid="8558694453556945172">"napr. 1–5, 8, 11–13"</string> diff --git a/packages/SettingsLib/AppPreference/res/layout/preference_app.xml b/packages/SettingsLib/AppPreference/res/layout/preference_app.xml index b198f5a35630..711dad4b5b55 100644 --- a/packages/SettingsLib/AppPreference/res/layout/preference_app.xml +++ b/packages/SettingsLib/AppPreference/res/layout/preference_app.xml @@ -48,37 +48,32 @@ android:paddingTop="16dp" android:paddingBottom="16dp"> - <TextView android:id="@android:id/title" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:singleLine="true" - android:textAppearance="?android:attr/textAppearanceListItem" - android:ellipsize="marquee" - android:fadingEdge="horizontal"/> + <TextView + android:id="@android:id/title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:ellipsize="marquee" + android:fadingEdge="horizontal" + android:singleLine="true" + android:textAppearance="?android:attr/textAppearanceListItem"/> - <LinearLayout - android:id="@+id/summary_container" + <TextView + android:id="@android:id/summary" android:layout_width="match_parent" android:layout_height="wrap_content" - android:visibility="gone"> - <TextView android:id="@android:id/summary" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_weight="1" - android:textAppearance="?android:attr/textAppearanceSmall" - android:textAlignment="viewStart" - android:textColor="?android:attr/textColorSecondary"/> + android:textAppearance="?android:attr/textAppearanceSmall" + android:textColor="?android:attr/textColorSecondary"/> + + <TextView + android:id="@+id/appendix" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:ellipsize="end" + android:maxLines="1" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textColor="?android:attr/textColorSecondary" + android:visibility="gone"/> - <TextView android:id="@+id/appendix" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_weight="1" - android:textAppearance="?android:attr/textAppearanceSmall" - android:textAlignment="viewEnd" - android:textColor="?android:attr/textColorSecondary" - android:maxLines="1" - android:ellipsize="end"/> - </LinearLayout> <ProgressBar android:id="@android:id/progress" style="?android:attr/progressBarStyleHorizontal" diff --git a/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/apppreference/AppPreference.java b/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/apppreference/AppPreference.java index ab51a346dc6f..e88ac565913c 100644 --- a/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/apppreference/AppPreference.java +++ b/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/apppreference/AppPreference.java @@ -17,7 +17,6 @@ package com.android.settingslib.widget.apppreference; import android.content.Context; -import android.text.TextUtils; import android.util.AttributeSet; import android.view.View; import android.widget.ProgressBar; @@ -52,8 +51,6 @@ public class AppPreference extends Preference { public void onBindViewHolder(PreferenceViewHolder view) { super.onBindViewHolder(view); - view.findViewById(R.id.summary_container) - .setVisibility(TextUtils.isEmpty(getSummary()) ? View.GONE : View.VISIBLE); final ProgressBar progress = (ProgressBar) view.findViewById(android.R.id.progress); if (mProgressVisible) { progress.setProgress(mProgress); diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml index 835fcc2445c4..f12dfb87fbf7 100644 --- a/packages/SettingsLib/res/values-af/strings.xml +++ b/packages/SettingsLib/res/values-af/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Beskikbaar via %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Tik om aan te meld"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Gekoppel, geen internet nie"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Geen internet nie"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Aanmelding word vereis"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Toegangspunt is tydelik vol"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Gekoppel (geen media nie), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Gekoppel (geen foon of media nie), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktief, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batterykrag"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batterykrag"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktief"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media-oudio"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Foonoproepe"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Sal waarskynlik hou tot omtrent <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Sal waarskynlik hou tot omtrent <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Tot <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Minder as <xliff:g id="THRESHOLD">%1$s</xliff:g> oor"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Minder as <xliff:g id="THRESHOLD">%1$s</xliff:g> oor (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Meer as <xliff:g id="TIME_REMAINING">%1$s</xliff:g> oor (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Vra elke keer"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Totdat jy dit afskakel"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Sopas"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Foonluidspreker"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml index 11dde979f496..9e395252a683 100644 --- a/packages/SettingsLib/res/values-am/strings.xml +++ b/packages/SettingsLib/res/values-am/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"በ%1$s በኩል የሚገኝ"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"ለመመዝገብ መታ ያድርጉ"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"ተገናኝቷል፣ ምንም በይነመረብ የለም"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"ምንም በይነመረብ የለም"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"ወደ መለያ መግባት ያስፈልጋል"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"የመዳረሻ ነጥብ ለጊዜው ሞልቷል"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"ተገናኝቷል (ምንም ማህደረ መረጃ የለም)፣ ባትሪ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"ተገናኝቷል (ምንም ስልክ ወይም ማህደረ መረጃ የለም)፣ ባትሪ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"ንቁ፣ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ባትሪ"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ባትሪ"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"ንቁ"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"የማህደረ መረጃ ኦዲዮ"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"የስልክ ጥሪዎች"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"እስከ <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>) ገደማ ድረስ መቆየት አለበት"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"እስከ <xliff:g id="TIME">%1$s</xliff:g> ገደማ መቆየት አለበት"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"እስከ <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"ከ<xliff:g id="THRESHOLD">%1$s</xliff:g> ያነሰ ይቀራል"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"ከ<xliff:g id="THRESHOLD">%1$s</xliff:g> ያነሰ ይቀራል (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"ከ<xliff:g id="TIME_REMAINING">%1$s</xliff:g> በላይ ይቀራል (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"ሁልጊዜ ጠይቅ"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"እስኪያጠፉት ድረስ"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"ልክ አሁን"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"የስልክ ድምጽ ማጉያ"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml index 10d4ee587564..137d7b8fe5c2 100644 --- a/packages/SettingsLib/res/values-ar/strings.xml +++ b/packages/SettingsLib/res/values-ar/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"متوفرة عبر %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"انقر للاشتراك."</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"متصلة ولكن بلا إنترنت"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"لا يتوفر اتصال إنترنت."</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"يلزم تسجيل الدخول"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"نقطة الدخول ممتلئة مؤقتًا"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"الجهاز متصل (من دون وسائط)، ومستوى طاقة البطارية <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"الجهاز متّصل (من دون هاتف أو وسائط)، ومستوى طاقة البطارية <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"نشط، ومستوى طاقة البطارية <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"مستوى طاقة البطارية <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"نشط"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"الإعدادات الصوتية للوسائط"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"المكالمات الهاتفية"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"قد تكفي طاقة البطارية حتى حوالي الساعة <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string> <string name="power_discharge_by_only" msgid="107616694963545745">"قد تكفي طاقة البطارية حتى حوالي الساعة <xliff:g id="TIME">%1$s</xliff:g>."</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"حتى <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"يتبقى أقل من <xliff:g id="THRESHOLD">%1$s</xliff:g>."</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"يتبقى أقل من <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"يتبقى أكثر من <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string> @@ -461,5 +469,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"الطلب في كل مرة"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"إلى أن توقف الوضع يدويًا"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"للتو"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"مكبر صوت الهاتف"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml index dee399e3c3aa..3aefb12a2b30 100644 --- a/packages/SettingsLib/res/values-as/strings.xml +++ b/packages/SettingsLib/res/values-as/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"%1$sৰ মাধ্যমেৰে উপলব্ধ"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"ছাইন আপ কৰিবলৈ টিপক"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"সংযোজিত, ইণ্টাৰনেট নাই"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"ইণ্টাৰনেট সংযোগ নাই"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"ছাইন ইন কৰা দৰকাৰী"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"একচেছ পইণ্ট কিছু সময়ৰ বাবে পূৰ্ণ হৈ আছে"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"সংযোগ কৰা হ’ল (মিডিয়া নাই), বেটাৰিৰ স্তৰ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"সংযোগ কৰা হ’ল (কোনো ফ\'ন বা মিডিয়া নাই), বেটাৰিৰ স্তৰ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"সক্ৰিয়, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> বেটাৰি"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> বেটাৰি"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"সক্ৰিয়"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"মিডিয়াৰ অডিঅ’"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ফ\'ন কলসমূহ"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"বেটাৰি আনুমানিকভাৱে <xliff:g id="TIME">%1$s</xliff:g> লৈকে চলিব (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"বেটাৰি আনুমানিকভাৱে <xliff:g id="TIME">%1$s</xliff:g> লৈকে চলিব"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g> পৰ্যন্ত"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"<xliff:g id="THRESHOLD">%1$s</xliff:g>তকৈও কম সময় বাকী আছে"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"<xliff:g id="THRESHOLD">%1$s</xliff:g>তকৈও কম সময় বাকী আছে (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>তকৈও বেছি সময় বাকী আছে (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"প্ৰতিবাৰতে সোধক"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"আপুনি অফ নকৰা পর্যন্ত"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"এই মাত্ৰ"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"ফ’নৰ স্পীকাৰ"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml index 73e3d51f373c..57aec7c7b44f 100644 --- a/packages/SettingsLib/res/values-az/strings.xml +++ b/packages/SettingsLib/res/values-az/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s vasitəsilə əlçatandır"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Qeydiyyatdan keçmək üçün klikləyin"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Qoşuludur, internet yoxdur"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"İnternet yoxdur"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Giriş tələb olunur"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Giriş nöqtəsi müvəqqəti olaraq doludur"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Qoşuludur (media yoxdur), batareya <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Qoşuludur (telefon və ya media yoxdur), batareya <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktiv, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batareya"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batareya"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktiv"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefon zəngləri"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Təxminən <xliff:g id="TIME">%1$s</xliff:g> olana qədər davam edəcək (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Təxminən <xliff:g id="TIME">%1$s</xliff:g> olana qədər davam edəcək"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g> olana qədər"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Qalan vaxt <xliff:g id="THRESHOLD">%1$s</xliff:g> və daha azdır"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Qalan vaxt <xliff:g id="THRESHOLD">%1$s</xliff:g> və daha azdır (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Qalan vaxt <xliff:g id="TIME_REMAINING">%1$s</xliff:g> və daha çoxdur (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Hər dəfə soruşun"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Deaktiv edənə qədər"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"İndicə"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Telefon spikeri"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml index 47b536c75c35..4701771d94b1 100644 --- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml +++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Dostupna je preko pristupne tačke %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Dodirnite da biste se registrovali"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Veza je uspostavljena, nema interneta"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Nema interneta"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Treba da se prijavite"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Pristupna tačka je privremeno zauzeta"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Povezano (bez medija), nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Povezano (bez telefona ili medija), nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktivan, nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktivan"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Zvuk medija"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonski pozivi"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Trajaće približno do <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Trajaće približno do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Preostalo je manje od <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Preostalo je manje od <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Preostalo je više od <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -458,5 +466,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Uvek pitaj"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Dok ne isključite"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Upravo"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Zvučnik telefona"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml index ee662fa5af6c..633670549c03 100644 --- a/packages/SettingsLib/res/values-be/strings.xml +++ b/packages/SettingsLib/res/values-be/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Даступна праз %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Націсніце, каб зарэгістравацца"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Падключана, без доступу да інтэрнэту"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Не падключана да інтэрнэту"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Трэба выканаць уваход"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Пункт доступу часова заняты"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Падключана прылада <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (без аўдыя). Узровень зараду яе акумулятара: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Падключана прылада <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (без званкоў і аўдыя). Узровень зараду яе акумулятара: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Уключана, зарад <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Узровень зараду: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Уключана"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Аўдыё медыяпрылады"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Тэлефонныя выклікі"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Зараду (<xliff:g id="LEVEL">%2$s</xliff:g>) хопіць прыблізна да <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Зараду хопіць прыблізна да <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Да <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Засталося менш за <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Узровень зараду батарэі: <xliff:g id="LEVEL">%2$s</xliff:g> (хопіць менш чым на <xliff:g id="THRESHOLD">%1$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Узровень зараду батарэі: <xliff:g id="LEVEL">%2$s</xliff:g> (хопіць больш чым на <xliff:g id="TIME_REMAINING">%1$s</xliff:g>)"</string> @@ -459,5 +467,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Заўсёды пытацца"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Пакуль не выключыце"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Зараз"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Дынамік тэлефона"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml index 4e4ac9bd3d06..cdd5a0903bf0 100644 --- a/packages/SettingsLib/res/values-bg/strings.xml +++ b/packages/SettingsLib/res/values-bg/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Мрежата е достъпна през „%1$s“"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Докоснете, за да се регистрирате"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Установена е връзка – няма достъп до интернет"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Няма връзка с интернет"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Изисква се вход в профила"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Точката за достъп временно е пълна"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Свързано (без мултимедия), батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Свързано (без телефон или мултимедия), батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Активно. Батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Активно"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Мултимедийно аудио"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Телефонни обаждания"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Следва да издържи приблизително до <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Следва да издържи до около <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"До <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Остава/т по-малко от <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Остава/т по-малко от <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Остава/т повече от <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Да се пита винаги"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"До изключване"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Току-що"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Високоговорител на телефона"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml index c7d1c0a61dd9..ceb81a12a206 100644 --- a/packages/SettingsLib/res/values-bn/strings.xml +++ b/packages/SettingsLib/res/values-bn/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s এর মাধ্যমে উপলব্ধ"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"সাইন-আপ করতে ট্যাপ করুন"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"কানেক্ট, ইন্টারনেট নেই"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"ইন্টারনেট কানেকশন নেই"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"সাইন-ইন করা দরকার"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"এই মুহূর্তে অ্যাক্সেস পয়েন্টের কোনও কানেকশন ফাঁকা নেই"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"কানেক্ট করা আছে (মিডিয়ার অডিও ছাড়া), ব্যাটারি <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"কানেক্ট করা আছে (ফোনের বা মিডিয়ার অডিও ছাড়া), ব্যাটারি <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"চালু আছে, চার্জ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"চার্জ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"চালু আছে"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"মিডিয়া অডিও"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ফোন কল"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"আনুমানিক <xliff:g id="TIME">%1$s</xliff:g> পর্যন্ত চলবে (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"আনুমানিক <xliff:g id="TIME">%1$s</xliff:g> পর্যন্ত চলবে"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g> পর্যন্ত"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"<xliff:g id="THRESHOLD">%1$s</xliff:g> এর থেকেও কম বাকি আছে"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"আর <xliff:g id="THRESHOLD">%1$s</xliff:g>-এর কম চার্জ বাকি আছে (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"আরও <xliff:g id="TIME_REMAINING">%1$s</xliff:g>-এর বেশি চলবে (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"প্রতিবার জিজ্ঞেস করা হবে"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"যতক্ষণ না আপনি বন্ধ করছেন"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"এখনই"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"ফেনের স্পিকার"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml index d5d13d10ffe3..fd9475a623f3 100644 --- a/packages/SettingsLib/res/values-bs/strings.xml +++ b/packages/SettingsLib/res/values-bs/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Dostupan preko %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Dodirnite za prijavu"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Povezano, nema interneta"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Nema internetske veze"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Potrebna je prijava"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Pristupna tačka je privremeno puna"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Povezano (bez medija), baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Povezano (bez telefona ili medija), baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktivan, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktivan"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Zvuk medija"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonski pozivi"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Trebala bi trajati do otprilike <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Trebala bi trajati otprilike do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Preostalo je manje od <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Preostalo je manje od <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Preostalo je više od <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -458,5 +466,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Pitaj svaki put"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Dok ne isključite"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Upravo"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Zvučnik telefona"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml index c000a3c1281b..9aa1bf3e40f9 100644 --- a/packages/SettingsLib/res/values-ca/strings.xml +++ b/packages/SettingsLib/res/values-ca/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Disponible mitjançant %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Toca per registrar-te"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Connectada, sense Internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Sense connexió a Internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Cal iniciar la sessió"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"El punt d\'accés està temporalment ple"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> connectat (sense accés al contingut multimèdia), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> connectat (sense accés al telèfon ni al contingut multimèdia), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Actiu, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Actiu"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Àudio multimèdia"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Trucades telefòniques"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"La bateria hauria de durar aproximadament fins a les <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"La bateria hauria de durar aproximadament fins a les <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Fins a les <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Temps restant inferior a <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Temps restant inferior a <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Temps restant superior a <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Pregunta sempre"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Fins que no ho desactivis"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Ara mateix"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Altaveu del telèfon"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml index 37b7c516ec9d..409932d05e65 100644 --- a/packages/SettingsLib/res/values-cs/strings.xml +++ b/packages/SettingsLib/res/values-cs/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Dostupné prostřednictvím %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Klepnutím se zaregistrujete"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Připojeno, není k dispozici internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Nejste připojeni k internetu"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Je vyžadováno přihlášení"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Přístupový bod je dočasně zaplněn"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Připojeno k zařízení <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (bez médií), úroveň baterie <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Připojeno k zařízení <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (bez telefonu a médií), úroveň baterie <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktivní, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterie"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterie"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktivní"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Zvuk médií"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonní hovory"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Vydrží asi do <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Vydrží asi do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Zbývá méně než <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Zbývá méně než <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Zbývá více než <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -459,5 +467,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Pokaždé se zeptat"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Dokud tuto funkci nevypnete"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Právě teď"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Reproduktor telefonu"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml index 628df26b602e..5d7569aae72e 100644 --- a/packages/SettingsLib/res/values-da/strings.xml +++ b/packages/SettingsLib/res/values-da/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Tilgængelig via %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Tryk for at registrere dig"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Tilsluttet – intet internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Intet internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Login er påkrævet"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Adgangspunktet er midlertidigt fuldt"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Tilsluttet <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (ingen medier) – batteriniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Tilsluttet <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (ingen telefon eller medier) – batteriniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktivt, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktivt"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Medielyd"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonopkald"</string> @@ -201,7 +207,7 @@ <string name="enable_adb_summary" msgid="4881186971746056635">"Fejlretningstilstand, når USB er tilsluttet"</string> <string name="clear_adb_keys" msgid="4038889221503122743">"Tilbagekald tilladelser for USB-fejlfinding"</string> <string name="bugreport_in_power" msgid="7923901846375587241">"Genvej til fejlrapporting"</string> - <string name="bugreport_in_power_summary" msgid="1778455732762984579">"Vis en knap til oprettelse af fejlrapporter i menu for slukknap"</string> + <string name="bugreport_in_power_summary" msgid="1778455732762984579">"Vis en knap til oprettelse af fejlrapporter i afbrydermenuen"</string> <string name="keep_screen_on" msgid="1146389631208760344">"Lås ikke"</string> <string name="keep_screen_on_summary" msgid="2173114350754293009">"Skærmen går ikke i dvale under opladning"</string> <string name="bt_hci_snoop_log" msgid="3340699311158865670">"Aktivér Bluetooth HCI spionlog"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Bør holde indtil ca. <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Bør holde indtil ca. <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Indtil <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Der er mindre end <xliff:g id="THRESHOLD">%1$s</xliff:g> tilbage"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Der er mindre end <xliff:g id="THRESHOLD">%1$s</xliff:g> tilbage (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Der er mere end <xliff:g id="TIME_REMAINING">%1$s</xliff:g> tilbage (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Spørg hver gang"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Indtil du deaktiverer"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Lige nu"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Telefonens højttaler"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml index 7b63f3420dfb..a6f792703b79 100644 --- a/packages/SettingsLib/res/values-de/strings.xml +++ b/packages/SettingsLib/res/values-de/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Verfügbar über %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Zum Anmelden tippen"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Verbunden, kein Internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Kein Internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Anmeldung erforderlich"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Zugangspunkt vorübergehend voll belegt"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Mit <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> verbunden (kein Medien-Audio), Akkustand bei <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Mit <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> verbunden (weder Telefon- noch Medien-Audio), Akkustand bei <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktiv, Akkustand: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Akkustand: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktiv"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Medien-Audio"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonanrufe"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Sollte etwa bis <xliff:g id="TIME">%1$s</xliff:g> reichen (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Sollte etwa bis <xliff:g id="TIME">%1$s</xliff:g> reichen"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Bis <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Weniger als <xliff:g id="THRESHOLD">%1$s</xliff:g> verbleibend"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Weniger als <xliff:g id="THRESHOLD">%1$s</xliff:g> verbleibend (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Mehr als <xliff:g id="TIME_REMAINING">%1$s</xliff:g> verbleibend (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Jedes Mal fragen"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Bis zur Deaktivierung"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Gerade eben"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Telefon-Lautsprecher"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml index 7ddd3fc58bf8..030a527619d0 100644 --- a/packages/SettingsLib/res/values-el/strings.xml +++ b/packages/SettingsLib/res/values-el/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Διαθέσιμο μέσω %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Πατήστε για εγγραφή"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Συνδέθηκε, χωρίς σύνδεση στο διαδίκτυο"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Δεν υπάρχει σύνδεση στο διαδίκτυο"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Απαιτείται σύνδεση"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Το σημείο πρόσβασης είναι προσωρινά πλήρες"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Σε σύνδεση (χωρίς μέσα), μπαταρία <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Σε σύνδεση (χωρίς τηλέφωνο ή μέσα), μπαταρία <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Ενεργό, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> μπαταρία"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> μπαταρία"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Ενεργό"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Ήχος πολυμέσων"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Τηλεφωνικές κλήσεις"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Θα διαρκέσει μέχρι τις <xliff:g id="TIME">%1$s</xliff:g> περίπου (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Θα διαρκέσει μέχρι τις <xliff:g id="TIME">%1$s</xliff:g> περίπου"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Έως τις <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Απομένει/ουν λιγότερo/α από <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Απομένει/ουν λιγότερo/α από <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Απομένουν περισσότερα/ες από <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Να ερωτώμαι κάθε φορά"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Μέχρι την απενεργοποίηση"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Μόλις τώρα"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Ηχείο τηλεφώνου"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml index 47f31b436891..3fdc64dad9b5 100644 --- a/packages/SettingsLib/res/values-en-rAU/strings.xml +++ b/packages/SettingsLib/res/values-en-rAU/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Tap to sign up"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Connected, no Internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"No Internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Sign-in required"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Access point temporarily full"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Connected (no media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Connected (no phone or media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Active, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Active"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Phone calls"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Should last until about <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Should last until about <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Until <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> remaining"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> remaining (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"More than <xliff:g id="TIME_REMAINING">%1$s</xliff:g> remaining (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Ask every time"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Until you turn off"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Just now"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Phone speaker"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml index 47f31b436891..3fdc64dad9b5 100644 --- a/packages/SettingsLib/res/values-en-rCA/strings.xml +++ b/packages/SettingsLib/res/values-en-rCA/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Tap to sign up"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Connected, no Internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"No Internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Sign-in required"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Access point temporarily full"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Connected (no media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Connected (no phone or media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Active, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Active"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Phone calls"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Should last until about <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Should last until about <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Until <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> remaining"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> remaining (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"More than <xliff:g id="TIME_REMAINING">%1$s</xliff:g> remaining (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Ask every time"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Until you turn off"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Just now"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Phone speaker"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml index 47f31b436891..3fdc64dad9b5 100644 --- a/packages/SettingsLib/res/values-en-rGB/strings.xml +++ b/packages/SettingsLib/res/values-en-rGB/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Tap to sign up"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Connected, no Internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"No Internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Sign-in required"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Access point temporarily full"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Connected (no media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Connected (no phone or media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Active, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Active"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Phone calls"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Should last until about <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Should last until about <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Until <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> remaining"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> remaining (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"More than <xliff:g id="TIME_REMAINING">%1$s</xliff:g> remaining (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Ask every time"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Until you turn off"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Just now"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Phone speaker"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml index 47f31b436891..3fdc64dad9b5 100644 --- a/packages/SettingsLib/res/values-en-rIN/strings.xml +++ b/packages/SettingsLib/res/values-en-rIN/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Tap to sign up"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Connected, no Internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"No Internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Sign-in required"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Access point temporarily full"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Connected (no media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Connected (no phone or media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Active, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Active"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Phone calls"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Should last until about <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Should last until about <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Until <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> remaining"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> remaining (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"More than <xliff:g id="TIME_REMAINING">%1$s</xliff:g> remaining (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Ask every time"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Until you turn off"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Just now"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Phone speaker"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml index bb36101b7cf2..c7417377ef8d 100644 --- a/packages/SettingsLib/res/values-en-rXC/strings.xml +++ b/packages/SettingsLib/res/values-en-rXC/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Tap to sign up"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Connected, no internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"No internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Sign in required"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Access point temporarily full"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Connected (no media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Connected (no phone or media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Active, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Active"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Phone calls"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Should last until about <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Should last until about <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Until <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> remaining"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> remaining (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"More than <xliff:g id="TIME_REMAINING">%1$s</xliff:g> remaining (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Ask every time"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Until you turn off"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Just now"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Phone speaker"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index 22d4748678ea..3b67eeadfaf7 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Disponible a través de %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Presiona para registrarte"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Conectado pero sin conexión a Internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Sin Internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Acceso obligatorio"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"El punto de acceso está completo temporalmente"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Conectado (sin archivos multimedia) a <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería)"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Conectado (sin teléfono ni archivos multimedia) a <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería)"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Activado (batería: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>)"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Activado"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio multimedia"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Llamadas telefónicas"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Duración aproximada hasta: <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Debería durar aproximadamente hasta <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Hasta <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Tiempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Tiempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Tiempo restante: más de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Preguntar siempre"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Hasta que lo desactives"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Recién"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Altavoz del teléfono"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml index 47b1dfa1f5c5..46935a24cc33 100644 --- a/packages/SettingsLib/res/values-es/strings.xml +++ b/packages/SettingsLib/res/values-es/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Disponible a través de %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Toca para registrarte"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Conexión sin Internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Sin Internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Debes iniciar sesión"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Punto de acceso temporalmente lleno"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Conectado (sin audio multimedia) a <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería)"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Conectado (sin audio de teléfono ni multimedia) a <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería)"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Activo, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Activo"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio multimedia"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Llamadas de teléfono"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Debería durar aproximadamente hasta <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Duración aproximada hasta: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Hasta: <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Tiempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Queda menos del <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Queda más del <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Preguntar siempre"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Hasta que se desactive"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Justo ahora"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Altavoz del teléfono"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml index 1a704e29553b..9a71c19dc262 100644 --- a/packages/SettingsLib/res/values-et/strings.xml +++ b/packages/SettingsLib/res/values-et/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Saadaval üksuse %1$s kaudu"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Puudutage registreerumiseks"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Ühendatud, Interneti-ühendus puudub"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Interneti-ühendus puudub"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Nõutav on sisselogimine"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Pääsupunkt on ajutiselt täis"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Ühendatud (meediat pole), aku <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Ühendatud (telefoni ega meediat pole), aku <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktiivne, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> akut"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> akut"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktiivne"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Meedia heli"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonikõned"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Peaks kestma kuni <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Peaks kestma kuni <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Kuni <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Jäänud on alla <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Jäänud on alla <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Jäänud on üle <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Küsi iga kord"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Kuni välja lülitate"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Äsja"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Telefoni kõlar"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml index 9e1af11ba477..c4d16aa3a1af 100644 --- a/packages/SettingsLib/res/values-eu/strings.xml +++ b/packages/SettingsLib/res/values-eu/strings.xml @@ -33,7 +33,7 @@ <string name="wifi_check_password_try_again" msgid="516958988102584767">"Egiaztatu pasahitza zuzena dela eta saiatu berriro"</string> <string name="wifi_not_in_range" msgid="1136191511238508967">"Urrunegi"</string> <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Ez da konektatuko automatikoki"</string> - <string name="wifi_no_internet" msgid="4663834955626848401">"Ezin da atzitu Internet"</string> + <string name="wifi_no_internet" msgid="4663834955626848401">"Ezin da konektatu Internetera"</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> aplikazioak gorde du"</string> <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s bidez automatikoki konektatuta"</string> <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automatikoki konektatuta sareen balorazioen hornitzailearen bidez"</string> @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s bidez erabilgarri"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Sakatu erregistratzeko"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Konektatuta; ezin da atzitu Internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Ez dago Interneteko konexiorik"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Saioa hasi behar da"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Sarbide-puntua beteta dago aldi baterako"</string> @@ -73,13 +75,17 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Konektatuta (gailuaren audiorik gabe). Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>."</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Konektatuta (telefonoaren edo gailuaren audiorik gabe). Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>."</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktibo. Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktibo"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Euskarriaren audioa"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefono-deiak"</string> <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Fitxategi-transferentzia"</string> <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Sarrerako gailua"</string> - <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Interneterako sarbidea"</string> + <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Interneteko konexioa"</string> <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Kontaktuak partekatzea"</string> <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Erabili kontaktuak partekatzeko"</string> <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Interneteko konexioa partekatzea"</string> @@ -96,9 +102,9 @@ <string name="bluetooth_sap_profile_summary_connected" msgid="8561765057453083838">"SAP sarbide-puntura konektatuta"</string> <string name="bluetooth_opp_profile_summary_not_connected" msgid="1267091356089086285">"Fitxategi-transferentziako zerbitzarira konektatu gabe"</string> <string name="bluetooth_hid_profile_summary_connected" msgid="3381760054215168689">"Sarrerako gailura konektatuta"</string> - <string name="bluetooth_pan_user_profile_summary_connected" msgid="6436258151814414028">"Gailura konektatuta Interneteko sarbiderako"</string> + <string name="bluetooth_pan_user_profile_summary_connected" msgid="6436258151814414028">"Gailura konektatuta Internet atzitzeko"</string> <string name="bluetooth_pan_nap_profile_summary_connected" msgid="1322694224800769308">"Tokiko Interneteko konexioa gailu batekin partekatzea"</string> - <string name="bluetooth_pan_profile_summary_use_for" msgid="5736111170225304239">"Erabili Internet atzitzeko"</string> + <string name="bluetooth_pan_profile_summary_use_for" msgid="5736111170225304239">"Erabili Internetera konektatzeko"</string> <string name="bluetooth_map_profile_summary_use_for" msgid="5154200119919927434">"Erabili maparako"</string> <string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"Erabili SIM txartelerako sarbiderako"</string> <string name="bluetooth_a2dp_profile_summary_use_for" msgid="4630849022250168427">"Erabili euskarriaren audiorako"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Ordu honetara arte iraungo du, gutxi gorabehera: <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Ordu honetara arte iraungo du, gutxi gorabehera: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g> arte"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"<xliff:g id="THRESHOLD">%1$s</xliff:g> baino gutxiago gelditzen dira"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"<xliff:g id="THRESHOLD">%1$s</xliff:g> baino gutxiago gelditzen da (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> baino gehiago gelditzen da (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Galdetu beti"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Desaktibatu arte"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Oraintxe"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Telefonoaren bozgorailua"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index 087a7ff0e835..dd9f9fbfd2ca 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"در دسترس از طریق %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"برای ثبتنام ضربه بزنید"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"متصل، بدون اینترنت"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"عدم دسترسی به اینترنت"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"ورود به سیستم لازم است"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ظرفیت نقطه دسترسی موقتاً تکمیل شده است"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"متصل (بدون رسانه)، باتری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"متصل (بدون تلفن یا رسانه)، باتری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"فعال، <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> شارژ باتری"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> شارژ باتری"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"فعال"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"رسانه صوتی"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"تماسهای تلفنی"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"باید حدوداً تا <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>) شارژ داشته باشید"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"باید حدوداً تا <xliff:g id="TIME">%1$s</xliff:g> شارژ داشته باشید"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"تا <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"کمتر از <xliff:g id="THRESHOLD">%1$s</xliff:g> باقی مانده"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"کمتر از <xliff:g id="THRESHOLD">%1$s</xliff:g> شارژ باقی مانده است (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"بیش از <xliff:g id="TIME_REMAINING">%1$s</xliff:g> شارژ باقی مانده است (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"هربار پرسیده شود"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"تا زمانیکه آن را خاموش کنید"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"هماکنون"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"بلندگوی تلفن"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml index ac1f8a5a9738..7ecb7cb20e29 100644 --- a/packages/SettingsLib/res/values-fi/strings.xml +++ b/packages/SettingsLib/res/values-fi/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Käytettävissä seuraavan kautta: %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Rekisteröidy napauttamalla"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Yhdistetty, ei internetyhteyttä"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Ei internetyhteyttä"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Sisäänkirjautuminen vaaditaan"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Yhteyspiste tilapäisesti täynnä"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Yhdistetty (ei median ääntä), akun varaus <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Yhdistetty (ei puhelimen tai median ääntä), akun varaustaso <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktiivinen, akun taso <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Akun taso <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktiivinen"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Median ääni"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Puhelut"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Varaus loppuu noin <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Varaus loppuu noin <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g> saakka"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Alle <xliff:g id="THRESHOLD">%1$s</xliff:g> jäljellä"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Alle <xliff:g id="THRESHOLD">%1$s</xliff:g> jäljellä (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Yli <xliff:g id="TIME_REMAINING">%1$s</xliff:g> jäljellä (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Kysy aina"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Kunnes poistat sen käytöstä"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Äsken"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Puhelimen kaiutin"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml index acbc0287fa99..c0c0f37b88bf 100644 --- a/packages/SettingsLib/res/values-fr-rCA/strings.xml +++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Accessible par %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Toucher pour vous connecter"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Connecté, aucun accès à Internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Aucune connexion Internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Connexion requise"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Le point d\'accès est temporairement plein"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Connecté (aucun média), pile chargée à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Connecté (aucun téléphone ni média), pile chargée à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Actif, pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Actif"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Paramètres audio du support"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Appels téléphoniques"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Jusqu\'à <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Il reste plus de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Toujours demander"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Jusqu\'à la désactivation"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"À l\'instant"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Haut-parleur du téléphone"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml index 080074aaab9b..f40675571fb3 100644 --- a/packages/SettingsLib/res/values-fr/strings.xml +++ b/packages/SettingsLib/res/values-fr/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Disponible via %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Appuyez ici pour vous connecter"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Connecté, aucun accès à Internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Aucun accès à Internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Connexion requise"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Point d\'accès temporairement plein"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Connecté (aucun contenu multimédia), batterie à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Connecté (aucun téléphone ni contenu multimédia), batterie à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Actif, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batterie"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batterie"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Actif"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Multimédia"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Appels téléphoniques"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Jusqu\'à <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Il reste plus de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Toujours demander"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Jusqu\'à la désactivation"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"À l\'instant"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Haut-parleur du téléphone"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml index 26ee53dfbfd1..ab1a00364a85 100644 --- a/packages/SettingsLib/res/values-gl/strings.xml +++ b/packages/SettingsLib/res/values-gl/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Dispoñible a través de %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Toca para rexistrarte"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Conexión sen Internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Non hai conexión a Internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"É obrigatorio iniciar sesión"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"O punto de acceso está temporalmente cheo"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Conectado a <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (sen audio multimedia), batería ao <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Conectado a <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (sen teléfono nin audio multimedia), batería ao <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Dispositivo activo, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Activo"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio multimedia"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Chamadas telefónicas"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Debería durar aproximadamente ata a seguinte hora: <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Debería durar aproximadamente ata a seguinte hora: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Ata: <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Tempo restante inferior a <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Tempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Tempo restante: máis de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Preguntar sempre"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Ata a desactivación"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Agora mesmo"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Altofalante do teléfono"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml index 937fc3077d86..9c0b4702df51 100644 --- a/packages/SettingsLib/res/values-gu/strings.xml +++ b/packages/SettingsLib/res/values-gu/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s દ્વારા ઉપલબ્ધ"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"સાઇન અપ કરવા માટે ટૅપ કરો"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"કનેક્ટ કર્યું, કોઈ ઇન્ટરનેટ નથી"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"ઇન્ટરનેટ ઍક્સેસ નથી"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"સાઇન ઇન આવશ્યક"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ઍક્સેસ પૉઇન્ટ અસ્થાયીરૂપે ભરાયેલ છે"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> સાથે કનેક્ટ થયેલ (કોઈ મીડિયા નથી), બૅટરી <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> સાથે કનેક્ટ થયેલ (કોઈ ફોન અથવા મીડિયા નથી), બૅટરી <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"સક્રિય, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"સક્રિય"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"મીડિયા ઑડિઓ"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ફોન કૉલ"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"લગભગ <xliff:g id="TIME">%1$s</xliff:g> સુધી ચાલવી જોઈએ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"લગભગ <xliff:g id="TIME">%1$s</xliff:g> સુધી ચાલવી જોઈએ"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g> સુધી"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"<xliff:g id="THRESHOLD">%1$s</xliff:g> કરતાં ઓછો સમય બાકી છે"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"<xliff:g id="THRESHOLD">%1$s</xliff:g> કરતાં ઓછો સમય બાકી છે (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> કરતાં વધુ સમય બાકી છે (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"દર વખતે પૂછો"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"તમે બંધ ન કરો ત્યાં સુધી"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"હમણાં જ"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"ફોન સ્પીકર"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml index 0026d3e63c77..76097fd22531 100644 --- a/packages/SettingsLib/res/values-hi/strings.xml +++ b/packages/SettingsLib/res/values-hi/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s के द्वारा उपलब्ध"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"साइन अप करने के लिए टैप करें"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"कनेक्ट हो गया है, लेकिन इंटरनेट नहीं है"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"इंटरनेट कनेक्शन नहीं है"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"साइन इन करना ज़रूरी है"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"एक्सेस पॉइंट फ़िलहाल भरा हुआ है"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"जुड़ गया (मीडिया ऑडियो को छोड़कर), बैटरी का लेवल <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"जुड़ गया (फ़ोन या मीडिया ऑडियो को छोड़कर), बैटरी का लेवल <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"चालू, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बैटरी"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बैटरी"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"चालू"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"मीडिया ऑडियो"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"फ़ोन कॉल"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"बैटरी लगभग <xliff:g id="TIME">%1$s</xliff:g> चलेगी (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"बैटरी लगभग <xliff:g id="TIME">%1$s</xliff:g> चलेगी"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g> तक"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"<xliff:g id="THRESHOLD">%1$s</xliff:g> से कम समय बचा है"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"<xliff:g id="THRESHOLD">%1$s</xliff:g> से कम बैटरी बची है (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> से ज़्यादा चलने लायक बैटरी बची है (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"हर बार पूछें"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"जब तक आप इसे बंद नहीं करते"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"अभी-अभी"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"फ़ोन स्पीकर"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml index f06d01d3046b..f5e984528b08 100644 --- a/packages/SettingsLib/res/values-hr/strings.xml +++ b/packages/SettingsLib/res/values-hr/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Dostupno putem %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Dodirnite da biste se registrirali"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Povezano, bez interneta"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Nema interneta"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Obavezna prijava"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Pristupna je točka privremeno puna"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Povezano (bez medija), baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Povezano (bez telefona i medija), baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktivan, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktivan"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Medijski zvuk"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonski pozivi"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Otprilike bi trebalo trajati do <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Otprilike bi trebalo trajati do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Preostalo je manje od <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Preostalo je manje od <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Preostalo je više od <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -458,5 +466,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Pitaj svaki put"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Dok ne isključite"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Upravo sad"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Zvučnik telefona"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml index 92b4e2013ec2..473f1ce2fbe1 100644 --- a/packages/SettingsLib/res/values-hu/strings.xml +++ b/packages/SettingsLib/res/values-hu/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Elérhető a következőn keresztül: %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Koppintson a regisztrációhoz"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Csatlakozva, nincs internet-hozzáférés"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Nincs internetkapcsolat"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Bejelentkezést igényel"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"A hozzáférési pont átmenetileg megtelt"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Csatlakoztatva (médiahang nélkül); az akkumulátor töltöttségi szintje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Csatlakoztatva (nincs telefon- és médiahang); az akkumulátor töltöttségi szintje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktív, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>-os töltöttség"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Akkumulátor: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktív"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Média audió"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonhívások"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Nagyjából még ennyit bír: <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Nagyjából még ennyit bír: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Eddig: <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Kevesebb mint <xliff:g id="THRESHOLD">%1$s</xliff:g> van hátra"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Kevesebb mint <xliff:g id="THRESHOLD">%1$s</xliff:g> van hátra (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Kevesebb mint <xliff:g id="TIME_REMAINING">%1$s</xliff:g> van hátra (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Mindig kérdezzen rá"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Kikapcsolásig"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Az imént"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Telefon hangszórója"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml index b5e5cf5d8a98..aac766c0df92 100644 --- a/packages/SettingsLib/res/values-hy/strings.xml +++ b/packages/SettingsLib/res/values-hy/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Հասանելի է %1$s-ի միջոցով"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Հպեք՝ գրանցվելու համար"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Միացված է, սակայն ինտերնետ կապ չկա"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Ինտերնետ կապ չկա"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Անհրաժեշտ է մուտք գործել"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Հասանելիության կետը ժամանակավորապես լիքն է"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Միացված է (մեդիա չկա), մարտկոցի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Միացված է (հեռախոս կամ մեդիա չկա), մարտկոցի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Ակտիվ է։ Մարտկոցի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Մարտկոցի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Ակտիվ է"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Մեդիա աուդիո"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Հեռախոսազանգեր"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Լիցքը (<xliff:g id="LEVEL">%2$s</xliff:g>) պետք է, որ բավականացնի մոտ <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Լիցքը պետք է, որ բավականացնի մոտ <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Մինչև <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Մնացել է <xliff:g id="THRESHOLD">%1$s</xliff:g>-ից պակաս"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Մնացել է <xliff:g id="THRESHOLD">%1$s</xliff:g>-ից պակաս (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Մնացել է ավելի քան <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Հարցնել ամեն անգամ"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Մինչև չանջատեք"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Հենց նոր"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Հեռախոսի բարձրախոս"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml index 6bd2876456fa..79616cee7b54 100644 --- a/packages/SettingsLib/res/values-in/strings.xml +++ b/packages/SettingsLib/res/values-in/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Tersedia melalui %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Tap untuk mendaftar"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Tersambung, tidak ada internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Tidak ada internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Perlu login"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Titik akses penuh untuk sementara"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Terhubung (tanpa media), baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Terhubung (tanpa ponsel atau media), baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktif, baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktif"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio media"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Panggilan telepon"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Akan bertahan kira-kira sampai <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Akan bertahan kira-kira sampai <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Hingga <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Tersisa kurang dari <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Tersisa kurang dari <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Tersisa lebih dari <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Selalu tanya"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Sampai Anda menonaktifkannya"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Baru saja"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Speaker ponsel"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml index 87006ac3c669..2ae43a4ae804 100644 --- a/packages/SettingsLib/res/values-is/strings.xml +++ b/packages/SettingsLib/res/values-is/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Í boði í gegnum %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Ýttu til að skrá þig"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Tengt, enginn netaðgangur"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Engin nettenging"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Innskráningar krafist"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Aðgangsstaður tímabundið fullur"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Tengt (ekkert efni), staða rafhlöðu <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Tengt (enginn sími eða efni), staða rafhlöðu <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Tengt, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> rafhlöðuhleðsla"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> rafhlöðuhleðsla"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Virkt"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Hljóð efnis"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Símtöl"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Ætti að endast til u.þ.b. <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Ætti að endast til u.þ.b. <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Til klukkan <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Minna en <xliff:g id="THRESHOLD">%1$s</xliff:g> eftir"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Minna en <xliff:g id="THRESHOLD">%1$s</xliff:g> eftir (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Meira en <xliff:g id="TIME_REMAINING">%1$s</xliff:g> eftir (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Spyrja í hvert skipti"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Þar til þú slekkur"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Rétt í þessu"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Símahátalari"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml index b00badac94b0..c63204164aec 100644 --- a/packages/SettingsLib/res/values-it/strings.xml +++ b/packages/SettingsLib/res/values-it/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Disponibile tramite %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Tocca per registrarti"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Connesso, senza Internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Nessuna connessione a Internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Accesso richiesto"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Punto di accesso momentaneamente al completo"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> connesso (contenuti multimediali esclusi), batteria al <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> connesso (telefono o contenuti multimediali esclusi), batteria al <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Attivo - Batteria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Batteria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Attivo"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio multimediale"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonate"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Tempo stimato rimanente: <xliff:g id="TIME">%1$s</xliff:g> circa (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Tempo stimato rimanente: <xliff:g id="TIME">%1$s</xliff:g> circa"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Fino alle ore <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Tempo rimanente: meno di <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Tempo rimanente: meno di <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Tempo rimanente: più di <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Chiedi ogni volta"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Fino alla disattivazione"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Adesso"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Altoparlante telefono"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml index ae16ecbb28bb..8a9a57bac26b 100644 --- a/packages/SettingsLib/res/values-iw/strings.xml +++ b/packages/SettingsLib/res/values-iw/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"זמינה דרך %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"יש להקיש כדי להירשם"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"מחובר. אין אינטרנט"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"אין אינטרנט"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"נדרשת כניסה"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"נקודת הגישה מלאה באופן זמני"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"מחובר (ללא מדיה), שיעור הסוללה <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"מחובר (ללא טלפון או מדיה), שיעור הסוללה <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"פעיל, טעינת הסוללה: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"טעינת הסוללה: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"פעיל"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"אודיו של מדיה"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"שיחות טלפון"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"אמורה להחזיק מעמד בערך עד <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"אמורה להחזיק מעמד בערך עד <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"עד <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"נותרו פחות מ-<xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"נותרו פחות מ-<xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"נותרו יותר מ-<xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -459,5 +467,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"שאל בכל פעם"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"עד הכיבוי"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"הרגע"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"רמקול של טלפון"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml index cc7ff1eaabda..e773b43e9d95 100644 --- a/packages/SettingsLib/res/values-ja/strings.xml +++ b/packages/SettingsLib/res/values-ja/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s経由で使用可能"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"タップして登録してください"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"接続済み、インターネット接続なし"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"インターネット未接続"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"ログインが必要"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"アクセス ポイントが一時的にいっぱいです"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"接続済み(メディアなし)、電池残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>: <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"接続済み(電話、メディアなし)、電池残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>: <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"有効、電池 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"電池 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"有効"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"メディアの音声"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"電話"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"電池切れの推定時間: <xliff:g id="TIME">%1$s</xliff:g>(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"電池切れの推定時間: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g> まで"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"残り時間: <xliff:g id="THRESHOLD">%1$s</xliff:g>未満"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"残り時間: <xliff:g id="THRESHOLD">%1$s</xliff:g>未満(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"残り時間: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>以上(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"毎回確認"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"OFF にするまで"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"たった今"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"スマートフォンのスピーカー"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml index c54fdfd8386d..e3f7a5f5e6c2 100644 --- a/packages/SettingsLib/res/values-ka/strings.xml +++ b/packages/SettingsLib/res/values-ka/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"ხელმისაწვდომია %1$s-ით"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"შეეხეთ რეგისტრაციისთვის"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"დაკავშირებულია, ინტერნეტის გარეშე"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"ინტერნეტ-კავშირი არ არის"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"აუცილებელია სისტემაში შესვლა"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"წვდომის წერტილი დროებით გადატვირთულია"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"დაკავშირებულია (მედია არ არის). ბატარეა: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"დაკავშირებულია (ტელეფონი ან მედია არ არის). ბატარეის დონე: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"აქტიურია, ბატარეა <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>-ს შეადგენს"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ბატარეა"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"აქტიური"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"მედია აუდიო"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"სატელეფონო ზარები"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"უნდა იმუშაოს დაახლოებით <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"უნდა იმუშაოს დაახლოებით <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g>-მდე"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"დარჩენილია <xliff:g id="THRESHOLD">%1$s</xliff:g>-ზე ნაკლები"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"დარჩენილია <xliff:g id="THRESHOLD">%1$s</xliff:g>-ზე ნაკლები დრო (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"დარჩენილია <xliff:g id="TIME_REMAINING">%1$s</xliff:g>-ზე მეტი დრო (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"ყოველთვის მკითხეთ"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"გამორთვამდე"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"ახლახან"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"ტელეფონის დინამიკი"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml index e2b40bbd0abb..5ae32cd3fdeb 100644 --- a/packages/SettingsLib/res/values-kk/strings.xml +++ b/packages/SettingsLib/res/values-kk/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s арқылы қолжетімді"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Тіркелу үшін түртіңіз."</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Қосылған, интернет жоқ"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Интернетпен байланыс жоқ"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Есептік жазбаға кіру керек"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Кіру нүктесі уақытша бос емес"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Жалғанды (аудиосыз), батарея заряды: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Жалғанды (телефонсыз не аудиосыз), батарея заряды: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Қосулы, батарея қуаты: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Батарея қуаты: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Қосулы"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Meдиа аудиосы"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Телефон қоңыраулары"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Шамамен <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>) уақытқа жетеді"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Шамамен <xliff:g id="TIME">%1$s</xliff:g> уақытқа жетеді"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g> дейін"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"<xliff:g id="THRESHOLD">%1$s</xliff:g> шамасынан аз қалды"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"<xliff:g id="THRESHOLD">%1$s</xliff:g> шамасынан аз қалды (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> шамасынан көп уақыт қалды (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Әрдайым сұрау"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Өшірілгенге дейін"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Дәл қазір"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Телефон динамигі"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml index 165483178e36..6c83ec2a498c 100644 --- a/packages/SettingsLib/res/values-km/strings.xml +++ b/packages/SettingsLib/res/values-km/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"មានតាមរយៈ %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"ចុចដើម្បីចុះឈ្មោះ"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"បានភ្ជាប់ ប៉ុន្តែគ្មានអ៊ីនធឺណិតទេ"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"គ្មានអ៊ីនធឺណិតទេ"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"តម្រូវឱ្យចូលគណនី"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ចំណុចចូលប្រើពេញជាបណ្តោះអាសន្ន"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"បានភ្ជាប់ (គ្មានមេឌៀទេ) ហើយថ្មមានកម្រិត <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"បានភ្ជាប់ (គ្មានទូរសព្ទ ឬមេឌៀទេ) ហើយថ្មមានកម្រិត <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"សកម្ម ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"សកម្ម"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"សំឡេងមេឌៀ"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ការហៅទូរសព្ទ"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"គួរតែអាចប្រើបានរហូតដល់ម៉ោងប្រហែល <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"គួរតែអាចប្រើបានរហូតដល់ម៉ោងប្រហែល <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"រហូតដល់ម៉ោង <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"នៅសល់តិចជាង <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"នៅសល់តិចជាង <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"នៅសល់ច្រើនជាង <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"សួរគ្រប់ពេល"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"រហូតទាល់តែអ្នកបិទ"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"អម្បាញ់មិញ"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"ឧបករណ៍បំពងសំឡេងទូរសព្ទ"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml index 457a163b776e..c879be5215d6 100644 --- a/packages/SettingsLib/res/values-kn/strings.xml +++ b/packages/SettingsLib/res/values-kn/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s ಮೂಲಕ ಲಭ್ಯವಿದೆ"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"ಸೈನ್ ಅಪ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ, ಇಂಟರ್ನೆಟ್ ಇಲ್ಲ"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"ಇಂಟರ್ನೆಟ್ ಇಲ್ಲ"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"ಸೈನ್ ಇನ್ ಮಾಡುವ ಅಗತ್ಯವಿದೆ"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ಪ್ರವೇಶ ಕೇಂದ್ರ ತಾತ್ಕಾಲಿಕವಾಗಿ ಭರ್ತಿಯಾಗಿದೆ"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"ಸಂಪರ್ಕಗೊಂಡಿದೆ (ಮಾಧ್ಯಮವಿಲ್ಲ), ಬ್ಯಾಟರಿ ಚಾರ್ಜ್ ಮಟ್ಟ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"ಸಂಪರ್ಕಗೊಂಡಿದೆ (ಫೋನ್ ಅಥವಾ ಮಾಧ್ಯಮವಿಲ್ಲ), ಬ್ಯಾಟರಿ ಚಾರ್ಜ್ ಮಟ್ಟ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"ಸಕ್ರಿಯ, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ಬ್ಯಾಟರಿ"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ಬ್ಯಾಟರಿ"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"ಸಕ್ರಿಯ"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"ಮಾಧ್ಯಮ ಆಡಿಯೋ"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ಫೋನ್ ಕರೆಗಳು"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"<xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>) ಸಮಯದವರೆಗೆ ಫೋನ್ ರನ್ ಆಗಬೇಕು"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"<xliff:g id="TIME">%1$s</xliff:g> ಸಮಯದವರೆಗೆ ಫೋನ್ ರನ್ ಆಗಬೇಕು"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g> ರವರೆಗೆ"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"<xliff:g id="THRESHOLD">%1$s</xliff:g> ನಿಮಿಷಕ್ಕಿಂತ ಕಡಿಮೆ ಸಮಯ ಉಳಿದಿದೆ"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"<xliff:g id="THRESHOLD">%1$s</xliff:g> ಕ್ಕಿಂತ ಕಡಿಮೆ (<xliff:g id="LEVEL">%2$s</xliff:g>) ಬಾಕಿ"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ಕ್ಕಿಂತ ಹೆಚ್ಚು (<xliff:g id="LEVEL">%2$s</xliff:g>) ಬಾಕಿ"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"ಪ್ರತಿ ಬಾರಿ ಕೇಳಿ"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"ನೀವು ಆಫ್ ಮಾಡುವವರೆಗೆ"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"ಇದೀಗ"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"ಫೋನ್ ಸ್ಪೀಕರ್"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml index d19b9f2dd62f..739212fb5b42 100644 --- a/packages/SettingsLib/res/values-ko/strings.xml +++ b/packages/SettingsLib/res/values-ko/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s을(를) 통해 사용 가능"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"탭하여 가입"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"연결됨, 인터넷 사용 불가"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"인터넷 연결 없음"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"로그인 필요"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"액세스 포인트가 일시적으로 가득 참"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"연결됨(미디어 없음), 배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"연결됨(전화 또는 미디어 없음), 배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"활성, 배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"활성"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"미디어 오디오"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"전화 통화"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"약 <xliff:g id="TIME">%1$s</xliff:g>까지 사용 가능(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"약 <xliff:g id="TIME">%1$s</xliff:g>까지 사용 가능"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g>까지"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"<xliff:g id="THRESHOLD">%1$s</xliff:g> 미만 남음"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"<xliff:g id="THRESHOLD">%1$s</xliff:g> 미만 남음(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> 이상 남음(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"항상 확인"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"사용 중지할 때까지"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"조금 전"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"휴대전화 스피커"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml index 9bc6d58a6494..b898725421e7 100644 --- a/packages/SettingsLib/res/values-ky/strings.xml +++ b/packages/SettingsLib/res/values-ky/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s аркылуу жеткиликтүү"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Катталуу үчүн таптап коюңуз"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Туташып турат, Интернет жок"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Интернет жок"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Аккаунтка кирүү талап кылынат"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Байланыш түйүнүнө өтө көп түзмөк туташып турат"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Туташып турат (медиасыз), батареянын деңгээли – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Туташып турат (телефониясыз же медиасыз), батареянын деңгээли – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Жигердүү, батареянын деңгээли: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Батареянын деңгээли: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Жигердүү"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Аудио"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Телефон чалуулар"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Болжол менен <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>) кийин өчөт"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Болжол менен <xliff:g id="TIME">%1$s</xliff:g> кийин өчөт"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g> чейин"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"<xliff:g id="THRESHOLD">%1$s</xliff:g> жетпеген убакыт калды"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"<xliff:g id="THRESHOLD">%1$s</xliff:g> жетпеген убакыт калды (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ашыгыраак убакыт калды (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Ар дайым суралсын"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Бул функция өчүрүлгөнгө чейин"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Азыр эле"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Телефондун динамиги"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml index 5c10aabc7d70..1fbb2a4a748d 100644 --- a/packages/SettingsLib/res/values-lo/strings.xml +++ b/packages/SettingsLib/res/values-lo/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"ມີໃຫ້ຜ່ານ %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"ແຕະເພື່ອສະໝັກ"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"ເຊື່ອມຕໍ່ແລ້ວ, ບໍ່ມີອິນເຕີເນັດ"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"ບໍ່ມີອິນເຕີເນັດ"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"ຈຳເປັນຕ້ອງເຂົ້າສູ່ລະບົບ"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ຈຸດການເຂົ້າເຖິງເຕັມຊົ່ວຄາວ"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"ເຊື່ອມຕໍ່ແລ້ວ (ບໍ່ມີມີເດຍ), ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"ເຊື່ອມຕໍ່ແລ້ວ (ບໍ່ມີໂທລະສັບ ຫຼື ມີເດຍ), ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"ເປີດໃຊ້ຢູ່, ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"ອອນລາຍ"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"ສຽງ"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ການໂທ"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Should last until about <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Should last until about <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"ຈົນກວ່າຈະຮອດ <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"ຍັງເຫຼືອໜ້ອຍກວ່າ <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"ຍັງເຫຼືອໜ້ອຍກວ່າ <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"ຍັງເຫຼືອຫຼາຍກວ່າ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"ຖາມທຸກເທື່ອ"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"ຈົນກວ່າທ່ານຈະປິດ"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"ຕອນນີ້"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"ລຳໂພງໂທລະສັບ"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml index d437bc768b20..c289c938477a 100644 --- a/packages/SettingsLib/res/values-lt/strings.xml +++ b/packages/SettingsLib/res/values-lt/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Pasiekiama naudojant „%1$s“"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Palieskite, kad prisiregistruotumėte"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Prisijungta, nėra interneto"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Nėra interneto ryšio"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Reikia prisijungti"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Prieigos taškas laikinai visiškai užimtas"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Prisijungta (<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>), (medijos nėra), akumuliatoriaus įkrovos lygis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Prisijungta (<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>), (telefono ar medijos nėra), akumuliatoriaus įkrovos lygis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktyvus, akumuliatoriaus įkrova: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Akumuliatoriaus įkrova: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktyvus"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Laikmenos garsas"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefono skambučiai"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Turėtų išsikrauti maždaug po <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Turėtų išsikrauti maždaug po <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Iki <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Liko mažiau nei <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Liko mažiau nei <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Liko daugiau nei <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -459,5 +467,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Klausti kaskart"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Kol išjungsite"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Ką tik"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Telefono garsiakalbis"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml index afa91274d507..f01f9931f577 100644 --- a/packages/SettingsLib/res/values-lv/strings.xml +++ b/packages/SettingsLib/res/values-lv/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Pieejams, izmantojot %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Pieskarieties, lai reģistrētos"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Savienojums izveidots, nav piekļuves internetam"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Nav piekļuves internetam"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Nepieciešama pierakstīšanās"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Piekļuves punkts īslaicīgi ir pilns"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Savienojums izveidots (<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>) (nav multivide), akumulatora uzlādes līmenis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Savienojums izveidots (nav tālrunis vai multivide) (<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>), akumulatora uzlādes līmenis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktīvs, akumulatora uzlādes līmenis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Akumulatora uzlādes līmenis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktīvs"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Multivides audio"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Tālruņa zvani"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Darbosies aptuveni līdz <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Darbosies aptuveni līdz <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Līdz <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Atlikušais laiks — mazāk nekā <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Atlicis mazāk nekā <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Atlicis vairāk nekā <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -458,5 +466,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Vaicāt katru reizi"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Līdz brīdim, kad izslēgsiet"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Tikko"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Tālruņa skaļrunis"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml index ebc4fda5c7c5..1e2d844c3f5c 100644 --- a/packages/SettingsLib/res/values-mk/strings.xml +++ b/packages/SettingsLib/res/values-mk/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Достапно преку %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Допрете за да се регистрирате"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Поврзана, нема интернет"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Нема интернет"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Потребно е најавување"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Пристапната точка привремено е преоптоварена"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Поврзан со <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (без аудиовизуелни содржини), ниво на батеријата <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Поврзан со <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (без телефон и аудиовизуелни содржини), ниво на батеријата <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Активен, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батерија"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батерија"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Активен"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Аудио на медиуми"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Телефонски повици"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Треба да трае до околу <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Треба да трае до околу <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"До <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Уште помалку од <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Уште помалку од <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Уште повеќе од <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Секогаш прашувај"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Додека не го исклучите"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Неодамнешни"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Телефонски звучник"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml index f04bfcc5c677..7ff715c28308 100644 --- a/packages/SettingsLib/res/values-ml/strings.xml +++ b/packages/SettingsLib/res/values-ml/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s വഴി ലഭ്യം"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"സൈൻ അപ്പ് ചെയ്യാൻ ടാപ്പ് ചെയ്യുക"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"കണക്റ്റ് ചെയ്തു, ഇന്റർനെറ്റ് ഇല്ല"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"ഇന്റർനെറ്റ് ഇല്ല"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"സൈൻ ഇൻ ചെയ്യേണ്ടത് ആവശ്യമാണ്"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ആക്സസ് പോയിന്റ് താൽക്കാലികമായി നിറഞ്ഞിരിക്കുന്നു"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"കണക്റ്റ് ചെയ്തു (മീഡിയ ഇല്ല), ബാറ്ററി <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"കണക്റ്റ് ചെയ്തു (ഫോണോ മീഡിയയോ ഇല്ല), ബാറ്ററി നില <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"സജീവം, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ബാറ്ററി"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ബാറ്ററി"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"സജീവം"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"മീഡിയ ഓഡിയോ"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ഫോണ് കോളുകൾ"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"ഏകദേശം <xliff:g id="TIME">%1$s</xliff:g> വരെ നീണ്ടുനിൽക്കേണ്ടതാണ് (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"ഏകദേശം <xliff:g id="TIME">%1$s</xliff:g> വരെ നീണ്ടുനിൽക്കേണ്ടതാണ്"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g> വരെ"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"<xliff:g id="THRESHOLD">%1$s</xliff:g>-ൽ കുറവ് സമയം ശേഷിക്കുന്നു"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"<xliff:g id="THRESHOLD">%1$s</xliff:g>-ൽ കുറവ് സമയം ശേഷിക്കുന്നു (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>-ൽ കൂടുതൽ സമയം ശേഷിക്കുന്നു (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"എപ്പോഴും ചോദിക്കുക"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"നിങ്ങൾ ഓഫാക്കുന്നത് വരെ"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"ഇപ്പോൾ"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"ഫോൺ സ്പീക്കർ"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml index 498b855e0b7d..ec2cacf579e7 100644 --- a/packages/SettingsLib/res/values-mn/strings.xml +++ b/packages/SettingsLib/res/values-mn/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s-р боломжтой"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Бүртгүүлэхийн тулд товшино уу"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Холбогдсон хэдий ч интернет алга"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Интернэт алга"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Нэвтрэх шаардлагатай"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Хандах цэг түр хугацаанд дүүрсэн байна"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Холбогдсон (медиа байхгүй), батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Холбогдсон (утас эсвэл медиа байхгүй), батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Идэвхтэй, батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Идэвхтэй"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Медиа аудио"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Утасны дуудлага"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Ойролцоогоор <xliff:g id="TIME">%1$s</xliff:g> хүртэл барих ёстой (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Ойролцоогоор <xliff:g id="TIME">%1$s</xliff:g> хүртэл барих ёстой"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g> хүртэл"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"<xliff:g id="THRESHOLD">%1$s</xliff:g>-с бага хугацаа үлдсэн"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"<xliff:g id="THRESHOLD">%1$s</xliff:g>-с бага хугацаа үлдсэн (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>-с их хугацаа үлдсэн (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Тухай бүрт асуух"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Таныг унтраах хүртэл"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Дөнгөж сая"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Утасны чанга яригч"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml index 7729f2166e9d..82ed3d5f8422 100644 --- a/packages/SettingsLib/res/values-mr/strings.xml +++ b/packages/SettingsLib/res/values-mr/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s द्वारे उपलब्ध"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"साइन अप करण्यासाठी टॅप करा"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"कनेक्ट केले, इंटरनेट नाही"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"इंटरनेट नाही"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"साइन इन करणे आवश्यक आहे"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"अॅक्सेस पॉइंट तात्पुरते भरलेले"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"कनेक्ट केले (मीडिया नाही), बॅटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"कनेक्ट केले (फोन किंवा मीडिया नाही), बॅटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"अॅक्टिव्ह, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बॅटरी"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बॅटरी"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"अॅक्टिव्ह"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"मीडिया ऑडिओ"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"फोन कॉल"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"सुमारे <xliff:g id="TIME">%1$s</xliff:g> पर्यंत टिकेल (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"सुमारे <xliff:g id="TIME">%1$s</xliff:g> पर्यंत टिकावी"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g> पर्यंत"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"<xliff:g id="THRESHOLD">%1$s</xliff:g> पेक्षा कमी शिल्लक आहे"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"<xliff:g id="THRESHOLD">%1$s</xliff:g> पेक्षा कमी वेळ शिल्लक आहे (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> पेक्षा जास्त वेळ शिल्लक आहे (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"प्रत्येक वेळी विचारा"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"तुम्ही बंद करेपर्यंत"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"आत्ताच"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"फोनचा स्पीकर"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml index 236e30d307b2..59157af60c93 100644 --- a/packages/SettingsLib/res/values-ms/strings.xml +++ b/packages/SettingsLib/res/values-ms/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Tersedia melalui %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Ketik untuk daftar"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Disambungkan, tiada Internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Tiada Internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Log masuk diperlukan"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Titik akses penuh buat sementara waktu"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Disambungkan (tiada media), bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Disambungkan (tiada telefon atau media), bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktif, bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktif"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio media"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Panggilan telefon"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Seharusnya boleh digunakan hingga kira-kira <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Seharusnya boleh digunakan hingga kira-kira <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Hingga <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Tinggal kurang daripada <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Kurang daripada <xliff:g id="THRESHOLD">%1$s</xliff:g> lagi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Lebih daripada <xliff:g id="TIME_REMAINING">%1$s</xliff:g> lagi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Tanya setiap kali"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Sehingga anda matikan"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Sebentar tadi"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Pembesar suara telefon"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml index 88eef5607a67..04d4a3bb028d 100644 --- a/packages/SettingsLib/res/values-my/strings.xml +++ b/packages/SettingsLib/res/values-my/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s မှတစ်ဆင့်ရနိုင်သည်"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"အကောင့်ဖွင့်ရန် တို့ပါ"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"ချိတ်ဆက်ထားသည်၊ အင်တာနက်မရှိ"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"အင်တာနက် မရှိပါ"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"လက်မှတ်ထိုးဝင်ရန် လိုအပ်သည်"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ကွန်ရက်ချိတ်ဆက်မှု ယာယီပြည့်နေသည်"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"ချိတ်ဆက်ပြီးပြီ (မီဒီယာ မရှိပါ)၊ ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"ချိတ်ဆက်ပြီးပြီ (ဖုန်း (သို့) မီဒီယာ မရှိပါ)၊ ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"ဖွင့်ထားသည်၊ ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"ဖွင့်ထားသည်"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"မီဒီယာ အသံ"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ဖုန်းခေါ်ဆိုမှုများ"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"<xliff:g id="TIME">%1$s</xliff:g> ခန့်အထိ သုံးနိုင်သည် (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"<xliff:g id="TIME">%1$s</xliff:g> ခန့်အထိ သုံးနိုင်သည်"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g> အထိ"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"<xliff:g id="THRESHOLD">%1$s</xliff:g> ခန့်သာ ကျန်တော့သည်"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"<xliff:g id="THRESHOLD">%1$s</xliff:g> အောက်သာ ကျန်သည် (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ကျော် ကျန်သည် (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"အမြဲမေးပါ"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"သင်ပိတ်လိုက်သည် အထိ"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"ယခုလေးတင်"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"ဖုန်းစပီကာ"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml index 259ed34a3ca7..361bc40b3a7a 100644 --- a/packages/SettingsLib/res/values-nb/strings.xml +++ b/packages/SettingsLib/res/values-nb/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Tilgjengelig via %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Trykk for å registrere deg"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Tilkoblet – ingen Internett-tilgang"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Ingen internettilkobling"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Pålogging kreves"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Tilgangspunktet er midlertidig fullt"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Koblet til (ingen medier), batteri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Koblet til (ingen telefon eller medier), batteri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktiv, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktiv"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Medielyd"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonsamtaler"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Skal vare til omtrent <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Skal vare til omtrent <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Til <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Mindre enn <xliff:g id="THRESHOLD">%1$s</xliff:g> gjenstår"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Mindre enn <xliff:g id="THRESHOLD">%1$s</xliff:g> gjenstår (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Mer enn <xliff:g id="TIME_REMAINING">%1$s</xliff:g> gjenstår (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Spør hver gang"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Til du slår av"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Nå nettopp"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Telefonhøyttaler"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml index 451691b7f538..5283e2d9c8f2 100644 --- a/packages/SettingsLib/res/values-ne/strings.xml +++ b/packages/SettingsLib/res/values-ne/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s मार्फत उपलब्ध"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"साइन अप गर्न ट्याप गर्नुहोस्"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"जडान गरियो तर इन्टरनेट छैन"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"इन्टरनेटमाथिको पहुँच छैन"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"साइन इन गर्न आवश्यक छ"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"पहुँचसम्बन्धी स्थान अस्थायी रूपमा भरिएको छ"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"जडान गरियो (मिडियाबाहेक), ब्याट्री <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"जडान गरियो (फोन वा मिडियाबाहेक), ब्याट्री <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"सक्रिय, ब्याट्रीको स्तर: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"ब्याट्रीको स्तर: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"सक्रिय"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"मिडिया अडियो"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"फोन कलहरू"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"ब्याट्री लगभग <xliff:g id="TIME">%1$s</xliff:g> सम्म टिक्नु पर्छ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"लगभग <xliff:g id="TIME">%1$s</xliff:g> सम्म टिक्नु पर्छ"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g> सम्म"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"<xliff:g id="THRESHOLD">%1$s</xliff:g> भन्दा कम समय बाँकी छ"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"<xliff:g id="THRESHOLD">%1$s</xliff:g> भन्दा कम समय बाँकी (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> भन्दा बढी समय बाँकी (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"प्रत्येक पटक सोध्नुहोस्"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"तपाईंले निष्क्रिय नपार्दासम्म"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"अहिले भर्खरै"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"फोनको स्पिकर"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml index 00c36decf55f..1949ff722327 100644 --- a/packages/SettingsLib/res/values-nl/strings.xml +++ b/packages/SettingsLib/res/values-nl/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Beschikbaar via %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Tik om aan te melden"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Verbonden, geen internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Geen internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Inloggen vereist"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Toegangspunt tijdelijk vol"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Verbonden: <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (geen media), batterij: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Verbonden: <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (geen telefoon of media), batterij: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Actief, batterijniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Batterijniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Actief"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media-audio"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefoongesprekken"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Is nog genoeg tot ongeveer <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Is nog genoeg tot ongeveer <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Tot <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Minder dan <xliff:g id="THRESHOLD">%1$s</xliff:g> resterend"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Minder dan <xliff:g id="THRESHOLD">%1$s</xliff:g> resterend (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Meer dan <xliff:g id="TIME_REMAINING">%1$s</xliff:g> resterend (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Altijd vragen"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Totdat je uitschakelt"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Zojuist"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Telefoonluidspreker"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml index b24b4a29e91c..0523eabb2183 100644 --- a/packages/SettingsLib/res/values-or/strings.xml +++ b/packages/SettingsLib/res/values-or/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s ମାଧ୍ୟମରେ ଉପଲବ୍ଧ"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"ସାଇନ୍ ଅପ୍ ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"ସଂଯୁକ୍ତ, ଇଣ୍ଟର୍ନେଟ୍ ନାହିଁ"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"କୌଣସି ଇଣ୍ଟରନେଟ୍ ନାହିଁ"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"ସାଇନ୍-ଇନ୍ ଆବଶ୍ୟକ"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ଆକ୍ସେସ୍ ପଏଣ୍ଟ ସାମୟିକ ଭାବେ ପୂର୍ଣ୍ଣ"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"ସଂଯୁକ୍ତ ହେଲା (ମିଡିଆ ନୁହେଁ), ବ୍ୟାଟେରୀ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"ସଂଯୁକ୍ତ ହେଲା (ଫୋନ୍ କିମ୍ବା ମେଡିଆ ନୁହେଁ), ବ୍ୟାଟେରୀ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"ସକ୍ରିୟ, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ବ୍ୟାଟେରୀ"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ବ୍ୟାଟେରୀ"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"ସକ୍ରିୟ"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"ମିଡିଆ ଅଡିଓ"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ଫୋନ୍ କଲ୍ଗୁଡ଼ିକ"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"ବ୍ୟାଟେରୀ ପାଖାପାଖି <xliff:g id="TIME">%1$s</xliff:g> ଚାଲିବ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"ବ୍ୟାଟେରୀ <xliff:g id="TIME">%1$s</xliff:g> ପର୍ଯ୍ୟନ୍ତ ଚାଲିବ"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g> ପର୍ଯ୍ୟନ୍ତ"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"<xliff:g id="THRESHOLD">%1$s</xliff:g>ରୁ କମ୍ ସମୟ ବଳକା ଅଛି"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"<xliff:g id="THRESHOLD">%1$s</xliff:g> ରୁ କମ୍ ସମୟ ବଳକା ଅଛି (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>ରୁ ଅଧିକ ସମୟ ବଳକା ଅଛି(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"ପ୍ରତ୍ୟେକ ଥର ପଚାରନ୍ତୁ"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"ଆପଣ ବନ୍ଦ ନକରିବା ପର୍ଯ୍ୟନ୍ତ DND ଅନ୍ ରହିବ"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"ଏହିକ୍ଷଣି"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"ଫୋନ୍ ସ୍ପିକର୍"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml index 21a7ab9b27ce..2505f2e73abf 100644 --- a/packages/SettingsLib/res/values-pa/strings.xml +++ b/packages/SettingsLib/res/values-pa/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s ਰਾਹੀਂ ਉਪਲਬਧ"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"ਸਾਈਨ-ਅੱਪ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"ਕਨੈਕਟ ਕੀਤਾ, ਕੋਈ ਇੰਟਰਨੈੱਟ ਨਹੀਂ"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"ਇੰਟਰਨੈੱਟ ਨਹੀਂ"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"ਸਾਈਨ-ਇਨ ਲੋੜੀਂਦਾ ਹੈ"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ਐਕਸੈੱਸ ਪੁਆਇੰਟ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਸੰਪੂਰਨ ਰੁਝੇਂਵੇਂ ਵਿੱਚ ਹੈ"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"ਕਨੈਕਟ ਕੀਤਾ ਹੋਇਆ (ਕੋਈ ਮੀਡੀਆ ਨਹੀਂ), ਬੈਟਰੀ ਦਾ ਪੱਧਰ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"ਕਨੈਕਟ ਕੀਤਾ ਹੋਇਆ (ਕੋਈ ਫ਼ੋਨ ਜਾਂ ਮੀਡੀਆ ਨਹੀਂ), ਬੈਟਰੀ ਦਾ ਪੱਧਰ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"ਕਿਰਿਆਸ਼ੀਲ, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ਬੈਟਰੀ"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ਬੈਟਰੀ"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"ਕਿਰਿਆਸ਼ੀਲ"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"ਮੀਡੀਆ ਆਡੀਓ"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ਫ਼ੋਨ ਕਾਲਾਂ"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"ਲਗਭਗ <xliff:g id="TIME">%1$s</xliff:g> ਚੱਲੇਗਾ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"ਲਗਭਗ <xliff:g id="TIME">%1$s</xliff:g> ਚੱਲੇਗਾ"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g> ਤੱਕ"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"<xliff:g id="THRESHOLD">%1$s</xliff:g> ਤੋਂ ਘੱਟ ਸਮਾਂ ਬਾਕੀ"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"<xliff:g id="THRESHOLD">%1$s</xliff:g> ਤੋਂ ਘੱਟ ਸਮਾਂ ਬਾਕੀ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ਤੋਂ ਵੱਧ ਸਮਾਂ ਬਾਕੀ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"ਹਰ ਵਾਰ ਪੁੱਛੋ"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਬੰਦ ਨਹੀਂ ਕਰਦੇ"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"ਹੁਣੇ ਹੀ"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"ਫ਼ੋਨ ਦਾ ਸਪੀਕਰ"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml index e053514b18ce..211c09780aff 100644 --- a/packages/SettingsLib/res/values-pl/strings.xml +++ b/packages/SettingsLib/res/values-pl/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Dostępne przez %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Kliknij, by się zarejestrować"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Połączono, brak internetu"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Brak internetu"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Musisz się zalogować"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Punkt dostępu jest tymczasowo zajęty"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Połączono (bez multimediów), bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> – <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Połączono (bez telefonu i multimediów), bateria <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> – <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktywne, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> naładowania baterii"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> naładowania baterii"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Urządzenie aktywne"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Dźwięk multimediów"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Połączenia telefoniczne"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Powinno wystarczyć do <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Powinno wystarczyć do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Pozostało mniej niż <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Pozostało mniej niż <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Pozostało ponad: <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -459,5 +467,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Zawsze pytaj"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Dopóki nie wyłączysz"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Przed chwilą"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Głośnik telefonu"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml index 46b2f937c16d..7adcdf626674 100644 --- a/packages/SettingsLib/res/values-pt-rBR/strings.xml +++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Disponível via %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Toque para se inscrever"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Conectada, sem Internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Sem Internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"É necessário fazer login"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Ponto de acesso temporariamente cheio"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Conectado (sem mídia), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> de bateria"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Conectado (sem telefone ou mídia), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> de bateria"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Ativo, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Ativo"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Áudio da mídia"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Chamadas telefônicas"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Deve durar até cerca de <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Deve durar até cerca de <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Até <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Menos de <xliff:g id="THRESHOLD">%1$s</xliff:g> restante(s)"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Menos de <xliff:g id="THRESHOLD">%1$s</xliff:g> restante(s) (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Mais de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> restante(s) (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Perguntar sempre"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Até você desativar"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Agora"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Alto-falante do smartphone"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml index dd7861d5dabc..5b3bb4e789b5 100644 --- a/packages/SettingsLib/res/values-pt-rPT/strings.xml +++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Disponível através de %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Toque para se inscrever"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Ligado, sem Internet."</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Sem Internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"É necessário iniciar sessão"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Ponto de acesso temporariamente cheio"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Ligado (sem multimédia), bateria a <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Ligado (sem telemóvel nem multimédia), bateria a <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Ativo, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Ativo"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Áudio de multimédia"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Chamadas telefónicas"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Deve durar até cerca da(s) <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Deve durar até cerca da(s) <xliff:g id="TIME">%1$s</xliff:g>."</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Até à(s) <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Resta(m) menos de <xliff:g id="THRESHOLD">%1$s</xliff:g>."</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Resta(m) menos de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Resta(m) mais de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Perguntar sempre"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Até ser desativado"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Agora mesmo"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Altifalante do telemóvel"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml index 46b2f937c16d..7adcdf626674 100644 --- a/packages/SettingsLib/res/values-pt/strings.xml +++ b/packages/SettingsLib/res/values-pt/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Disponível via %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Toque para se inscrever"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Conectada, sem Internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Sem Internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"É necessário fazer login"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Ponto de acesso temporariamente cheio"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Conectado (sem mídia), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> de bateria"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Conectado (sem telefone ou mídia), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> de bateria"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Ativo, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Ativo"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Áudio da mídia"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Chamadas telefônicas"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Deve durar até cerca de <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Deve durar até cerca de <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Até <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Menos de <xliff:g id="THRESHOLD">%1$s</xliff:g> restante(s)"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Menos de <xliff:g id="THRESHOLD">%1$s</xliff:g> restante(s) (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Mais de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> restante(s) (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Perguntar sempre"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Até você desativar"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Agora"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Alto-falante do smartphone"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml index 3364ce5a6d3b..24911e59ec2e 100644 --- a/packages/SettingsLib/res/values-ro/strings.xml +++ b/packages/SettingsLib/res/values-ro/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Disponibilă prin %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Atingeți pentru a vă înscrie"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Conectată, fără internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Fără conexiune la internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Trebuie să vă conectați"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Punctul de acces este temporar plin"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Conectat (fără conținut media), baterie <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Conectat (fără telefon sau conținut media), baterie <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Activ, baterie <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Nivelul bateriei: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Activ"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Conținut media audio"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Apeluri telefonice"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Ar trebui să reziste până la <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Ar trebui să reziste până la <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Până la <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"a mai rămas mai puțin de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"A mai rămas mai puțin de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"A mai rămas mai mult de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -458,5 +466,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Întreabă de fiecare dată"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Până când dezactivați"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Chiar acum"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Difuzorul telefonului"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml index ffd477db821a..abe3ea22e0c3 100644 --- a/packages/SettingsLib/res/values-ru/strings.xml +++ b/packages/SettingsLib/res/values-ru/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Доступно через %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Нажмите, чтобы зарегистрироваться"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Подключено, без доступа к Интернету"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Нет подключения к Интернету"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Требуется выполнить вход."</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"К точке доступа подключено слишком много устройств"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Подключено (кроме аудио), уровень заряда батареи: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Подключено (кроме звонков и аудио), уровень заряда батареи: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Активно. Уровень заряда: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Уровень заряда: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Активно"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Профиль A2DP"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Звонки"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Заряда (<xliff:g id="LEVEL">%2$s</xliff:g>) хватит примерно до <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Заряда хватит примерно до <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"До <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Осталось менее <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Уровень заряда батареи: <xliff:g id="LEVEL">%2$s</xliff:g> (хватит менее чем на <xliff:g id="THRESHOLD">%1$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Уровень заряда батареи: <xliff:g id="LEVEL">%2$s</xliff:g> (хватит более чем на <xliff:g id="TIME_REMAINING">%1$s</xliff:g>)"</string> @@ -459,5 +467,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Всегда спрашивать"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Пока вы не отключите"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Только что"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Встроенный динамик"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml index f3372b3c1ed2..29524a176079 100644 --- a/packages/SettingsLib/res/values-si/strings.xml +++ b/packages/SettingsLib/res/values-si/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s හරහා ලබා ගැනීමට හැකිය"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"ලියාපදිංචි වීමට තට්ටු කරන්න"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"සම්බන්ධයි, අන්තර්ජාලය නැත"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"අන්තර්ජාලය නැත"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"පිරීම අවශ්යයි"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ප්රවේශ ලක්ෂ්ය තාවකාලිකව පිරී ඇත"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"සම්බන්ධිතයි (මාධ්ය නැත), බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"සම්බන්ධිතයි (දුරකථනය හෝ මාධ්ය නැත), බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"ක්රියාකාරී, බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"ක්රියාකාරී"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"මාධ්ය ශ්රව්ය"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"දුරකථන ඇමතුම්"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"<xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>) පමණ වන තෙක් තිබිය යුතුය"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"<xliff:g id="TIME">%1$s</xliff:g> පමණ වන තෙක් තිබිය යුතුය"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g> දක්වා"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"<xliff:g id="THRESHOLD">%1$s</xliff:g>ට වඩා අඩුවෙන් ඉතිරිව ඇත"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"<xliff:g id="THRESHOLD">%1$s</xliff:g>ට වඩා අඩුවෙන් ඉතිරිය (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>ට වඩා වැඩියෙන් ඉතිරිය (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"සෑම විටම ඉල්ලන්න"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"ඔබ ක්රියාවිරහිත කරන තුරු"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"මේ දැන්"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"දුරකථන ස්පීකරය"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml index 5451a0be6729..1f6337427e47 100644 --- a/packages/SettingsLib/res/values-sk/strings.xml +++ b/packages/SettingsLib/res/values-sk/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"K dispozícii prostredníctvom %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Prihláste sa klepnutím"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Pripojené, žiadny internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Žiadny internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Vyžaduje sa prihlásenie"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Prístupový bod je dočasne plný"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Pripojené k zariadeniu <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (bez médií), úroveň batérie <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Pripojené k zariadeniu <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (bez telefónu a médií), úroveň batérie <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktívne, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batérie"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Batéria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktívne"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Zvuk medií"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonické hovory"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Mal by vydržať približne <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Mal by vydržať približne do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Zostáva menej ako <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Zostáva menej ako <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Zostáva viac ako <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -459,5 +467,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Vždy sa opýtať"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Dokiaľ túto funkciu nevypnete"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Teraz"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Reproduktor telefónu"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml index 57265ca31514..132e9d0bbef3 100644 --- a/packages/SettingsLib/res/values-sl/strings.xml +++ b/packages/SettingsLib/res/values-sl/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Na voljo prek: %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Dotaknite se, če se želite registrirati"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Vzpostavljena povezava, brez interneta"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Brez internetne povezave"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Zahtevana je prijava"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Dostopna točka je trenutno zasedena"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Povezano (brez predstavnosti), raven napolnjenosti akumulatorja je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Povezano (brez telefona ali predstavnosti), raven napolnjenosti akumulatorja je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktivna, akumulator na <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Akumulator na <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktivna"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Zvok predstavnosti"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonski klici"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Naprava bi morala delovati do približno <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Naprava bi morala delovati do približno <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Preostalo manj kot <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Preostanek: manj kot <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Preostali čas delovanja: manj kot <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -459,5 +467,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Vedno vprašaj"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Dokler ne izklopite"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Pravkar"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Zvočnik telefona"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml index 231cc1e900fa..fa0eb830ceba 100644 --- a/packages/SettingsLib/res/values-sq/strings.xml +++ b/packages/SettingsLib/res/values-sq/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"E mundshme përmes %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Trokit për t\'u regjistruar"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"U lidh, por nuk ka internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Nuk ka internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Kërkohet identifikimi"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Pika e qasjes është përkohësisht plot"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"E lidhur (pa media), bateria <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"E lidhur (pa telefon ose media), bateria <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktiv, bateria <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Bateria <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktiv"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audioja e klipit \"media\""</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonatat"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Duhet të zgjasë deri në rreth <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Duhet të zgjasë deri në rreth <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Deri në <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Më pak se <xliff:g id="THRESHOLD">%1$s</xliff:g> të mbetura"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Mbeten më pak se <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Mbeten më shumë se <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Pyet çdo herë"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Deri sa ta çaktivizosh"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Pikërisht tani"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Altoparlanti i telefonit"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml index 42900f71b2f0..574b216be79c 100644 --- a/packages/SettingsLib/res/values-sr/strings.xml +++ b/packages/SettingsLib/res/values-sr/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Доступна је преко приступне тачке %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Додирните да бисте се регистровали"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Веза је успостављена, нема интернета"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Нема интернета"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Треба да се пријавите"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Приступна тачка је привремено заузета"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Повезано (без медија), ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Повезано (без телефона или медија), ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Активан, ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Активан"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Звук медија"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Телефонски позиви"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Трајаће приближно до <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Трајаће приближно до <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"До <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Преостало је мање од <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Преостало је мање од <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Преостало је више од <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -458,5 +466,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Увек питај"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Док не искључите"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Управо"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Звучник телефона"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml index cc5b76bbebcd..1a5fbf9e75b9 100644 --- a/packages/SettingsLib/res/values-sv/strings.xml +++ b/packages/SettingsLib/res/values-sv/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Tillgängligt via %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Tryck för att logga in"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Ansluten, inget internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Inget internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Inloggning krävs"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Åtkomstpunkten har inga platser över för tillfället"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Ansluten (inga medier), batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Ansluten (ingen mobil och inga medier), batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktiv. <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktiv"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Medialjud"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonsamtal"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Bör räcka ungefär till klockan <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Bör räcka ungefär till klockan <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Till kl. <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Mindre än <xliff:g id="THRESHOLD">%1$s</xliff:g> återstår"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Mindre än <xliff:g id="THRESHOLD">%1$s</xliff:g> återstår (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Mer än <xliff:g id="TIME_REMAINING">%1$s</xliff:g> återstår (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Fråga varje gång"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Tills du inaktiverar funktionen"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Nyss"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Mobilens högtalare"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml index ebe15016d4ab..42837adce1c7 100644 --- a/packages/SettingsLib/res/values-sw/strings.xml +++ b/packages/SettingsLib/res/values-sw/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Inapatikana kupitia %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Gusa ili ujisajili"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Imeunganishwa, hakuna intaneti"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Hakuna intaneti"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Unahitaji kuingia katika akaunti"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Lango la mtandao lina shughuli nyingi kwa sasa"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Imeunganishwa (hamna kifaa cha sauti), kiasi cha chaji ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Imeunganishwa (hamna simu au kifaa cha sauti), kiasi cha chaji ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Inatumika, chaji ya betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Chaji ya betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Unaendelea"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media ya sauti"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Simu"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Inapaswa kudumu kwa takribani <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Inapaswa kudumu hadi <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Hadi <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Zimesalia chini ya <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Zimesalia chini ya <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Zimesalia zaidi ya <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Uliza kila wakati"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Hadi utakapoizima"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Sasa hivi"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Spika ya simu"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml index 951bf99adca4..3960f4428d57 100644 --- a/packages/SettingsLib/res/values-ta/strings.xml +++ b/packages/SettingsLib/res/values-ta/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s வழியாகக் கிடைக்கிறது"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"பதிவு செய்யத் தட்டவும்"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"இணைக்கப்பட்டுள்ளது, ஆனால் இண்டர்நெட் இல்லை"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"இணைய இணைப்பு இல்லை"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"உள்நுழைய வேண்டும்"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"தற்காலிகமாக அணுகல் புள்ளி நிரம்பியுள்ளது"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"இணைக்கப்பட்டது (மீடியா இல்லை), பேட்டரி <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"இணைக்கப்பட்டது (மொபைல் அல்லது மீடியா இல்லை), பேட்டரி <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"செயலில் உள்ளது, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> பேட்டரி"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> பேட்டரி"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"செயலில் உள்ளது"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"மீடியா ஆடியோ"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ஃபோன் அழைப்புகள்"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"<xliff:g id="TIME">%1$s</xliff:g> வரை பயன்படுத்த முடியும் (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"<xliff:g id="TIME">%1$s</xliff:g> வரை பயன்படுத்த முடியும்"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g> வரை"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"<xliff:g id="THRESHOLD">%1$s</xliff:g>க்கும் குறைவாகவே பயன்படுத்த முடியும்"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"<xliff:g id="THRESHOLD">%1$s</xliff:g>க்கும் குறைவாகவே பயன்படுத்த முடியும் (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>க்கும் மேல் பயன்படுத்த முடியும் (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"ஒவ்வொரு முறையும் கேள்"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"ஆஃப் செய்யும் வரை"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"சற்றுமுன்"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"மொபைல் ஸ்பீக்கர்"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml index f7b98d1d46cd..359513676091 100644 --- a/packages/SettingsLib/res/values-te/strings.xml +++ b/packages/SettingsLib/res/values-te/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s ద్వారా అందుబాటులో ఉంది"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"సైన్ అప్ చేయడానికి నొక్కండి"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"కనెక్ట్ చేయబడింది, ఇంటర్నెట్ లేదు"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"ఇంటర్నెట్ లేదు"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"సైన్ ఇన్ చేయాలి"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"యాక్సెస్ పాయింట్ తాత్కాలికంగా నిండుకుంది"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"కనెక్ట్ చేయబడింది (మీడియా కాదు), బ్యాటరీ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"కనెక్ట్ చేయబడింది (ఫోన్ లేదా మీడియా కాదు), బ్యాటరీ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"యాక్టివ్గా ఉంది, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> బ్యాటరీ"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> బ్యాటరీ"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"యాక్టివ్గా ఉంది"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"మీడియా ఆడియో"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ఫోన్ కాల్లు"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"దాదాపు <xliff:g id="TIME">%1$s</xliff:g> వరకు ఉండాలి (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"దాదాపు <xliff:g id="TIME">%1$s</xliff:g> వరకు ఉండాలి"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g> వరకు"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"<xliff:g id="THRESHOLD">%1$s</xliff:g> కంటే తక్కువ సమయం మిగిలి ఉంది"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"<xliff:g id="THRESHOLD">%1$s</xliff:g> కంటే తక్కువ సమయం మిగిలి ఉంది (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> కంటే ఎక్కువ సమయం మిగిలి ఉంది (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"ప్రతిసారి అడుగు"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"మీరు ఆఫ్ చేసే వరకు"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"ఇప్పుడే"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"ఫోన్ స్పీకర్"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml index 7d161bb7dee4..2edf1a9473f7 100644 --- a/packages/SettingsLib/res/values-th/strings.xml +++ b/packages/SettingsLib/res/values-th/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"พร้อมใช้งานผ่านทาง %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"แตะเพื่อลงชื่อสมัครใช้"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"เชื่อมต่อแล้ว ไม่พบอินเทอร์เน็ต"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"ไม่มีอินเทอร์เน็ต"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"ต้องลงชื่อเข้าใช้"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"จุดเข้าใช้งานเต็มชั่วคราว"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"เชื่อมต่อแล้ว (ไม่รวมสื่อ) แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"เชื่อมต่อแล้ว (ไม่รวมโทรศัพท์หรือสื่อ) แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"ใช้งานอยู่ แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"ใช้งานอยู่"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"เสียงของสื่อ"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"โทรศัพท์"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"น่าจะใช้งานได้ถึงเวลาประมาณ <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"น่าจะใช้งานได้ถึงเวลาประมาณ <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"จนถึง <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"เหลืออีกไม่ถึง <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"เหลือเวลาอีกไม่ถึง <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"เหลือเวลามากกว่า <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"ถามทุกครั้ง"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"จนกว่าคุณจะปิด"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"เมื่อสักครู่"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"ลำโพงโทรศัพท์"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml index e9a2a6f9728f..763a45d2318e 100644 --- a/packages/SettingsLib/res/values-tl/strings.xml +++ b/packages/SettingsLib/res/values-tl/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Available sa pamamagitan ng %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"I-tap para mag-sign up"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Nakakonekta, walang internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Walang internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Kinakailangang mag-sign in"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Pansamantalang puno ang access point"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Nakakonekta (walang media), baterya <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Nakakonekta (walang telepono o media), baterya <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktibo, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterya"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterya"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktibo"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio ng media"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Mga tawag sa telepono"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Tatagal dapat nang hanggang humigit-kumulang <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Tatagal hanggang mga <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Hanggang <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Wala nang <xliff:g id="THRESHOLD">%1$s</xliff:g> ang natitira"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Wala nang <xliff:g id="THRESHOLD">%1$s</xliff:g> ang natitira (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Mahigit <xliff:g id="TIME_REMAINING">%1$s</xliff:g> pa ang natitira (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Magtanong palagi"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Hanggang sa i-off mo"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Ngayon lang"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Speaker ng telepono"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml index 73f1c40e3b6a..8da091c50c46 100644 --- a/packages/SettingsLib/res/values-tr/strings.xml +++ b/packages/SettingsLib/res/values-tr/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s üzerinden kullanılabilir"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Kaydolmak için dokunun"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Bağlı, internet yok"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"İnternet yok"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Oturum açılması gerekiyor"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Erişim noktası geçici olarak dolu"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> cihazına bağlandı (medya yok), pil <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> cihazına bağlandı (telefon veya medya yok), pil seviyesi <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Etkin, pil düzeyi <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Pil düzeyi <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Etkin"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Medya sesi"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefon çağrıları"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Saat yaklaşık <xliff:g id="TIME">%1$s</xliff:g> olana kadar kullanılabilmelidir (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Saat yaklaşık <xliff:g id="TIME">%1$s</xliff:g> olana kadar kullanılabilmelidir"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Şu saate kadar: <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"En fazla <xliff:g id="THRESHOLD">%1$s</xliff:g> kaldı"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"En çok <xliff:g id="THRESHOLD">%1$s</xliff:g> kaldı (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"En az <xliff:g id="TIME_REMAINING">%1$s</xliff:g> kaldı (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Her zaman sor"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Siz kapatana kadar"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Az önce"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Telefon hoparlörü"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml index 41d68838cb09..54d39c6a999c 100644 --- a/packages/SettingsLib/res/values-uk/strings.xml +++ b/packages/SettingsLib/res/values-uk/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Доступ через %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Торкніться, щоб увійти"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Під’єднано, але немає доступу до Інтернету"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Немає Інтернету"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Потрібно ввійти в обліковий запис"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Точка доступу тимчасово переповнена"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> під’єднано (без медіа), заряд акумулятора – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> під’єднано (без телефона й медіа), заряд акумулятора – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Активовано, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> заряду акумулятора"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> заряду акумулятора"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Активовано"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Звук медіа-файлів"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Телефонні дзвінки"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Вистачить приблизно до <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Вистачить приблизно до <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"До <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Залишилося менше ніж <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Залишилося менше ніж <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Залишилося понад <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -459,5 +467,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Запитувати щоразу"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Доки ви не вимкнете"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Щойно"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Динамік телефона"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml index 0478a76dc4e2..b2fc3d99a330 100644 --- a/packages/SettingsLib/res/values-ur/strings.xml +++ b/packages/SettingsLib/res/values-ur/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"دستیاب بذریعہ %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"سائن اپ کے لیے تھپتھپائیں"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"منسلک، انٹرنیٹ نہیں ہے"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"انٹرنیٹ نہیں ہے"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"سائن ان درکار ہے"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"رسائی پوائنٹ عارضی طور پر فُل ہے"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"منسلک ہے (میڈیا کے علاوہ)، بیٹری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"منسلک ہے (فون یا میڈیا کے علاوہ)، بیٹری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"فعال، <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> بیٹری"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> بیٹری"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"فعال"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"میڈيا آڈیو"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"فون کالز"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"تقریباً <xliff:g id="TIME">%1$s</xliff:g> تک بیٹری چلے گی (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"تقریباً <xliff:g id="TIME">%1$s</xliff:g> تک بیٹری چلے گی"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g> تک"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"<xliff:g id="THRESHOLD">%1$s</xliff:g> سے کم باقی ہے"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"<xliff:g id="THRESHOLD">%1$s</xliff:g> سے کم باقی ہے (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> سے زیادہ باقی ہے (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"ہر بار پوچھیں"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"یہاں تک کہ آپ آف کر دیں"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"ابھی ابھی"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"فون اسپیکر"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml index d4eb44bb9a79..40333806ce99 100644 --- a/packages/SettingsLib/res/values-uz/strings.xml +++ b/packages/SettingsLib/res/values-uz/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s orqali ishlaydi"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Yozilish uchun bosing"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Ulangan, lekin internet aloqasi yo‘q"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Internet yo‘q"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Hisob bilan kirish zarur"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Internet kirish nuqtasi vaqtinchalik to‘lgan"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> ulandi (mediadan tashqari), batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> ulandi (telefon yoki mediadan tashqari), batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Faol, batariya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Faol"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefon chaqiruvlari"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Taxminan <xliff:g id="TIME">%1$s</xliff:g> gacha davom etadi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Taxminan <xliff:g id="TIME">%1$s</xliff:g> gacha davom etadi"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g> gacha"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"<xliff:g id="THRESHOLD">%1$s</xliff:g>dan kamroq vaqt qoldi"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"<xliff:g id="THRESHOLD">%1$s</xliff:g>dan kamroq vaqt qoldi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>dan ko‘proq vaqt qoldi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Har safar so‘ralsin"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Bekor qilinmaguncha"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Hozir"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Telefon karnayi"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml index 050ee9cdcbd6..65e3c17f308d 100644 --- a/packages/SettingsLib/res/values-vi/strings.xml +++ b/packages/SettingsLib/res/values-vi/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Có sẵn qua %1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Nhấn để đăng ký"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Đã kết nối, không có Internet"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Không có Internet"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Yêu cầu đăng nhập"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Điểm truy cập tạm thời đã đạt đến giới hạn số lượng thiết bị truy cập."</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Đã kết nối (không có phương tiện), mức pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Đã kết nối (không có điện thoại hoặc phương tiện), mức pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Đang hoạt động, mức pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Mức pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Đang hoạt động"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Âm thanh của phương tiện"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Cuộc gọi điện thoại"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Sẽ hết pin cho tới khoảng <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Sẽ hết pin cho tới khoảng <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Cho đến <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Còn lại không đến <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Còn lại không đến <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Còn lại hơn <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Luôn hỏi"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Cho đến khi bạn tắt"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Vừa xong"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Loa điện thoại"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml index e25e4dcf38c3..e9b8c93f447b 100644 --- a/packages/SettingsLib/res/values-zh-rCN/strings.xml +++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"可通过%1$s连接"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"点按即可注册"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"已连接,但无法访问互联网"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"无法访问互联网"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"必须登录"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"接入点暂时满载"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"已连接(无媒体信号),电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"已连接(无手机或媒体信号),电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"使用中,电池电量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"电池电量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"使用中"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"媒体音频"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"通话"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"目前电量为 <xliff:g id="LEVEL">%2$s</xliff:g>,估计能用到<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"估计能用到<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"直到<xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"剩余电池续航时间不到 <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"电量剩余使用时间不到 <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"电量剩余使用时间超过 <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"每次都询问"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"直到您将其关闭"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"刚刚"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"手机扬声器"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml index 3e357b1ce450..f431c8b354af 100644 --- a/packages/SettingsLib/res/values-zh-rHK/strings.xml +++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"可透過 %1$s 連線"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"輕按即可登入"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"已連線,但沒有互聯網"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"沒有互聯網連線"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"必須登入"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"存取點暫時已滿"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"已連接 (無媒體音訊),電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"已連接 (無手機或媒體音訊),電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"使用中,電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"使用中"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"媒體音效"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"通話"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"電量剩餘約 <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"電量剩餘約 <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"還可用到<xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"剩餘電量時間少於 <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"還有少於 <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"還有超過 <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"每次都詢問"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"直至您關閉為止"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"剛剛"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"手機喇叭"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml index 60330eff4a10..33f18b7a7657 100644 --- a/packages/SettingsLib/res/values-zh-rTW/strings.xml +++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"可透過 %1$s 使用"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"輕觸即可註冊"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"已連線,沒有網際網路"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"沒有網際網路連線"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"必須登入"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"存取點暫時滿載"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"已連線 (無媒體音訊),電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"已連線 (無手機或媒體音訊),電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"使用中,電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"使用中"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"媒體音訊"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"通話"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"目前電量 <xliff:g id="LEVEL">%2$s</xliff:g>,預估還能持續使用到<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"預估還能持續使用到<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"還能持續使用到<xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"電池可用時間不到 <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"電池可用時間不到 <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"電池可用時間超過 <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"每次都詢問"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"直到你關閉為止"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"剛剛"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"手機喇叭"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml index a1be06c94d9f..364ac8c45200 100644 --- a/packages/SettingsLib/res/values-zu/strings.xml +++ b/packages/SettingsLib/res/values-zu/strings.xml @@ -42,6 +42,8 @@ <string name="available_via_passpoint" msgid="1617440946846329613">"Iyatholakala nge-%1$s"</string> <string name="tap_to_sign_up" msgid="6449724763052579434">"Thepha ukuze ubhalisele"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Kuxhunyiwe, ayikho i-inthanethi"</string> + <!-- no translation found for wifi_limited_connection (7717855024753201527) --> + <skip /> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Ayikho i-inthanethi"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Ukungena ngemvume kuyadingeka"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Iphoyinti lokufinyelela ligcwele okwesikhashana"</string> @@ -73,7 +75,11 @@ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Ixhunyiwe (ayikho imidiya), ibhethri iku-<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Ixhunyiwe (ayikho ifoni noma imidiya), ibhethri ngu-<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Kuyasebenza, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ibhethri"</string> + <!-- no translation found for bluetooth_active_battery_level_untethered (6662649951391456747) --> + <skip /> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ibhethri"</string> + <!-- no translation found for bluetooth_battery_level_untethered (5974406100211667177) --> + <skip /> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Iyasebenza"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Umsindo wemidiya"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Amakholi efoni"</string> @@ -384,6 +390,8 @@ <string name="power_discharge_by" msgid="6453537733650125582">"Kumele ihlale cishe kube ngu-<xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="107616694963545745">"Kumele ihlale cishe kube ngu-<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Kuze kube ngu-<xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_suggestion_extend_battery (4401408879069551485) --> + <skip /> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Kusele okungaphansi kunokungu-<xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Ngaphansi kuka-<xliff:g id="THRESHOLD">%1$s</xliff:g> osele (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Ngaphezu kuka-<xliff:g id="TIME_REMAINING">%1$s</xliff:g> osele (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -457,5 +465,6 @@ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Buza njalo"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Uze uvale isikrini"</string> <string name="time_unit_just_now" msgid="6363336622778342422">"Khona manje"</string> - <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Isipikha sefoni"</string> + <!-- no translation found for media_transfer_this_device_name (1636276898262571213) --> + <skip /> </resources> diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java index b34f445d91f5..b025df44738e 100644 --- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java @@ -185,14 +185,14 @@ public class BatterySaverUtils { */ public static void revertScheduleToNoneIfNeeded(Context context) { ContentResolver resolver = context.getContentResolver(); - final int currentMode = Global.getInt(resolver, Global.AUTOMATIC_POWER_SAVER_MODE, - PowerManager.POWER_SAVER_MODE_PERCENTAGE); + final int currentMode = Global.getInt(resolver, Global.AUTOMATIC_POWER_SAVE_MODE, + PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE); boolean providerConfigured = !TextUtils.isEmpty(context.getString( com.android.internal.R.string.config_batterySaverScheduleProvider)); - if (currentMode == PowerManager.POWER_SAVER_MODE_DYNAMIC && !providerConfigured) { + if (currentMode == PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC && !providerConfigured) { Global.putInt(resolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0); - Global.putInt(resolver, Global.AUTOMATIC_POWER_SAVER_MODE, - PowerManager.POWER_SAVER_MODE_PERCENTAGE); + Global.putInt(resolver, Global.AUTOMATIC_POWER_SAVE_MODE, + PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE); } } } diff --git a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaManager.java index 3a738d23f452..151aa8d0cf6f 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaManager.java @@ -277,14 +277,39 @@ public class BluetoothMediaManager extends MediaManager implements BluetoothCall public void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile) { Log.d(TAG, "onActiveDeviceChanged : device : " + activeDevice + ", profile : " + bluetoothProfile); - if (BluetoothProfile.HEARING_AID == bluetoothProfile - || BluetoothProfile.A2DP == bluetoothProfile) { + + if (BluetoothProfile.HEARING_AID == bluetoothProfile) { + if (activeDevice != null) { + dispatchConnectedDeviceChanged(MediaDeviceUtils.getId(activeDevice)); + } + } else if (BluetoothProfile.A2DP == bluetoothProfile) { + // When active device change to Hearing Aid, + // BluetoothEventManager also send onActiveDeviceChanged() to notify that active device + // of A2DP profile is null. To handle this case, check hearing aid device + // is active device or not + final MediaDevice activeHearingAidDevice = findActiveHearingAidDevice(); final String id = activeDevice == null - ? PhoneMediaDevice.ID : MediaDeviceUtils.getId(activeDevice); + ? activeHearingAidDevice == null + ? PhoneMediaDevice.ID : activeHearingAidDevice.getId() + : MediaDeviceUtils.getId(activeDevice); dispatchConnectedDeviceChanged(id); } } + private MediaDevice findActiveHearingAidDevice() { + final HearingAidProfile hearingAidProfile = mProfileManager.getHearingAidProfile(); + + if (hearingAidProfile != null) { + final List<BluetoothDevice> activeDevices = hearingAidProfile.getActiveDevices(); + for (BluetoothDevice btDevice : activeDevices) { + if (btDevice != null) { + return findMediaDevice(MediaDeviceUtils.getId(btDevice)); + } + } + } + return null; + } + @Override public void onServiceConnected() { if (!mIsA2dpProfileReady || !mIsHearingAidProfileReady) { diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java index bdddaf394f89..f181150de513 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java @@ -15,6 +15,8 @@ */ package com.android.settingslib.media; +import android.bluetooth.BluetoothDevice; + import androidx.mediarouter.media.MediaRouter; import com.android.settingslib.bluetooth.CachedBluetoothDevice; @@ -34,6 +36,16 @@ public class MediaDeviceUtils { } /** + * Use BluetoothDevice address to represent unique id + * + * @param bluetoothDevice the BluetoothDevice + * @return BluetoothDevice address + */ + public static String getId(BluetoothDevice bluetoothDevice) { + return bluetoothDevice.getAddress(); + } + + /** * Use RouteInfo id to represent unique id * * @param route the RouteInfo diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaManagerTest.java index 48449f20699d..70b04ab40c34 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaManagerTest.java @@ -425,4 +425,34 @@ public class BluetoothMediaManagerTest { verify(mCallback, never()).onConnectedDeviceChanged(any()); } + + @Test + public void onActiveDeviceChanged_hearingAidDeviceIsActive_returnHearingAidDeviceId() { + final BluetoothDevice bluetoothDevice = mock(BluetoothDevice.class); + final List<BluetoothDevice> devices = new ArrayList<>(); + devices.add(bluetoothDevice); + final BluetoothMediaDevice bluetoothMediaDevice = mock(BluetoothMediaDevice.class); + mMediaManager.mMediaDevices.add(bluetoothMediaDevice); + + when(bluetoothDevice.getAddress()).thenReturn(TEST_ADDRESS); + when(mHapProfile.getActiveDevices()).thenReturn(devices); + when(bluetoothMediaDevice.getId()).thenReturn(TEST_ADDRESS); + + mMediaManager.registerCallback(mCallback); + mMediaManager.onActiveDeviceChanged(null, BluetoothProfile.A2DP); + + verify(mCallback).onConnectedDeviceChanged(TEST_ADDRESS); + } + + @Test + public void onActiveDeviceChanged_hearingAidDeviceNotActive_returnPhoneDeviceId() { + final List<BluetoothDevice> devices = new ArrayList<>(); + + when(mHapProfile.getActiveDevices()).thenReturn(devices); + + mMediaManager.registerCallback(mCallback); + mMediaManager.onActiveDeviceChanged(null, BluetoothProfile.A2DP); + + verify(mCallback).onConnectedDeviceChanged(PhoneMediaDevice.ID); + } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceUtilsTest.java index 6e29e137c9f2..1e5545f8539f 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceUtilsTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceUtilsTest.java @@ -20,6 +20,8 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.when; +import android.bluetooth.BluetoothDevice; + import androidx.mediarouter.media.MediaRouter; import com.android.settingslib.bluetooth.CachedBluetoothDevice; @@ -38,7 +40,9 @@ public class MediaDeviceUtilsTest { private static final String TEST_ROUTE_ID = "test_route_id"; @Mock - private CachedBluetoothDevice mDevice; + private CachedBluetoothDevice mCachedDevice; + @Mock + private BluetoothDevice mBluetoothDevice; @Mock private MediaRouter.RouteInfo mRouteInfo; @@ -48,10 +52,19 @@ public class MediaDeviceUtilsTest { } @Test + public void getId_returnCachedBluetoothDeviceAddress() { + when(mCachedDevice.getAddress()).thenReturn(TEST_ADDRESS); + + final String id = MediaDeviceUtils.getId(mCachedDevice); + + assertThat(id).isEqualTo(TEST_ADDRESS); + } + + @Test public void getId_returnBluetoothDeviceAddress() { - when(mDevice.getAddress()).thenReturn(TEST_ADDRESS); + when(mBluetoothDevice.getAddress()).thenReturn(TEST_ADDRESS); - final String id = MediaDeviceUtils.getId(mDevice); + final String id = MediaDeviceUtils.getId(mBluetoothDevice); assertThat(id).isEqualTo(TEST_ADDRESS); } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/apppreference/AppPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/apppreference/AppPreferenceTest.java index 042616aa2015..284888888589 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/apppreference/AppPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/apppreference/AppPreferenceTest.java @@ -57,24 +57,6 @@ public class AppPreferenceTest { } @Test - public void setSummary_showSummaryContainer() { - mPref.setSummary("test"); - mPref.onBindViewHolder(mHolder); - - assertThat(mHolder.findViewById(R.id.summary_container).getVisibility()) - .isEqualTo(View.VISIBLE); - } - - @Test - public void noSummary_hideSummaryContainer() { - mPref.setSummary(null); - mPref.onBindViewHolder(mHolder); - - assertThat(mHolder.findViewById(R.id.summary_container).getVisibility()) - .isEqualTo(View.GONE); - } - - @Test public void foobar_testName() { float iconSize = mContext.getResources().getDimension(R.dimen.secondary_app_icon_size); assertThat(Float.floatToIntBits(iconSize)).isEqualTo(Float.floatToIntBits(32)); diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java index a33f9a8709d9..e374db310737 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -844,7 +844,7 @@ class SettingsProtoDumpUtil { Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL_MAX, GlobalSettingsProto.LowPowerMode.TRIGGER_LEVEL_MAX); dumpSetting(s, p, - Settings.Global.AUTOMATIC_POWER_SAVER_MODE, + Settings.Global.AUTOMATIC_POWER_SAVE_MODE, GlobalSettingsProto.LowPowerMode.AUTOMATIC_POWER_SAVER_MODE); dumpSetting(s, p, Settings.Global.LOW_POWER_MODE_STICKY, @@ -2410,12 +2410,6 @@ class SettingsProtoDumpUtil { Settings.Secure.WAKE_GESTURE_ENABLED, SecureSettingsProto.WAKE_GESTURE_ENABLED); - final long launcherToken = p.start(SecureSettingsProto.LAUNCHER); - dumpSetting(s, p, - Settings.Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED, - SecureSettingsProto.Launcher.SWIPE_UP_TO_SWITCH_APPS_ENABLED); - p.end(launcherToken); - final long zenToken = p.start(SecureSettingsProto.ZEN); dumpSetting(s, p, Settings.Secure.ZEN_DURATION, diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index ff25ad9f037b..4b342b37ac20 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -19,6 +19,12 @@ package com.android.providers.settings; import static android.os.Process.ROOT_UID; import static android.os.Process.SHELL_UID; import static android.os.Process.SYSTEM_UID; +import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON; +import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON_OVERLAY; +import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON; +import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY; +import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL; +import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY; import android.Manifest; import android.annotation.NonNull; @@ -33,6 +39,8 @@ import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.om.IOverlayManager; +import android.content.om.OverlayInfo; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; @@ -1066,8 +1074,7 @@ public class SettingsProvider extends ContentProvider { Slog.v(LOG_TAG, "getConfigSetting(" + name + ")"); } - // TODO(b/117663715): Ensure the caller can access the setting. - // enforceReadPermission(READ_DEVICE_CONFIG); + DeviceConfig.enforceReadPermission(getContext(), /*namespace=*/name.split("/")[0]); // Get the value. synchronized (mLock) { @@ -3235,7 +3242,7 @@ public class SettingsProvider extends ContentProvider { } private final class UpgradeController { - private static final int SETTINGS_VERSION = 175; + private static final int SETTINGS_VERSION = 177; private final int mUserId; @@ -4286,6 +4293,82 @@ public class SettingsProvider extends ContentProvider { currentVersion = 175; } + if (currentVersion == 175) { + // Version 175: Set the default value for System Settings: + // RING_VIBRATION_INTENSITY. If the notification vibration intensity has been + // set and ring vibration intensity hasn't, the ring vibration intensity should + // followed notification vibration intensity. + + final SettingsState systemSettings = getSystemSettingsLocked(userId); + + Setting notificationVibrationIntensity = systemSettings.getSettingLocked( + Settings.System.NOTIFICATION_VIBRATION_INTENSITY); + + Setting ringVibrationIntensity = systemSettings.getSettingLocked( + Settings.System.RING_VIBRATION_INTENSITY); + + if (!notificationVibrationIntensity.isNull() + && ringVibrationIntensity.isNull()) { + systemSettings.insertSettingLocked( + Settings.System.RING_VIBRATION_INTENSITY, + notificationVibrationIntensity.getValue(), + null , true, SettingsState.SYSTEM_PACKAGE_NAME); + } + + currentVersion = 176; + } + + if (currentVersion == 176) { + // Version 176: Migrate the existing swipe up setting into the resource overlay + // for the navigation bar interaction mode. + + final IOverlayManager overlayManager = IOverlayManager.Stub.asInterface( + ServiceManager.getService(Context.OVERLAY_SERVICE)); + int navBarMode = -1; + + // Migrate the swipe up setting only if it is set + final SettingsState secureSettings = getSecureSettingsLocked(userId); + final Setting swipeUpSetting = secureSettings.getSettingLocked( + "swipe_up_to_switch_apps_enabled"); + if (swipeUpSetting != null && !swipeUpSetting.isNull()) { + navBarMode = swipeUpSetting.getValue().equals("1") + ? NAV_BAR_MODE_2BUTTON + : NAV_BAR_MODE_3BUTTON; + } + + // Temporary: Only for migration for dogfooders, to be removed + try { + final OverlayInfo info = overlayManager.getOverlayInfo( + "com.android.internal.experiment.navbar.type.inset", + UserHandle.USER_CURRENT); + if (info != null && info.isEnabled()) { + navBarMode = NAV_BAR_MODE_GESTURAL; + } + } catch (RemoteException e) { + // Ingore, fall through + } + + if (navBarMode != -1) { + try { + overlayManager.setEnabled(NAV_BAR_MODE_3BUTTON_OVERLAY, + navBarMode == NAV_BAR_MODE_3BUTTON, + UserHandle.USER_CURRENT); + overlayManager.setEnabled(NAV_BAR_MODE_2BUTTON_OVERLAY, + navBarMode == NAV_BAR_MODE_2BUTTON, + UserHandle.USER_CURRENT); + overlayManager.setEnabled(NAV_BAR_MODE_GESTURAL_OVERLAY, + navBarMode == NAV_BAR_MODE_GESTURAL, + UserHandle.USER_CURRENT); + } catch (RemoteException e) { + throw new IllegalStateException( + "Failed to set nav bar interaction mode overlay"); + } + } + + currentVersion = 177; + } + + // vXXX: Add new settings above this point. if (currentVersion != newVersion) { diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 441f88c193d6..d6e61ebbbd6e 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -182,6 +182,10 @@ <!-- Permission needed to run keyguard manager tests in CTS --> <uses-permission android:name="android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS" /> + <!-- Permission needed to test wallpaper component --> + <uses-permission android:name="android.permission.SET_WALLPAPER" /> + <uses-permission android:name="android.permission.SET_WALLPAPER_COMPONENT" /> + <application android:label="@string/app_label" android:defaultToDeviceProtectedStorage="true" android:directBootAware="true"> diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java index a9ff21fef99c..1060c7b7ce79 100644 --- a/packages/Shell/src/com/android/shell/BugreportProgressService.java +++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java @@ -1095,6 +1095,7 @@ public class BugreportProgressService extends Service { new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... params) { + Looper.prepare(); zipBugreport(info); sendBugreportNotification(info, takingScreenshot); return null; diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 6df6c7355e3b..d654f5aa23e0 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -438,7 +438,7 @@ <activity android:name=".media.MediaProjectionPermissionActivity" android:exported="true" - android:theme="@style/Theme.AlertDialogHost" + android:theme="@style/Theme.MediaProjectionAlertDialog" android:finishOnCloseSystemDialogs="true" android:launchMode="singleTop" android:excludeFromRecents="true" diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS index e7e2c1aafa78..c071b8b15a43 100644 --- a/packages/SystemUI/OWNERS +++ b/packages/SystemUI/OWNERS @@ -21,6 +21,7 @@ juliatuttle@google.com kchyn@google.com kozynski@google.com kprevas@google.com +lynhan@google.com madym@google.com mankoff@google.com nbenbernou@google.com diff --git a/packages/SystemUI/docs/physics-animation-layout-control-methods.png b/packages/SystemUI/docs/physics-animation-layout-control-methods.png Binary files differdeleted file mode 100644 index e77c676bc13f..000000000000 --- a/packages/SystemUI/docs/physics-animation-layout-control-methods.png +++ /dev/null diff --git a/packages/SystemUI/docs/physics-animation-layout.md b/packages/SystemUI/docs/physics-animation-layout.md index 300f63a3d285..488c4657333f 100644 --- a/packages/SystemUI/docs/physics-animation-layout.md +++ b/packages/SystemUI/docs/physics-animation-layout.md @@ -25,22 +25,74 @@ Value to add every time chained animations update the subsequent animation in th Returns a SpringForce instance to use for animations of the given property. This allows the controller to configure stiffness and bounciness values. Since the physics animations internally use SpringForce instances to hold inflight animation values, this method needs to return a new SpringForce instance each time - no constants allowed. ### Animation Control Methods - Once the layout has used the controller’s configuration properties to build the animations, the controller can use them to actually run animations. This is done for two reasons - reacting to a view being added or removed, or responding to another class (such as a touch handler or broadcast receiver) requesting an animation. ```onChildAdded```, ```onChildRemoved```, and ```setChildVisibility``` are called automatically by the layout, giving the controller the opportunity to animate the child in/out/visible/gone. Custom methods are called by anyone with access to the controller instance to do things like expand, collapse, or move the child views. -In either case, the controller has access to the layout’s protected ```animateValueForChildAtIndex(ViewProperty property, int index, float value)``` method. This method is used to actually run an animation. +In either case, the controller can use `super.animationForChild` to retrieve a `PhysicsPropertyAnimator` instance. This object behaves similarly to the `ViewPropertyAnimator` object you would receive from `View.animate()`. -For example, moving the first child view to *(100, 200)*: +#### PhysicsPropertyAnimator + +Like `ViewPropertyAnimator`, `PhysicsPropertyAnimator` provides the following methods for animating properties: +- `alpha(float)` +- `translationX/Y/Z(float)` +- `scaleX/Y(float)` + +It also provides the following configuration methods: +- `withStartDelay(int)`, for starting the animation after a given delay. +- `withStartVelocity(float)`, for starting the animation with the given start velocity. +- `withPositionStartVelocities(float, float)`, for setting specific start velocities for TRANSLATION_X and TRANSLATION_Y, since these typically differ. +- `start(Runnable)`, to start the animation, with an optional end action to call when the animations for every property (including chained animations) have completed. + +For example, moving the first child view: ``` -animateValueForChildAtIndex(TRANSLATION_X, 0, 100); -animateValueForChildAtIndex(TRANSLATION_Y, 0, 200); +animationForChild(getChildAt(0)) + .translationX(100) + .translationY(200) + .setStartDelay(500) + .start(); ``` -This would use the physics animations constructed by the layout to spring the view to *(100, 200)*. +This would use the physics animations constructed by the layout to spring the view to *(100, 200)* after 500ms. If the controller’s ```getNextAnimationInChain``` method set up the first child’s TRANSLATION_X/Y animations to be chained to the second child’s, this would result in the second child also springing towards (100, 200), plus any offset returned by ```getOffsetForChainedPropertyAnimation```. +##### Advanced Usage +The animator has additional functionality to reduce the amount of boilerplate required for typical physics animation use cases. + +- Often, animations will set starting values for properties before the animation begins. Property methods like `translationX` have an overloaded variant: `translationX(from, to)`. When `start()` is called, the animation will set the view's translationX property to `from` before beginning the animation to `to`. +- We may want to use different end actions for each property. For example, if we're animating a view to the bottom of the screen, and also fading it out, we might want to perform an action as soon as the fade out is complete. We can use `alpha(to, endAction)`, which will call endAction as soon as the alpha animation is finished. A special case is `position(x, y, endAction)`, where the endAction is called when both translationX and translationY animations have completed. + +`PhysicsAnimationController` also provides `animationsForChildrenFromIndex(int, ChildAnimationConfigurator)`. This is a convenience method for starting animations on multiple child views, starting at the given index. The `ChildAnimationConfigurator` is called with a `PhysicsPropertyAnimator` for each child, where calls to methods like `translationX` and `withStartVelocity` can be made. `animationsForChildrenFromIndex` returns a `MultiAnimationStarter` with a single method, `startAll(endAction)`, which starts all of the animations and calls the end action when they have all completed. + +##### Examples +Spring the stack of bubbles (whose animations are chained) to the bottom of the screen, shrinking them to 50% size. Once the first bubble is done shrinking, begin fading them out, and then remove them all from the parent once all bubbles have faded out: + +``` +animationForChild(leadBubble) + .position(screenCenter, screenBottom) + .scaleX(0.5f) + .scaleY(0.5f, () -> animationForChild(leadBubble).alpha(0).start(removeAllFromParent)) + .start(); +``` + +'Drop in' a child view that was just added to the layout: + +``` +animationForChild(newView) + .scaleX(1.15f /* from */, 1f /* to */) + .scaleY(1.15f /* from */, 1f /* to */) + .alpha(0f /* from */, 1f /* to */) + .position(posX, posY) + .start(); +``` + +Move every view except for the first to x = (index - 1) * 50, then remove the first view. + +``` +animationsForChildrenFromIndex(1, (index, anim) -> anim.translationX((index - 1) * 50)) + .startAll(removeFirstView); +``` + ## PhysicsAnimationLayout The layout itself is a FrameLayout descendant with a few extra methods: diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java index 3d2f570bde87..0a0530c056af 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java @@ -60,6 +60,7 @@ public interface VolumeDialogController { boolean areCaptionsEnabled(); void setCaptionsEnabled(boolean isEnabled); + boolean isCaptionStreamOptedOut(); void getCaptionsComponentState(boolean fromTooltip); diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml index 081ed45f3acd..c7b6ccdcd80d 100644 --- a/packages/SystemUI/res-keyguard/values-ar/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml @@ -205,66 +205,13 @@ <item msgid="2233497913571137419">"العاشرة"</item> <item msgid="5621554266768657830">"الحادية عشرة"</item> </string-array> - <string-array name="type_clock_minutes"> - <item msgid="8322049385467207985">"بالضبط"</item> - <item msgid="8837126587669001578">"الواحدة بالضبط"</item> - <item msgid="4294343372940455660">"الثانية بالضبط"</item> - <item msgid="7129166637707421536">"الثالثة بالضبط"</item> - <item msgid="7579404865008788673">"الرابعة بالضبط"</item> - <item msgid="3873924689207380586">"الخاسة بالضبط"</item> - <item msgid="4849565597850069377">"السادسة بالضبط"</item> - <item msgid="4404219424523572364">"السابعة بالضبط"</item> - <item msgid="8740481214764087329">"الثامنة بالضبط"</item> - <item msgid="1713216865806811237">"التاسعة بالضبط"</item> - <item msgid="3508406095411245038">"عَشر"</item> - <item msgid="7161996337755311711">"إحدى عشرة"</item> - <item msgid="4044549963329624197">"اثنتا عشرة"</item> - <item msgid="333373157917379088">"ثلاث عشرة"</item> - <item msgid="2631202907124819385">"أربع عشرة"</item> - <item msgid="6472396076858033453">"خمس عشرة"</item> - <item msgid="8656981856181581643">"ست عشرة"</item> - <item msgid="7289026608562030619">"سبع عشرة"</item> - <item msgid="3881477602692646573">"ثمان عشرة"</item> - <item msgid="3358129827772984226">"تسع عشرة"</item> - <item msgid="3308575407402865807">"عشرون"</item> - <item msgid="5346560955382229629">"إحدى\nوعشرون"</item> - <item msgid="226750304761473436">"اثنتان\nوعشرون"</item> - <item msgid="616811325336838734">"ثلاث\nوعشرون"</item> - <item msgid="616346116869053440">"أربع\nوعشرون"</item> - <item msgid="4642996410384042830">"خمس\nوعشرون"</item> - <item msgid="7506092849993571465">"ست\nوعشرون"</item> - <item msgid="1915078191101042031">"سبع\nوعشرون"</item> - <item msgid="4292378641900520252">"ثمانٍ\nوعشرون"</item> - <item msgid="5339513901773103696">"تسع\nوعشرون"</item> - <item msgid="3574673250891657607">"ثلاثون"</item> - <item msgid="5796923836589110940">"إحدى\nوثلاثون"</item> - <item msgid="5859323597571702052">"اثنتا\nوثلاثون"</item> - <item msgid="5133326723148876507">"ثلاث\nوثلاثون"</item> - <item msgid="2693999494655663096">"أربع\nوثلاثون"</item> - <item msgid="3316754944962836197">"خمس\nوثلاثون"</item> - <item msgid="816891008836796723">"ست\nوثلاثون"</item> - <item msgid="9158890488666520078">"سبع\nوثلاثون"</item> - <item msgid="1894769703213894011">"ثمانٍ\nوثلاثون"</item> - <item msgid="5638820345598572399">"تسع\nوثلاثون"</item> - <item msgid="8838304023017895439">"أربعون"</item> - <item msgid="1834742948932559597">"واحد\nوأربعون"</item> - <item msgid="6573707308847773944">"اثنتان\nوأربعون"</item> - <item msgid="2450149950652678001">"ثلاث\nوأربعون"</item> - <item msgid="2874667401318178036">"أربع\nوأربعون"</item> - <item msgid="3391101532763048862">"خمس\nوأربعون"</item> - <item msgid="1671489330863254362">"ست\nوأربعون"</item> - <item msgid="5916017359554531038">"سبع\nوأربعون"</item> - <item msgid="8205413177993059967">"ثمانٍ\nوأربعون"</item> - <item msgid="6607867415142171302">"تسع\nوأربعون"</item> - <item msgid="8358850748472089162">"خمسون"</item> - <item msgid="3551313125255080234">"إحدى\nوخمسون"</item> - <item msgid="1559678130725716542">"اثنتان\nوخمسون"</item> - <item msgid="431441994725492377">"ثلاث\nوخمسون"</item> - <item msgid="6345774640539623024">"أربع\nوخمسون"</item> - <item msgid="8018192990793931120">"خمس\nوخمسون"</item> - <item msgid="6187650843754604534">"ست\nوخمسون"</item> - <item msgid="8727240174015993259">"سبع\nوخمسون"</item> - <item msgid="848339003778952950">"ثمانٍ\nوخمسون"</item> - <item msgid="5798985802835423618">"تسع\nوخمسون"</item> - </string-array> + <!-- no translation found for type_clock_minutes:1 (2091812961809760681) --> + <!-- no translation found for type_clock_minutes:2 (1496435384877290709) --> + <!-- no translation found for type_clock_minutes:3 (881846472976674129) --> + <!-- no translation found for type_clock_minutes:4 (2784477043911540584) --> + <!-- no translation found for type_clock_minutes:5 (1610928853656700614) --> + <!-- no translation found for type_clock_minutes:6 (2317806244043886658) --> + <!-- no translation found for type_clock_minutes:7 (3318687539120971327) --> + <!-- no translation found for type_clock_minutes:8 (5701600693712102348) --> + <!-- no translation found for type_clock_minutes:9 (3247381605947372495) --> </resources> diff --git a/packages/SystemUI/res-keyguard/values-ca/strings.xml b/packages/SystemUI/res-keyguard/values-ca/strings.xml index 053162653273..62c313c4e054 100644 --- a/packages/SystemUI/res-keyguard/values-ca/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ca/strings.xml @@ -169,66 +169,13 @@ <item msgid="2233497913571137419">"Deu"</item> <item msgid="5621554266768657830">"i onze"</item> </string-array> - <string-array name="type_clock_minutes"> - <item msgid="8322049385467207985">"en punt"</item> - <item msgid="8837126587669001578">"i un"</item> - <item msgid="4294343372940455660">"i dos"</item> - <item msgid="7129166637707421536">"i tres"</item> - <item msgid="7579404865008788673">"i quatre"</item> - <item msgid="3873924689207380586">"i cinc"</item> - <item msgid="4849565597850069377">"i sis"</item> - <item msgid="4404219424523572364">"i set"</item> - <item msgid="8740481214764087329">"i vuit"</item> - <item msgid="1713216865806811237">"i nou"</item> - <item msgid="3508406095411245038">"i deu"</item> - <item msgid="7161996337755311711">"i onze"</item> - <item msgid="4044549963329624197">"i dotze"</item> - <item msgid="333373157917379088">"i tretze"</item> - <item msgid="2631202907124819385">"i catorze"</item> - <item msgid="6472396076858033453">"i quinze"</item> - <item msgid="8656981856181581643">"i setze"</item> - <item msgid="7289026608562030619">"i disset"</item> - <item msgid="3881477602692646573">"i divuit"</item> - <item msgid="3358129827772984226">"i dinou"</item> - <item msgid="3308575407402865807">"i vint"</item> - <item msgid="5346560955382229629">"i vint-i-\nu"</item> - <item msgid="226750304761473436">"i vint-i-\ndos"</item> - <item msgid="616811325336838734">"i vint-i-\ntres"</item> - <item msgid="616346116869053440">"i vint-i-\nquatre"</item> - <item msgid="4642996410384042830">"i vint-i-\ncinc"</item> - <item msgid="7506092849993571465">"i vint-i-\nsis"</item> - <item msgid="1915078191101042031">"i vint-i-\nset"</item> - <item msgid="4292378641900520252">"i vint-i-\nvuit"</item> - <item msgid="5339513901773103696">"i vint-i-\nnou"</item> - <item msgid="3574673250891657607">"i trenta"</item> - <item msgid="5796923836589110940">"i trenta-\nu"</item> - <item msgid="5859323597571702052">"i trenta-\ndos"</item> - <item msgid="5133326723148876507">"i trenta-\ntres"</item> - <item msgid="2693999494655663096">"i trenta-\nquatre"</item> - <item msgid="3316754944962836197">"i trenta-\ncinc"</item> - <item msgid="816891008836796723">"i trenta-\nsis"</item> - <item msgid="9158890488666520078">"i trenta-\nset"</item> - <item msgid="1894769703213894011">"i trenta-\nvuit"</item> - <item msgid="5638820345598572399">"i trenta-\nnou"</item> - <item msgid="8838304023017895439">"i quaranta"</item> - <item msgid="1834742948932559597">"i quaranta-\nu"</item> - <item msgid="6573707308847773944">"i quaranta-\ndos"</item> - <item msgid="2450149950652678001">"i quaranta-\ntres"</item> - <item msgid="2874667401318178036">"quaranta-\nquatre"</item> - <item msgid="3391101532763048862">"i quaranta-\ncinc"</item> - <item msgid="1671489330863254362">"i quaranta-\nsis"</item> - <item msgid="5916017359554531038">"i quaranta-\nset"</item> - <item msgid="8205413177993059967">"i quaranta-\nvuit"</item> - <item msgid="6607867415142171302">"i quaranta-\nnou"</item> - <item msgid="8358850748472089162">"i cinquanta"</item> - <item msgid="3551313125255080234">"i cinquanta-\nun"</item> - <item msgid="1559678130725716542">"i cinquanta-\ndos"</item> - <item msgid="431441994725492377">"i cinquanta-\ntres"</item> - <item msgid="6345774640539623024">"cinquanta-\nquatre"</item> - <item msgid="8018192990793931120">"i cinquanta-\ncinc"</item> - <item msgid="6187650843754604534">"i cinquanta-\nsis"</item> - <item msgid="8727240174015993259">"i cinquanta-\nset"</item> - <item msgid="848339003778952950">"i cinquanta-\nvuit"</item> - <item msgid="5798985802835423618">"i cinquanta-\nnou"</item> - </string-array> + <!-- no translation found for type_clock_minutes:1 (2091812961809760681) --> + <!-- no translation found for type_clock_minutes:2 (1496435384877290709) --> + <!-- no translation found for type_clock_minutes:3 (881846472976674129) --> + <!-- no translation found for type_clock_minutes:4 (2784477043911540584) --> + <!-- no translation found for type_clock_minutes:5 (1610928853656700614) --> + <!-- no translation found for type_clock_minutes:6 (2317806244043886658) --> + <!-- no translation found for type_clock_minutes:7 (3318687539120971327) --> + <!-- no translation found for type_clock_minutes:8 (5701600693712102348) --> + <!-- no translation found for type_clock_minutes:9 (3247381605947372495) --> </resources> diff --git a/packages/SystemUI/res-keyguard/values-de/strings.xml b/packages/SystemUI/res-keyguard/values-de/strings.xml index 130959967a48..84603200b90b 100644 --- a/packages/SystemUI/res-keyguard/values-de/strings.xml +++ b/packages/SystemUI/res-keyguard/values-de/strings.xml @@ -169,66 +169,13 @@ <item msgid="2233497913571137419">"zehn Uhr"</item> <item msgid="5621554266768657830">"elf Uhr"</item> </string-array> - <string-array name="type_clock_minutes"> - <item msgid="8322049385467207985"></item> - <item msgid="8837126587669001578">"eins"</item> - <item msgid="4294343372940455660">"zwei"</item> - <item msgid="7129166637707421536">"drei"</item> - <item msgid="7579404865008788673">"vier"</item> - <item msgid="3873924689207380586">"fünf"</item> - <item msgid="4849565597850069377">"sechs"</item> - <item msgid="4404219424523572364">"sieben"</item> - <item msgid="8740481214764087329">"acht"</item> - <item msgid="1713216865806811237">"neun"</item> - <item msgid="3508406095411245038">"zehn"</item> - <item msgid="7161996337755311711">"elf"</item> - <item msgid="4044549963329624197">"zwölf"</item> - <item msgid="333373157917379088">"dreizehn"</item> - <item msgid="2631202907124819385">"vierzehn"</item> - <item msgid="6472396076858033453">"fünfzehn"</item> - <item msgid="8656981856181581643">"sechzehn"</item> - <item msgid="7289026608562030619">"siebzehn"</item> - <item msgid="3881477602692646573">"achtzehn"</item> - <item msgid="3358129827772984226">"neunzehn"</item> - <item msgid="3308575407402865807">"zwanzig"</item> - <item msgid="5346560955382229629">"einund-\nzwanzig"</item> - <item msgid="226750304761473436">"zweiund-\nzwanzig"</item> - <item msgid="616811325336838734">"dreiund-\nzwanzig"</item> - <item msgid="616346116869053440">"vierund-\nzwanzig"</item> - <item msgid="4642996410384042830">"fünfund-\nzwanzig"</item> - <item msgid="7506092849993571465">"sechsund-\nzwanzig"</item> - <item msgid="1915078191101042031">"siebenund-\nzwanzig"</item> - <item msgid="4292378641900520252">"achtund-\nzwanzig"</item> - <item msgid="5339513901773103696">"neunund-\nzwanzig"</item> - <item msgid="3574673250891657607">"dreißig"</item> - <item msgid="5796923836589110940">"einund-\ndreißig"</item> - <item msgid="5859323597571702052">"zweiund-\ndreißig"</item> - <item msgid="5133326723148876507">"dreiund-\ndreißig"</item> - <item msgid="2693999494655663096">"vierund-\ndreißig"</item> - <item msgid="3316754944962836197">"fünfund-\ndreißig"</item> - <item msgid="816891008836796723">"sechsund-\ndreißig"</item> - <item msgid="9158890488666520078">"siebenund-\ndreißig"</item> - <item msgid="1894769703213894011">"achtund-\ndreißig"</item> - <item msgid="5638820345598572399">"neunund-\ndreißig"</item> - <item msgid="8838304023017895439">"vierzig"</item> - <item msgid="1834742948932559597">"einund-\nvierzig"</item> - <item msgid="6573707308847773944">"zweiund-\nvierzig"</item> - <item msgid="2450149950652678001">"dreiund-\nvierzig"</item> - <item msgid="2874667401318178036">"vierund-\nvierzig"</item> - <item msgid="3391101532763048862">"fünfund-\nvierzig"</item> - <item msgid="1671489330863254362">"sechsund-\nvierzig"</item> - <item msgid="5916017359554531038">"siebenund-\nvierzig"</item> - <item msgid="8205413177993059967">"achtund-\nvierzig"</item> - <item msgid="6607867415142171302">"neunund-\nvierzig"</item> - <item msgid="8358850748472089162">"fünfzig"</item> - <item msgid="3551313125255080234">"einund-\nfünfzig"</item> - <item msgid="1559678130725716542">"zweiund-\nfünfzig"</item> - <item msgid="431441994725492377">"dreiund-\nfünfzig"</item> - <item msgid="6345774640539623024">"vierund-\nfünfzig"</item> - <item msgid="8018192990793931120">"fünfund-\nfünfzig"</item> - <item msgid="6187650843754604534">"sechsund-\nfünfzig"</item> - <item msgid="8727240174015993259">"siebenund-\nfünfzig"</item> - <item msgid="848339003778952950">"achtund-\nfünfzig"</item> - <item msgid="5798985802835423618">"neunund-\nfünfzig"</item> - </string-array> + <!-- no translation found for type_clock_minutes:1 (2091812961809760681) --> + <!-- no translation found for type_clock_minutes:2 (1496435384877290709) --> + <!-- no translation found for type_clock_minutes:3 (881846472976674129) --> + <!-- no translation found for type_clock_minutes:4 (2784477043911540584) --> + <!-- no translation found for type_clock_minutes:5 (1610928853656700614) --> + <!-- no translation found for type_clock_minutes:6 (2317806244043886658) --> + <!-- no translation found for type_clock_minutes:7 (3318687539120971327) --> + <!-- no translation found for type_clock_minutes:8 (5701600693712102348) --> + <!-- no translation found for type_clock_minutes:9 (3247381605947372495) --> </resources> diff --git a/packages/SystemUI/res-keyguard/values-es/strings.xml b/packages/SystemUI/res-keyguard/values-es/strings.xml index 3e4561c55df6..9db0c6af1d41 100644 --- a/packages/SystemUI/res-keyguard/values-es/strings.xml +++ b/packages/SystemUI/res-keyguard/values-es/strings.xml @@ -169,66 +169,13 @@ <item msgid="2233497913571137419">"Diez"</item> <item msgid="5621554266768657830">"Once"</item> </string-array> - <string-array name="type_clock_minutes"> - <item msgid="8322049385467207985">"En punto"</item> - <item msgid="8837126587669001578">"una"</item> - <item msgid="4294343372940455660">"dos"</item> - <item msgid="7129166637707421536">"tres"</item> - <item msgid="7579404865008788673">"cuatro"</item> - <item msgid="3873924689207380586">"cinco"</item> - <item msgid="4849565597850069377">"seis"</item> - <item msgid="4404219424523572364">"siete"</item> - <item msgid="8740481214764087329">"ocho"</item> - <item msgid="1713216865806811237">"nueve"</item> - <item msgid="3508406095411245038">"Diez"</item> - <item msgid="7161996337755311711">"Once"</item> - <item msgid="4044549963329624197">"Doce"</item> - <item msgid="333373157917379088">"Trece"</item> - <item msgid="2631202907124819385">"Catorce"</item> - <item msgid="6472396076858033453">"Quince"</item> - <item msgid="8656981856181581643">"Dieciséis"</item> - <item msgid="7289026608562030619">"Diecisiete"</item> - <item msgid="3881477602692646573">"Dieciocho"</item> - <item msgid="3358129827772984226">"Diecinueve"</item> - <item msgid="3308575407402865807">"Veinte"</item> - <item msgid="5346560955382229629">"Veintiuno\n"</item> - <item msgid="226750304761473436">"Veintidós\n"</item> - <item msgid="616811325336838734">"Veintitrés\n"</item> - <item msgid="616346116869053440">"Veinticuatro\n"</item> - <item msgid="4642996410384042830">"Veinticinco\n"</item> - <item msgid="7506092849993571465">"Veintiséis\n"</item> - <item msgid="1915078191101042031">"Veintisiete\n"</item> - <item msgid="4292378641900520252">"Veintiocho\n"</item> - <item msgid="5339513901773103696">"Veintinueve\n"</item> - <item msgid="3574673250891657607">"Treinta"</item> - <item msgid="5796923836589110940">"Treinta\ny uno"</item> - <item msgid="5859323597571702052">"Treinta\ny dos"</item> - <item msgid="5133326723148876507">"Treinta\ny tres"</item> - <item msgid="2693999494655663096">"Treinta\ny cuatro"</item> - <item msgid="3316754944962836197">"Treinta\ny cinco"</item> - <item msgid="816891008836796723">"Treinta\ny seis"</item> - <item msgid="9158890488666520078">"Treinta\ny siete"</item> - <item msgid="1894769703213894011">"Treinta\ny ocho"</item> - <item msgid="5638820345598572399">"Treinta\ny nueve"</item> - <item msgid="8838304023017895439">"Cuarenta"</item> - <item msgid="1834742948932559597">"Cuarenta\ny uno"</item> - <item msgid="6573707308847773944">"Cuarenta\ny dos"</item> - <item msgid="2450149950652678001">"Cuarenta\ny tres"</item> - <item msgid="2874667401318178036">"Cuarenta\ny cuatro"</item> - <item msgid="3391101532763048862">"Cuarenta\ny cinco"</item> - <item msgid="1671489330863254362">"Cuarenta\n y seis"</item> - <item msgid="5916017359554531038">"Cuarenta\ny siete"</item> - <item msgid="8205413177993059967">"Cuarenta\ny ocho"</item> - <item msgid="6607867415142171302">"Cuarenta\ny nueve"</item> - <item msgid="8358850748472089162">"Cincuenta"</item> - <item msgid="3551313125255080234">"Cincuenta\ny uno"</item> - <item msgid="1559678130725716542">"Cincuenta\ny dos"</item> - <item msgid="431441994725492377">"Cincuenta\ny tres"</item> - <item msgid="6345774640539623024">"Cincuenta\ny cuatro"</item> - <item msgid="8018192990793931120">"Cincuenta\ny cinco"</item> - <item msgid="6187650843754604534">"Cincuenta\ny seis"</item> - <item msgid="8727240174015993259">"Cincuenta\ny siete"</item> - <item msgid="848339003778952950">"Cincuenta\ny ocho"</item> - <item msgid="5798985802835423618">"Cincuenta\ny nueve"</item> - </string-array> + <!-- no translation found for type_clock_minutes:1 (2091812961809760681) --> + <!-- no translation found for type_clock_minutes:2 (1496435384877290709) --> + <!-- no translation found for type_clock_minutes:3 (881846472976674129) --> + <!-- no translation found for type_clock_minutes:4 (2784477043911540584) --> + <!-- no translation found for type_clock_minutes:5 (1610928853656700614) --> + <!-- no translation found for type_clock_minutes:6 (2317806244043886658) --> + <!-- no translation found for type_clock_minutes:7 (3318687539120971327) --> + <!-- no translation found for type_clock_minutes:8 (5701600693712102348) --> + <!-- no translation found for type_clock_minutes:9 (3247381605947372495) --> </resources> diff --git a/packages/SystemUI/res-keyguard/values-eu/strings.xml b/packages/SystemUI/res-keyguard/values-eu/strings.xml index 9a40eb817ca6..b69a57651940 100644 --- a/packages/SystemUI/res-keyguard/values-eu/strings.xml +++ b/packages/SystemUI/res-keyguard/values-eu/strings.xml @@ -169,66 +169,13 @@ <item msgid="2233497913571137419">"Hamarrak"</item> <item msgid="5621554266768657830">"Hamaikak"</item> </string-array> - <string-array name="type_clock_minutes"> - <item msgid="8322049385467207985">"dira"</item> - <item msgid="8837126587669001578">"bat"</item> - <item msgid="4294343372940455660">"bi"</item> - <item msgid="7129166637707421536">"hiru"</item> - <item msgid="7579404865008788673">"lau"</item> - <item msgid="3873924689207380586">"bost"</item> - <item msgid="4849565597850069377">"sei"</item> - <item msgid="4404219424523572364">"zazpi"</item> - <item msgid="8740481214764087329">"zortzi"</item> - <item msgid="1713216865806811237">"bederatzi"</item> - <item msgid="3508406095411245038">"hamar"</item> - <item msgid="7161996337755311711">"hamaika"</item> - <item msgid="4044549963329624197">"hamabi"</item> - <item msgid="333373157917379088">"hamahiru"</item> - <item msgid="2631202907124819385">"hamalau"</item> - <item msgid="6472396076858033453">"hamabost"</item> - <item msgid="8656981856181581643">"hamasei"</item> - <item msgid="7289026608562030619">"hamazazpi"</item> - <item msgid="3881477602692646573">"hemezortzi"</item> - <item msgid="3358129827772984226">"hemeretzi"</item> - <item msgid="3308575407402865807">"hogei"</item> - <item msgid="5346560955382229629">"hogeita\nbat"</item> - <item msgid="226750304761473436">"hogeita\nbi"</item> - <item msgid="616811325336838734">"hogeita\nhiru"</item> - <item msgid="616346116869053440">"hogeita\nlau"</item> - <item msgid="4642996410384042830">"hogeita\nbost"</item> - <item msgid="7506092849993571465">"hogeita\nsei"</item> - <item msgid="1915078191101042031">"hogeita\nzazpi"</item> - <item msgid="4292378641900520252">"hogeita\nzortzi"</item> - <item msgid="5339513901773103696">"hogeita\nbederatzi"</item> - <item msgid="3574673250891657607">"hogeita hamar"</item> - <item msgid="5796923836589110940">"hogeita\nhamaika"</item> - <item msgid="5859323597571702052">"hogeita\nhamabi"</item> - <item msgid="5133326723148876507">"hogeita\nhamahiru"</item> - <item msgid="2693999494655663096">"hogeita\nhamalau"</item> - <item msgid="3316754944962836197">"hogeita\nhamabost"</item> - <item msgid="816891008836796723">"hogeita\nhamasei"</item> - <item msgid="9158890488666520078">"hogeita\nhamazazpi"</item> - <item msgid="1894769703213894011">"hogeita\nhemezortzi"</item> - <item msgid="5638820345598572399">"hogeita\nhemeretzi"</item> - <item msgid="8838304023017895439">"berrogei"</item> - <item msgid="1834742948932559597">"berrogeita\nbat"</item> - <item msgid="6573707308847773944">"berrogeita\nbi"</item> - <item msgid="2450149950652678001">"berrogeita\nhiru"</item> - <item msgid="2874667401318178036">"berrogeita\nlau"</item> - <item msgid="3391101532763048862">"berrogeita\nbost"</item> - <item msgid="1671489330863254362">"berrogeita\nsei"</item> - <item msgid="5916017359554531038">"berrogeita\nzazpi"</item> - <item msgid="8205413177993059967">"berrogeita\nzortzi"</item> - <item msgid="6607867415142171302">"berrogeita\nbederatzi"</item> - <item msgid="8358850748472089162">"berrogeita hamar"</item> - <item msgid="3551313125255080234">"berrogeita\nhamaika"</item> - <item msgid="1559678130725716542">"berrogeita\nhamabi"</item> - <item msgid="431441994725492377">"berrogeita\nhamahiru"</item> - <item msgid="6345774640539623024">"berrogeita\nhamalau"</item> - <item msgid="8018192990793931120">"berrogeita\nhamabost"</item> - <item msgid="6187650843754604534">"berrogeita\nhamasei"</item> - <item msgid="8727240174015993259">"berrogeita\nhamazazpi"</item> - <item msgid="848339003778952950">"berrogeita\nhemezortzi"</item> - <item msgid="5798985802835423618">"berrogeita\nhemeretzi"</item> - </string-array> + <!-- no translation found for type_clock_minutes:1 (2091812961809760681) --> + <!-- no translation found for type_clock_minutes:2 (1496435384877290709) --> + <!-- no translation found for type_clock_minutes:3 (881846472976674129) --> + <!-- no translation found for type_clock_minutes:4 (2784477043911540584) --> + <!-- no translation found for type_clock_minutes:5 (1610928853656700614) --> + <!-- no translation found for type_clock_minutes:6 (2317806244043886658) --> + <!-- no translation found for type_clock_minutes:7 (3318687539120971327) --> + <!-- no translation found for type_clock_minutes:8 (5701600693712102348) --> + <!-- no translation found for type_clock_minutes:9 (3247381605947372495) --> </resources> diff --git a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml index 73c686a162aa..a8771287aec6 100644 --- a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml @@ -169,66 +169,13 @@ <item msgid="2233497913571137419">"Dix h."</item> <item msgid="5621554266768657830">"Onze h."</item> </string-array> - <string-array name="type_clock_minutes"> - <item msgid="8322049385467207985">"heures"</item> - <item msgid="8837126587669001578">"une"</item> - <item msgid="4294343372940455660">"deux"</item> - <item msgid="7129166637707421536">"trois"</item> - <item msgid="7579404865008788673">"quatre"</item> - <item msgid="3873924689207380586">"cinq"</item> - <item msgid="4849565597850069377">"six"</item> - <item msgid="4404219424523572364">"sept"</item> - <item msgid="8740481214764087329">"huit"</item> - <item msgid="1713216865806811237">"neuf"</item> - <item msgid="3508406095411245038">"dix"</item> - <item msgid="7161996337755311711">"onze"</item> - <item msgid="4044549963329624197">"douze"</item> - <item msgid="333373157917379088">"treize"</item> - <item msgid="2631202907124819385">"quatorze"</item> - <item msgid="6472396076858033453">"quinze"</item> - <item msgid="8656981856181581643">"seize"</item> - <item msgid="7289026608562030619">"dix-sept"</item> - <item msgid="3881477602692646573">"dix-huit"</item> - <item msgid="3358129827772984226">"dix-neuf"</item> - <item msgid="3308575407402865807">"vingt"</item> - <item msgid="5346560955382229629">"vingt\n-et-un"</item> - <item msgid="226750304761473436">"vingt\n-deux"</item> - <item msgid="616811325336838734">"vingt\n-trois"</item> - <item msgid="616346116869053440">"vingt\n-quatre"</item> - <item msgid="4642996410384042830">"vingt\n-cinq"</item> - <item msgid="7506092849993571465">"vingt\n-six"</item> - <item msgid="1915078191101042031">"vingt\n-sept"</item> - <item msgid="4292378641900520252">"vingt\n-huit"</item> - <item msgid="5339513901773103696">"vingt\n-neuf"</item> - <item msgid="3574673250891657607">"trente"</item> - <item msgid="5796923836589110940">"trente\n-et-un"</item> - <item msgid="5859323597571702052">"trente\n-deux"</item> - <item msgid="5133326723148876507">"trente\n-trois"</item> - <item msgid="2693999494655663096">"trente\n-quatre"</item> - <item msgid="3316754944962836197">"trente\n-cinq"</item> - <item msgid="816891008836796723">"trente\n-six"</item> - <item msgid="9158890488666520078">"trente\n-sept"</item> - <item msgid="1894769703213894011">"trente\n-huit"</item> - <item msgid="5638820345598572399">"trente\n-neuf"</item> - <item msgid="8838304023017895439">"quarante"</item> - <item msgid="1834742948932559597">"quarante\n-et-un"</item> - <item msgid="6573707308847773944">"quarante\n-deux"</item> - <item msgid="2450149950652678001">"quarante\n-trois"</item> - <item msgid="2874667401318178036">"quarante\n-quatre"</item> - <item msgid="3391101532763048862">"quarante\n-cinq"</item> - <item msgid="1671489330863254362">"quarante\n-six"</item> - <item msgid="5916017359554531038">"quarante\n-sept"</item> - <item msgid="8205413177993059967">"quarante\n-huit"</item> - <item msgid="6607867415142171302">"quarante\n-neuf"</item> - <item msgid="8358850748472089162">"cinquante"</item> - <item msgid="3551313125255080234">"cinquante\n-et-un"</item> - <item msgid="1559678130725716542">"cinquante\n-deux"</item> - <item msgid="431441994725492377">"cinquante\n-trois"</item> - <item msgid="6345774640539623024">"cinquante\n-quatre"</item> - <item msgid="8018192990793931120">"cinquante\n-cinq"</item> - <item msgid="6187650843754604534">"cinquante\n-six"</item> - <item msgid="8727240174015993259">"cinquante\n-sept"</item> - <item msgid="848339003778952950">"cinquante\n-huit"</item> - <item msgid="5798985802835423618">"cinquante\n-neuf"</item> - </string-array> + <!-- no translation found for type_clock_minutes:1 (2091812961809760681) --> + <!-- no translation found for type_clock_minutes:2 (1496435384877290709) --> + <!-- no translation found for type_clock_minutes:3 (881846472976674129) --> + <!-- no translation found for type_clock_minutes:4 (2784477043911540584) --> + <!-- no translation found for type_clock_minutes:5 (1610928853656700614) --> + <!-- no translation found for type_clock_minutes:6 (2317806244043886658) --> + <!-- no translation found for type_clock_minutes:7 (3318687539120971327) --> + <!-- no translation found for type_clock_minutes:8 (5701600693712102348) --> + <!-- no translation found for type_clock_minutes:9 (3247381605947372495) --> </resources> diff --git a/packages/SystemUI/res-keyguard/values-fr/strings.xml b/packages/SystemUI/res-keyguard/values-fr/strings.xml index 868847365b54..197e9e18e037 100644 --- a/packages/SystemUI/res-keyguard/values-fr/strings.xml +++ b/packages/SystemUI/res-keyguard/values-fr/strings.xml @@ -169,66 +169,13 @@ <item msgid="2233497913571137419">"dix heures"</item> <item msgid="5621554266768657830">"onze heures"</item> </string-array> - <string-array name="type_clock_minutes"> - <item msgid="8322049385467207985"></item> - <item msgid="8837126587669001578">"une"</item> - <item msgid="4294343372940455660">"deux"</item> - <item msgid="7129166637707421536">"trois"</item> - <item msgid="7579404865008788673">"quatre"</item> - <item msgid="3873924689207380586">"cinq"</item> - <item msgid="4849565597850069377">"six"</item> - <item msgid="4404219424523572364">"sept"</item> - <item msgid="8740481214764087329">"huit"</item> - <item msgid="1713216865806811237">"neuf"</item> - <item msgid="3508406095411245038">"dix"</item> - <item msgid="7161996337755311711">"onze"</item> - <item msgid="4044549963329624197">"douze"</item> - <item msgid="333373157917379088">"treize"</item> - <item msgid="2631202907124819385">"quatorze"</item> - <item msgid="6472396076858033453">"quinze"</item> - <item msgid="8656981856181581643">"seize"</item> - <item msgid="7289026608562030619">"dix-sept"</item> - <item msgid="3881477602692646573">"dix-huit"</item> - <item msgid="3358129827772984226">"dix-neuf"</item> - <item msgid="3308575407402865807">"vingt"</item> - <item msgid="5346560955382229629">"vingt\net un"</item> - <item msgid="226750304761473436">"vingt-\ndeux"</item> - <item msgid="616811325336838734">"vingt-\ntrois"</item> - <item msgid="616346116869053440">"vingt-\nquatre"</item> - <item msgid="4642996410384042830">"vingt-\ncinq"</item> - <item msgid="7506092849993571465">"vingt-\nsix"</item> - <item msgid="1915078191101042031">"vingt-\nsept"</item> - <item msgid="4292378641900520252">"vingt-\nhuit"</item> - <item msgid="5339513901773103696">"vingt-\nneuf"</item> - <item msgid="3574673250891657607">"trente"</item> - <item msgid="5796923836589110940">"trente\net un"</item> - <item msgid="5859323597571702052">"trente-\ndeux"</item> - <item msgid="5133326723148876507">"trente-\ntrois"</item> - <item msgid="2693999494655663096">"trente-\nquatre"</item> - <item msgid="3316754944962836197">"trente-\ncinq"</item> - <item msgid="816891008836796723">"trente-\nsix"</item> - <item msgid="9158890488666520078">"trente-\nsept"</item> - <item msgid="1894769703213894011">"trente-\nhuit"</item> - <item msgid="5638820345598572399">"trente-\nneuf"</item> - <item msgid="8838304023017895439">"quarante"</item> - <item msgid="1834742948932559597">"quarante\net un"</item> - <item msgid="6573707308847773944">"quarante-\ndeux"</item> - <item msgid="2450149950652678001">"quarante-\ntrois"</item> - <item msgid="2874667401318178036">"quarante-\nquatre"</item> - <item msgid="3391101532763048862">"quarante-\ncinq"</item> - <item msgid="1671489330863254362">"quarante-\nsix"</item> - <item msgid="5916017359554531038">"quarante-\nsept"</item> - <item msgid="8205413177993059967">"quarante-\nhuit"</item> - <item msgid="6607867415142171302">"quarante-\nneuf"</item> - <item msgid="8358850748472089162">"cinquante"</item> - <item msgid="3551313125255080234">"cinquante\net un"</item> - <item msgid="1559678130725716542">"cinquante-\ndeux"</item> - <item msgid="431441994725492377">"cinquante-\ntrois"</item> - <item msgid="6345774640539623024">"cinquante-\nquatre"</item> - <item msgid="8018192990793931120">"cinquante-\ncinq"</item> - <item msgid="6187650843754604534">"cinquante-\nsix"</item> - <item msgid="8727240174015993259">"cinquante-\nsept"</item> - <item msgid="848339003778952950">"cinquante-\nhuit"</item> - <item msgid="5798985802835423618">"cinquante-\nneuf"</item> - </string-array> + <!-- no translation found for type_clock_minutes:1 (2091812961809760681) --> + <!-- no translation found for type_clock_minutes:2 (1496435384877290709) --> + <!-- no translation found for type_clock_minutes:3 (881846472976674129) --> + <!-- no translation found for type_clock_minutes:4 (2784477043911540584) --> + <!-- no translation found for type_clock_minutes:5 (1610928853656700614) --> + <!-- no translation found for type_clock_minutes:6 (2317806244043886658) --> + <!-- no translation found for type_clock_minutes:7 (3318687539120971327) --> + <!-- no translation found for type_clock_minutes:8 (5701600693712102348) --> + <!-- no translation found for type_clock_minutes:9 (3247381605947372495) --> </resources> diff --git a/packages/SystemUI/res-keyguard/values-hy/strings.xml b/packages/SystemUI/res-keyguard/values-hy/strings.xml index a030ab9985a5..b1c2c783110c 100644 --- a/packages/SystemUI/res-keyguard/values-hy/strings.xml +++ b/packages/SystemUI/res-keyguard/values-hy/strings.xml @@ -102,7 +102,7 @@ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="8476407539834855">"Դուք կատարել եք հեռախոսն ապակողպելու <xliff:g id="NUMBER">%d</xliff:g> անհաջող փորձ: Աշխատանքային պրոֆիլը կհեռացվի և պրոֆիլի բոլոր տվյալները կջնջվեն:"</string> <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="956706236554092172">"Դուք կատարել եք ապակողպման նախշը մուտքագրելու <xliff:g id="NUMBER_0">%1$d</xliff:g> անհաջող փորձ: Եվս <xliff:g id="NUMBER_1">%2$d</xliff:g> անհաջող փորձից հետո ձեզանից կպահանջվի ապակողպել պլանշետը էլփոստի հաշվի միջոցով։\n\n Խնդրում ենք փորձել կրկին <xliff:g id="NUMBER_2">%3$d</xliff:g> վայրկյանից:"</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="8364140853305528449">"Դուք կատարել եք ապակողպման նախշը մուտքագրելու <xliff:g id="NUMBER_0">%1$d</xliff:g> անհաջող փորձ: Եվս <xliff:g id="NUMBER_1">%2$d</xliff:g> անհաջող փորձից հետո ձեզանից կպահանջվի ապակողպել հեռախոսը էլփոստի հաշվի միջոցով։\n\n Խնդրում ենք փորձել կրկին <xliff:g id="NUMBER_2">%3$d</xliff:g> վայրկյանից:"</string> - <string name="kg_password_wrong_pin_code_pukked" msgid="3389829202093674267">"SIM PIN կոդը սխալ է։ Այժմ պետք է դիմեք ձեր օպերատորին՝ սարքն արգելաբացելու համար:"</string> + <string name="kg_password_wrong_pin_code_pukked" msgid="3389829202093674267">"SIM PIN կոդը սխալ է։ Այժմ պետք է դիմեք ձեր օպերատորին՝ սարքն արգելահանելու համար:"</string> <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="4314341367727055967"> <item quantity="one">Incorrect SIM PIN code, you have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts.</item> <item quantity="other">SIM PIN կոդը սխալ է: Մնաց <xliff:g id="NUMBER_1">%d</xliff:g> փորձ:</item> @@ -117,7 +117,7 @@ <string name="kg_pin_accepted" msgid="7637293533973802143">"Կոդն ընդունվեց:"</string> <string name="keyguard_carrier_default" msgid="4274828292998453695">"Ծառայությունն անհասանելի է։"</string> <string name="accessibility_ime_switch_button" msgid="2695096475319405612">"Փոխել ներածման եղանակը"</string> - <string name="airplane_mode" msgid="3807209033737676010">"Ինքնաթիռի ռեժիմ"</string> + <string name="airplane_mode" msgid="3807209033737676010">"Ավիառեժիմ"</string> <string name="kg_prompt_reason_restart_pattern" msgid="7246972020562621506">"Սարքը վերագործարկելուց հետո անհրաժեշտ է մուտքագրել նախշը"</string> <string name="kg_prompt_reason_restart_pin" msgid="6303592361322290145">"Սարքը վերագործարկելուց հետո անհրաժեշտ է մուտքագրել PIN կոդը"</string> <string name="kg_prompt_reason_restart_password" msgid="6984641181515902406">"Սարքը վերագործարկելուց հետո անհրաժեշտ է մուտքագրել գաղտնաբառը"</string> @@ -169,66 +169,13 @@ <item msgid="2233497913571137419">"տասը"</item> <item msgid="5621554266768657830">"տասնմեկ"</item> </string-array> - <string-array name="type_clock_minutes"> - <item msgid="8322049385467207985">"ուղիղ"</item> - <item msgid="8837126587669001578">"զրո մեկ"</item> - <item msgid="4294343372940455660">"զրո երկու"</item> - <item msgid="7129166637707421536">"զրո երեք"</item> - <item msgid="7579404865008788673">"զրո չորս"</item> - <item msgid="3873924689207380586">"զրո հինգ"</item> - <item msgid="4849565597850069377">"զրո վեց"</item> - <item msgid="4404219424523572364">"զրո յոթ"</item> - <item msgid="8740481214764087329">"ութ"</item> - <item msgid="1713216865806811237">"զրո ինը"</item> - <item msgid="3508406095411245038">"տասը"</item> - <item msgid="7161996337755311711">"տասնմեկ"</item> - <item msgid="4044549963329624197">"տասներկու"</item> - <item msgid="333373157917379088">"տասներեք"</item> - <item msgid="2631202907124819385">"տասնչորս"</item> - <item msgid="6472396076858033453">"տասնհինգ"</item> - <item msgid="8656981856181581643">"տասնվեց"</item> - <item msgid="7289026608562030619">"տասնյոթ"</item> - <item msgid="3881477602692646573">"տասնութ"</item> - <item msgid="3358129827772984226">"տասնինը"</item> - <item msgid="3308575407402865807">"քսան"</item> - <item msgid="5346560955382229629">"քսան\nմեկ"</item> - <item msgid="226750304761473436">"քսան\nերկու"</item> - <item msgid="616811325336838734">"քսան\nերեք"</item> - <item msgid="616346116869053440">"քսան\nչորս"</item> - <item msgid="4642996410384042830">"քսան\nհինգ"</item> - <item msgid="7506092849993571465">"քսան\nվեց"</item> - <item msgid="1915078191101042031">"քսան\nյոթ"</item> - <item msgid="4292378641900520252">"քսան\nութ"</item> - <item msgid="5339513901773103696">"քսան\nինը"</item> - <item msgid="3574673250891657607">"երեսուն"</item> - <item msgid="5796923836589110940">"երեսուն\nմեկ"</item> - <item msgid="5859323597571702052">"երեսուն\nերկու"</item> - <item msgid="5133326723148876507">"երեսուն\nերեք"</item> - <item msgid="2693999494655663096">"երեսուն\nչորս"</item> - <item msgid="3316754944962836197">"երեսուն\nհինգ"</item> - <item msgid="816891008836796723">"երեսուն\nվեց"</item> - <item msgid="9158890488666520078">"երեսուն\nյոթ"</item> - <item msgid="1894769703213894011">"երեսուն\nութ"</item> - <item msgid="5638820345598572399">"երեսուն\nինը"</item> - <item msgid="8838304023017895439">"քառասուն"</item> - <item msgid="1834742948932559597">"քառասուն\nմեկ"</item> - <item msgid="6573707308847773944">"քառասուն\nերկու"</item> - <item msgid="2450149950652678001">"քառասուն\nերեք"</item> - <item msgid="2874667401318178036">"քառասուն\nչորս"</item> - <item msgid="3391101532763048862">"քառասուն\nհինգ"</item> - <item msgid="1671489330863254362">"քառասուն\nվեց"</item> - <item msgid="5916017359554531038">"քառասուն\nյոթ"</item> - <item msgid="8205413177993059967">"քառասուն\nութ"</item> - <item msgid="6607867415142171302">"քառասուն\nինը"</item> - <item msgid="8358850748472089162">"հիսուն"</item> - <item msgid="3551313125255080234">"հիսուն\nմեկ"</item> - <item msgid="1559678130725716542">"հիսուն\nերկու"</item> - <item msgid="431441994725492377">"հիսուն\nերեք"</item> - <item msgid="6345774640539623024">"հիսուն\nչորս"</item> - <item msgid="8018192990793931120">"հիսուն\nհինգ"</item> - <item msgid="6187650843754604534">"հիսուն\nվեց"</item> - <item msgid="8727240174015993259">"հիսուն\nյոթ"</item> - <item msgid="848339003778952950">"հիսուն\nութ"</item> - <item msgid="5798985802835423618">"հիսուն\nինը"</item> - </string-array> + <!-- no translation found for type_clock_minutes:1 (2091812961809760681) --> + <!-- no translation found for type_clock_minutes:2 (1496435384877290709) --> + <!-- no translation found for type_clock_minutes:3 (881846472976674129) --> + <!-- no translation found for type_clock_minutes:4 (2784477043911540584) --> + <!-- no translation found for type_clock_minutes:5 (1610928853656700614) --> + <!-- no translation found for type_clock_minutes:6 (2317806244043886658) --> + <!-- no translation found for type_clock_minutes:7 (3318687539120971327) --> + <!-- no translation found for type_clock_minutes:8 (5701600693712102348) --> + <!-- no translation found for type_clock_minutes:9 (3247381605947372495) --> </resources> diff --git a/packages/SystemUI/res-keyguard/values-kk/strings.xml b/packages/SystemUI/res-keyguard/values-kk/strings.xml index f13385dda3a6..9710dc9e5d5a 100644 --- a/packages/SystemUI/res-keyguard/values-kk/strings.xml +++ b/packages/SystemUI/res-keyguard/values-kk/strings.xml @@ -169,66 +169,13 @@ <item msgid="2233497913571137419">"Он"</item> <item msgid="5621554266768657830">"Он бір"</item> </string-array> - <string-array name="type_clock_minutes"> - <item msgid="8322049385467207985"></item> - <item msgid="8837126587669001578">"Нөл бір"</item> - <item msgid="4294343372940455660">"Нөл екі"</item> - <item msgid="7129166637707421536">"Нөл үш"</item> - <item msgid="7579404865008788673">"Нөл төрт"</item> - <item msgid="3873924689207380586">"Нөл бес"</item> - <item msgid="4849565597850069377">"Нөл алты"</item> - <item msgid="4404219424523572364">"Нөл жеті"</item> - <item msgid="8740481214764087329">"Нөл сегіз"</item> - <item msgid="1713216865806811237">"Нөл тоғыз"</item> - <item msgid="3508406095411245038">"Он"</item> - <item msgid="7161996337755311711">"Он бір"</item> - <item msgid="4044549963329624197">"Он екі"</item> - <item msgid="333373157917379088">"Он үш"</item> - <item msgid="2631202907124819385">"Он төрт"</item> - <item msgid="6472396076858033453">"Он бес"</item> - <item msgid="8656981856181581643">"Он алты"</item> - <item msgid="7289026608562030619">"Он жеті"</item> - <item msgid="3881477602692646573">"Он сегіз"</item> - <item msgid="3358129827772984226">"Он тоғыз"</item> - <item msgid="3308575407402865807">"Жиырма"</item> - <item msgid="5346560955382229629">"Жиырма\nбір"</item> - <item msgid="226750304761473436">"Жиырма\nекі"</item> - <item msgid="616811325336838734">"Жиырма\nүш"</item> - <item msgid="616346116869053440">"Жиырма\nтөрт"</item> - <item msgid="4642996410384042830">"Жиырма\nбес"</item> - <item msgid="7506092849993571465">"Жиырма\nалты"</item> - <item msgid="1915078191101042031">"Жиырма\nжеті"</item> - <item msgid="4292378641900520252">"Жиырма\nсегіз"</item> - <item msgid="5339513901773103696">"Жиырма\nтоғыз"</item> - <item msgid="3574673250891657607">"Отыз"</item> - <item msgid="5796923836589110940">"Отыз\nбір"</item> - <item msgid="5859323597571702052">"Отыз\nекі"</item> - <item msgid="5133326723148876507">"Отыз\nүш"</item> - <item msgid="2693999494655663096">"Отыз\nтөрт"</item> - <item msgid="3316754944962836197">"Отыз\nбес"</item> - <item msgid="816891008836796723">"Отыз\nалты"</item> - <item msgid="9158890488666520078">"Отыз\nжеті"</item> - <item msgid="1894769703213894011">"Отыз\nсегіз"</item> - <item msgid="5638820345598572399">"Отыз\nтоғыз"</item> - <item msgid="8838304023017895439">"Қырық"</item> - <item msgid="1834742948932559597">"Қырық\nбір"</item> - <item msgid="6573707308847773944">"Қырық\nекі"</item> - <item msgid="2450149950652678001">"Қырық\nүш"</item> - <item msgid="2874667401318178036">"Қырық\nтөрт"</item> - <item msgid="3391101532763048862">"Қырық\nбес"</item> - <item msgid="1671489330863254362">"Қырық\nалты"</item> - <item msgid="5916017359554531038">"Қырық\nжеті"</item> - <item msgid="8205413177993059967">"Қырық\nсегіз"</item> - <item msgid="6607867415142171302">"Қырық\nтоғыз"</item> - <item msgid="8358850748472089162">"Елу"</item> - <item msgid="3551313125255080234">"Елу\nбір"</item> - <item msgid="1559678130725716542">"Елу\nекі"</item> - <item msgid="431441994725492377">"Елу\nүш"</item> - <item msgid="6345774640539623024">"Елу\nтөрт"</item> - <item msgid="8018192990793931120">"Елу\nбес"</item> - <item msgid="6187650843754604534">"Елу\nалты"</item> - <item msgid="8727240174015993259">"Елу\nжеті"</item> - <item msgid="848339003778952950">"Елу\nсегіз"</item> - <item msgid="5798985802835423618">"Елу\nтоғыз"</item> - </string-array> + <!-- no translation found for type_clock_minutes:1 (2091812961809760681) --> + <!-- no translation found for type_clock_minutes:2 (1496435384877290709) --> + <!-- no translation found for type_clock_minutes:3 (881846472976674129) --> + <!-- no translation found for type_clock_minutes:4 (2784477043911540584) --> + <!-- no translation found for type_clock_minutes:5 (1610928853656700614) --> + <!-- no translation found for type_clock_minutes:6 (2317806244043886658) --> + <!-- no translation found for type_clock_minutes:7 (3318687539120971327) --> + <!-- no translation found for type_clock_minutes:8 (5701600693712102348) --> + <!-- no translation found for type_clock_minutes:9 (3247381605947372495) --> </resources> diff --git a/packages/SystemUI/res-keyguard/values-kn/strings.xml b/packages/SystemUI/res-keyguard/values-kn/strings.xml index 29eb0ecc3a17..94ca6f3e594b 100644 --- a/packages/SystemUI/res-keyguard/values-kn/strings.xml +++ b/packages/SystemUI/res-keyguard/values-kn/strings.xml @@ -169,66 +169,13 @@ <item msgid="2233497913571137419">"ಹತ್ತು"</item> <item msgid="5621554266768657830">"ಹನ್ನೊಂದು"</item> </string-array> - <string-array name="type_clock_minutes"> - <item msgid="8322049385467207985">"ಗಂಟೆ"</item> - <item msgid="8837126587669001578">"ಒಂದು"</item> - <item msgid="4294343372940455660">"ಎರಡು"</item> - <item msgid="7129166637707421536">"ಮೂರು"</item> - <item msgid="7579404865008788673">"ನಾಲ್ಕು"</item> - <item msgid="3873924689207380586">"ಐದು"</item> - <item msgid="4849565597850069377">"ಆರು"</item> - <item msgid="4404219424523572364">"ಏಳು"</item> - <item msgid="8740481214764087329">"ಎಂಟು"</item> - <item msgid="1713216865806811237">"ಒಂಬತ್ತು"</item> - <item msgid="3508406095411245038">"ಹತ್ತು"</item> - <item msgid="7161996337755311711">"ಹನ್ನೊಂದು"</item> - <item msgid="4044549963329624197">"ಹನ್ನೆರಡು"</item> - <item msgid="333373157917379088">"ಹದಿಮೂರು"</item> - <item msgid="2631202907124819385">"ಹದಿನಾಲ್ಕು"</item> - <item msgid="6472396076858033453">"ಹದಿನೈದು"</item> - <item msgid="8656981856181581643">"ಹದಿನಾರು"</item> - <item msgid="7289026608562030619">"ಹದಿನೇಳು"</item> - <item msgid="3881477602692646573">"ಹದಿನೆಂಟು"</item> - <item msgid="3358129827772984226">"ಹತ್ತೊಂಬತ್ತು"</item> - <item msgid="3308575407402865807">"ಇಪ್ಪತ್ತು"</item> - <item msgid="5346560955382229629">"ಇಪ್ಪತ್ತೊಂದು\n"</item> - <item msgid="226750304761473436">"ಇಪ್ಪತ್ತೆರಡು\n"</item> - <item msgid="616811325336838734">"ಇಪ್ಪತ್ತಮೂರು\n"</item> - <item msgid="616346116869053440">"ಇಪ್ಪತ್ತನಾಲ್ಕು\n"</item> - <item msgid="4642996410384042830">"ಇಪ್ಪತ್ತೈದು\n"</item> - <item msgid="7506092849993571465">"ಇಪ್ಪತ್ತಾರು\n"</item> - <item msgid="1915078191101042031">"ಇಪ್ಪತ್ತೇಳು\n"</item> - <item msgid="4292378641900520252">"ಇಪ್ಪತ್ತೆಂಟು\n"</item> - <item msgid="5339513901773103696">"ಇಪ್ಪತ್ತೊಂಬತ್ತು\n"</item> - <item msgid="3574673250891657607">"ಮೂವತ್ತು"</item> - <item msgid="5796923836589110940">"ಮೂವತ್ತೊಂದು\n"</item> - <item msgid="5859323597571702052">"ಮೂವತ್ತೆರಡು\n"</item> - <item msgid="5133326723148876507">"ಮೂವತ್ಮೂರು\n"</item> - <item msgid="2693999494655663096">"ಮೂವತ್ತು\nನಾಲ್ಕು"</item> - <item msgid="3316754944962836197">"ಮೂವತ್ತೈದು\n"</item> - <item msgid="816891008836796723">"ಮೂವತ್ತಾರು\n"</item> - <item msgid="9158890488666520078">"ಮೂವತ್ತೇಳು\n"</item> - <item msgid="1894769703213894011">"ಮೂವತ್ತೆಂಟು \n"</item> - <item msgid="5638820345598572399">"ಮೂವತ್ತೊಂಬತ್ತು\n"</item> - <item msgid="8838304023017895439">"ನಲವತ್ತು"</item> - <item msgid="1834742948932559597">"ನಲವತ್ತೊಂದು\n"</item> - <item msgid="6573707308847773944">"ನಲವತ್ತೇರಡು\n"</item> - <item msgid="2450149950652678001">"ನಲವತ್ಮೂರು\n"</item> - <item msgid="2874667401318178036">"ನಲವತ್ತು\nನಾಲ್ಕು"</item> - <item msgid="3391101532763048862">"ನಲವತ್ತೈದು\n"</item> - <item msgid="1671489330863254362">"ನಲವತ್ತಾರು\n"</item> - <item msgid="5916017359554531038">"ನಲವತ್ತೇಳು\n"</item> - <item msgid="8205413177993059967">"ನಲವತ್ತೆಂಟು\n"</item> - <item msgid="6607867415142171302">"ನಲವತ್ತೊಂಬತ್ತು\n"</item> - <item msgid="8358850748472089162">"ಐವತ್ತು"</item> - <item msgid="3551313125255080234">"ಐವತ್ತೊಂದು\n"</item> - <item msgid="1559678130725716542">"ಐವತ್ತೇರಡು\n"</item> - <item msgid="431441994725492377">"ಐವತ್ಮೂರು\n"</item> - <item msgid="6345774640539623024">"ಐವತ್ನಾಲ್ಕು\n"</item> - <item msgid="8018192990793931120">"ಐವತ್ತೈದು\n"</item> - <item msgid="6187650843754604534">"ಐವತ್ತಾರು\n"</item> - <item msgid="8727240174015993259">"ಐವತ್ತೇಳು\n"</item> - <item msgid="848339003778952950">"ಐವತ್ತೆಂಟು\n"</item> - <item msgid="5798985802835423618">"ಐವತ್ತೊಂಬತ್ತು\n"</item> - </string-array> + <!-- no translation found for type_clock_minutes:1 (2091812961809760681) --> + <!-- no translation found for type_clock_minutes:2 (1496435384877290709) --> + <!-- no translation found for type_clock_minutes:3 (881846472976674129) --> + <!-- no translation found for type_clock_minutes:4 (2784477043911540584) --> + <!-- no translation found for type_clock_minutes:5 (1610928853656700614) --> + <!-- no translation found for type_clock_minutes:6 (2317806244043886658) --> + <!-- no translation found for type_clock_minutes:7 (3318687539120971327) --> + <!-- no translation found for type_clock_minutes:8 (5701600693712102348) --> + <!-- no translation found for type_clock_minutes:9 (3247381605947372495) --> </resources> diff --git a/packages/SystemUI/res-keyguard/values-mr/strings.xml b/packages/SystemUI/res-keyguard/values-mr/strings.xml index 75c5aab185a2..5a7b0cf3c616 100644 --- a/packages/SystemUI/res-keyguard/values-mr/strings.xml +++ b/packages/SystemUI/res-keyguard/values-mr/strings.xml @@ -169,66 +169,13 @@ <item msgid="2233497913571137419">"दहा"</item> <item msgid="5621554266768657830">"एकरा"</item> </string-array> - <string-array name="type_clock_minutes"> - <item msgid="8322049385467207985">"वाजता"</item> - <item msgid="8837126587669001578">"एक"</item> - <item msgid="4294343372940455660">"दोन"</item> - <item msgid="7129166637707421536">"तीन"</item> - <item msgid="7579404865008788673">"चार"</item> - <item msgid="3873924689207380586">"पाच"</item> - <item msgid="4849565597850069377">"सहा"</item> - <item msgid="4404219424523572364">"सात"</item> - <item msgid="8740481214764087329">"आठ"</item> - <item msgid="1713216865806811237">"नऊ"</item> - <item msgid="3508406095411245038">"दहा"</item> - <item msgid="7161996337755311711">"एकरा"</item> - <item msgid="4044549963329624197">"बारा"</item> - <item msgid="333373157917379088">"तेरा"</item> - <item msgid="2631202907124819385">"चौदा"</item> - <item msgid="6472396076858033453">"पंधरा"</item> - <item msgid="8656981856181581643">"सोळा"</item> - <item msgid="7289026608562030619">"सतरा"</item> - <item msgid="3881477602692646573">"अठरा"</item> - <item msgid="3358129827772984226">"एकोणीस"</item> - <item msgid="3308575407402865807">"वीस"</item> - <item msgid="5346560955382229629">"एकवीस\n"</item> - <item msgid="226750304761473436">"बावीस\n"</item> - <item msgid="616811325336838734">"तेवीस\n"</item> - <item msgid="616346116869053440">"चोवीस\n"</item> - <item msgid="4642996410384042830">"पंचवीस\n"</item> - <item msgid="7506092849993571465">"सव्वीस\n"</item> - <item msgid="1915078191101042031">"सत्तावीस\n"</item> - <item msgid="4292378641900520252">"अठ्ठावीस\n"</item> - <item msgid="5339513901773103696">"एकोणतीस\n"</item> - <item msgid="3574673250891657607">"तीस"</item> - <item msgid="5796923836589110940">"एकतीस\n"</item> - <item msgid="5859323597571702052">"बत्तीस\n"</item> - <item msgid="5133326723148876507">"तेहतीस\n"</item> - <item msgid="2693999494655663096">"चौतीस\n"</item> - <item msgid="3316754944962836197">"पस्तीस\n"</item> - <item msgid="816891008836796723">"छत्तीस\n"</item> - <item msgid="9158890488666520078">"सदतीस\n"</item> - <item msgid="1894769703213894011">"अडतीस\n"</item> - <item msgid="5638820345598572399">"एकोणचाळीस\n"</item> - <item msgid="8838304023017895439">"चाळीस"</item> - <item msgid="1834742948932559597">"एकेचाळीस\n"</item> - <item msgid="6573707308847773944">"बेचाळीस\n"</item> - <item msgid="2450149950652678001">"त्रेचाळीस\n"</item> - <item msgid="2874667401318178036">"चव्वेचाळीस\n"</item> - <item msgid="3391101532763048862">"पंचेचाळीस\n"</item> - <item msgid="1671489330863254362">"शेहेचाळीस\n"</item> - <item msgid="5916017359554531038">"सत्तेचाळीस\n"</item> - <item msgid="8205413177993059967">"अठ्ठेचाळीस\n"</item> - <item msgid="6607867415142171302">"एकोणपन्नास\n"</item> - <item msgid="8358850748472089162">"पन्नास"</item> - <item msgid="3551313125255080234">"एकावन्न\n"</item> - <item msgid="1559678130725716542">"बावन्न\n"</item> - <item msgid="431441994725492377">"त्रेपन्न\n"</item> - <item msgid="6345774640539623024">"चौपन्न\n"</item> - <item msgid="8018192990793931120">"पंचावन्न\n"</item> - <item msgid="6187650843754604534">"छप्पन\n"</item> - <item msgid="8727240174015993259">"सत्तावन्न\n"</item> - <item msgid="848339003778952950">"अठ्ठावन्न\n"</item> - <item msgid="5798985802835423618">"एकोणसाठ\n"</item> - </string-array> + <!-- no translation found for type_clock_minutes:1 (2091812961809760681) --> + <!-- no translation found for type_clock_minutes:2 (1496435384877290709) --> + <!-- no translation found for type_clock_minutes:3 (881846472976674129) --> + <!-- no translation found for type_clock_minutes:4 (2784477043911540584) --> + <!-- no translation found for type_clock_minutes:5 (1610928853656700614) --> + <!-- no translation found for type_clock_minutes:6 (2317806244043886658) --> + <!-- no translation found for type_clock_minutes:7 (3318687539120971327) --> + <!-- no translation found for type_clock_minutes:8 (5701600693712102348) --> + <!-- no translation found for type_clock_minutes:9 (3247381605947372495) --> </resources> diff --git a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml index 4da36e5012c6..159f8c081976 100644 --- a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml @@ -169,66 +169,13 @@ <item msgid="2233497913571137419">"Dez"</item> <item msgid="5621554266768657830">"Onze"</item> </string-array> - <string-array name="type_clock_minutes"> - <item msgid="8322049385467207985"></item> - <item msgid="8837126587669001578">"Um"</item> - <item msgid="4294343372940455660">"Dois"</item> - <item msgid="7129166637707421536">"Três"</item> - <item msgid="7579404865008788673">"Quatro"</item> - <item msgid="3873924689207380586">"Cinco"</item> - <item msgid="4849565597850069377">"Seis"</item> - <item msgid="4404219424523572364">"Sete"</item> - <item msgid="8740481214764087329">"Oito"</item> - <item msgid="1713216865806811237">"Nove"</item> - <item msgid="3508406095411245038">"Dez"</item> - <item msgid="7161996337755311711">"Onze"</item> - <item msgid="4044549963329624197">"Doze"</item> - <item msgid="333373157917379088">"Treze"</item> - <item msgid="2631202907124819385">"Catorze"</item> - <item msgid="6472396076858033453">"Quinze"</item> - <item msgid="8656981856181581643">"Dezasseis"</item> - <item msgid="7289026608562030619">"Dezassete"</item> - <item msgid="3881477602692646573">"Dezoito"</item> - <item msgid="3358129827772984226">"Dezanove"</item> - <item msgid="3308575407402865807">"Vinte"</item> - <item msgid="5346560955382229629">"Vinte\ne um"</item> - <item msgid="226750304761473436">"Vinte\ne dois"</item> - <item msgid="616811325336838734">"Vinte\ne três"</item> - <item msgid="616346116869053440">"Vinte\ne quatro"</item> - <item msgid="4642996410384042830">"Vinte\ne cinco"</item> - <item msgid="7506092849993571465">"Vinte\ne seis"</item> - <item msgid="1915078191101042031">"Vinte\ne sete"</item> - <item msgid="4292378641900520252">"Vinte\ne oito"</item> - <item msgid="5339513901773103696">"Vinte\ne nove"</item> - <item msgid="3574673250891657607">"Trinta"</item> - <item msgid="5796923836589110940">"Trinta\ne um"</item> - <item msgid="5859323597571702052">"Trinta\ne dois"</item> - <item msgid="5133326723148876507">"Trinta\ne três"</item> - <item msgid="2693999494655663096">"Trinta\ne quatro"</item> - <item msgid="3316754944962836197">"Trinta\ne cinco"</item> - <item msgid="816891008836796723">"Trinta\ne seis"</item> - <item msgid="9158890488666520078">"Trinta\ne sete"</item> - <item msgid="1894769703213894011">"Trinta\ne oito"</item> - <item msgid="5638820345598572399">"Trinta\ne nove"</item> - <item msgid="8838304023017895439">"Quarenta"</item> - <item msgid="1834742948932559597">"Quarenta\ne um"</item> - <item msgid="6573707308847773944">"Quarenta\ne dois"</item> - <item msgid="2450149950652678001">"Quarenta\ne três"</item> - <item msgid="2874667401318178036">"Quarenta\ne quatro"</item> - <item msgid="3391101532763048862">"Quarenta\ne cinco"</item> - <item msgid="1671489330863254362">"Quarenta\ne seis"</item> - <item msgid="5916017359554531038">"Quarenta\ne sete"</item> - <item msgid="8205413177993059967">"Quarenta\ne oito"</item> - <item msgid="6607867415142171302">"Quarenta\ne nove"</item> - <item msgid="8358850748472089162">"Cinquenta"</item> - <item msgid="3551313125255080234">"Cinquenta\ne um"</item> - <item msgid="1559678130725716542">"Cinquenta\ne dois"</item> - <item msgid="431441994725492377">"Cinquenta\ne três"</item> - <item msgid="6345774640539623024">"Cinquenta\ne quatro"</item> - <item msgid="8018192990793931120">"Cinquenta\ne cinco"</item> - <item msgid="6187650843754604534">"Cinquenta\ne seis"</item> - <item msgid="8727240174015993259">"Cinquenta\ne sete"</item> - <item msgid="848339003778952950">"Cinquenta\ne oito"</item> - <item msgid="5798985802835423618">"Cinquenta\ne nove"</item> - </string-array> + <!-- no translation found for type_clock_minutes:1 (2091812961809760681) --> + <!-- no translation found for type_clock_minutes:2 (1496435384877290709) --> + <!-- no translation found for type_clock_minutes:3 (881846472976674129) --> + <!-- no translation found for type_clock_minutes:4 (2784477043911540584) --> + <!-- no translation found for type_clock_minutes:5 (1610928853656700614) --> + <!-- no translation found for type_clock_minutes:6 (2317806244043886658) --> + <!-- no translation found for type_clock_minutes:7 (3318687539120971327) --> + <!-- no translation found for type_clock_minutes:8 (5701600693712102348) --> + <!-- no translation found for type_clock_minutes:9 (3247381605947372495) --> </resources> diff --git a/packages/SystemUI/res-keyguard/values-sk/strings.xml b/packages/SystemUI/res-keyguard/values-sk/strings.xml index 011905e397a6..e586cbfe4360 100644 --- a/packages/SystemUI/res-keyguard/values-sk/strings.xml +++ b/packages/SystemUI/res-keyguard/values-sk/strings.xml @@ -187,66 +187,13 @@ <item msgid="2233497913571137419">"Desať"</item> <item msgid="5621554266768657830">"Jedenásť"</item> </string-array> - <string-array name="type_clock_minutes"> - <item msgid="8322049385467207985">"hod."</item> - <item msgid="8837126587669001578">"Jedna hodina"</item> - <item msgid="4294343372940455660">"Dve hodiny"</item> - <item msgid="7129166637707421536">"Tri hodiny"</item> - <item msgid="7579404865008788673">"Štyri hodiny"</item> - <item msgid="3873924689207380586">"Päť hodín"</item> - <item msgid="4849565597850069377">"Šesť hodín"</item> - <item msgid="4404219424523572364">"Sedem hodín"</item> - <item msgid="8740481214764087329">"Osem hodín"</item> - <item msgid="1713216865806811237">"Deväť hodín"</item> - <item msgid="3508406095411245038">"Desať"</item> - <item msgid="7161996337755311711">"Jedenásť"</item> - <item msgid="4044549963329624197">"Dvanásť"</item> - <item msgid="333373157917379088">"Trinásť"</item> - <item msgid="2631202907124819385">"Štrnásť"</item> - <item msgid="6472396076858033453">"Päťnásť"</item> - <item msgid="8656981856181581643">"Šesťnásť"</item> - <item msgid="7289026608562030619">"Sedemnásť"</item> - <item msgid="3881477602692646573">"Osemnásť"</item> - <item msgid="3358129827772984226">"Deväťnásť"</item> - <item msgid="3308575407402865807">"Dvadsať"</item> - <item msgid="5346560955382229629">"Dvadsaťjeden\n"</item> - <item msgid="226750304761473436">"Dvadsaťdva\n"</item> - <item msgid="616811325336838734">"Dvadsaťtri\n"</item> - <item msgid="616346116869053440">"Dvadsaťštyri\n"</item> - <item msgid="4642996410384042830">"Dvadsaťpäť\n"</item> - <item msgid="7506092849993571465">"Dvadsaťšesť\n"</item> - <item msgid="1915078191101042031">"Dvadsaťsedem\n"</item> - <item msgid="4292378641900520252">"Dvadsaťosem\n"</item> - <item msgid="5339513901773103696">"Dvadsaťdeväť\n"</item> - <item msgid="3574673250891657607">"Tridsať"</item> - <item msgid="5796923836589110940">"Tridsaťjeden\n"</item> - <item msgid="5859323597571702052">"Tridsaťdva\n"</item> - <item msgid="5133326723148876507">"Tridsaťtri\n"</item> - <item msgid="2693999494655663096">"Tridsaťštyri\n"</item> - <item msgid="3316754944962836197">"Tridsaťpäť\n"</item> - <item msgid="816891008836796723">"Tridsaťšesť\n"</item> - <item msgid="9158890488666520078">"Tridsaťsedem\n"</item> - <item msgid="1894769703213894011">"Tridsaťosem\n"</item> - <item msgid="5638820345598572399">"Tridsaťdeväť\n"</item> - <item msgid="8838304023017895439">"Štyridsať"</item> - <item msgid="1834742948932559597">"Štyridsaťjeden\n"</item> - <item msgid="6573707308847773944">"Štyridsaťdva\n"</item> - <item msgid="2450149950652678001">"Štyridsaťtri\n"</item> - <item msgid="2874667401318178036">"Štyridsaťštyri\n"</item> - <item msgid="3391101532763048862">"Štyridsaťpäť\n"</item> - <item msgid="1671489330863254362">"Štyridsaťšesť\n"</item> - <item msgid="5916017359554531038">"Štyridsaťsedem\n"</item> - <item msgid="8205413177993059967">"Štyridsaťosem\n"</item> - <item msgid="6607867415142171302">"Štyridsaťdeväť\n"</item> - <item msgid="8358850748472089162">"Päťdesiať"</item> - <item msgid="3551313125255080234">"Päťdesiatjeden\n"</item> - <item msgid="1559678130725716542">"Päťdesiatdva\n"</item> - <item msgid="431441994725492377">"Päťdesiattri\n"</item> - <item msgid="6345774640539623024">"Päťdesiatštyri\n"</item> - <item msgid="8018192990793931120">"Päťdesiaťpäť\n"</item> - <item msgid="6187650843754604534">"Päťdesiatšesť\n"</item> - <item msgid="8727240174015993259">"Päťdesiatsedem\n"</item> - <item msgid="848339003778952950">"Päťdesiatosem\n"</item> - <item msgid="5798985802835423618">"Päťdesiatdeväť\n"</item> - </string-array> + <!-- no translation found for type_clock_minutes:1 (2091812961809760681) --> + <!-- no translation found for type_clock_minutes:2 (1496435384877290709) --> + <!-- no translation found for type_clock_minutes:3 (881846472976674129) --> + <!-- no translation found for type_clock_minutes:4 (2784477043911540584) --> + <!-- no translation found for type_clock_minutes:5 (1610928853656700614) --> + <!-- no translation found for type_clock_minutes:6 (2317806244043886658) --> + <!-- no translation found for type_clock_minutes:7 (3318687539120971327) --> + <!-- no translation found for type_clock_minutes:8 (5701600693712102348) --> + <!-- no translation found for type_clock_minutes:9 (3247381605947372495) --> </resources> diff --git a/packages/SystemUI/res-keyguard/values-ta/strings.xml b/packages/SystemUI/res-keyguard/values-ta/strings.xml index 0f78466e662e..d52b6e124c9b 100644 --- a/packages/SystemUI/res-keyguard/values-ta/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ta/strings.xml @@ -169,66 +169,13 @@ <item msgid="2233497913571137419">"பத்து"</item> <item msgid="5621554266768657830">"பதினொன்று"</item> </string-array> - <string-array name="type_clock_minutes"> - <item msgid="8322049385467207985">"மணி"</item> - <item msgid="8837126587669001578">"ஒன்று"</item> - <item msgid="4294343372940455660">"இரண்டு"</item> - <item msgid="7129166637707421536">"மூன்று"</item> - <item msgid="7579404865008788673">"நான்கு"</item> - <item msgid="3873924689207380586">"ஐந்து"</item> - <item msgid="4849565597850069377">"ஆறு"</item> - <item msgid="4404219424523572364">"ஏழு"</item> - <item msgid="8740481214764087329">"எட்டு"</item> - <item msgid="1713216865806811237">"ஒன்பது"</item> - <item msgid="3508406095411245038">"பத்து"</item> - <item msgid="7161996337755311711">"பதினொன்று"</item> - <item msgid="4044549963329624197">"பன்னிரண்டு"</item> - <item msgid="333373157917379088">"பதிமூன்று"</item> - <item msgid="2631202907124819385">"பதினான்கு"</item> - <item msgid="6472396076858033453">"பதினைந்து"</item> - <item msgid="8656981856181581643">"பதினாறு"</item> - <item msgid="7289026608562030619">"பதினேழு"</item> - <item msgid="3881477602692646573">"பதினெட்டு"</item> - <item msgid="3358129827772984226">"பத்தொன்பது"</item> - <item msgid="3308575407402865807">"இருபது"</item> - <item msgid="5346560955382229629">"இருபத்து\nஒன்று"</item> - <item msgid="226750304761473436">"இருபத்து\nஇரண்டு"</item> - <item msgid="616811325336838734">"இருபத்து\nமூன்று"</item> - <item msgid="616346116869053440">"இருபத்து\nநான்கு"</item> - <item msgid="4642996410384042830">"இருபத்து\nஐந்து"</item> - <item msgid="7506092849993571465">"இருபத்து\nஆறு"</item> - <item msgid="1915078191101042031">"இருபத்து\nஏழு"</item> - <item msgid="4292378641900520252">"இருபத்து\nஎட்டு"</item> - <item msgid="5339513901773103696">"இருபத்து\nஒன்பது"</item> - <item msgid="3574673250891657607">"முப்பது"</item> - <item msgid="5796923836589110940">"முப்பத்து\nஒன்று"</item> - <item msgid="5859323597571702052">"முப்பத்து\nஇரண்டு"</item> - <item msgid="5133326723148876507">"முப்பத்து\nமூன்று"</item> - <item msgid="2693999494655663096">"முப்பத்து\nநான்கு"</item> - <item msgid="3316754944962836197">"முப்பத்து\nஐந்து"</item> - <item msgid="816891008836796723">"முப்பத்து\nஆறு"</item> - <item msgid="9158890488666520078">"முப்பத்து\nஏழு"</item> - <item msgid="1894769703213894011">"முப்பத்து\nஎட்டு"</item> - <item msgid="5638820345598572399">"முப்பத்து\nஒன்பது"</item> - <item msgid="8838304023017895439">"நாற்பது"</item> - <item msgid="1834742948932559597">"நாற்பத்து\nஒன்று"</item> - <item msgid="6573707308847773944">"நாற்பத்து\nஇரண்டு"</item> - <item msgid="2450149950652678001">"நாற்பத்து\nமூன்று"</item> - <item msgid="2874667401318178036">"நாற்பத்து\nநான்கு"</item> - <item msgid="3391101532763048862">"நாற்பத்து\nஐந்து"</item> - <item msgid="1671489330863254362">"நாற்பத்து\nஆறு"</item> - <item msgid="5916017359554531038">"நாற்பத்து\nஏழு"</item> - <item msgid="8205413177993059967">"நாற்பத்து\nஎட்டு"</item> - <item msgid="6607867415142171302">"நாற்பத்து\nஒன்பது"</item> - <item msgid="8358850748472089162">"ஐம்பது"</item> - <item msgid="3551313125255080234">"ஐம்பத்து\nஒன்று"</item> - <item msgid="1559678130725716542">"ஐம்பத்து\nஇரண்டு"</item> - <item msgid="431441994725492377">"ஐம்பத்து\nமூன்று"</item> - <item msgid="6345774640539623024">"ஐம்பத்து\nநான்கு"</item> - <item msgid="8018192990793931120">"முப்பத்து\nஐந்து"</item> - <item msgid="6187650843754604534">"ஐம்பத்து\nஆறு"</item> - <item msgid="8727240174015993259">"ஐம்பத்து\nஏழு"</item> - <item msgid="848339003778952950">"ஐம்பத்து\nஎட்டு"</item> - <item msgid="5798985802835423618">"ஐம்பத்து\nஒன்பது"</item> - </string-array> + <!-- no translation found for type_clock_minutes:1 (2091812961809760681) --> + <!-- no translation found for type_clock_minutes:2 (1496435384877290709) --> + <!-- no translation found for type_clock_minutes:3 (881846472976674129) --> + <!-- no translation found for type_clock_minutes:4 (2784477043911540584) --> + <!-- no translation found for type_clock_minutes:5 (1610928853656700614) --> + <!-- no translation found for type_clock_minutes:6 (2317806244043886658) --> + <!-- no translation found for type_clock_minutes:7 (3318687539120971327) --> + <!-- no translation found for type_clock_minutes:8 (5701600693712102348) --> + <!-- no translation found for type_clock_minutes:9 (3247381605947372495) --> </resources> diff --git a/packages/SystemUI/res-keyguard/values-vi/strings.xml b/packages/SystemUI/res-keyguard/values-vi/strings.xml index 8113094f3081..6498cf15b236 100644 --- a/packages/SystemUI/res-keyguard/values-vi/strings.xml +++ b/packages/SystemUI/res-keyguard/values-vi/strings.xml @@ -169,66 +169,13 @@ <item msgid="2233497913571137419">"Mười"</item> <item msgid="5621554266768657830">"Mười một"</item> </string-array> - <string-array name="type_clock_minutes"> - <item msgid="8322049385467207985">"Giờ"</item> - <item msgid="8837126587669001578">"Một"</item> - <item msgid="4294343372940455660">"Hai"</item> - <item msgid="7129166637707421536">"Ba"</item> - <item msgid="7579404865008788673">"Bốn"</item> - <item msgid="3873924689207380586">"Năm"</item> - <item msgid="4849565597850069377">"Sáu"</item> - <item msgid="4404219424523572364">"Bảy"</item> - <item msgid="8740481214764087329">"Tám"</item> - <item msgid="1713216865806811237">"Chín"</item> - <item msgid="3508406095411245038">"Mười"</item> - <item msgid="7161996337755311711">"Mười một"</item> - <item msgid="4044549963329624197">"Mười hai"</item> - <item msgid="333373157917379088">"Mười ba"</item> - <item msgid="2631202907124819385">"Mười bốn"</item> - <item msgid="6472396076858033453">"Mười lăm"</item> - <item msgid="8656981856181581643">"Mười sáu"</item> - <item msgid="7289026608562030619">"Mười bảy"</item> - <item msgid="3881477602692646573">"Mười tám"</item> - <item msgid="3358129827772984226">"Mười chín"</item> - <item msgid="3308575407402865807">"Hai mươi"</item> - <item msgid="5346560955382229629">"Hai mươi\nmốt"</item> - <item msgid="226750304761473436">"Hai mươi\nhai"</item> - <item msgid="616811325336838734">"Hai mươi\nba"</item> - <item msgid="616346116869053440">"Hai mươi\nbốn"</item> - <item msgid="4642996410384042830">"Hai mươi\nlăm"</item> - <item msgid="7506092849993571465">"Hai mươi\nsáu"</item> - <item msgid="1915078191101042031">"Hai mươi\nbảy"</item> - <item msgid="4292378641900520252">"Hai mươi\ntám"</item> - <item msgid="5339513901773103696">"Hai mươi\nchín"</item> - <item msgid="3574673250891657607">"Ba mươi"</item> - <item msgid="5796923836589110940">"Ba mươi\nmốt"</item> - <item msgid="5859323597571702052">"Ba mươi\nhai"</item> - <item msgid="5133326723148876507">"Ba mươi\nba"</item> - <item msgid="2693999494655663096">"Ba mươi\ntư"</item> - <item msgid="3316754944962836197">"Ba mươi\nlăm"</item> - <item msgid="816891008836796723">"Ba mươi\nsáu"</item> - <item msgid="9158890488666520078">"Ba mươi\nbảy"</item> - <item msgid="1894769703213894011">"Ba mươi\ntám"</item> - <item msgid="5638820345598572399">"Ba mươi\nchín"</item> - <item msgid="8838304023017895439">"Bốn mươi"</item> - <item msgid="1834742948932559597">"Bốn mươi\nmốt"</item> - <item msgid="6573707308847773944">"Bốn mươi\nhai"</item> - <item msgid="2450149950652678001">"Bốn mươi\nba"</item> - <item msgid="2874667401318178036">"Bốn mươi\nbốn"</item> - <item msgid="3391101532763048862">"Bốn mươi\nlăm"</item> - <item msgid="1671489330863254362">"Bốn mươi\nsáu"</item> - <item msgid="5916017359554531038">"Bốn mươi\nbảy"</item> - <item msgid="8205413177993059967">"Bốn mươi\ntám"</item> - <item msgid="6607867415142171302">"Bốn mươi\nchín"</item> - <item msgid="8358850748472089162">"Năm mươi"</item> - <item msgid="3551313125255080234">"Năm mươi\nmốt"</item> - <item msgid="1559678130725716542">"Năm mươi\nhai"</item> - <item msgid="431441994725492377">"Năm mươi\nba"</item> - <item msgid="6345774640539623024">"Năm mươi\nbốn"</item> - <item msgid="8018192990793931120">"Năm mươi\nlăm"</item> - <item msgid="6187650843754604534">"Năm mươi\nsáu"</item> - <item msgid="8727240174015993259">"Năm mươi\nbảy"</item> - <item msgid="848339003778952950">"Năm mươi\ntám"</item> - <item msgid="5798985802835423618">"Năm mươi\nchín"</item> - </string-array> + <!-- no translation found for type_clock_minutes:1 (2091812961809760681) --> + <!-- no translation found for type_clock_minutes:2 (1496435384877290709) --> + <!-- no translation found for type_clock_minutes:3 (881846472976674129) --> + <!-- no translation found for type_clock_minutes:4 (2784477043911540584) --> + <!-- no translation found for type_clock_minutes:5 (1610928853656700614) --> + <!-- no translation found for type_clock_minutes:6 (2317806244043886658) --> + <!-- no translation found for type_clock_minutes:7 (3318687539120971327) --> + <!-- no translation found for type_clock_minutes:8 (5701600693712102348) --> + <!-- no translation found for type_clock_minutes:9 (3247381605947372495) --> </resources> diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml index 5714556ae8a3..2f2f84a97434 100644 --- a/packages/SystemUI/res-keyguard/values/strings.xml +++ b/packages/SystemUI/res-keyguard/values/strings.xml @@ -444,15 +444,15 @@ number">%d</xliff:g> remaining attempts before SIM becomes permanently unusable. <!-- Minutes displayed in words on the typographic clock face. [CHAR LIMIT=20] --> <string-array name="type_clock_minutes"> <item>O\u2019Clock</item> - <item>O\u2019One</item> - <item>O\u2019Two</item> - <item>O\u2019Three</item> - <item>O\u2019Four</item> - <item>O\u2019Five</item> - <item>O\u2019Six</item> - <item>O\u2019Seven</item> - <item>O\u2019Eight</item> - <item>O\u2019Nine</item> + <item>Oh One</item> + <item>Oh Two</item> + <item>Oh Three</item> + <item>Oh Four</item> + <item>Oh Five</item> + <item>Oh Six</item> + <item>Oh Seven</item> + <item>Oh Eight</item> + <item>Oh Nine</item> <item>Ten</item> <item>Eleven</item> <item>Twelve</item> diff --git a/packages/SystemUI/res/color/caption_tint_color_selector.xml b/packages/SystemUI/res/color/caption_tint_color_selector.xml new file mode 100644 index 000000000000..30843ec70f91 --- /dev/null +++ b/packages/SystemUI/res/color/caption_tint_color_selector.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2019 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> +<selector xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:sysui="http://schemas.android.com/apk/res-auto"> + <item sysui:optedOut="true" + android:color="?android:attr/colorButtonNormal"/> + + <item android:color="?android:attr/colorAccent"/> +</selector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_signal_sensors.xml b/packages/SystemUI/res/drawable/ic_signal_sensors.xml deleted file mode 100644 index faaddf6473c4..000000000000 --- a/packages/SystemUI/res/drawable/ic_signal_sensors.xml +++ /dev/null @@ -1,28 +0,0 @@ -<!-- - Copyright (C) 2018 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<vector android:height="48dp" android:viewportHeight="5" - android:viewportWidth="5" android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android"> - <path android:fillColor="#00000000" - android:pathData="m4.762,0.661 l-4.233,4.233" - android:strokeAlpha="1" android:strokeColor="#000000" - android:strokeLineCap="round" android:strokeLineJoin="miter" android:strokeWidth=".5"/> - <path android:fillColor="#00000000" - android:pathData="M0.265,2.778L1.058,2.778l0.529,-1.323 0.529,2.646 0.529,-3.175 0.529,2.646 0.529,-1.587 0.265,0.794h1.058" - android:strokeAlpha="1" android:strokeColor="#000000" - android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth=".33"/> -</vector> - diff --git a/packages/SystemUI/res/drawable/stat_sys_sensors_off.xml b/packages/SystemUI/res/drawable/stat_sys_sensors_off.xml new file mode 100644 index 000000000000..ca8f9931f148 --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_sensors_off.xml @@ -0,0 +1,41 @@ +<!-- + Copyright (C) 2019 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:insetLeft="3dp" + android:insetRight="3dp" + android:width="17dp" + android:height="17dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:pathData="M21.966,2 L2,22" + android:strokeLineCap="round" + android:strokeColor="#000000" + android:fillColor="#00000000" + android:strokeWidth="1.6521436" + android:strokeLineJoin="miter" + android:strokeAlpha="1"/> + <path + android:pathData="M0.752,12L4.496,12l2.496,-6.25 2.496,12.5 2.496,-15 2.496,12.5 2.496,-7.5 1.248,3.75h4.992" + android:strokeLineCap="round" + android:strokeColor="#000000" + android:fillColor="#00000000" + android:strokeWidth="1.25090861" + android:strokeLineJoin="round" + android:strokeAlpha="1"/> +</vector> + diff --git a/packages/SystemUI/res/layout/biometric_dialog.xml b/packages/SystemUI/res/layout/biometric_dialog.xml index 83557f266da0..8f7a45f02c46 100644 --- a/packages/SystemUI/res/layout/biometric_dialog.xml +++ b/packages/SystemUI/res/layout/biometric_dialog.xml @@ -128,7 +128,6 @@ android:textSize="12sp" android:gravity="center_horizontal" android:accessibilityLiveRegion="polite" - android:contentDescription="@string/accessibility_biometric_dialog_help_area" android:textColor="?android:attr/textColorSecondary"/> <LinearLayout diff --git a/packages/SystemUI/res/layout/bubble_permission_view.xml b/packages/SystemUI/res/layout/bubble_permission_view.xml index c9d8a9128d7c..df5264cc7706 100644 --- a/packages/SystemUI/res/layout/bubble_permission_view.xml +++ b/packages/SystemUI/res/layout/bubble_permission_view.xml @@ -58,7 +58,7 @@ android:layout_height="wrap_content" android:layout_marginTop="8dp" android:text="@string/bubbles_prompt" - style="@*android:style/TextAppearance.Material.Body1" /> + style="@*android:style/TextAppearance.DeviceDefault.Notification.Title"/> <!-- Buttons --> <LinearLayout diff --git a/packages/SystemUI/res/layout/media_projection_dialog_title.xml b/packages/SystemUI/res/layout/media_projection_dialog_title.xml new file mode 100644 index 000000000000..c4d784ba23f7 --- /dev/null +++ b/packages/SystemUI/res/layout/media_projection_dialog_title.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2019, The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" + xmlns:android="http://schemas.android.com/apk/res/android" + android:theme="@style/Theme.MediaProjectionAlertDialog" + android:paddingStart="?android:attr/dialogPreferredPadding" + android:paddingEnd="?android:attr/dialogPreferredPadding" + android:paddingTop="?android:attr/dialogPreferredPadding"> + <ImageView + android:id="@+id/dialog_icon" + android:src="@drawable/ic_media_projection_permission" + android:layout_height="wrap_content" + android:layout_width="match_parent" + android:layout_marginBottom="20dp" + android:layout_centerInParent="true"/> + <TextView + android:id="@+id/dialog_title" + android:gravity="center" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_below="@id/dialog_icon" + android:textColor="?android:attr/colorPrimary" + android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Title" /> +</RelativeLayout> diff --git a/packages/SystemUI/res/layout/qs_footer_impl.xml b/packages/SystemUI/res/layout/qs_footer_impl.xml index 669d53bfdc60..a02962e5e1e6 100644 --- a/packages/SystemUI/res/layout/qs_footer_impl.xml +++ b/packages/SystemUI/res/layout/qs_footer_impl.xml @@ -30,13 +30,6 @@ android:clipChildren="false" android:clipToPadding="false"> - <View - android:id="@+id/qs_footer_divider" - android:layout_width="match_parent" - android:layout_height="1dp" - android:layout_gravity="top" - android:background="?android:attr/dividerHorizontal"/> - <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" @@ -99,7 +92,6 @@ android:layout_width="@dimen/multi_user_avatar_expanded_size" android:layout_height="@dimen/multi_user_avatar_expanded_size" android:layout_gravity="center" - android:tint="?android:attr/colorAccent" android:scaleType="centerInside"/> </com.android.systemui.statusbar.phone.MultiUserSwitch> diff --git a/packages/SystemUI/res/layout/quick_qs_status_icons.xml b/packages/SystemUI/res/layout/quick_qs_status_icons.xml index fa74536532b8..dc31b70cd091 100644 --- a/packages/SystemUI/res/layout/quick_qs_status_icons.xml +++ b/packages/SystemUI/res/layout/quick_qs_status_icons.xml @@ -19,7 +19,7 @@ android:id="@+id/quick_qs_status_icons" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="8dp" + android:layout_marginTop="@dimen/qs_header_top_margin" android:layout_marginBottom="14dp" android:layout_marginStart="@dimen/status_bar_padding_start" android:layout_marginEnd="@dimen/status_bar_padding_end" diff --git a/packages/SystemUI/res/layout/quick_settings_header_info.xml b/packages/SystemUI/res/layout/quick_settings_header_info.xml index 075f51d2e17a..da640fd1e164 100644 --- a/packages/SystemUI/res/layout/quick_settings_header_info.xml +++ b/packages/SystemUI/res/layout/quick_settings_header_info.xml @@ -19,7 +19,9 @@ android:layout_width="match_parent" android:layout_height="@dimen/qs_header_tooltip_height" android:layout_below="@id/quick_status_bar_system_icons" - android:layout_marginTop="12dp"> + android:layout_marginTop="@dimen/qs_header_top_margin" + android:paddingStart="@dimen/status_bar_padding_start" + android:paddingEnd="@dimen/status_bar_padding_end"> <TextView android:id="@+id/long_press_tooltip" diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml index 1d0a24274b12..d1c80c43b3e9 100644 --- a/packages/SystemUI/res/layout/volume_dialog.xml +++ b/packages/SystemUI/res/layout/volume_dialog.xml @@ -15,6 +15,7 @@ --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:sysui="http://schemas.android.com/apk/res-auto" android:id="@+id/volume_dialog_container" android:layout_width="wrap_content" android:layout_height="wrap_content" @@ -117,16 +118,17 @@ android:clipToPadding="false" android:translationZ="@dimen/volume_dialog_elevation" android:background="@drawable/rounded_bg_full"> - <com.android.keyguard.AlphaOptimizedImageButton + <com.android.systemui.volume.CaptionsToggleImageButton android:id="@+id/odi_captions_icon" android:src="@drawable/ic_volume_odi_captions_disabled" style="@style/VolumeButtons" android:background="@drawable/rounded_ripple" android:layout_width="match_parent" android:layout_height="match_parent" - android:tint="@color/accent_tint_color_selector" + android:tint="@color/caption_tint_color_selector" android:layout_gravity="center" - android:soundEffectsEnabled="false" /> + android:soundEffectsEnabled="false" + sysui:optedOut="false"/> </FrameLayout> </LinearLayout> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index f1904f81a236..84eb9713bee5 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -108,12 +108,13 @@ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"إلغاء القفل دون استخدام بصمة إصبعك"</string> <string name="accessibility_scanning_face" msgid="769545173211758586">"مسح الوجه"</string> <string name="accessibility_send_smart_reply" msgid="7766727839703044493">"إرسال"</string> + <!-- no translation found for accessibility_manage_notification (2026361503393549753) --> + <skip /> <string name="unlock_label" msgid="8779712358041029439">"إلغاء القفل"</string> <string name="phone_label" msgid="2320074140205331708">"فتح الهاتف"</string> <string name="voice_assist_label" msgid="3956854378310019854">"فتح المساعد الصوتي"</string> <string name="camera_label" msgid="7261107956054836961">"فتح الكاميرا"</string> <string name="cancel" msgid="6442560571259935130">"إلغاء"</string> - <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"منطقة رسالة المساعدة"</string> <string name="biometric_dialog_confirm" msgid="6468457350041712674">"تأكيد"</string> <string name="biometric_dialog_try_again" msgid="1900185172633183201">"إعادة المحاولة"</string> <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"المس جهاز استشعار بصمات الإصبع"</string> @@ -179,6 +180,8 @@ <string name="accessibility_cell_data" msgid="5326139158682385073">"بيانات الجوّال"</string> <string name="accessibility_cell_data_on" msgid="5927098403452994422">"تشغيل بيانات الجوال"</string> <string name="cell_data_off_content_description" msgid="4356113230238585072">"تم إيقاف بيانات الجوال"</string> + <!-- no translation found for not_default_data_content_description (9194667237765917844) --> + <skip /> <string name="cell_data_off" msgid="1051264981229902873">"إيقاف"</string> <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ربط البلوتوث."</string> <string name="accessibility_airplane_mode" msgid="834748999790763092">"وضع الطائرة."</string> @@ -220,9 +223,12 @@ <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"تم تشغيل وضع الطائرة."</string> <string name="accessibility_quick_settings_dnd_none_on" msgid="2960643943620637020">"كتم الصوت تمامًا"</string> <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3357131899365865386">"المنبِّهات فقط"</string> - <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"عدم الإزعاج."</string> - <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"تم إيقاف \"عدم الإزعاج\"."</string> - <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"تم تشغيل \"عدم الإزعاج\"."</string> + <!-- no translation found for accessibility_quick_settings_dnd (5555155552520665891) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_off (2757071272328547807) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_on (6808220653747701059) --> + <skip /> <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"البلوتوث."</string> <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"إيقاف البلوتوث."</string> <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"تشغيل البلوتوث."</string> @@ -269,7 +275,6 @@ <string name="accessibility_location_active" msgid="2427290146138169014">"طلبات الموقع نشطة"</string> <string name="accessibility_clear_all" msgid="5235938559247164925">"محو جميع الإشعارات."</string> <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string> - <string name="notification_group_overflow_indicator_ambient" msgid="879560382990377886">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>، + <xliff:g id="OVERFLOW">%2$s</xliff:g>"</string> <plurals name="notification_group_overflow_description" formatted="false" msgid="4579313201268495404"> <item quantity="zero"><xliff:g id="NUMBER_1">%s</xliff:g> إشعار آخر بداخل المجموعة.</item> <item quantity="two">إشعاران (<xliff:g id="NUMBER_1">%s</xliff:g>) آخران بداخل المجموعة.</item> @@ -290,7 +295,8 @@ <string name="start_dreams" msgid="5640361424498338327">"شاشة التوقف"</string> <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string> <string name="quick_settings_header_onboarding_text" msgid="8030309023792936283">"انقر مع الاستمرار على الرموز للحصول على المزيد من الخيارات."</string> - <string name="quick_settings_dnd_label" msgid="8735855737575028208">"عدم الإزعاج"</string> + <!-- no translation found for quick_settings_dnd_label (7112342227663678739) --> + <skip /> <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"الأولوية فقط"</string> <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"التنبيهات فقط"</string> <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"كتم الصوت تمامًا"</string> @@ -449,8 +455,10 @@ <string name="battery_saver_notification_title" msgid="8614079794522291840">"تم تفعيل ميزة توفير شحن البطارية"</string> <string name="battery_saver_notification_text" msgid="820318788126672692">"لخفض مستوى الأداء وبيانات الخلفية"</string> <string name="battery_saver_notification_action_text" msgid="132118784269455533">"إيقاف ميزة توفير شحن البطارية"</string> - <string name="media_projection_dialog_text" msgid="1443042478990422751">"سيبدأ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> في التقاط كل ما يظهر على شاشتك بما في ذلك الإشعارات وكلمات المرور والصور والرسائل ومعلومات الدفع."</string> - <string name="media_projection_dialog_title" msgid="7574971526813630219">"هل تريد السماح لـ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> بتسجيل شاشتك أو إرسال محتواها؟"</string> + <!-- no translation found for media_projection_dialog_text (5751657130671431216) --> + <skip /> + <!-- no translation found for media_projection_dialog_title (8124184308671641248) --> + <skip /> <string name="media_projection_remember_text" msgid="3103510882172746752">"عدم الإظهار مرة أخرى"</string> <string name="clear_all_notifications_text" msgid="814192889771462828">"محو الكل"</string> <string name="manage_notifications_text" msgid="2386728145475108753">"إدارة"</string> @@ -525,6 +533,10 @@ <string name="accessibility_volume_settings" msgid="4915364006817819212">"إعدادات الصوت"</string> <string name="accessibility_volume_expand" msgid="5946812790999244205">"توسيع"</string> <string name="accessibility_volume_collapse" msgid="3609549593031810875">"تصغير"</string> + <!-- no translation found for volume_odi_captions_tip (1193653197906918269) --> + <skip /> + <!-- no translation found for accessibility_volume_close_odi_captions_tip (1163987066404128967) --> + <skip /> <string name="accessibility_output_chooser" msgid="8185317493017988680">"تبديل جهاز الاستماع"</string> <string name="screen_pinning_title" msgid="3273740381976175811">"تم تثبيت الشاشة"</string> <string name="screen_pinning_description" msgid="8909878447196419623">"يؤدي هذا إلى استمرار عرض الشاشة المُختارة إلى أن تتم إزالة تثبيتها. المس مع الاستمرار الزرين \"رجوع\" و\"نظرة عامة\" لإزالة التثبيت."</string> @@ -625,6 +637,8 @@ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"يتم عرض هذه الإشعارات مع تنبيه صوتي"</string> <string name="inline_blocking_helper" msgid="3055064577771478591">"أنت تتجاهل عادةً هذه الإشعارات. \nهل تريد الاستمرار في عرضها؟"</string> <string name="inline_done_button" msgid="492513001558716452">"تمّ"</string> + <!-- no translation found for inline_ok_button (966006867967928987) --> + <skip /> <string name="inline_keep_showing" msgid="8945102997083836858">"هل تريد الاستمرار في تلقي هذه الإشعارات؟"</string> <string name="inline_stop_button" msgid="4172980096860941033">"إيقاف الإشعارات"</string> <string name="inline_deliver_silently_button" msgid="7756289895745629140">"عرض الإشعارات بدون تنبيه صوتي"</string> @@ -633,9 +647,16 @@ <string name="inline_minimize_button" msgid="966233327974702195">"تصغير"</string> <string name="inline_silent_button_silent" msgid="4411510650503783646">"عرض بدون تنبيه صوتي"</string> <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"متابعة عرض الإشعارات بدون صوت"</string> - <string name="inline_silent_button_alert" msgid="7961887853830826523">"إرسال تنبيه إليّ"</string> + <!-- no translation found for inline_silent_button_alert (2273030946176140380) --> + <skip /> <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"متابعة إرسال التنبيهات"</string> <string name="inline_keep_showing_app" msgid="1723113469580031041">"هل تريد الاستمرار في تلقي إشعارات من هذا التطبيق؟"</string> + <!-- no translation found for hint_text_block (3554459167504485284) --> + <skip /> + <!-- no translation found for hint_text_silent (859468056340177016) --> + <skip /> + <!-- no translation found for hint_text_alert (428122667751463119) --> + <skip /> <string name="notification_unblockable_desc" msgid="1037434112919403708">"يتعذَّر إيقاف هذه الإشعارات."</string> <string name="notification_delegate_header" msgid="9167022191405284627">"عبر <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="appops_camera" msgid="8100147441602585776">"يستخدم هذا التطبيق الكاميرا."</string> @@ -723,9 +744,11 @@ <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"التقويم"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"عرض مع عناصر التحكم في مستوى الصوت"</string> - <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"عدم الإزعاج"</string> + <!-- no translation found for volume_and_do_not_disturb (1750270820297253561) --> + <skip /> <string name="volume_dnd_silent" msgid="4363882330723050727">"اختصار أزرار مستوى الصوت"</string> - <string name="volume_up_silent" msgid="7141255269783588286">"إيقاف \"عدم الإزعاج\" عند رفع مستوى الصوت"</string> + <!-- no translation found for volume_up_silent (7545869833038212815) --> + <skip /> <string name="battery" msgid="7498329822413202973">"البطارية"</string> <string name="clock" msgid="7416090374234785905">"الساعة"</string> <string name="headset" msgid="4534219457597457353">"سماعة الرأس"</string> @@ -895,48 +918,44 @@ <string name="open_saver_setting_action" msgid="8314624730997322529">"الإعدادات"</string> <string name="auto_saver_okay_action" msgid="2701221740227683650">"حسنًا"</string> <string name="heap_dump_tile_name" msgid="9141031328971226374">"تفريغ ذاكرة SysUI"</string> - <plurals name="ongoing_privacy_chip_multiple_apps" formatted="false" msgid="1406406529558080714"> - <item quantity="zero"><xliff:g id="NUM_APPS_2">%d</xliff:g> تطبيق</item> - <item quantity="two">تطبيقان (<xliff:g id="NUM_APPS_2">%d</xliff:g>)</item> - <item quantity="few"><xliff:g id="NUM_APPS_1">%d</xliff:g> تطبيقات</item> - <item quantity="many"><xliff:g id="NUM_APPS_2">%d</xliff:g> تطبيقًا</item> - <item quantity="other"><xliff:g id="NUM_APPS_2">%d</xliff:g> تطبيق</item> - <item quantity="one">تطبيق واحد (<xliff:g id="NUM_APPS_0">%d</xliff:g>)</item> - </plurals> <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"التطبيق <xliff:g id="APP">%1$s</xliff:g> يستخدم <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"تستخدم التطبيقات <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> - <string name="ongoing_privacy_chip_in_use" msgid="5174331553211609272">"قيد الاستخدام:"</string> - <plurals name="ongoing_privacy_chip_content_multiple_apps_single_op" formatted="false" msgid="4871926099254314088"> - <item quantity="zero">هناك <xliff:g id="NUM_APPS_4">%1$d</xliff:g> تطبيق يستخدِم <xliff:g id="TYPE_5">%2$s</xliff:g>.</item> - <item quantity="two">هناك تطبيقان (<xliff:g id="NUM_APPS_4">%1$d</xliff:g>) يستخدِمان <xliff:g id="TYPE_5">%2$s</xliff:g>.</item> - <item quantity="few">هناك <xliff:g id="NUM_APPS_2">%1$d</xliff:g> تطبيقات تستخدِم <xliff:g id="TYPE_3">%2$s</xliff:g>.</item> - <item quantity="many">هناك <xliff:g id="NUM_APPS_4">%1$d</xliff:g> تطبيقًا يستخدِم <xliff:g id="TYPE_5">%2$s</xliff:g>.</item> - <item quantity="other">هناك <xliff:g id="NUM_APPS_4">%1$d</xliff:g> تطبيق يستخدِم <xliff:g id="TYPE_5">%2$s</xliff:g>.</item> - <item quantity="one">هناك تطبيق واحد (<xliff:g id="NUM_APPS_0">%1$d</xliff:g>) يستخدِم <xliff:g id="TYPE_1">%2$s</xliff:g>.</item> - </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"حسنًا"</string> <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"إعدادات الخصوصية"</string> - <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"التطبيق الذي يستخدِم <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> + <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"التطبيق الذي يستخدم <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"التطبيقات التي تستخدِم <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">"، "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="2400503446627122483">" و "</string> <string name="privacy_type_camera" msgid="1676604631892420333">"الكاميرا"</string> <string name="privacy_type_location" msgid="6435497989657286700">"الموقع"</string> <string name="privacy_type_microphone" msgid="4153045784928554506">"الميكروفون"</string> - <plurals name="ongoing_privacy_dialog_overflow_text" formatted="false" msgid="3441296594927649172"> - <item quantity="zero"><xliff:g id="NUM_APPS_1">%d</xliff:g> تطبيق آخر</item> - <item quantity="two">تطبيقان (<xliff:g id="NUM_APPS_1">%d</xliff:g>) آخران</item> - <item quantity="few"><xliff:g id="NUM_APPS_1">%d</xliff:g> تطبيقات أخرى</item> - <item quantity="many"><xliff:g id="NUM_APPS_1">%d</xliff:g> تطبيقًا آخر</item> - <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> تطبيق آخر</item> - <item quantity="one">تطبيق واحد (<xliff:g id="NUM_APPS_0">%d</xliff:g>) آخر</item> - </plurals> <string name="sensor_privacy_mode" msgid="8982771253020769598">"إيقاف أجهزة الاستشعار"</string> <string name="device_services" msgid="1191212554435440592">"خدمات الأجهزة"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"بلا عنوان"</string> + <!-- no translation found for restart_button_description (2035077840254950187) --> + <skip /> <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"فتح <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> - <string name="bubbles_settings_button_description" msgid="1940331766151865776">"فتح إعدادات الإشعارات في <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> - <string name="bubbles_prompt" msgid="2684301469286150276">"هل تريد السماح بالفقاعات التفسيرية من هذا التطبيق؟"</string> - <string name="no_bubbles" msgid="7173621233904687258">"حظر"</string> + <!-- no translation found for bubbles_settings_button_description (2970630476657287189) --> + <skip /> + <!-- no translation found for bubbles_prompt (8807968030159469710) --> + <skip /> + <!-- no translation found for no_bubbles (337101288173078247) --> + <skip /> <string name="yes_bubbles" msgid="668809525728633841">"سماح"</string> + <!-- no translation found for ask_me_later_bubbles (2147688438402939029) --> + <skip /> + <!-- no translation found for bubble_content_description_single (1184462974339387516) --> + <skip /> + <!-- no translation found for bubble_content_description_stack (8666349184095622232) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move (1794879742234803840) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_left (104736832249802724) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_right (1671844272347036806) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_left (206369104473183217) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_right (8705660152384312329) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index c19a1ef93651..0703954246ba 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -108,12 +108,13 @@ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Desbloqueja sense utilitzar l\'empremta digital"</string> <string name="accessibility_scanning_face" msgid="769545173211758586">"S\'està escanejant la cara"</string> <string name="accessibility_send_smart_reply" msgid="7766727839703044493">"Envia"</string> + <!-- no translation found for accessibility_manage_notification (2026361503393549753) --> + <skip /> <string name="unlock_label" msgid="8779712358041029439">"desbloqueja"</string> <string name="phone_label" msgid="2320074140205331708">"obre el telèfon"</string> <string name="voice_assist_label" msgid="3956854378310019854">"obre l\'assistència per veu"</string> <string name="camera_label" msgid="7261107956054836961">"obre la càmera"</string> <string name="cancel" msgid="6442560571259935130">"Cancel·la"</string> - <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Àrea de missatge d\'ajuda"</string> <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Confirma"</string> <string name="biometric_dialog_try_again" msgid="1900185172633183201">"Torna-ho a provar"</string> <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Toca el sensor d\'empremtes digitals"</string> @@ -179,6 +180,8 @@ <string name="accessibility_cell_data" msgid="5326139158682385073">"Dades mòbils"</string> <string name="accessibility_cell_data_on" msgid="5927098403452994422">"Dades mòbils activades"</string> <string name="cell_data_off_content_description" msgid="4356113230238585072">"S\'han desactivat les dades mòbils"</string> + <!-- no translation found for not_default_data_content_description (9194667237765917844) --> + <skip /> <string name="cell_data_off" msgid="1051264981229902873">"Desactivades"</string> <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Compartició de xarxa per Bluetooth"</string> <string name="accessibility_airplane_mode" msgid="834748999790763092">"Mode d\'avió."</string> @@ -220,9 +223,12 @@ <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"S\'ha activat el Mode d\'avió."</string> <string name="accessibility_quick_settings_dnd_none_on" msgid="2960643943620637020">"silenci total"</string> <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3357131899365865386">"només alarmes"</string> - <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"Mode No molestis."</string> - <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"S\'ha desactivat el mode No molestis."</string> - <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"S\'ha activat el mode No molestis."</string> + <!-- no translation found for accessibility_quick_settings_dnd (5555155552520665891) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_off (2757071272328547807) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_on (6808220653747701059) --> + <skip /> <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"Bluetooth."</string> <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"Bluetooth desactivat."</string> <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"Bluetooth activat."</string> @@ -269,7 +275,6 @@ <string name="accessibility_location_active" msgid="2427290146138169014">"Sol·licituds d\'ubicació actives"</string> <string name="accessibility_clear_all" msgid="5235938559247164925">"Esborra totes les notificacions."</string> <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string> - <string name="notification_group_overflow_indicator_ambient" msgid="879560382990377886">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> i <xliff:g id="OVERFLOW">%2$s</xliff:g> més"</string> <plurals name="notification_group_overflow_description" formatted="false" msgid="4579313201268495404"> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> notificacions més a l\'interior.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> notificació més a l\'interior.</item> @@ -286,7 +291,8 @@ <string name="start_dreams" msgid="5640361424498338327">"Estalvi de pantalla"</string> <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string> <string name="quick_settings_header_onboarding_text" msgid="8030309023792936283">"Mantén premudes les icones per veure més opcions"</string> - <string name="quick_settings_dnd_label" msgid="8735855737575028208">"No molestis"</string> + <!-- no translation found for quick_settings_dnd_label (7112342227663678739) --> + <skip /> <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Només amb prioritat"</string> <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Només alarmes"</string> <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Silenci total"</string> @@ -437,8 +443,10 @@ <string name="battery_saver_notification_title" msgid="8614079794522291840">"S\'ha activat l\'estalvi de bateria"</string> <string name="battery_saver_notification_text" msgid="820318788126672692">"Redueix el rendiment i l\'ús de les dades en segon pla."</string> <string name="battery_saver_notification_action_text" msgid="132118784269455533">"Desactiva l\'estalvi de bateria"</string> - <string name="media_projection_dialog_text" msgid="1443042478990422751">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> començarà a capturar tot el que es mostri a la pantalla, com ara els missatges, les notificacions, les contrasenyes, les fotos i la informació de pagament."</string> - <string name="media_projection_dialog_title" msgid="7574971526813630219">"Vols permetre que <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> gravi o emeti la pantalla?"</string> + <!-- no translation found for media_projection_dialog_text (5751657130671431216) --> + <skip /> + <!-- no translation found for media_projection_dialog_title (8124184308671641248) --> + <skip /> <string name="media_projection_remember_text" msgid="3103510882172746752">"No ho tornis a mostrar"</string> <string name="clear_all_notifications_text" msgid="814192889771462828">"Esborra-ho tot"</string> <string name="manage_notifications_text" msgid="2386728145475108753">"Gestió"</string> @@ -513,6 +521,10 @@ <string name="accessibility_volume_settings" msgid="4915364006817819212">"Configuració del so"</string> <string name="accessibility_volume_expand" msgid="5946812790999244205">"Amplia"</string> <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Replega"</string> + <!-- no translation found for volume_odi_captions_tip (1193653197906918269) --> + <skip /> + <!-- no translation found for accessibility_volume_close_odi_captions_tip (1163987066404128967) --> + <skip /> <string name="accessibility_output_chooser" msgid="8185317493017988680">"Canvia el dispositiu de sortida"</string> <string name="screen_pinning_title" msgid="3273740381976175811">"La pantalla està fixada"</string> <string name="screen_pinning_description" msgid="8909878447196419623">"Aquest element es continuarà mostrant fins que deixis de fixar-lo. Per fer-ho, toca i mantén premudes els botons Enrere i Aplicacions recents."</string> @@ -613,6 +625,8 @@ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"Aquestes notificacions t\'enviaran una alerta"</string> <string name="inline_blocking_helper" msgid="3055064577771478591">"Normalment ignores aquestes notificacions. \nVols que es continuïn mostrant?"</string> <string name="inline_done_button" msgid="492513001558716452">"Fet"</string> + <!-- no translation found for inline_ok_button (966006867967928987) --> + <skip /> <string name="inline_keep_showing" msgid="8945102997083836858">"Vols continuar rebent aquestes notificacions?"</string> <string name="inline_stop_button" msgid="4172980096860941033">"Deixa d\'enviar notificacions"</string> <string name="inline_deliver_silently_button" msgid="7756289895745629140">"Envia de manera silenciosa"</string> @@ -621,9 +635,16 @@ <string name="inline_minimize_button" msgid="966233327974702195">"Minimitza"</string> <string name="inline_silent_button_silent" msgid="4411510650503783646">"Mostra de manera silenciosa"</string> <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Continua silenciant"</string> - <string name="inline_silent_button_alert" msgid="7961887853830826523">"Avisa\'m"</string> + <!-- no translation found for inline_silent_button_alert (2273030946176140380) --> + <skip /> <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Continua avisant-me"</string> <string name="inline_keep_showing_app" msgid="1723113469580031041">"Vols continuar rebent notificacions d\'aquesta aplicació?"</string> + <!-- no translation found for hint_text_block (3554459167504485284) --> + <skip /> + <!-- no translation found for hint_text_silent (859468056340177016) --> + <skip /> + <!-- no translation found for hint_text_alert (428122667751463119) --> + <skip /> <string name="notification_unblockable_desc" msgid="1037434112919403708">"Aquestes notificacions no es poden desactivar"</string> <string name="notification_delegate_header" msgid="9167022191405284627">"mitjançant <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="appops_camera" msgid="8100147441602585776">"Aquesta aplicació utilitza la càmera."</string> @@ -703,9 +724,11 @@ <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendari"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Mostra amb els controls de volum"</string> - <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"No molestis"</string> + <!-- no translation found for volume_and_do_not_disturb (1750270820297253561) --> + <skip /> <string name="volume_dnd_silent" msgid="4363882330723050727">"Drecera per als botons de volum"</string> - <string name="volume_up_silent" msgid="7141255269783588286">"Desactiva el mode No molestis apujant el volum"</string> + <!-- no translation found for volume_up_silent (7545869833038212815) --> + <skip /> <string name="battery" msgid="7498329822413202973">"Bateria"</string> <string name="clock" msgid="7416090374234785905">"Rellotge"</string> <string name="headset" msgid="4534219457597457353">"Auriculars"</string> @@ -875,17 +898,8 @@ <string name="open_saver_setting_action" msgid="8314624730997322529">"Configuració"</string> <string name="auto_saver_okay_action" msgid="2701221740227683650">"D\'acord"</string> <string name="heap_dump_tile_name" msgid="9141031328971226374">"Aboca espai de SysUI"</string> - <plurals name="ongoing_privacy_chip_multiple_apps" formatted="false" msgid="1406406529558080714"> - <item quantity="other"><xliff:g id="NUM_APPS_2">%d</xliff:g> aplicacions</item> - <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> aplicació</item> - </plurals> <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> està fent servir el següent: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Algunes aplicacions estan fent servir el següent: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> - <string name="ongoing_privacy_chip_in_use" msgid="5174331553211609272">"En ús:"</string> - <plurals name="ongoing_privacy_chip_content_multiple_apps_single_op" formatted="false" msgid="4871926099254314088"> - <item quantity="other"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> aplicacions estan fent servir: <xliff:g id="TYPE_5">%2$s</xliff:g>.</item> - <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> aplicació està fent servir: <xliff:g id="TYPE_1">%2$s</xliff:g>.</item> - </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"D\'acord"</string> <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Config. de privadesa"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Aplicació que fa servir: <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> @@ -895,16 +909,33 @@ <string name="privacy_type_camera" msgid="1676604631892420333">"càmera"</string> <string name="privacy_type_location" msgid="6435497989657286700">"ubicació"</string> <string name="privacy_type_microphone" msgid="4153045784928554506">"micròfon"</string> - <plurals name="ongoing_privacy_dialog_overflow_text" formatted="false" msgid="3441296594927649172"> - <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> aplicacions més</item> - <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> aplicació més</item> - </plurals> <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensors desactivats"</string> <string name="device_services" msgid="1191212554435440592">"Serveis per a dispositius"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Sense títol"</string> + <!-- no translation found for restart_button_description (2035077840254950187) --> + <skip /> <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Obre <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> - <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Obre la configuració de notificacions de l\'aplicació <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> - <string name="bubbles_prompt" msgid="2684301469286150276">"Vols permetre els quadres d\'ajuda d\'aquesta aplicació?"</string> - <string name="no_bubbles" msgid="7173621233904687258">"Bloqueja"</string> + <!-- no translation found for bubbles_settings_button_description (2970630476657287189) --> + <skip /> + <!-- no translation found for bubbles_prompt (8807968030159469710) --> + <skip /> + <!-- no translation found for no_bubbles (337101288173078247) --> + <skip /> <string name="yes_bubbles" msgid="668809525728633841">"Permet"</string> + <!-- no translation found for ask_me_later_bubbles (2147688438402939029) --> + <skip /> + <!-- no translation found for bubble_content_description_single (1184462974339387516) --> + <skip /> + <!-- no translation found for bubble_content_description_stack (8666349184095622232) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move (1794879742234803840) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_left (104736832249802724) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_right (1671844272347036806) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_left (206369104473183217) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_right (8705660152384312329) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index b6ca09c7eef7..72e754481c14 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -108,12 +108,13 @@ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Ohne Verwendung des Fingerabdrucks entsperren"</string> <string name="accessibility_scanning_face" msgid="769545173211758586">"Gesicht wird gescannt"</string> <string name="accessibility_send_smart_reply" msgid="7766727839703044493">"Senden"</string> + <!-- no translation found for accessibility_manage_notification (2026361503393549753) --> + <skip /> <string name="unlock_label" msgid="8779712358041029439">"Entsperren"</string> <string name="phone_label" msgid="2320074140205331708">"Telefon öffnen"</string> <string name="voice_assist_label" msgid="3956854378310019854">"Sprachassistent öffnen"</string> <string name="camera_label" msgid="7261107956054836961">"Kamera öffnen"</string> <string name="cancel" msgid="6442560571259935130">"Abbrechen"</string> - <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Bereich für die Hilfemeldung"</string> <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Bestätigen"</string> <string name="biometric_dialog_try_again" msgid="1900185172633183201">"Noch einmal versuchen"</string> <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Berühre den Fingerabdrucksensor"</string> @@ -179,6 +180,8 @@ <string name="accessibility_cell_data" msgid="5326139158682385073">"Mobile Daten"</string> <string name="accessibility_cell_data_on" msgid="5927098403452994422">"Mobile Datennutzung aktiviert"</string> <string name="cell_data_off_content_description" msgid="4356113230238585072">"Mobile Daten deaktiviert"</string> + <!-- no translation found for not_default_data_content_description (9194667237765917844) --> + <skip /> <string name="cell_data_off" msgid="1051264981229902873">"Aus"</string> <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth-Tethering"</string> <string name="accessibility_airplane_mode" msgid="834748999790763092">"Flugmodus"</string> @@ -224,9 +227,12 @@ <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"Der Flugmodus ist aktiviert."</string> <string name="accessibility_quick_settings_dnd_none_on" msgid="2960643943620637020">"lautlos"</string> <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3357131899365865386">"nur Wecker"</string> - <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"Bitte nicht stören."</string> - <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"\"Bitte nicht stören\" deaktiviert"</string> - <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"\"Bitte nicht stören\" aktiviert"</string> + <!-- no translation found for accessibility_quick_settings_dnd (5555155552520665891) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_off (2757071272328547807) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_on (6808220653747701059) --> + <skip /> <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"Bluetooth."</string> <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"Bluetooth deaktiviert"</string> <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"Bluetooth aktiviert"</string> @@ -273,7 +279,6 @@ <string name="accessibility_location_active" msgid="2427290146138169014">"Standortanfragen aktiv"</string> <string name="accessibility_clear_all" msgid="5235938559247164925">"Alle Benachrichtigungen löschen"</string> <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string> - <string name="notification_group_overflow_indicator_ambient" msgid="879560382990377886">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>, +<xliff:g id="OVERFLOW">%2$s</xliff:g>"</string> <plurals name="notification_group_overflow_description" formatted="false" msgid="4579313201268495404"> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> weitere Benachrichtigungen vorhanden.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> weitere Benachrichtigung vorhanden.</item> @@ -290,7 +295,8 @@ <string name="start_dreams" msgid="5640361424498338327">"Bildschirmschoner"</string> <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string> <string name="quick_settings_header_onboarding_text" msgid="8030309023792936283">"Halte die Symbole gedrückt, um weitere Optionen zu sehen"</string> - <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Bitte nicht stören"</string> + <!-- no translation found for quick_settings_dnd_label (7112342227663678739) --> + <skip /> <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Nur wichtige Unterbrechungen"</string> <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Nur Wecker"</string> <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Lautlos"</string> @@ -441,8 +447,10 @@ <string name="battery_saver_notification_title" msgid="8614079794522291840">"Energiesparmodus ist aktiviert"</string> <string name="battery_saver_notification_text" msgid="820318788126672692">"Reduzierung der Leistung und Hintergrunddaten"</string> <string name="battery_saver_notification_action_text" msgid="132118784269455533">"Energiesparmodus deaktivieren"</string> - <string name="media_projection_dialog_text" msgid="1443042478990422751">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> beginnt damit, alles auf deinem Bildschirm zu erfassen, z. B. Benachrichtigungen, Passwörter, Fotos, Nachrichten und Zahlungsinformationen."</string> - <string name="media_projection_dialog_title" msgid="7574971526813630219">"Darf <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> deinen Bildschirm aufzeichnen oder streamen?"</string> + <!-- no translation found for media_projection_dialog_text (5751657130671431216) --> + <skip /> + <!-- no translation found for media_projection_dialog_title (8124184308671641248) --> + <skip /> <string name="media_projection_remember_text" msgid="3103510882172746752">"Nicht mehr anzeigen"</string> <string name="clear_all_notifications_text" msgid="814192889771462828">"Alle löschen"</string> <string name="manage_notifications_text" msgid="2386728145475108753">"Verwalten"</string> @@ -517,6 +525,10 @@ <string name="accessibility_volume_settings" msgid="4915364006817819212">"Toneinstellungen"</string> <string name="accessibility_volume_expand" msgid="5946812790999244205">"Maximieren"</string> <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Minimieren"</string> + <!-- no translation found for volume_odi_captions_tip (1193653197906918269) --> + <skip /> + <!-- no translation found for accessibility_volume_close_odi_captions_tip (1163987066404128967) --> + <skip /> <string name="accessibility_output_chooser" msgid="8185317493017988680">"Ausgabegerät wechseln"</string> <string name="screen_pinning_title" msgid="3273740381976175811">"Bildschirm ist fixiert"</string> <string name="screen_pinning_description" msgid="8909878447196419623">"Der Bildschirm bleibt so lange eingeblendet, bis du die Fixierung aufhebst. Berühre und halte dazu \"Zurück\" und \"Übersicht\"."</string> @@ -617,6 +629,8 @@ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"Diese Benachrichtigungen werden als Warnungen angezeigt"</string> <string name="inline_blocking_helper" msgid="3055064577771478591">"Normalerweise schließt du diese Benachrichtigungen. \nSollen sie trotzdem weiter angezeigt werden?"</string> <string name="inline_done_button" msgid="492513001558716452">"Fertig"</string> + <!-- no translation found for inline_ok_button (966006867967928987) --> + <skip /> <string name="inline_keep_showing" msgid="8945102997083836858">"Diese Benachrichtigungen weiterhin anzeigen?"</string> <string name="inline_stop_button" msgid="4172980096860941033">"Benachrichtigungen nicht mehr anzeigen"</string> <string name="inline_deliver_silently_button" msgid="7756289895745629140">"Ohne Ton zustellen"</string> @@ -625,9 +639,16 @@ <string name="inline_minimize_button" msgid="966233327974702195">"Minimieren"</string> <string name="inline_silent_button_silent" msgid="4411510650503783646">"Ohne Ton anzeigen"</string> <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Weiter lautlos bleiben"</string> - <string name="inline_silent_button_alert" msgid="7961887853830826523">"Benachrichtigung an mich"</string> + <!-- no translation found for inline_silent_button_alert (2273030946176140380) --> + <skip /> <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Weiterhin Benachrichtigungen senden"</string> <string name="inline_keep_showing_app" msgid="1723113469580031041">"Benachrichtigungen dieser App weiterhin anzeigen?"</string> + <!-- no translation found for hint_text_block (3554459167504485284) --> + <skip /> + <!-- no translation found for hint_text_silent (859468056340177016) --> + <skip /> + <!-- no translation found for hint_text_alert (428122667751463119) --> + <skip /> <string name="notification_unblockable_desc" msgid="1037434112919403708">"Diese Benachrichtigungen können nicht deaktiviert werden"</string> <string name="notification_delegate_header" msgid="9167022191405284627">"über <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="appops_camera" msgid="8100147441602585776">"Diese App verwendet die Kamera."</string> @@ -707,9 +728,11 @@ <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalender"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Einschließlich Lautstärkeregler anzeigen"</string> - <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Bitte nicht stören"</string> + <!-- no translation found for volume_and_do_not_disturb (1750270820297253561) --> + <skip /> <string name="volume_dnd_silent" msgid="4363882330723050727">"Tastenkombination für Lautstärketasten"</string> - <string name="volume_up_silent" msgid="7141255269783588286">"\"Bitte nicht stören\" bei \"Lauter\" deaktivieren"</string> + <!-- no translation found for volume_up_silent (7545869833038212815) --> + <skip /> <string name="battery" msgid="7498329822413202973">"Akku"</string> <string name="clock" msgid="7416090374234785905">"Uhr"</string> <string name="headset" msgid="4534219457597457353">"Headset"</string> @@ -879,17 +902,8 @@ <string name="open_saver_setting_action" msgid="8314624730997322529">"Einstellungen"</string> <string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string> <string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string> - <plurals name="ongoing_privacy_chip_multiple_apps" formatted="false" msgid="1406406529558080714"> - <item quantity="other"><xliff:g id="NUM_APPS_2">%d</xliff:g> Apps</item> - <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> App</item> - </plurals> <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> verwendet gerade Folgendes: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Apps verwenden gerade Folgendes: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> - <string name="ongoing_privacy_chip_in_use" msgid="5174331553211609272">"Im Einsatz:"</string> - <plurals name="ongoing_privacy_chip_content_multiple_apps_single_op" formatted="false" msgid="4871926099254314088"> - <item quantity="other"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> Apps verwenden gerade: <xliff:g id="TYPE_5">%2$s</xliff:g>.</item> - <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> App verwendet gerade: <xliff:g id="TYPE_1">%2$s</xliff:g>.</item> - </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"OK"</string> <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Datenschutzeinst."</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"App, die <xliff:g id="TYPES_LIST">%s</xliff:g> verwendet"</string> @@ -899,16 +913,33 @@ <string name="privacy_type_camera" msgid="1676604631892420333">"Kamera"</string> <string name="privacy_type_location" msgid="6435497989657286700">"Standort"</string> <string name="privacy_type_microphone" msgid="4153045784928554506">"Mikrofon"</string> - <plurals name="ongoing_privacy_dialog_overflow_text" formatted="false" msgid="3441296594927649172"> - <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> weitere Apps</item> - <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> weitere App</item> - </plurals> <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensoren aus"</string> <string name="device_services" msgid="1191212554435440592">"Gerätedienste"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Kein Titel"</string> + <!-- no translation found for restart_button_description (2035077840254950187) --> + <skip /> <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"<xliff:g id="APP_NAME">%1$s</xliff:g> öffnen"</string> - <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Benachrichtigungseinstellungen für <xliff:g id="APP_NAME">%1$s</xliff:g> öffnen"</string> - <string name="bubbles_prompt" msgid="2684301469286150276">"Infofelder von dieser App zulassen?"</string> - <string name="no_bubbles" msgid="7173621233904687258">"Blockieren"</string> + <!-- no translation found for bubbles_settings_button_description (2970630476657287189) --> + <skip /> + <!-- no translation found for bubbles_prompt (8807968030159469710) --> + <skip /> + <!-- no translation found for no_bubbles (337101288173078247) --> + <skip /> <string name="yes_bubbles" msgid="668809525728633841">"Zulassen"</string> + <!-- no translation found for ask_me_later_bubbles (2147688438402939029) --> + <skip /> + <!-- no translation found for bubble_content_description_single (1184462974339387516) --> + <skip /> + <!-- no translation found for bubble_content_description_stack (8666349184095622232) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move (1794879742234803840) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_left (104736832249802724) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_right (1671844272347036806) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_left (206369104473183217) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_right (8705660152384312329) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index bccfdd36e8d3..e4ae787b2fe0 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -108,12 +108,13 @@ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Desbloquear sin usar tu huella digital"</string> <string name="accessibility_scanning_face" msgid="769545173211758586">"Escaneando cara"</string> <string name="accessibility_send_smart_reply" msgid="7766727839703044493">"Enviar"</string> + <!-- no translation found for accessibility_manage_notification (2026361503393549753) --> + <skip /> <string name="unlock_label" msgid="8779712358041029439">"desbloquear"</string> <string name="phone_label" msgid="2320074140205331708">"abrir teléfono"</string> <string name="voice_assist_label" msgid="3956854378310019854">"abrir el asistente de voz"</string> <string name="camera_label" msgid="7261107956054836961">"abrir cámara"</string> <string name="cancel" msgid="6442560571259935130">"Cancelar"</string> - <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Área de mensaje de ayuda"</string> <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Confirmar"</string> <string name="biometric_dialog_try_again" msgid="1900185172633183201">"Reintentar"</string> <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Toca el sensor de huellas digitales"</string> @@ -179,6 +180,8 @@ <string name="accessibility_cell_data" msgid="5326139158682385073">"Datos móviles"</string> <string name="accessibility_cell_data_on" msgid="5927098403452994422">"Datos móviles activados"</string> <string name="cell_data_off_content_description" msgid="4356113230238585072">"Datos desactiv."</string> + <!-- no translation found for not_default_data_content_description (9194667237765917844) --> + <skip /> <string name="cell_data_off" msgid="1051264981229902873">"Desactivados"</string> <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Compartir conexión por Bluetooth"</string> <string name="accessibility_airplane_mode" msgid="834748999790763092">"Modo avión"</string> @@ -220,9 +223,12 @@ <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"Modo avión activado."</string> <string name="accessibility_quick_settings_dnd_none_on" msgid="2960643943620637020">"silencio total"</string> <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3357131899365865386">"solo alarmas"</string> - <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"No molestar."</string> - <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"No molestar desactivado."</string> - <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"No molestar activado."</string> + <!-- no translation found for accessibility_quick_settings_dnd (5555155552520665891) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_off (2757071272328547807) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_on (6808220653747701059) --> + <skip /> <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"Bluetooth."</string> <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"Bluetooth desactivado."</string> <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"Bluetooth activado."</string> @@ -269,7 +275,6 @@ <string name="accessibility_location_active" msgid="2427290146138169014">"Solicitudes de ubicación activas"</string> <string name="accessibility_clear_all" msgid="5235938559247164925">"Borrar todas las notificaciones"</string> <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"<xliff:g id="NUMBER">%s</xliff:g> más"</string> - <string name="notification_group_overflow_indicator_ambient" msgid="879560382990377886">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> (+ <xliff:g id="OVERFLOW">%2$s</xliff:g>)"</string> <plurals name="notification_group_overflow_description" formatted="false" msgid="4579313201268495404"> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> notificaciones más dentro.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> notificación más dentro.</item> @@ -286,7 +291,8 @@ <string name="start_dreams" msgid="5640361424498338327">"Salvapantallas"</string> <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string> <string name="quick_settings_header_onboarding_text" msgid="8030309023792936283">"Mantén pulsados los iconos para ver más opciones"</string> - <string name="quick_settings_dnd_label" msgid="8735855737575028208">"No molestar"</string> + <!-- no translation found for quick_settings_dnd_label (7112342227663678739) --> + <skip /> <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Solo prioritarias"</string> <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Solo alarmas"</string> <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Silencio total"</string> @@ -437,8 +443,10 @@ <string name="battery_saver_notification_title" msgid="8614079794522291840">"Ahorro de batería activado"</string> <string name="battery_saver_notification_text" msgid="820318788126672692">"Reduce el rendimiento y los datos en segundo plano"</string> <string name="battery_saver_notification_action_text" msgid="132118784269455533">"Desactivar Ahorro de batería"</string> - <string name="media_projection_dialog_text" msgid="1443042478990422751">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> empezará a capturar todo lo que aparezca en la pantalla, como notificaciones, contraseñas, fotos, mensajes y datos de pago."</string> - <string name="media_projection_dialog_title" msgid="7574971526813630219">"¿Quieres permitir que <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> grabe o envíe el contenido de tu pantalla?"</string> + <!-- no translation found for media_projection_dialog_text (5751657130671431216) --> + <skip /> + <!-- no translation found for media_projection_dialog_title (8124184308671641248) --> + <skip /> <string name="media_projection_remember_text" msgid="3103510882172746752">"No volver a mostrar"</string> <string name="clear_all_notifications_text" msgid="814192889771462828">"Borrar todo"</string> <string name="manage_notifications_text" msgid="2386728145475108753">"Gestionar"</string> @@ -513,6 +521,10 @@ <string name="accessibility_volume_settings" msgid="4915364006817819212">"Ajustes de sonido"</string> <string name="accessibility_volume_expand" msgid="5946812790999244205">"Mostrar"</string> <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Ocultar"</string> + <!-- no translation found for volume_odi_captions_tip (1193653197906918269) --> + <skip /> + <!-- no translation found for accessibility_volume_close_odi_captions_tip (1163987066404128967) --> + <skip /> <string name="accessibility_output_chooser" msgid="8185317493017988680">"Cambiar dispositivo de salida"</string> <string name="screen_pinning_title" msgid="3273740381976175811">"Pantalla fijada"</string> <string name="screen_pinning_description" msgid="8909878447196419623">"La pantalla se mantiene visible hasta que dejas de fijarla. Para ello, mantén pulsados los botones Atrás y Aplicaciones recientes."</string> @@ -613,6 +625,8 @@ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"Estas notificaciones te avisarán con sonido"</string> <string name="inline_blocking_helper" msgid="3055064577771478591">"Normalmente ignoras estas notificaciones. \n¿Quieres seguir viéndolas?"</string> <string name="inline_done_button" msgid="492513001558716452">"Listo"</string> + <!-- no translation found for inline_ok_button (966006867967928987) --> + <skip /> <string name="inline_keep_showing" msgid="8945102997083836858">"¿Quieres seguir viendo estas notificaciones?"</string> <string name="inline_stop_button" msgid="4172980096860941033">"Detener las notificaciones"</string> <string name="inline_deliver_silently_button" msgid="7756289895745629140">"Enviar en silencio"</string> @@ -621,9 +635,16 @@ <string name="inline_minimize_button" msgid="966233327974702195">"Minimizar"</string> <string name="inline_silent_button_silent" msgid="4411510650503783646">"Mostrar en silencio"</string> <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Silenciar notificaciones"</string> - <string name="inline_silent_button_alert" msgid="7961887853830826523">"Quiero recibir alertas"</string> + <!-- no translation found for inline_silent_button_alert (2273030946176140380) --> + <skip /> <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Quiero seguir recibiendo alertas"</string> <string name="inline_keep_showing_app" msgid="1723113469580031041">"¿Quieres seguir viendo las notificaciones de esta aplicación?"</string> + <!-- no translation found for hint_text_block (3554459167504485284) --> + <skip /> + <!-- no translation found for hint_text_silent (859468056340177016) --> + <skip /> + <!-- no translation found for hint_text_alert (428122667751463119) --> + <skip /> <string name="notification_unblockable_desc" msgid="1037434112919403708">"Estas notificaciones no se pueden desactivar"</string> <string name="notification_delegate_header" msgid="9167022191405284627">"mediante <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="appops_camera" msgid="8100147441602585776">"Esta aplicación está usando la cámara."</string> @@ -703,9 +724,11 @@ <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendario"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Mostrar con controles de volumen"</string> - <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"No molestar"</string> + <!-- no translation found for volume_and_do_not_disturb (1750270820297253561) --> + <skip /> <string name="volume_dnd_silent" msgid="4363882330723050727">"Combinación de teclas para los botones de volumen"</string> - <string name="volume_up_silent" msgid="7141255269783588286">"Salir de No molestar al subir el volumen"</string> + <!-- no translation found for volume_up_silent (7545869833038212815) --> + <skip /> <string name="battery" msgid="7498329822413202973">"Batería"</string> <string name="clock" msgid="7416090374234785905">"Reloj"</string> <string name="headset" msgid="4534219457597457353">"Auriculares"</string> @@ -875,17 +898,8 @@ <string name="open_saver_setting_action" msgid="8314624730997322529">"Ajustes"</string> <string name="auto_saver_okay_action" msgid="2701221740227683650">"Entendido"</string> <string name="heap_dump_tile_name" msgid="9141031328971226374">"Volcar pila de SysUI"</string> - <plurals name="ongoing_privacy_chip_multiple_apps" formatted="false" msgid="1406406529558080714"> - <item quantity="other"><xliff:g id="NUM_APPS_2">%d</xliff:g> apps</item> - <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> app</item> - </plurals> <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> está usando tu <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Hay aplicaciones que usan tu <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> - <string name="ongoing_privacy_chip_in_use" msgid="5174331553211609272">"En uso:"</string> - <plurals name="ongoing_privacy_chip_content_multiple_apps_single_op" formatted="false" msgid="4871926099254314088"> - <item quantity="other"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> aplicaciones están usando tu <xliff:g id="TYPE_5">%2$s</xliff:g>.</item> - <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> aplicación está usando tu <xliff:g id="TYPE_1">%2$s</xliff:g>.</item> - </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Entendido"</string> <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Ajustes privacidad"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Aplicación que usa tu <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> @@ -895,16 +909,33 @@ <string name="privacy_type_camera" msgid="1676604631892420333">"cámara"</string> <string name="privacy_type_location" msgid="6435497989657286700">"ubicación"</string> <string name="privacy_type_microphone" msgid="4153045784928554506">"micrófono"</string> - <plurals name="ongoing_privacy_dialog_overflow_text" formatted="false" msgid="3441296594927649172"> - <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> aplicaciones más</item> - <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> aplicación más</item> - </plurals> <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensores desactivados"</string> <string name="device_services" msgid="1191212554435440592">"Servicios del dispositivo"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Sin título"</string> + <!-- no translation found for restart_button_description (2035077840254950187) --> + <skip /> <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Abrir <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> - <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Abrir los ajustes de notificaciones de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> - <string name="bubbles_prompt" msgid="2684301469286150276">"¿Quieres permitir burbujas de esta aplicación?"</string> - <string name="no_bubbles" msgid="7173621233904687258">"Bloquear"</string> + <!-- no translation found for bubbles_settings_button_description (2970630476657287189) --> + <skip /> + <!-- no translation found for bubbles_prompt (8807968030159469710) --> + <skip /> + <!-- no translation found for no_bubbles (337101288173078247) --> + <skip /> <string name="yes_bubbles" msgid="668809525728633841">"Permitir"</string> + <!-- no translation found for ask_me_later_bubbles (2147688438402939029) --> + <skip /> + <!-- no translation found for bubble_content_description_single (1184462974339387516) --> + <skip /> + <!-- no translation found for bubble_content_description_stack (8666349184095622232) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move (1794879742234803840) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_left (104736832249802724) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_right (1671844272347036806) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_left (206369104473183217) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_right (8705660152384312329) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 7fb5950eb30b..03ea7b824ffd 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -108,12 +108,13 @@ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Desblokeatu hatz-markaren bidez"</string> <string name="accessibility_scanning_face" msgid="769545173211758586">"Aurpegia eskaneatzen"</string> <string name="accessibility_send_smart_reply" msgid="7766727839703044493">"Bidali"</string> + <!-- no translation found for accessibility_manage_notification (2026361503393549753) --> + <skip /> <string name="unlock_label" msgid="8779712358041029439">"desblokeatu"</string> <string name="phone_label" msgid="2320074140205331708">"ireki telefonoan"</string> <string name="voice_assist_label" msgid="3956854378310019854">"ireki ahots-laguntza"</string> <string name="camera_label" msgid="7261107956054836961">"ireki kamera"</string> <string name="cancel" msgid="6442560571259935130">"Utzi"</string> - <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Laguntza-mezuaren eremua"</string> <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Berretsi"</string> <string name="biometric_dialog_try_again" msgid="1900185172633183201">"Saiatu berriro"</string> <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Sakatu hatz-marken sentsorea"</string> @@ -179,6 +180,8 @@ <string name="accessibility_cell_data" msgid="5326139158682385073">"Datu-konexioa"</string> <string name="accessibility_cell_data_on" msgid="5927098403452994422">"Datu-konexioa aktibatuta"</string> <string name="cell_data_off_content_description" msgid="4356113230238585072">"Desaktibatuta dago datu-konexioa"</string> + <!-- no translation found for not_default_data_content_description (9194667237765917844) --> + <skip /> <string name="cell_data_off" msgid="1051264981229902873">"Desaktibatuta"</string> <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Konexioa partekatzea (Bluetooth)"</string> <string name="accessibility_airplane_mode" msgid="834748999790763092">"Hegaldi-modua"</string> @@ -220,9 +223,12 @@ <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"Hegaldi modua aktibatu egin da."</string> <string name="accessibility_quick_settings_dnd_none_on" msgid="2960643943620637020">"isiltasun osoa"</string> <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3357131899365865386">"alarmak soilik"</string> - <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"Ez molestatu."</string> - <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"\"Ez molestatu\" aukera desaktibatuta dago."</string> - <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"\"Ez molestatu\" aukera aktibatuta dago."</string> + <!-- no translation found for accessibility_quick_settings_dnd (5555155552520665891) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_off (2757071272328547807) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_on (6808220653747701059) --> + <skip /> <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"Bluetooth."</string> <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"Bluetooth konexioa desaktibatuta dago."</string> <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"Bluetooth konexioa aktibatuta dago."</string> @@ -269,7 +275,6 @@ <string name="accessibility_location_active" msgid="2427290146138169014">"Aplikazioen kokapen-eskaerak aktibo daude"</string> <string name="accessibility_clear_all" msgid="5235938559247164925">"Garbitu jakinarazpen guztiak."</string> <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string> - <string name="notification_group_overflow_indicator_ambient" msgid="879560382990377886">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>, +<xliff:g id="OVERFLOW">%2$s</xliff:g>"</string> <plurals name="notification_group_overflow_description" formatted="false" msgid="4579313201268495404"> <item quantity="other">Beste <xliff:g id="NUMBER_1">%s</xliff:g> jakinarazpen daude barnean.</item> <item quantity="one">Beste <xliff:g id="NUMBER_0">%s</xliff:g> jakinarazpen daude barnean.</item> @@ -286,7 +291,8 @@ <string name="start_dreams" msgid="5640361424498338327">"Pantaila-babeslea"</string> <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string> <string name="quick_settings_header_onboarding_text" msgid="8030309023792936283">"Aukera gehiago ikusteko, eduki sakatuta ikonoak"</string> - <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Ez molestatu"</string> + <!-- no translation found for quick_settings_dnd_label (7112342227663678739) --> + <skip /> <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Lehentasunezkoak soilik"</string> <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Alarmak soilik"</string> <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Isiltasun osoa"</string> @@ -437,8 +443,10 @@ <string name="battery_saver_notification_title" msgid="8614079794522291840">"Aktibatuta dago bateria-aurrezlea"</string> <string name="battery_saver_notification_text" msgid="820318788126672692">"Errendimendua eta atzeko planoko datuak murrizten ditu"</string> <string name="battery_saver_notification_action_text" msgid="132118784269455533">"Desaktibatu bateria-aurrezlea"</string> - <string name="media_projection_dialog_text" msgid="1443042478990422751">"Pantailan duzun guztia erregistratzen hasiko da <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>, jakinarazpenak, pasahitzak, argazkiak, mezuak eta ordainketa-informazioa barne."</string> - <string name="media_projection_dialog_title" msgid="7574971526813630219">"Pantaila grabatu edo igortzeko baimena eman nahi diozu <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aplikazioari?"</string> + <!-- no translation found for media_projection_dialog_text (5751657130671431216) --> + <skip /> + <!-- no translation found for media_projection_dialog_title (8124184308671641248) --> + <skip /> <string name="media_projection_remember_text" msgid="3103510882172746752">"Ez erakutsi berriro"</string> <string name="clear_all_notifications_text" msgid="814192889771462828">"Garbitu guztiak"</string> <string name="manage_notifications_text" msgid="2386728145475108753">"Kudeatu"</string> @@ -513,6 +521,10 @@ <string name="accessibility_volume_settings" msgid="4915364006817819212">"Soinuaren ezarpenak"</string> <string name="accessibility_volume_expand" msgid="5946812790999244205">"Zabaldu"</string> <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Tolestu"</string> + <!-- no translation found for volume_odi_captions_tip (1193653197906918269) --> + <skip /> + <!-- no translation found for accessibility_volume_close_odi_captions_tip (1163987066404128967) --> + <skip /> <string name="accessibility_output_chooser" msgid="8185317493017988680">"Aldatu irteerako gailua"</string> <string name="screen_pinning_title" msgid="3273740381976175811">"Pantaila ainguratuta dago"</string> <string name="screen_pinning_description" msgid="8909878447196419623">"Horrela, ikusgai egongo da aingura kendu arte. Aingura kentzeko, eduki sakatuta \"Atzera\" eta \"Ikuspegi orokorra\" botoiak."</string> @@ -613,6 +625,8 @@ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"Jakinarazpen hauek soinu bidezko alerta bidez erakutsiko dira"</string> <string name="inline_blocking_helper" msgid="3055064577771478591">"Baztertu egin ohi dituzu jakinarazpen hauek. \nHaiek erakusten jarraitzea nahi duzu?"</string> <string name="inline_done_button" msgid="492513001558716452">"Eginda"</string> + <!-- no translation found for inline_ok_button (966006867967928987) --> + <skip /> <string name="inline_keep_showing" msgid="8945102997083836858">"Jakinarazpenak erakusten jarraitzea nahi duzu?"</string> <string name="inline_stop_button" msgid="4172980096860941033">"Blokeatu jakinarazpenak"</string> <string name="inline_deliver_silently_button" msgid="7756289895745629140">"Erakutsi soinurik egin gabe"</string> @@ -621,9 +635,16 @@ <string name="inline_minimize_button" msgid="966233327974702195">"Minimizatu"</string> <string name="inline_silent_button_silent" msgid="4411510650503783646">"Erakutsi soinurik egin gabepen"</string> <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Jarraitu isilik"</string> - <string name="inline_silent_button_alert" msgid="7961887853830826523">"Bidali jakinarazpenak"</string> + <!-- no translation found for inline_silent_button_alert (2273030946176140380) --> + <skip /> <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Jarraitu jakinarazpenak bidaltzen"</string> <string name="inline_keep_showing_app" msgid="1723113469580031041">"Aplikazio honen jakinarazpenak erakusten jarraitzea nahi duzu?"</string> + <!-- no translation found for hint_text_block (3554459167504485284) --> + <skip /> + <!-- no translation found for hint_text_silent (859468056340177016) --> + <skip /> + <!-- no translation found for hint_text_alert (428122667751463119) --> + <skip /> <string name="notification_unblockable_desc" msgid="1037434112919403708">"Jakinarazpen hauek ezin dira desaktibatu"</string> <string name="notification_delegate_header" msgid="9167022191405284627">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioaren bidez"</string> <string name="appops_camera" msgid="8100147441602585776">"Kamera erabiltzen ari da aplikazioa."</string> @@ -703,9 +724,11 @@ <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendar"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Erakutsi bolumena kontrolatzeko aukerekin"</string> - <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Ez molestatu"</string> + <!-- no translation found for volume_and_do_not_disturb (1750270820297253561) --> + <skip /> <string name="volume_dnd_silent" msgid="4363882330723050727">"Bolumen-botoietarako lasterbidea"</string> - <string name="volume_up_silent" msgid="7141255269783588286">"Irten \"Ez molestatu\" egoeratik bolumena igotzean"</string> + <!-- no translation found for volume_up_silent (7545869833038212815) --> + <skip /> <string name="battery" msgid="7498329822413202973">"Bateria"</string> <string name="clock" msgid="7416090374234785905">"Erlojua"</string> <string name="headset" msgid="4534219457597457353">"Mikrofonodun entzungailua"</string> @@ -875,17 +898,8 @@ <string name="open_saver_setting_action" msgid="8314624730997322529">"Ezarpenak"</string> <string name="auto_saver_okay_action" msgid="2701221740227683650">"Ados"</string> <string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string> - <plurals name="ongoing_privacy_chip_multiple_apps" formatted="false" msgid="1406406529558080714"> - <item quantity="other"><xliff:g id="NUM_APPS_2">%d</xliff:g> aplikazio</item> - <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> aplikazio</item> - </plurals> <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="TYPES_LIST">%2$s</xliff:g> erabiltzen ari da."</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Aplikazio batzuk <xliff:g id="TYPES_LIST">%s</xliff:g> erabiltzen ari dira."</string> - <string name="ongoing_privacy_chip_in_use" msgid="5174331553211609272">"Erabiltzen ari direnak:"</string> - <plurals name="ongoing_privacy_chip_content_multiple_apps_single_op" formatted="false" msgid="4871926099254314088"> - <item quantity="other"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> aplikazio ari dira <xliff:g id="TYPE_5">%2$s</xliff:g> erabiltzen.</item> - <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> aplikazio ari da <xliff:g id="TYPE_1">%2$s</xliff:g> erabiltzen.</item> - </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Ados"</string> <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Pribatutasun-ezarpenak"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"<xliff:g id="TYPES_LIST">%s</xliff:g> erabiltzen ari den aplikazioa"</string> @@ -895,16 +909,33 @@ <string name="privacy_type_camera" msgid="1676604631892420333">"kamera"</string> <string name="privacy_type_location" msgid="6435497989657286700">"kokapena"</string> <string name="privacy_type_microphone" msgid="4153045784928554506">"mikrofonoa"</string> - <plurals name="ongoing_privacy_dialog_overflow_text" formatted="false" msgid="3441296594927649172"> - <item quantity="other">beste <xliff:g id="NUM_APPS_1">%d</xliff:g> aplikazio</item> - <item quantity="one">beste <xliff:g id="NUM_APPS_0">%d</xliff:g> aplikazio</item> - </plurals> <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sentsoreak desaktibatuta daude"</string> <string name="device_services" msgid="1191212554435440592">"Gailuetarako zerbitzuak"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Ez du izenik"</string> + <!-- no translation found for restart_button_description (2035077840254950187) --> + <skip /> <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Ireki <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> - <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Ireki <xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioaren jakinarazpen-ezarpenak"</string> - <string name="bubbles_prompt" msgid="2684301469286150276">"Aplikazio honen globoak onartu nahi dituzu?"</string> - <string name="no_bubbles" msgid="7173621233904687258">"Blokeatu"</string> + <!-- no translation found for bubbles_settings_button_description (2970630476657287189) --> + <skip /> + <!-- no translation found for bubbles_prompt (8807968030159469710) --> + <skip /> + <!-- no translation found for no_bubbles (337101288173078247) --> + <skip /> <string name="yes_bubbles" msgid="668809525728633841">"Onartu"</string> + <!-- no translation found for ask_me_later_bubbles (2147688438402939029) --> + <skip /> + <!-- no translation found for bubble_content_description_single (1184462974339387516) --> + <skip /> + <!-- no translation found for bubble_content_description_stack (8666349184095622232) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move (1794879742234803840) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_left (104736832249802724) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_right (1671844272347036806) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_left (206369104473183217) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_right (8705660152384312329) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index c273475371cd..be5ec211382a 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -108,12 +108,13 @@ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Déverrouiller le système sans utiliser votre empreinte digitale"</string> <string name="accessibility_scanning_face" msgid="769545173211758586">"Numérisation du visage"</string> <string name="accessibility_send_smart_reply" msgid="7766727839703044493">"Envoyer"</string> + <!-- no translation found for accessibility_manage_notification (2026361503393549753) --> + <skip /> <string name="unlock_label" msgid="8779712358041029439">"déverrouiller"</string> <string name="phone_label" msgid="2320074140205331708">"Ouvrir le téléphone"</string> <string name="voice_assist_label" msgid="3956854378310019854">"ouvrir l\'assistance vocale"</string> <string name="camera_label" msgid="7261107956054836961">"Ouvrir l\'appareil photo"</string> <string name="cancel" msgid="6442560571259935130">"Annuler"</string> - <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Zone de message d\'aide"</string> <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Confirmer"</string> <string name="biometric_dialog_try_again" msgid="1900185172633183201">"Réessayer"</string> <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Touchez le capteur d\'empreintes digitales"</string> @@ -179,6 +180,8 @@ <string name="accessibility_cell_data" msgid="5326139158682385073">"Données cellulaires"</string> <string name="accessibility_cell_data_on" msgid="5927098403452994422">"Données cellulaires activées"</string> <string name="cell_data_off_content_description" msgid="4356113230238585072">"Désactivées"</string> + <!-- no translation found for not_default_data_content_description (9194667237765917844) --> + <skip /> <string name="cell_data_off" msgid="1051264981229902873">"Désactivé"</string> <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Partage de connexion Bluetooth"</string> <string name="accessibility_airplane_mode" msgid="834748999790763092">"Mode Avion"</string> @@ -220,9 +223,12 @@ <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"Le mode Avion est activé."</string> <string name="accessibility_quick_settings_dnd_none_on" msgid="2960643943620637020">"aucune interruption"</string> <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3357131899365865386">"alarmes seulement"</string> - <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"Ne pas déranger."</string> - <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"Le mode « Ne pas déranger » a bien été désactivé."</string> - <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"Le mode « Ne pas déranger » a bien été activé."</string> + <!-- no translation found for accessibility_quick_settings_dnd (5555155552520665891) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_off (2757071272328547807) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_on (6808220653747701059) --> + <skip /> <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"Bluetooth."</string> <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"Bluetooth désactivé."</string> <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"Bluetooth activé."</string> @@ -269,7 +275,6 @@ <string name="accessibility_location_active" msgid="2427290146138169014">"Demandes de localisation actives"</string> <string name="accessibility_clear_all" msgid="5235938559247164925">"Supprimer toutes les notifications"</string> <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string> - <string name="notification_group_overflow_indicator_ambient" msgid="879560382990377886">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>, + <xliff:g id="OVERFLOW">%2$s</xliff:g>"</string> <plurals name="notification_group_overflow_description" formatted="false" msgid="4579313201268495404"> <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> autre notification à l\'intérieur.</item> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> autres notifications à l\'intérieur.</item> @@ -286,7 +291,8 @@ <string name="start_dreams" msgid="5640361424498338327">"Écran de veille"</string> <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string> <string name="quick_settings_header_onboarding_text" msgid="8030309023792936283">"Maintenez le doigt sur les icônes pour afficher plus d\'options"</string> - <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Ne pas déranger"</string> + <!-- no translation found for quick_settings_dnd_label (7112342227663678739) --> + <skip /> <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Prioritaires seulement"</string> <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Alarmes seulement"</string> <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Aucune interruption"</string> @@ -437,8 +443,10 @@ <string name="battery_saver_notification_title" msgid="8614079794522291840">"La fonction Économie d\'énergie est activée"</string> <string name="battery_saver_notification_text" msgid="820318788126672692">"Réduire les performances et de fond"</string> <string name="battery_saver_notification_action_text" msgid="132118784269455533">"Désactiver la fonction Économie d\'énergie"</string> - <string name="media_projection_dialog_text" msgid="1443042478990422751">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> commencera à capturer tout ce qui se trouve votre écran, y compris les notifications, les mots de passe, les photos, les messages et les données relatives aux paiements."</string> - <string name="media_projection_dialog_title" msgid="7574971526813630219">"Autoriser <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> à enregistrer ou à diffuser votre écran?"</string> + <!-- no translation found for media_projection_dialog_text (5751657130671431216) --> + <skip /> + <!-- no translation found for media_projection_dialog_title (8124184308671641248) --> + <skip /> <string name="media_projection_remember_text" msgid="3103510882172746752">"Ne plus afficher"</string> <string name="clear_all_notifications_text" msgid="814192889771462828">"Tout effacer"</string> <string name="manage_notifications_text" msgid="2386728145475108753">"Gérer"</string> @@ -513,6 +521,10 @@ <string name="accessibility_volume_settings" msgid="4915364006817819212">"Paramètres sonores"</string> <string name="accessibility_volume_expand" msgid="5946812790999244205">"Développer"</string> <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Réduire"</string> + <!-- no translation found for volume_odi_captions_tip (1193653197906918269) --> + <skip /> + <!-- no translation found for accessibility_volume_close_odi_captions_tip (1163987066404128967) --> + <skip /> <string name="accessibility_output_chooser" msgid="8185317493017988680">"Changer d\'appareil de sortie"</string> <string name="screen_pinning_title" msgid="3273740381976175811">"L\'écran est épinglé"</string> <string name="screen_pinning_description" msgid="8909878447196419623">"Cet écran est épinglé jusqu\'à ce que vous annuliez l\'opération. Pour annuler l\'épinglage, maintenez le doigt sur « Retour » et « Aperçu »."</string> @@ -613,6 +625,8 @@ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"Ces notifications vous alerteront"</string> <string name="inline_blocking_helper" msgid="3055064577771478591">"Vous ignorez habituellement ces notifications. \nSouhaitez-vous continuer à les afficher?"</string> <string name="inline_done_button" msgid="492513001558716452">"Terminé"</string> + <!-- no translation found for inline_ok_button (966006867967928987) --> + <skip /> <string name="inline_keep_showing" msgid="8945102997083836858">"Continuer à afficher ces notifications?"</string> <string name="inline_stop_button" msgid="4172980096860941033">"Arrêter les notifications"</string> <string name="inline_deliver_silently_button" msgid="7756289895745629140">"Afficher silencieusement"</string> @@ -621,9 +635,16 @@ <string name="inline_minimize_button" msgid="966233327974702195">"Réduire"</string> <string name="inline_silent_button_silent" msgid="4411510650503783646">"Afficher en silence"</string> <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Continuer d\'util. mode silencieux"</string> - <string name="inline_silent_button_alert" msgid="7961887853830826523">"M\'alerter"</string> + <!-- no translation found for inline_silent_button_alert (2273030946176140380) --> + <skip /> <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Continuer d\'envoyer des alertes"</string> <string name="inline_keep_showing_app" msgid="1723113469580031041">"Continuer à afficher les notifications de cette application?"</string> + <!-- no translation found for hint_text_block (3554459167504485284) --> + <skip /> + <!-- no translation found for hint_text_silent (859468056340177016) --> + <skip /> + <!-- no translation found for hint_text_alert (428122667751463119) --> + <skip /> <string name="notification_unblockable_desc" msgid="1037434112919403708">"Ces notifications ne peuvent pas être désactivées"</string> <string name="notification_delegate_header" msgid="9167022191405284627">"par <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="appops_camera" msgid="8100147441602585776">"Cette application utilise l\'appareil photo."</string> @@ -703,9 +724,11 @@ <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Agenda"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Afficher avec les commandes de volume"</string> - <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Ne pas déranger"</string> + <!-- no translation found for volume_and_do_not_disturb (1750270820297253561) --> + <skip /> <string name="volume_dnd_silent" msgid="4363882330723050727">"Raccourci des boutons de volume"</string> - <string name="volume_up_silent" msgid="7141255269783588286">"Désactiver fonctionnalité Ne pas déranger avec bouton Volume +"</string> + <!-- no translation found for volume_up_silent (7545869833038212815) --> + <skip /> <string name="battery" msgid="7498329822413202973">"Pile"</string> <string name="clock" msgid="7416090374234785905">"Horloge"</string> <string name="headset" msgid="4534219457597457353">"Écouteurs"</string> @@ -875,17 +898,8 @@ <string name="open_saver_setting_action" msgid="8314624730997322529">"Paramètres"</string> <string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string> <string name="heap_dump_tile_name" msgid="9141031328971226374">"Capturer mémoire SysUI"</string> - <plurals name="ongoing_privacy_chip_multiple_apps" formatted="false" msgid="1406406529558080714"> - <item quantity="one"><xliff:g id="NUM_APPS_2">%d</xliff:g> application</item> - <item quantity="other"><xliff:g id="NUM_APPS_2">%d</xliff:g> applications</item> - </plurals> <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> utilise votre <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Des applications utilisent votre <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> - <string name="ongoing_privacy_chip_in_use" msgid="5174331553211609272">"Utilisé :"</string> - <plurals name="ongoing_privacy_chip_content_multiple_apps_single_op" formatted="false" msgid="4871926099254314088"> - <item quantity="one"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> application utilise votre <xliff:g id="TYPE_5">%2$s</xliff:g>.</item> - <item quantity="other"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> applications utilisent votre <xliff:g id="TYPE_5">%2$s</xliff:g>.</item> - </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"J\'ai compris"</string> <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Param. de confident."</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Application qui utilise votre <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> @@ -895,16 +909,33 @@ <string name="privacy_type_camera" msgid="1676604631892420333">"appareil photo"</string> <string name="privacy_type_location" msgid="6435497989657286700">"position"</string> <string name="privacy_type_microphone" msgid="4153045784928554506">"microphone"</string> - <plurals name="ongoing_privacy_dialog_overflow_text" formatted="false" msgid="3441296594927649172"> - <item quantity="one"><xliff:g id="NUM_APPS_1">%d</xliff:g> autre application</item> - <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> autres applications</item> - </plurals> <string name="sensor_privacy_mode" msgid="8982771253020769598">"Capteurs désactivés"</string> <string name="device_services" msgid="1191212554435440592">"Services de l\'appareil"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Sans titre"</string> + <!-- no translation found for restart_button_description (2035077840254950187) --> + <skip /> <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Ouvrir <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> - <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Ouvrir les paramètres de notifications pour <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> - <string name="bubbles_prompt" msgid="2684301469286150276">"Autoriser les bulles de cette application?"</string> - <string name="no_bubbles" msgid="7173621233904687258">"Bloquer"</string> + <!-- no translation found for bubbles_settings_button_description (2970630476657287189) --> + <skip /> + <!-- no translation found for bubbles_prompt (8807968030159469710) --> + <skip /> + <!-- no translation found for no_bubbles (337101288173078247) --> + <skip /> <string name="yes_bubbles" msgid="668809525728633841">"Autoriser"</string> + <!-- no translation found for ask_me_later_bubbles (2147688438402939029) --> + <skip /> + <!-- no translation found for bubble_content_description_single (1184462974339387516) --> + <skip /> + <!-- no translation found for bubble_content_description_stack (8666349184095622232) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move (1794879742234803840) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_left (104736832249802724) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_right (1671844272347036806) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_left (206369104473183217) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_right (8705660152384312329) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 493567285433..2f87f3209446 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -108,12 +108,13 @@ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Déverrouiller le système sans utiliser votre empreinte digitale"</string> <string name="accessibility_scanning_face" msgid="769545173211758586">"Analyse du visage en cours"</string> <string name="accessibility_send_smart_reply" msgid="7766727839703044493">"Envoyer"</string> + <!-- no translation found for accessibility_manage_notification (2026361503393549753) --> + <skip /> <string name="unlock_label" msgid="8779712358041029439">"déverrouiller"</string> <string name="phone_label" msgid="2320074140205331708">"ouvrir le téléphone"</string> <string name="voice_assist_label" msgid="3956854378310019854">"ouvrir l\'assistance vocale"</string> <string name="camera_label" msgid="7261107956054836961">"ouvrir l\'appareil photo"</string> <string name="cancel" msgid="6442560571259935130">"Annuler"</string> - <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Zone de message d\'aide"</string> <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Confirmer"</string> <string name="biometric_dialog_try_again" msgid="1900185172633183201">"Réessayer"</string> <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Appuyez sur le lecteur d\'empreinte digitale"</string> @@ -179,6 +180,8 @@ <string name="accessibility_cell_data" msgid="5326139158682385073">"Données mobiles"</string> <string name="accessibility_cell_data_on" msgid="5927098403452994422">"Données mobiles activées"</string> <string name="cell_data_off_content_description" msgid="4356113230238585072">"Désactivées"</string> + <!-- no translation found for not_default_data_content_description (9194667237765917844) --> + <skip /> <string name="cell_data_off" msgid="1051264981229902873">"Désactivées"</string> <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Partage de connexion Bluetooth"</string> <string name="accessibility_airplane_mode" msgid="834748999790763092">"Mode Avion"</string> @@ -220,9 +223,12 @@ <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"Le mode Avion est activé."</string> <string name="accessibility_quick_settings_dnd_none_on" msgid="2960643943620637020">"aucune interruption"</string> <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3357131899365865386">"alarmes uniquement"</string> - <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"Ne pas déranger."</string> - <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"Le mode \"Ne pas déranger\" a bien été désactivé."</string> - <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"Le mode \"Ne pas déranger\" a bien été activé."</string> + <!-- no translation found for accessibility_quick_settings_dnd (5555155552520665891) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_off (2757071272328547807) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_on (6808220653747701059) --> + <skip /> <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"Bluetooth."</string> <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"Bluetooth désactivé."</string> <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"Bluetooth activé."</string> @@ -269,7 +275,6 @@ <string name="accessibility_location_active" msgid="2427290146138169014">"Demandes de localisation actives"</string> <string name="accessibility_clear_all" msgid="5235938559247164925">"Supprimer toutes les notifications"</string> <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"<xliff:g id="NUMBER">%s</xliff:g> autres"</string> - <string name="notification_group_overflow_indicator_ambient" msgid="879560382990377886">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> + <xliff:g id="OVERFLOW">%2$s</xliff:g>"</string> <plurals name="notification_group_overflow_description" formatted="false" msgid="4579313201268495404"> <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> autre notification à l\'intérieur.</item> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> autres notifications à l\'intérieur.</item> @@ -286,7 +291,8 @@ <string name="start_dreams" msgid="5640361424498338327">"Économiseur d\'écran"</string> <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string> <string name="quick_settings_header_onboarding_text" msgid="8030309023792936283">"Appuyez de manière prolongée sur les icônes pour accéder à d\'autres options"</string> - <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Ne pas déranger"</string> + <!-- no translation found for quick_settings_dnd_label (7112342227663678739) --> + <skip /> <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Prioritaires uniquement"</string> <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Alarmes uniquement"</string> <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Aucune interruption"</string> @@ -437,8 +443,10 @@ <string name="battery_saver_notification_title" msgid="8614079794522291840">"Économiseur de batterie activé"</string> <string name="battery_saver_notification_text" msgid="820318788126672692">"Limite les performances et les données en arrière-plan."</string> <string name="battery_saver_notification_action_text" msgid="132118784269455533">"Désactiver l\'économiseur de batterie"</string> - <string name="media_projection_dialog_text" msgid="1443042478990422751">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> va commencer à enregistrer tous les contenus affichés à l\'écran, y compris les notifications, les mots de passe, les photos, les messages et les informations de paiement."</string> - <string name="media_projection_dialog_title" msgid="7574971526813630219">"Autoriser <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> à enregistrer ou à caster votre écran ?"</string> + <!-- no translation found for media_projection_dialog_text (5751657130671431216) --> + <skip /> + <!-- no translation found for media_projection_dialog_title (8124184308671641248) --> + <skip /> <string name="media_projection_remember_text" msgid="3103510882172746752">"Ne plus afficher"</string> <string name="clear_all_notifications_text" msgid="814192889771462828">"Tout effacer"</string> <string name="manage_notifications_text" msgid="2386728145475108753">"Gérer"</string> @@ -513,6 +521,10 @@ <string name="accessibility_volume_settings" msgid="4915364006817819212">"Paramètres audio"</string> <string name="accessibility_volume_expand" msgid="5946812790999244205">"Développer"</string> <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Réduire"</string> + <!-- no translation found for volume_odi_captions_tip (1193653197906918269) --> + <skip /> + <!-- no translation found for accessibility_volume_close_odi_captions_tip (1163987066404128967) --> + <skip /> <string name="accessibility_output_chooser" msgid="8185317493017988680">"Changer de périphérique de sortie"</string> <string name="screen_pinning_title" msgid="3273740381976175811">"Écran épinglé"</string> <string name="screen_pinning_description" msgid="8909878447196419623">"Cet écran est épinglé jusqu\'à l\'annulation de l\'opération. Pour annuler l\'épinglage, appuyez de manière prolongée sur les boutons Retour et Aperçu."</string> @@ -613,6 +625,8 @@ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"Ces notifications vous alerteront avec un son"</string> <string name="inline_blocking_helper" msgid="3055064577771478591">"Vous ignorez généralement ces notifications. \nSouhaitez-vous continuer de les recevoir ?"</string> <string name="inline_done_button" msgid="492513001558716452">"OK"</string> + <!-- no translation found for inline_ok_button (966006867967928987) --> + <skip /> <string name="inline_keep_showing" msgid="8945102997083836858">"Continuer d\'afficher ces notifications ?"</string> <string name="inline_stop_button" msgid="4172980096860941033">"Arrêter les notifications"</string> <string name="inline_deliver_silently_button" msgid="7756289895745629140">"Notifications silencieuses"</string> @@ -621,9 +635,16 @@ <string name="inline_minimize_button" msgid="966233327974702195">"Réduire"</string> <string name="inline_silent_button_silent" msgid="4411510650503783646">"Affichage silencieux"</string> <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Notifications silencieuses"</string> - <string name="inline_silent_button_alert" msgid="7961887853830826523">"M\'avertir"</string> + <!-- no translation found for inline_silent_button_alert (2273030946176140380) --> + <skip /> <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Continuer de m\'avertir"</string> <string name="inline_keep_showing_app" msgid="1723113469580031041">"Continuer d\'afficher les notifications de cette application ?"</string> + <!-- no translation found for hint_text_block (3554459167504485284) --> + <skip /> + <!-- no translation found for hint_text_silent (859468056340177016) --> + <skip /> + <!-- no translation found for hint_text_alert (428122667751463119) --> + <skip /> <string name="notification_unblockable_desc" msgid="1037434112919403708">"Ces notifications ne peuvent pas être désactivées"</string> <string name="notification_delegate_header" msgid="9167022191405284627">"via <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="appops_camera" msgid="8100147441602585776">"Cette application utilise la caméra."</string> @@ -703,9 +724,11 @@ <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Agenda"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Afficher avec les commandes de volume"</string> - <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Ne pas déranger"</string> + <!-- no translation found for volume_and_do_not_disturb (1750270820297253561) --> + <skip /> <string name="volume_dnd_silent" msgid="4363882330723050727">"Raccourci des boutons de volume"</string> - <string name="volume_up_silent" msgid="7141255269783588286">"Désactiver fonctionnalité Ne pas déranger via bouton Volume +"</string> + <!-- no translation found for volume_up_silent (7545869833038212815) --> + <skip /> <string name="battery" msgid="7498329822413202973">"Batterie"</string> <string name="clock" msgid="7416090374234785905">"Horloge"</string> <string name="headset" msgid="4534219457597457353">"Casque"</string> @@ -875,17 +898,8 @@ <string name="open_saver_setting_action" msgid="8314624730997322529">"Paramètres"</string> <string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string> <string name="heap_dump_tile_name" msgid="9141031328971226374">"Copier mémoire SysUI"</string> - <plurals name="ongoing_privacy_chip_multiple_apps" formatted="false" msgid="1406406529558080714"> - <item quantity="one"><xliff:g id="NUM_APPS_2">%d</xliff:g> application</item> - <item quantity="other"><xliff:g id="NUM_APPS_2">%d</xliff:g> applications</item> - </plurals> <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> utilise votre <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Des applications utilisent votre <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> - <string name="ongoing_privacy_chip_in_use" msgid="5174331553211609272">"Utilisé :"</string> - <plurals name="ongoing_privacy_chip_content_multiple_apps_single_op" formatted="false" msgid="4871926099254314088"> - <item quantity="one"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> application utilise votre <xliff:g id="TYPE_5">%2$s</xliff:g>.</item> - <item quantity="other"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> applications utilisent votre <xliff:g id="TYPE_5">%2$s</xliff:g>.</item> - </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"OK"</string> <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Confidentialité"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Application utilisant votre/vos <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> @@ -895,16 +909,33 @@ <string name="privacy_type_camera" msgid="1676604631892420333">"appareil photo"</string> <string name="privacy_type_location" msgid="6435497989657286700">"position"</string> <string name="privacy_type_microphone" msgid="4153045784928554506">"micro"</string> - <plurals name="ongoing_privacy_dialog_overflow_text" formatted="false" msgid="3441296594927649172"> - <item quantity="one"><xliff:g id="NUM_APPS_1">%d</xliff:g> autre application</item> - <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> autres applications</item> - </plurals> <string name="sensor_privacy_mode" msgid="8982771253020769598">"Capteurs désactivés"</string> <string name="device_services" msgid="1191212554435440592">"Services pour l\'appareil"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Sans titre"</string> + <!-- no translation found for restart_button_description (2035077840254950187) --> + <skip /> <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Ouvrir <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> - <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Ouvrir les paramètres de notification pour <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> - <string name="bubbles_prompt" msgid="2684301469286150276">"Autoriser les info-bulles de cette application ?"</string> - <string name="no_bubbles" msgid="7173621233904687258">"Bloquer"</string> + <!-- no translation found for bubbles_settings_button_description (2970630476657287189) --> + <skip /> + <!-- no translation found for bubbles_prompt (8807968030159469710) --> + <skip /> + <!-- no translation found for no_bubbles (337101288173078247) --> + <skip /> <string name="yes_bubbles" msgid="668809525728633841">"Autoriser"</string> + <!-- no translation found for ask_me_later_bubbles (2147688438402939029) --> + <skip /> + <!-- no translation found for bubble_content_description_single (1184462974339387516) --> + <skip /> + <!-- no translation found for bubble_content_description_stack (8666349184095622232) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move (1794879742234803840) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_left (104736832249802724) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_right (1671844272347036806) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_left (206369104473183217) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_right (8705660152384312329) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index 2f910b7e2914..b1a8509a155f 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -108,12 +108,13 @@ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Ապակողպել չօգտագործելով մատնահետքը"</string> <string name="accessibility_scanning_face" msgid="769545173211758586">"Դեմքի սկանավորում"</string> <string name="accessibility_send_smart_reply" msgid="7766727839703044493">"Ուղարկել"</string> + <!-- no translation found for accessibility_manage_notification (2026361503393549753) --> + <skip /> <string name="unlock_label" msgid="8779712358041029439">"ապակողպել"</string> <string name="phone_label" msgid="2320074140205331708">"բացել հեռախոսը"</string> <string name="voice_assist_label" msgid="3956854378310019854">"բացեք ձայնային հուշումը"</string> <string name="camera_label" msgid="7261107956054836961">"բացել ֆոտոխցիկը"</string> <string name="cancel" msgid="6442560571259935130">"Չեղարկել"</string> - <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Օգնության հաղորդագրության դաշտ"</string> <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Հաստատել"</string> <string name="biometric_dialog_try_again" msgid="1900185172633183201">"Նորից փորձել"</string> <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Հպեք մատնահետքերի սկաներին"</string> @@ -179,9 +180,11 @@ <string name="accessibility_cell_data" msgid="5326139158682385073">"Բջջային ինտերնետ"</string> <string name="accessibility_cell_data_on" msgid="5927098403452994422">"Բջջային տվյալները միացված են"</string> <string name="cell_data_off_content_description" msgid="4356113230238585072">"Բջջային ինտերնետն անջատված է"</string> + <!-- no translation found for not_default_data_content_description (9194667237765917844) --> + <skip /> <string name="cell_data_off" msgid="1051264981229902873">"Անջատված է"</string> <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth մոդեմ"</string> - <string name="accessibility_airplane_mode" msgid="834748999790763092">"Ինքնաթիռի ռեժիմ"</string> + <string name="accessibility_airplane_mode" msgid="834748999790763092">"Ավիառեժիմ"</string> <string name="accessibility_vpn_on" msgid="5993385083262856059">"Միացնել VPN-ը։"</string> <string name="accessibility_no_sims" msgid="3957997018324995781">"SIM քարտ չկա:"</string> <string name="carrier_network_change_mode" msgid="8149202439957837762">"Օպերատորի ցանցի փոփոխություն"</string> @@ -214,15 +217,18 @@ <string name="accessibility_quick_settings_wifi_changed_on" msgid="6440117170789528622">"Wifi-ը միացավ:"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Շարժական <xliff:g id="SIGNAL">%1$s</xliff:g>: <xliff:g id="TYPE">%2$s</xliff:g>: <xliff:g id="NETWORK">%3$s</xliff:g>:"</string> <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Մարտկոցը <xliff:g id="STATE">%s</xliff:g> է:"</string> - <string name="accessibility_quick_settings_airplane_off" msgid="7786329360056634412">"Ինքնաթիռի ռեժիմն անջատված է:"</string> - <string name="accessibility_quick_settings_airplane_on" msgid="6406141469157599296">"Ինքնաթիռի ռեժիմը միացված է:"</string> - <string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"Ինքնաթիռի ռեժիմն անջատվեց:"</string> - <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"Ինքնաթիռի ռեժիմը միացավ:"</string> + <string name="accessibility_quick_settings_airplane_off" msgid="7786329360056634412">"Ավիառեժիմն անջատված է:"</string> + <string name="accessibility_quick_settings_airplane_on" msgid="6406141469157599296">"Ավիառեժիմը միացված է:"</string> + <string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"Ավիառեժիմն անջատվեց:"</string> + <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"Ավիառեժիմը միացավ:"</string> <string name="accessibility_quick_settings_dnd_none_on" msgid="2960643943620637020">"կատարյալ լռություն"</string> <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3357131899365865386">"միայն զարթուցիչը"</string> - <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"Չանհանգստացնել:"</string> - <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"Չխանգարելու ընտրանքն անջատվեց:"</string> - <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"Չխանգարելու ընտրանքը միացվեց:"</string> + <!-- no translation found for accessibility_quick_settings_dnd (5555155552520665891) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_off (2757071272328547807) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_on (6808220653747701059) --> + <skip /> <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"Bluetooth:"</string> <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"Bluetooth-ն անջատված է:"</string> <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"Bluetooth-ը միացված է:"</string> @@ -269,7 +275,6 @@ <string name="accessibility_location_active" msgid="2427290146138169014">"Տեղադրության հարցումներն ակտիվ են"</string> <string name="accessibility_clear_all" msgid="5235938559247164925">"Մաքրել բոլոր ծանուցումները:"</string> <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string> - <string name="notification_group_overflow_indicator_ambient" msgid="879560382990377886">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>, +<xliff:g id="OVERFLOW">%2$s</xliff:g>"</string> <plurals name="notification_group_overflow_description" formatted="false" msgid="4579313201268495404"> <item quantity="one">Ներսում ևս <xliff:g id="NUMBER_1">%s</xliff:g> ծանուցում կա:</item> <item quantity="other">Ներսում ևս <xliff:g id="NUMBER_1">%s</xliff:g> ծանուցում կա:</item> @@ -286,7 +291,8 @@ <string name="start_dreams" msgid="5640361424498338327">"Էկրանապահ"</string> <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string> <string name="quick_settings_header_onboarding_text" msgid="8030309023792936283">"Լրացուցիչ կարգավորումները բացելու համար հպեք և պահեք պատկերակները"</string> - <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Չանհանգստացնել"</string> + <!-- no translation found for quick_settings_dnd_label (7112342227663678739) --> + <skip /> <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Միայն կարևոր ծանուցումների դեպքում"</string> <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Միայն զարթուցիչ"</string> <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Կատարյալ լռություն"</string> @@ -437,8 +443,10 @@ <string name="battery_saver_notification_title" msgid="8614079794522291840">"Մարտկոցի տնտեսումը միացված է"</string> <string name="battery_saver_notification_text" msgid="820318788126672692">"Նվազեցնում է ծանրաբեռնվածությունը և ֆոնային տվյալները"</string> <string name="battery_saver_notification_action_text" msgid="132118784269455533">"Անջատել մարտկոցի տնտեսումը"</string> - <string name="media_projection_dialog_text" msgid="1443042478990422751">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>-ը կլուսանկարի ամենը, ինչ հայտնվի սարքի էկրանին, այդ թվում՝ ծանուցումներ, գաղտնաբառեր, լուսանկարներ, հաղորդագրություններ և վճարային տվյալներ։"</string> - <string name="media_projection_dialog_title" msgid="7574971526813630219">"Թույլատրե՞լ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>-ին տեսագրել կամ հեռարձակել ձեր էկրանը"</string> + <!-- no translation found for media_projection_dialog_text (5751657130671431216) --> + <skip /> + <!-- no translation found for media_projection_dialog_title (8124184308671641248) --> + <skip /> <string name="media_projection_remember_text" msgid="3103510882172746752">"Այլևս ցույց չտալ"</string> <string name="clear_all_notifications_text" msgid="814192889771462828">"Մաքրել բոլորը"</string> <string name="manage_notifications_text" msgid="2386728145475108753">"Կառավարել"</string> @@ -513,6 +521,10 @@ <string name="accessibility_volume_settings" msgid="4915364006817819212">"Ձայնի կարգավորումներ"</string> <string name="accessibility_volume_expand" msgid="5946812790999244205">"Ընդարձակել"</string> <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Կոծկել"</string> + <!-- no translation found for volume_odi_captions_tip (1193653197906918269) --> + <skip /> + <!-- no translation found for accessibility_volume_close_odi_captions_tip (1163987066404128967) --> + <skip /> <string name="accessibility_output_chooser" msgid="8185317493017988680">"Փոխել արտածման սարքը"</string> <string name="screen_pinning_title" msgid="3273740381976175811">"Էկրանն ամրացված է"</string> <string name="screen_pinning_description" msgid="8909878447196419623">"Էկրանը կմնա տեսադաշտում, մինչև այն ապամրացնեք: Ապամրացնելու համար հպեք և պահեք Հետ և Համատեսք կոճակները:"</string> @@ -572,7 +584,7 @@ <string name="status_bar_ethernet" msgid="5044290963549500128">"Ethernet"</string> <string name="status_bar_alarm" msgid="8536256753575881818">"Զարթուցիչ"</string> <string name="status_bar_work" msgid="6022553324802866373">"Android for Work-ի պրոֆիլ"</string> - <string name="status_bar_airplane" msgid="7057575501472249002">"Ինքնաթիռի ռեժիմ"</string> + <string name="status_bar_airplane" msgid="7057575501472249002">"Ավիառեժիմ"</string> <string name="add_tile" msgid="2995389510240786221">"Սալիկի ավելացում"</string> <string name="broadcast_tile" msgid="3894036511763289383">"Սալիկի հեռարձակում"</string> <string name="zen_alarm_warning_indef" msgid="3482966345578319605">"Ժամը <xliff:g id="WHEN">%1$s</xliff:g>-ի զարթուցիչը չի զանգի, եթե մինչ այդ չանջատեք այս կարգավորումը"</string> @@ -613,6 +625,8 @@ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"Այս ծանուցումները կցուցադրվեն զգուշացումով"</string> <string name="inline_blocking_helper" msgid="3055064577771478591">"Դուք սովորաբար փակում եք այս ծանուցումները: \nՇարունակե՞լ ցուցադրել դրանք:"</string> <string name="inline_done_button" msgid="492513001558716452">"Փակել"</string> + <!-- no translation found for inline_ok_button (966006867967928987) --> + <skip /> <string name="inline_keep_showing" msgid="8945102997083836858">"Ցուցադրե՞լ այս ծանուցումները։"</string> <string name="inline_stop_button" msgid="4172980096860941033">"Չցուցադրել ծանուցումներ"</string> <string name="inline_deliver_silently_button" msgid="7756289895745629140">"Առաքել անձայն"</string> @@ -621,9 +635,16 @@ <string name="inline_minimize_button" msgid="966233327974702195">"Ծալել"</string> <string name="inline_silent_button_silent" msgid="4411510650503783646">"Ցույց տալ անձայն"</string> <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Չմիացնել ձայնը"</string> - <string name="inline_silent_button_alert" msgid="7961887853830826523">"Ծանուցել ինձ"</string> + <!-- no translation found for inline_silent_button_alert (2273030946176140380) --> + <skip /> <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Ծանուցել"</string> <string name="inline_keep_showing_app" msgid="1723113469580031041">"Ցուցադրե՞լ ծանուցումներ այս հավելվածից։"</string> + <!-- no translation found for hint_text_block (3554459167504485284) --> + <skip /> + <!-- no translation found for hint_text_silent (859468056340177016) --> + <skip /> + <!-- no translation found for hint_text_alert (428122667751463119) --> + <skip /> <string name="notification_unblockable_desc" msgid="1037434112919403708">"Այս ծանուցումները հնարավոր չէ անջատել"</string> <string name="notification_delegate_header" msgid="9167022191405284627">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածի միջոցով"</string> <string name="appops_camera" msgid="8100147441602585776">"Այս հավելվածն օգտագործում է տեսախցիկը:"</string> @@ -703,9 +724,11 @@ <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Օրացույց"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Ցույց տալ ձայնի ուժգնության կառավարման տարրերի հետ"</string> - <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Չանհանգստացնել"</string> + <!-- no translation found for volume_and_do_not_disturb (1750270820297253561) --> + <skip /> <string name="volume_dnd_silent" msgid="4363882330723050727">"Ձայնի կոճակների դյուրանցում"</string> - <string name="volume_up_silent" msgid="7141255269783588286">"Ելնել Չանհանգստացնել գործառույթից ձայնի ավելացման կոճակը սեղմելիս"</string> + <!-- no translation found for volume_up_silent (7545869833038212815) --> + <skip /> <string name="battery" msgid="7498329822413202973">"Մարտկոց"</string> <string name="clock" msgid="7416090374234785905">"Ժամացույց"</string> <string name="headset" msgid="4534219457597457353">"Ականջակալ"</string> @@ -875,17 +898,8 @@ <string name="open_saver_setting_action" msgid="8314624730997322529">"Կարգավորումներ"</string> <string name="auto_saver_okay_action" msgid="2701221740227683650">"Եղավ"</string> <string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string> - <plurals name="ongoing_privacy_chip_multiple_apps" formatted="false" msgid="1406406529558080714"> - <item quantity="one"><xliff:g id="NUM_APPS_2">%d</xliff:g> հավելված</item> - <item quantity="other"><xliff:g id="NUM_APPS_2">%d</xliff:g> հավելված</item> - </plurals> <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> հավելվածն օգտագործում է ձեր <xliff:g id="TYPES_LIST">%2$s</xliff:g>:"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Հավելվածներն օգտագործում են ձեր <xliff:g id="TYPES_LIST">%s</xliff:g>:"</string> - <string name="ongoing_privacy_chip_in_use" msgid="5174331553211609272">"Օգտագործվող՝"</string> - <plurals name="ongoing_privacy_chip_content_multiple_apps_single_op" formatted="false" msgid="4871926099254314088"> - <item quantity="one">Ձեր սարքում <xliff:g id="NUM_APPS_4">%1$d</xliff:g> հավելված օգտագործում է <xliff:g id="TYPE_5">%2$s</xliff:g>։</item> - <item quantity="other">Ձեր սարքում <xliff:g id="NUM_APPS_4">%1$d</xliff:g> հավելված օգտագործում է <xliff:g id="TYPE_5">%2$s</xliff:g>:</item> - </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Եղավ"</string> <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Գաղտնիություն"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Հավելված, որն օգտագործում է <xliff:g id="TYPES_LIST">%s</xliff:g> ձեր սարքում"</string> @@ -895,16 +909,33 @@ <string name="privacy_type_camera" msgid="1676604631892420333">"տեսախցիկը"</string> <string name="privacy_type_location" msgid="6435497989657286700">"վայրը"</string> <string name="privacy_type_microphone" msgid="4153045784928554506">"խոսափողը"</string> - <plurals name="ongoing_privacy_dialog_overflow_text" formatted="false" msgid="3441296594927649172"> - <item quantity="one">Եվս <xliff:g id="NUM_APPS_1">%d</xliff:g> հավելված</item> - <item quantity="other">Եվս <xliff:g id="NUM_APPS_1">%d</xliff:g> հավելված</item> - </plurals> <string name="sensor_privacy_mode" msgid="8982771253020769598">"Տվիչներն անջատած են"</string> <string name="device_services" msgid="1191212554435440592">"Սարքի ծառայություններ"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Անանուն"</string> + <!-- no translation found for restart_button_description (2035077840254950187) --> + <skip /> <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Բացել <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը"</string> - <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Բացել <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածի ծանուցումների կարգավորումները"</string> - <string name="bubbles_prompt" msgid="2684301469286150276">"Թույլատրե՞լ այս հավելվածի՝ ամպիկների տեսքով ծանուցումները:"</string> - <string name="no_bubbles" msgid="7173621233904687258">"Արգելափակել"</string> + <!-- no translation found for bubbles_settings_button_description (2970630476657287189) --> + <skip /> + <!-- no translation found for bubbles_prompt (8807968030159469710) --> + <skip /> + <!-- no translation found for no_bubbles (337101288173078247) --> + <skip /> <string name="yes_bubbles" msgid="668809525728633841">"Թույլատրել"</string> + <!-- no translation found for ask_me_later_bubbles (2147688438402939029) --> + <skip /> + <!-- no translation found for bubble_content_description_single (1184462974339387516) --> + <skip /> + <!-- no translation found for bubble_content_description_stack (8666349184095622232) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move (1794879742234803840) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_left (104736832249802724) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_right (1671844272347036806) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_left (206369104473183217) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_right (8705660152384312329) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index 34eb1083a0d3..25484cfe68c5 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -108,12 +108,13 @@ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Саусақ ізін пайдаланбай құлыпты ашу"</string> <string name="accessibility_scanning_face" msgid="769545173211758586">"Бетті сканерлеу"</string> <string name="accessibility_send_smart_reply" msgid="7766727839703044493">"Жіберу"</string> + <!-- no translation found for accessibility_manage_notification (2026361503393549753) --> + <skip /> <string name="unlock_label" msgid="8779712358041029439">"бекітпесін ашу"</string> <string name="phone_label" msgid="2320074140205331708">"телефонды ашу"</string> <string name="voice_assist_label" msgid="3956854378310019854">"ашық дауыс көмекшісі"</string> <string name="camera_label" msgid="7261107956054836961">"камераны ашу"</string> <string name="cancel" msgid="6442560571259935130">"Бас тарту"</string> - <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Анықтама хабары аумағы"</string> <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Растау"</string> <string name="biometric_dialog_try_again" msgid="1900185172633183201">"Қайталап көріңіз"</string> <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Саусақ ізін оқу сканерін түртіңіз"</string> @@ -179,6 +180,8 @@ <string name="accessibility_cell_data" msgid="5326139158682385073">"Мобильдік дерекқор"</string> <string name="accessibility_cell_data_on" msgid="5927098403452994422">"Мобильдік деректер қосулы"</string> <string name="cell_data_off_content_description" msgid="4356113230238585072">"Мобильдік деректер өшірулі"</string> + <!-- no translation found for not_default_data_content_description (9194667237765917844) --> + <skip /> <string name="cell_data_off" msgid="1051264981229902873">"Өшірулі"</string> <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth тетеринг."</string> <string name="accessibility_airplane_mode" msgid="834748999790763092">"Ұшақ режимі."</string> @@ -220,9 +223,12 @@ <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"Ұшақ режимі қосылды."</string> <string name="accessibility_quick_settings_dnd_none_on" msgid="2960643943620637020">"үнсіз"</string> <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3357131899365865386">"тек дабылдар"</string> - <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"Мазаламау."</string> - <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"Мазаламау режимі өшірілді."</string> - <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"Мазаламау режимі қосылды."</string> + <!-- no translation found for accessibility_quick_settings_dnd (5555155552520665891) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_off (2757071272328547807) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_on (6808220653747701059) --> + <skip /> <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"Bluetooth."</string> <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"Bluetooth өшірулі."</string> <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"Bluetooth қосулы."</string> @@ -269,7 +275,6 @@ <string name="accessibility_location_active" msgid="2427290146138169014">"Орын өтініштері қосылған"</string> <string name="accessibility_clear_all" msgid="5235938559247164925">"Барлық хабарларды жойыңыз."</string> <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string> - <string name="notification_group_overflow_indicator_ambient" msgid="879560382990377886">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>, +<xliff:g id="OVERFLOW">%2$s</xliff:g>"</string> <plurals name="notification_group_overflow_description" formatted="false" msgid="4579313201268495404"> <item quantity="other">Ішінде тағы <xliff:g id="NUMBER_1">%s</xliff:g> хабарландыру.</item> <item quantity="one">Ішінде тағы <xliff:g id="NUMBER_0">%s</xliff:g> хабарландыру.</item> @@ -286,7 +291,8 @@ <string name="start_dreams" msgid="5640361424498338327">"Экранды сақтау режимі"</string> <string name="ethernet_label" msgid="7967563676324087464">"Этернет"</string> <string name="quick_settings_header_onboarding_text" msgid="8030309023792936283">"Басқа опцияларды көру үшін белгішелерді түртіп ұстап тұрыңыз"</string> - <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Мазаламау"</string> + <!-- no translation found for quick_settings_dnd_label (7112342227663678739) --> + <skip /> <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Маңыздылары ғана"</string> <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Тек дабылдар"</string> <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Толық тыныштық"</string> @@ -437,8 +443,10 @@ <string name="battery_saver_notification_title" msgid="8614079794522291840">"Battery saver қосулы"</string> <string name="battery_saver_notification_text" msgid="820318788126672692">"Өнімділікті және фондық деректерді азайтады"</string> <string name="battery_saver_notification_action_text" msgid="132118784269455533">"Battery saver функциясын өшіру"</string> - <string name="media_projection_dialog_text" msgid="1443042478990422751">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> экранда көрсетілетін бүкіл мәліметті, соның ішінде хабарландыруларды, құпия сөздерді, фотосуреттерді, хабарларды және төлем туралы ақпаратты суретке түсіре бастайды."</string> - <string name="media_projection_dialog_title" msgid="7574971526813630219">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> қолданбасына экранды жазуға немесе трансляциялауға рұқсат етілсін бе?"</string> + <!-- no translation found for media_projection_dialog_text (5751657130671431216) --> + <skip /> + <!-- no translation found for media_projection_dialog_title (8124184308671641248) --> + <skip /> <string name="media_projection_remember_text" msgid="3103510882172746752">"Қайта көрсетпеу"</string> <string name="clear_all_notifications_text" msgid="814192889771462828">"Барлығын тазалау"</string> <string name="manage_notifications_text" msgid="2386728145475108753">"Басқару"</string> @@ -513,6 +521,10 @@ <string name="accessibility_volume_settings" msgid="4915364006817819212">"Дыбыс параметрлері"</string> <string name="accessibility_volume_expand" msgid="5946812790999244205">"Жаю"</string> <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Жию"</string> + <!-- no translation found for volume_odi_captions_tip (1193653197906918269) --> + <skip /> + <!-- no translation found for accessibility_volume_close_odi_captions_tip (1163987066404128967) --> + <skip /> <string name="accessibility_output_chooser" msgid="8185317493017988680">"Шығыс құрылғыны ауыстыру"</string> <string name="screen_pinning_title" msgid="3273740381976175811">"Экран түйрелді"</string> <string name="screen_pinning_description" msgid="8909878447196419623">"Экран босатылғанға дейін көрсетіліп тұрады. Оны босату үшін \"Артқа\" және \"Шолу\" түймелерін басып тұрыңыз."</string> @@ -613,6 +625,8 @@ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"Бұл хабарландырулар сізді ескертеді"</string> <string name="inline_blocking_helper" msgid="3055064577771478591">"Әдетте хабарландыруларды көрмейсіз. \nОлар көрсетілсін бе?"</string> <string name="inline_done_button" msgid="492513001558716452">"Дайын"</string> + <!-- no translation found for inline_ok_button (966006867967928987) --> + <skip /> <string name="inline_keep_showing" msgid="8945102997083836858">"Хабарландырулар көрсетілсін бе?"</string> <string name="inline_stop_button" msgid="4172980096860941033">"Хабарландыруларға тыйым салу"</string> <string name="inline_deliver_silently_button" msgid="7756289895745629140">"Дыбыссыз"</string> @@ -621,9 +635,16 @@ <string name="inline_minimize_button" msgid="966233327974702195">"Жасыру"</string> <string name="inline_silent_button_silent" msgid="4411510650503783646">"Дыбыссыз көрсету"</string> <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Хабарландырулар алғым келмейді"</string> - <string name="inline_silent_button_alert" msgid="7961887853830826523">"Хабарландырулар алғым келеді"</string> + <!-- no translation found for inline_silent_button_alert (2273030946176140380) --> + <skip /> <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Хабарландырулар келе берсін"</string> <string name="inline_keep_showing_app" msgid="1723113469580031041">"Осы қолданбаның хабарландырулары көрсетілсін бе?"</string> + <!-- no translation found for hint_text_block (3554459167504485284) --> + <skip /> + <!-- no translation found for hint_text_silent (859468056340177016) --> + <skip /> + <!-- no translation found for hint_text_alert (428122667751463119) --> + <skip /> <string name="notification_unblockable_desc" msgid="1037434112919403708">"Хабарландыруларды өшіру мүмкін емес"</string> <string name="notification_delegate_header" msgid="9167022191405284627">"<xliff:g id="APP_NAME">%1$s</xliff:g> арқылы"</string> <string name="appops_camera" msgid="8100147441602585776">"Бұл қолданба камераны пайдалануда."</string> @@ -703,9 +724,11 @@ <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Күнтізбе"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Дыбыс деңгейін басқару элементтерімен бірге көрсету"</string> - <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Мазаламау"</string> + <!-- no translation found for volume_and_do_not_disturb (1750270820297253561) --> + <skip /> <string name="volume_dnd_silent" msgid="4363882330723050727">"Дыбыс деңгейі түймелерінің төте жолы"</string> - <string name="volume_up_silent" msgid="7141255269783588286">"Дыбыс деңгейін көтергенде \"Мазаламау\" режимінен шығу"</string> + <!-- no translation found for volume_up_silent (7545869833038212815) --> + <skip /> <string name="battery" msgid="7498329822413202973">"Батарея"</string> <string name="clock" msgid="7416090374234785905">"Сағат"</string> <string name="headset" msgid="4534219457597457353">"Құлақаспап жинағы"</string> @@ -875,17 +898,8 @@ <string name="open_saver_setting_action" msgid="8314624730997322529">"Параметрлер"</string> <string name="auto_saver_okay_action" msgid="2701221740227683650">"Түсінікті"</string> <string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string> - <plurals name="ongoing_privacy_chip_multiple_apps" formatted="false" msgid="1406406529558080714"> - <item quantity="other"><xliff:g id="NUM_APPS_2">%d</xliff:g> қолданба</item> - <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> қолданба</item> - </plurals> <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> қолданбасында <xliff:g id="TYPES_LIST">%2$s</xliff:g> пайдалануда."</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Қолданбаларда <xliff:g id="TYPES_LIST">%s</xliff:g> пайдаланылуда."</string> - <string name="ongoing_privacy_chip_in_use" msgid="5174331553211609272">"Қолданыста:"</string> - <plurals name="ongoing_privacy_chip_content_multiple_apps_single_op" formatted="false" msgid="4871926099254314088"> - <item quantity="other"><xliff:g id="TYPE_5">%2$s</xliff:g> опциясын <xliff:g id="NUM_APPS_4">%1$d</xliff:g> қолданба пайдаланып жатыр.</item> - <item quantity="one"><xliff:g id="TYPE_1">%2$s</xliff:g> опциясын <xliff:g id="NUM_APPS_0">%1$d</xliff:g> қолданба пайдаланып жатыр.</item> - </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Түсінікті"</string> <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Құпиялылық параметрлері"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"<xliff:g id="TYPES_LIST">%s</xliff:g> пайдаланып жатқан қолданба"</string> @@ -895,16 +909,33 @@ <string name="privacy_type_camera" msgid="1676604631892420333">"камера"</string> <string name="privacy_type_location" msgid="6435497989657286700">"геодерек"</string> <string name="privacy_type_microphone" msgid="4153045784928554506">"микрофон"</string> - <plurals name="ongoing_privacy_dialog_overflow_text" formatted="false" msgid="3441296594927649172"> - <item quantity="other">Тағы <xliff:g id="NUM_APPS_1">%d</xliff:g> қолданба</item> - <item quantity="one">Тағы <xliff:g id="NUM_APPS_0">%d</xliff:g> қолданба</item> - </plurals> <string name="sensor_privacy_mode" msgid="8982771253020769598">"Датчиктер өшірулі"</string> <string name="device_services" msgid="1191212554435440592">"Құрылғы қызметтері"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Атауы жоқ"</string> + <!-- no translation found for restart_button_description (2035077840254950187) --> + <skip /> <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасын ашу"</string> - <string name="bubbles_settings_button_description" msgid="1940331766151865776">"<xliff:g id="APP_NAME">%1$s</xliff:g> хабарландыру параметрлерін ашу"</string> - <string name="bubbles_prompt" msgid="2684301469286150276">"Қолданбаның қалқымалы анықтамасына рұқсат берілсін бе?"</string> - <string name="no_bubbles" msgid="7173621233904687258">"Бөгеу"</string> + <!-- no translation found for bubbles_settings_button_description (2970630476657287189) --> + <skip /> + <!-- no translation found for bubbles_prompt (8807968030159469710) --> + <skip /> + <!-- no translation found for no_bubbles (337101288173078247) --> + <skip /> <string name="yes_bubbles" msgid="668809525728633841">"Рұқсат беру"</string> + <!-- no translation found for ask_me_later_bubbles (2147688438402939029) --> + <skip /> + <!-- no translation found for bubble_content_description_single (1184462974339387516) --> + <skip /> + <!-- no translation found for bubble_content_description_stack (8666349184095622232) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move (1794879742234803840) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_left (104736832249802724) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_right (1671844272347036806) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_left (206369104473183217) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_right (8705660152384312329) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index 8904b9e6983c..eba092b6d751 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -108,12 +108,13 @@ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"ನಿಮ್ಮ ಬೆರಳಚ್ಚು ಬಳಸದೆಯೇ ಅನ್ಲಾಕ್ ಮಾಡಿ"</string> <string name="accessibility_scanning_face" msgid="769545173211758586">"ಮುಖವನ್ನು ಸ್ಕ್ಯಾನ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string> <string name="accessibility_send_smart_reply" msgid="7766727839703044493">"ಕಳುಹಿಸಿ"</string> + <!-- no translation found for accessibility_manage_notification (2026361503393549753) --> + <skip /> <string name="unlock_label" msgid="8779712358041029439">"ಅನ್ಲಾಕ್ ಮಾಡು"</string> <string name="phone_label" msgid="2320074140205331708">"ಫೋನ್ ತೆರೆಯಿರಿ"</string> <string name="voice_assist_label" msgid="3956854378310019854">"ಧ್ವನಿ ಸಹಾಯಕವನ್ನು ತೆರೆ"</string> <string name="camera_label" msgid="7261107956054836961">"ಕ್ಯಾಮರಾ ತೆರೆಯಿರಿ"</string> <string name="cancel" msgid="6442560571259935130">"ರದ್ದುಮಾಡಿ"</string> - <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"ಸಹಾಯ ಸಂದೇಶ ಪ್ರದೇಶ"</string> <string name="biometric_dialog_confirm" msgid="6468457350041712674">"ದೃಢೀಕರಿಸಿ"</string> <string name="biometric_dialog_try_again" msgid="1900185172633183201">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ"</string> <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಅನ್ನು ಸ್ಪರ್ಶಿಸಿ"</string> @@ -179,6 +180,8 @@ <string name="accessibility_cell_data" msgid="5326139158682385073">"ಮೊಬೈಲ್ ಡೇಟಾ"</string> <string name="accessibility_cell_data_on" msgid="5927098403452994422">"ಮೊಬೈಲ್ ಡೇಟಾ ಆನ್"</string> <string name="cell_data_off_content_description" msgid="4356113230238585072">"ಮೊಬೈಲ್ ಡೇಟಾ ಆಫ್"</string> + <!-- no translation found for not_default_data_content_description (9194667237765917844) --> + <skip /> <string name="cell_data_off" msgid="1051264981229902873">"ಆಫ್"</string> <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ಬ್ಲೂಟೂತ್ ಟೆಥರಿಂಗ್."</string> <string name="accessibility_airplane_mode" msgid="834748999790763092">"ಏರೋಪ್ಲೇನ್ ಮೋಡ್"</string> @@ -220,9 +223,12 @@ <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"ಏರ್ಪ್ಲೇನ್ ಮೋಡ್ ಅನ್ನು ಆನ್ ಮಾಡಲಾಗಿದೆ."</string> <string name="accessibility_quick_settings_dnd_none_on" msgid="2960643943620637020">"ಸಂಪೂರ್ಣ ನಿಶ್ಯಬ್ಧ"</string> <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3357131899365865386">"ಅಲಾರಮ್ಗಳು ಮಾತ್ರ"</string> - <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ."</string> - <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"ತೊಂದರೆ ಮಾಡಬೇಡಿ ಆಫ್ ಮಾಡಲಾಗಿದೆ."</string> - <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಆನ್ ಮಾಡಲಾಗಿದೆ."</string> + <!-- no translation found for accessibility_quick_settings_dnd (5555155552520665891) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_off (2757071272328547807) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_on (6808220653747701059) --> + <skip /> <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"ಬ್ಲೂಟೂತ್."</string> <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"ಬ್ಲೂಟೂತ್ ಆಫ್ ಆಗಿದೆ."</string> <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿದೆ."</string> @@ -269,7 +275,6 @@ <string name="accessibility_location_active" msgid="2427290146138169014">"ಸ್ಥಳ ವಿನಂತಿಗಳು ಸಕ್ರಿಯವಾಗಿವೆ"</string> <string name="accessibility_clear_all" msgid="5235938559247164925">"ಎಲ್ಲಾ ಅಧಿಸೂಚನೆಗಳನ್ನು ತೆರವುಗೊಳಿಸು."</string> <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string> - <string name="notification_group_overflow_indicator_ambient" msgid="879560382990377886">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>, +<xliff:g id="OVERFLOW">%2$s</xliff:g>"</string> <plurals name="notification_group_overflow_description" formatted="false" msgid="4579313201268495404"> <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> ಕ್ಕಿಂತ ಹೆಚ್ಚು ಅಧಿಸೂಚನೆಗಳು ಒಳಗಿವೆ.</item> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> ಕ್ಕಿಂತ ಹೆಚ್ಚು ಅಧಿಸೂಚನೆಗಳು ಒಳಗಿವೆ.</item> @@ -286,7 +291,8 @@ <string name="start_dreams" msgid="5640361424498338327">"ಸ್ಕ್ರೀನ್ ಸೇವರ್"</string> <string name="ethernet_label" msgid="7967563676324087464">"ಇಥರ್ನೆಟ್"</string> <string name="quick_settings_header_onboarding_text" msgid="8030309023792936283">"ಹೆಚ್ಚಿನ ಆಯ್ಕೆಗಳಿಗಾಗಿ ಐಕಾನ್ಗಳನ್ನು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಒತ್ತಿಹಿಡಿಯಿರಿ"</string> - <string name="quick_settings_dnd_label" msgid="8735855737575028208">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ"</string> + <!-- no translation found for quick_settings_dnd_label (7112342227663678739) --> + <skip /> <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"ಆದ್ಯತೆ ಮಾತ್ರ"</string> <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"ಅಲಾರಮ್ಗಳು ಮಾತ್ರ"</string> <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"ಸಂಪೂರ್ಣ ನಿಶ್ಯಬ್ಧ"</string> @@ -437,8 +443,10 @@ <string name="battery_saver_notification_title" msgid="8614079794522291840">"ಬ್ಯಾಟರಿ ರಕ್ಷಕ ಆನ್ ಆಗಿದೆ"</string> <string name="battery_saver_notification_text" msgid="820318788126672692">"ಕಾರ್ಯಕ್ಷಮತೆ ಮತ್ತು ಹಿನ್ನೆಲೆ ಡೇಟಾವನ್ನು ಕಡಿಮೆ ಮಾಡುತ್ತದೆ"</string> <string name="battery_saver_notification_action_text" msgid="132118784269455533">"ಬ್ಯಾಟರಿ ಸೇವರ್ ಆಫ್ ಮಾಡಿ"</string> - <string name="media_projection_dialog_text" msgid="1443042478990422751">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ನಿಮ್ಮ ಪರದೆಯಲ್ಲಿರುವ - ಅಧಿಸೂಚನೆಗಳು, ಕರೆಗಳು, ಪಾಸ್ವರ್ಡ್ಗಳು ಸೇರಿದಂತೆ ಪ್ರತಿಯೊಂದನ್ನೂ ಕ್ಯಾಪ್ಚರ್ ಮಾಡುತ್ತದೆ."</string> - <string name="media_projection_dialog_title" msgid="7574971526813630219">"ರೆಕಾರ್ಡ್ ಮಾಡಲು ಅಥವಾ ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಬಿತ್ತರಿಸಲು <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ಅನ್ನು ಅನುಮತಿಸುವುದೇ?"</string> + <!-- no translation found for media_projection_dialog_text (5751657130671431216) --> + <skip /> + <!-- no translation found for media_projection_dialog_title (8124184308671641248) --> + <skip /> <string name="media_projection_remember_text" msgid="3103510882172746752">"ಮತ್ತೊಮ್ಮೆ ತೋರಿಸದಿರು"</string> <string name="clear_all_notifications_text" msgid="814192889771462828">"ಎಲ್ಲವನ್ನೂ ತೆರವುಗೊಳಿಸು"</string> <string name="manage_notifications_text" msgid="2386728145475108753">"ನಿರ್ವಹಿಸಿ"</string> @@ -513,6 +521,10 @@ <string name="accessibility_volume_settings" msgid="4915364006817819212">"ಸೌಂಡ್ ಸೆಟ್ಟಿಂಗ್ಗಳು"</string> <string name="accessibility_volume_expand" msgid="5946812790999244205">"ವಿಸ್ತರಿಸು"</string> <string name="accessibility_volume_collapse" msgid="3609549593031810875">"ಸಂಕುಚಿಸು"</string> + <!-- no translation found for volume_odi_captions_tip (1193653197906918269) --> + <skip /> + <!-- no translation found for accessibility_volume_close_odi_captions_tip (1163987066404128967) --> + <skip /> <string name="accessibility_output_chooser" msgid="8185317493017988680">"ಔಟ್ಪುಟ್ ಸಾಧನವನ್ನು ಬದಲಿಸಿ"</string> <string name="screen_pinning_title" msgid="3273740381976175811">"ಪರದೆಯನ್ನು ಪಿನ್ ಮಾಡಲಾಗಿದೆ"</string> <string name="screen_pinning_description" msgid="8909878447196419623">"ನೀವು ಅನ್ಪಿನ್ ಮಾಡುವವರೆಗೆ ಅದನ್ನು ವೀಕ್ಷಣೆಯಲ್ಲಿಡುತ್ತದೆ. ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ ಹಾಗೂ ಅನ್ಪಿನ್ ಮಾಡಲು ಅವಲೋಕಿಸಿ."</string> @@ -613,6 +625,8 @@ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"ಈ ಸೂಚನೆಗಳು ನಿಮ್ಮನ್ನು ಎಚ್ಚರಿಸುತ್ತವೆ"</string> <string name="inline_blocking_helper" msgid="3055064577771478591">"ನೀವು ಸಾಮಾನ್ಯವಾಗಿ ಈ ಅಧಿಸೂಚನೆಗಳನ್ನು ವಜಾಗೊಳಿಸಿದ್ದೀರಿ. \nಅವುಗಳನ್ನು ತೋರಿಸುತ್ತಲೇ ಇರಬೇಕೆ?"</string> <string name="inline_done_button" msgid="492513001558716452">"ಪೂರ್ಣಗೊಂಡಿದೆ"</string> + <!-- no translation found for inline_ok_button (966006867967928987) --> + <skip /> <string name="inline_keep_showing" msgid="8945102997083836858">"ಈ ಅಧಿಸೂಚನೆಗಳನ್ನು ತೋರಿಸುತ್ತಲೇ ಇರಬೇಕೆ?"</string> <string name="inline_stop_button" msgid="4172980096860941033">"ಅಧಿಸೂಚನೆಗಳನ್ನು ನಿಲ್ಲಿಸಿ"</string> <string name="inline_deliver_silently_button" msgid="7756289895745629140">"ಮೌನವಾಗಿ ವಿತರಿಸಿ"</string> @@ -621,9 +635,16 @@ <string name="inline_minimize_button" msgid="966233327974702195">"ಕಿರಿದುಗೊಳಿಸಿ"</string> <string name="inline_silent_button_silent" msgid="4411510650503783646">"ಮೌನವಾಗಿ ತೋರಿಸಿ"</string> <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"ಮೌನವಾಗಿರಿ"</string> - <string name="inline_silent_button_alert" msgid="7961887853830826523">"ನನ್ನನ್ನು ಎಚ್ಚರಿಸಿ"</string> + <!-- no translation found for inline_silent_button_alert (2273030946176140380) --> + <skip /> <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"ಎಚ್ಚರಿಸುತ್ತಿರಿ"</string> <string name="inline_keep_showing_app" msgid="1723113469580031041">"ಈ ಅಪ್ಲಿಕೇಶನ್ನಿಂದ ಅಧಿಸೂಚನೆಗಳನ್ನು ತೋರಿಸುತ್ತಲೇ ಇರಬೇಕೆ?"</string> + <!-- no translation found for hint_text_block (3554459167504485284) --> + <skip /> + <!-- no translation found for hint_text_silent (859468056340177016) --> + <skip /> + <!-- no translation found for hint_text_alert (428122667751463119) --> + <skip /> <string name="notification_unblockable_desc" msgid="1037434112919403708">"ಈ ಅಧಿಸೂಚನೆಗಳನ್ನು ಆಫ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string> <string name="notification_delegate_header" msgid="9167022191405284627">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಮೂಲಕ"</string> <string name="appops_camera" msgid="8100147441602585776">"ಈ ಅಪ್ಲಿಕೇಶನ್ ಕ್ಯಾಮರಾವನ್ನು ಬಳಸುತ್ತಿದೆ."</string> @@ -703,9 +724,11 @@ <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"ಕ್ಯಾಲೆಂಡರ್"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"ವಾಲ್ಯೂಮ್ ನಿಯಂತ್ರಣಗಳ ಜೊತೆಗೆ ತೋರಿಸು"</string> - <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ"</string> + <!-- no translation found for volume_and_do_not_disturb (1750270820297253561) --> + <skip /> <string name="volume_dnd_silent" msgid="4363882330723050727">"ವಾಲ್ಯೂಮ್ ಬಟನ್ಗಳ ಶಾರ್ಟ್ಕಟ್"</string> - <string name="volume_up_silent" msgid="7141255269783588286">"ವಾಲ್ಯೂಮ್ ಹೆಚ್ಚಳದಲ್ಲಿ \"ಅಡಚಣೆ ಮಾಡಬೇಡಿ\"ಯನ್ನು ತೊರೆಯಿರಿ"</string> + <!-- no translation found for volume_up_silent (7545869833038212815) --> + <skip /> <string name="battery" msgid="7498329822413202973">"ಬ್ಯಾಟರಿ"</string> <string name="clock" msgid="7416090374234785905">"ಗಡಿಯಾರ"</string> <string name="headset" msgid="4534219457597457353">"ಹೆಡ್ಸೆಟ್"</string> @@ -875,17 +898,8 @@ <string name="open_saver_setting_action" msgid="8314624730997322529">"ಸೆಟ್ಟಿಂಗ್ಗಳು"</string> <string name="auto_saver_okay_action" msgid="2701221740227683650">"ಅರ್ಥವಾಯಿತು"</string> <string name="heap_dump_tile_name" msgid="9141031328971226374">"SysUI ಹೀಪ್ ಡಂಪ್ ಮಾಡಿ"</string> - <plurals name="ongoing_privacy_chip_multiple_apps" formatted="false" msgid="1406406529558080714"> - <item quantity="one"><xliff:g id="NUM_APPS_2">%d</xliff:g> ಆ್ಯಪ್ಗಳು</item> - <item quantity="other"><xliff:g id="NUM_APPS_2">%d</xliff:g> ಆ್ಯಪ್ಗಳು</item> - </plurals> <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"ನಿಮ್ಮ <xliff:g id="TYPES_LIST">%2$s</xliff:g> ಅನ್ನು <xliff:g id="APP">%1$s</xliff:g> ಬಳಸುತ್ತಿದೆ."</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"ನಿಮ್ಮ <xliff:g id="TYPES_LIST">%s</xliff:g> ಅನ್ನು ಆ್ಯಪ್ಗಳು ಬಳಸುತ್ತಿವೆ."</string> - <string name="ongoing_privacy_chip_in_use" msgid="5174331553211609272">"ಬಳಕೆ:"</string> - <plurals name="ongoing_privacy_chip_content_multiple_apps_single_op" formatted="false" msgid="4871926099254314088"> - <item quantity="one"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> ಆ್ಯಪ್ಗಳು ನಿಮ್ಮ <xliff:g id="TYPE_5">%2$s</xliff:g> ಅನ್ನು ಬಳಸುತ್ತಿವೆ.</item> - <item quantity="other"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> ಆ್ಯಪ್ಗಳು ನಿಮ್ಮ <xliff:g id="TYPE_5">%2$s</xliff:g> ಅನ್ನು ಬಳಸುತ್ತಿವೆ.</item> - </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"ಅರ್ಥವಾಯಿತು"</string> <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"ಗೌಪ್ಯತಾಸೆಟ್ಟಿಂಗ್ಗಳು"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"ಆ್ಯಪ್ ನಿಮ್ಮ <xliff:g id="TYPES_LIST">%s</xliff:g> ಅನ್ನು ಬಳಸುತ್ತಿದೆ"</string> @@ -895,16 +909,33 @@ <string name="privacy_type_camera" msgid="1676604631892420333">"ಕ್ಯಾಮರಾ"</string> <string name="privacy_type_location" msgid="6435497989657286700">"ಸ್ಥಳ"</string> <string name="privacy_type_microphone" msgid="4153045784928554506">"ಮೈಕ್ರೋಫೋನ್"</string> - <plurals name="ongoing_privacy_dialog_overflow_text" formatted="false" msgid="3441296594927649172"> - <item quantity="one"><xliff:g id="NUM_APPS_1">%d</xliff:g> ಇತರ ಆ್ಯಪ್ಗಳು</item> - <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> ಇತರ ಆ್ಯಪ್ಗಳು</item> - </plurals> <string name="sensor_privacy_mode" msgid="8982771253020769598">"ಸೆನ್ಸರ್ಗಳು ಆಫ್"</string> <string name="device_services" msgid="1191212554435440592">"ಸಾಧನ ಸೇವೆಗಳು"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"ಯಾವುದೇ ಶೀರ್ಷಿಕೆಯಿಲ್ಲ"</string> + <!-- no translation found for restart_button_description (2035077840254950187) --> + <skip /> <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಅನ್ನು ತೆರೆಯಿರಿ"</string> - <string name="bubbles_settings_button_description" msgid="1940331766151865776">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಗಾಗಿ ಅಧಿಸೂಚನೆ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ತೆರೆಯಿರಿ"</string> - <string name="bubbles_prompt" msgid="2684301469286150276">"ಈ ಆ್ಯಪ್ನಿಂದ ಬಬ್ಬಲ್ಗಳನ್ನು ನೀವು ಅನುಮತಿಸುತ್ತೀರಾ?"</string> - <string name="no_bubbles" msgid="7173621233904687258">"ನಿರ್ಬಂಧಿಸಿ"</string> + <!-- no translation found for bubbles_settings_button_description (2970630476657287189) --> + <skip /> + <!-- no translation found for bubbles_prompt (8807968030159469710) --> + <skip /> + <!-- no translation found for no_bubbles (337101288173078247) --> + <skip /> <string name="yes_bubbles" msgid="668809525728633841">"ಅನುಮತಿಸಿ"</string> + <!-- no translation found for ask_me_later_bubbles (2147688438402939029) --> + <skip /> + <!-- no translation found for bubble_content_description_single (1184462974339387516) --> + <skip /> + <!-- no translation found for bubble_content_description_stack (8666349184095622232) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move (1794879742234803840) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_left (104736832249802724) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_right (1671844272347036806) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_left (206369104473183217) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_right (8705660152384312329) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml index 77e79c96b6a7..e7689399f507 100644 --- a/packages/SystemUI/res/values-land/dimens.xml +++ b/packages/SystemUI/res/values-land/dimens.xml @@ -33,7 +33,6 @@ <integer name="quick_settings_num_columns">4</integer> <bool name="quick_settings_wide">true</bool> <dimen name="qs_detail_margin_top">0dp</dimen> - <dimen name="qs_paged_tile_layout_padding_bottom">0dp</dimen> <dimen name="volume_tool_tip_right_margin">136dp</dimen> <dimen name="volume_tool_tip_top_margin">12dp</dimen> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index 7e58a395f016..6a26d3354640 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -108,12 +108,13 @@ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"तुमचे फिंगरप्रिंट न वापरता अनलॉक करा"</string> <string name="accessibility_scanning_face" msgid="769545173211758586">"चेहरा स्कॅन करत आहे"</string> <string name="accessibility_send_smart_reply" msgid="7766727839703044493">"पाठवा"</string> + <!-- no translation found for accessibility_manage_notification (2026361503393549753) --> + <skip /> <string name="unlock_label" msgid="8779712358041029439">"अनलॉक करा"</string> <string name="phone_label" msgid="2320074140205331708">"फोन उघडा"</string> <string name="voice_assist_label" msgid="3956854378310019854">"व्हॉइस सहाय्य उघडा"</string> <string name="camera_label" msgid="7261107956054836961">"कॅमेरा उघडा"</string> <string name="cancel" msgid="6442560571259935130">"रद्द करा"</string> - <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"मदत मेसेज परिसर"</string> <string name="biometric_dialog_confirm" msgid="6468457350041712674">"खात्री करा"</string> <string name="biometric_dialog_try_again" msgid="1900185172633183201">"पुन्हा प्रयत्न करा"</string> <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"फिंगरप्रिंट सेन्सरला स्पर्श करा"</string> @@ -179,6 +180,8 @@ <string name="accessibility_cell_data" msgid="5326139158682385073">"मोबाइल डेटा"</string> <string name="accessibility_cell_data_on" msgid="5927098403452994422">"मोबाइल डेटा चालू आहे"</string> <string name="cell_data_off_content_description" msgid="4356113230238585072">"मोबाइल डेटा बंद आहे"</string> + <!-- no translation found for not_default_data_content_description (9194667237765917844) --> + <skip /> <string name="cell_data_off" msgid="1051264981229902873">"बंद"</string> <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ब्लूटूथ टेदरिंग."</string> <string name="accessibility_airplane_mode" msgid="834748999790763092">"विमान मोड."</string> @@ -220,9 +223,12 @@ <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"विमान मोड चालू केला."</string> <string name="accessibility_quick_settings_dnd_none_on" msgid="2960643943620637020">"संपूर्ण शांतता"</string> <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3357131899365865386">"फक्त अलार्म"</string> - <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"व्यत्यय आणू नका."</string> - <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"व्यत्यय आणू नका बंद करा"</string> - <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"व्यत्यय आणू नका चालू करा"</string> + <!-- no translation found for accessibility_quick_settings_dnd (5555155552520665891) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_off (2757071272328547807) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_on (6808220653747701059) --> + <skip /> <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"ब्लूटूथ."</string> <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"ब्लूटूथ बंद."</string> <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"ब्लूटूथ चालू."</string> @@ -269,7 +275,6 @@ <string name="accessibility_location_active" msgid="2427290146138169014">"स्थान विनंत्या सक्रिय"</string> <string name="accessibility_clear_all" msgid="5235938559247164925">"सर्व सूचना साफ करा."</string> <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string> - <string name="notification_group_overflow_indicator_ambient" msgid="879560382990377886">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>, +<xliff:g id="OVERFLOW">%2$s</xliff:g>"</string> <plurals name="notification_group_overflow_description" formatted="false" msgid="4579313201268495404"> <item quantity="one">आत आणखी <xliff:g id="NUMBER_1">%s</xliff:g> सूचना.</item> <item quantity="other">आत आणखी <xliff:g id="NUMBER_1">%s</xliff:g> सूचना.</item> @@ -286,7 +291,8 @@ <string name="start_dreams" msgid="5640361424498338327">"स्क्रीन सेव्हर"</string> <string name="ethernet_label" msgid="7967563676324087464">"इथरनेट"</string> <string name="quick_settings_header_onboarding_text" msgid="8030309023792936283">"अधिक पर्यायांसाठी आयकनला स्पर्श करा आणि धरून ठेवा"</string> - <string name="quick_settings_dnd_label" msgid="8735855737575028208">"व्यत्यय आणू नका"</string> + <!-- no translation found for quick_settings_dnd_label (7112342227663678739) --> + <skip /> <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"केवळ प्राधान्य"</string> <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"केवळ अलार्म"</string> <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"संपूर्ण शांतता"</string> @@ -437,8 +443,10 @@ <string name="battery_saver_notification_title" msgid="8614079794522291840">"बॅटरी सेव्हर चालू आहे"</string> <string name="battery_saver_notification_text" msgid="820318788126672692">"कामगिरी आणि पार्श्वभूमीवरील डेटा कमी करते"</string> <string name="battery_saver_notification_action_text" msgid="132118784269455533">"बॅटरी सेव्हर बंद करा"</string> - <string name="media_projection_dialog_text" msgid="1443042478990422751">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> सूचना, पासवर्ड, फोटो, मेसेज आणि पेमेंट माहितीसह तुमच्या स्क्रीनवरील प्रत्येक गोष्ट कॅप्चर करण्यास सुरुवात करेल."</string> - <string name="media_projection_dialog_title" msgid="7574971526813630219">"तुमची स्क्रीन रेकॉर्ड किंवा कास्ट करण्याची <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ला अनुमती द्यायची का?"</string> + <!-- no translation found for media_projection_dialog_text (5751657130671431216) --> + <skip /> + <!-- no translation found for media_projection_dialog_title (8124184308671641248) --> + <skip /> <string name="media_projection_remember_text" msgid="3103510882172746752">"पुन्हा दर्शवू नका"</string> <string name="clear_all_notifications_text" msgid="814192889771462828">"सर्व साफ करा"</string> <string name="manage_notifications_text" msgid="2386728145475108753">"व्यवस्थापित करा"</string> @@ -513,6 +521,10 @@ <string name="accessibility_volume_settings" msgid="4915364006817819212">"आवाज सेटिंग्ज"</string> <string name="accessibility_volume_expand" msgid="5946812790999244205">"विस्तृत करा"</string> <string name="accessibility_volume_collapse" msgid="3609549593031810875">"संकुचित करा"</string> + <!-- no translation found for volume_odi_captions_tip (1193653197906918269) --> + <skip /> + <!-- no translation found for accessibility_volume_close_odi_captions_tip (1163987066404128967) --> + <skip /> <string name="accessibility_output_chooser" msgid="8185317493017988680">"आउटपुट डिव्हाइस स्विच करा"</string> <string name="screen_pinning_title" msgid="3273740381976175811">"स्क्रीन पिन केलेली आहे"</string> <string name="screen_pinning_description" msgid="8909878447196419623">"तुम्ही अनपिन करेर्यंत हे यास दृश्यामध्ये ठेवते. अनपिन करण्यासाठी परत आणि विहंगावलोकनास स्पर्श करा आणि धरून ठेवा."</string> @@ -613,6 +625,8 @@ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"या सूचना तुम्हाला इशारा देतील"</string> <string name="inline_blocking_helper" msgid="3055064577771478591">"तुम्ही या सूचना सामान्यतः डिसमिस करता. \nते दाखवत राहायचे?"</string> <string name="inline_done_button" msgid="492513001558716452">"पूर्ण झाले"</string> + <!-- no translation found for inline_ok_button (966006867967928987) --> + <skip /> <string name="inline_keep_showing" msgid="8945102997083836858">"या सूचना दाखवणे सुरू ठेवायचे?"</string> <string name="inline_stop_button" msgid="4172980096860941033">"सूचना थांबवा"</string> <string name="inline_deliver_silently_button" msgid="7756289895745629140">"शांतपणे पाठवा"</string> @@ -621,9 +635,16 @@ <string name="inline_minimize_button" msgid="966233327974702195">"लहान करा"</string> <string name="inline_silent_button_silent" msgid="4411510650503783646">"शांतपणे दर्शवा"</string> <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"सायलंट रहा"</string> - <string name="inline_silent_button_alert" msgid="7961887853830826523">"मला अॅलर्ट करा"</string> + <!-- no translation found for inline_silent_button_alert (2273030946176140380) --> + <skip /> <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"सूचना देत रहा"</string> <string name="inline_keep_showing_app" msgid="1723113469580031041">"या अॅपकडील सूचना दाखवणे सुरू ठेवायचे?"</string> + <!-- no translation found for hint_text_block (3554459167504485284) --> + <skip /> + <!-- no translation found for hint_text_silent (859468056340177016) --> + <skip /> + <!-- no translation found for hint_text_alert (428122667751463119) --> + <skip /> <string name="notification_unblockable_desc" msgid="1037434112919403708">"या सूचना बंद करता येत नाहीत"</string> <string name="notification_delegate_header" msgid="9167022191405284627">"<xliff:g id="APP_NAME">%1$s</xliff:g> मार्गे"</string> <string name="appops_camera" msgid="8100147441602585776">"हे अॅप कॅमेरा वापरत आहे."</string> @@ -703,9 +724,11 @@ <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"कॅलेंडर"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"आवाज नियंत्रणांसह दर्शवा"</string> - <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"व्यत्यय आणू नका"</string> + <!-- no translation found for volume_and_do_not_disturb (1750270820297253561) --> + <skip /> <string name="volume_dnd_silent" msgid="4363882330723050727">"आवाजाच्या बटणांचा शार्टकट"</string> - <string name="volume_up_silent" msgid="7141255269783588286">"आवाज वाढविल्यावर व्यत्यय आणू नका मधून बाहेर पडा"</string> + <!-- no translation found for volume_up_silent (7545869833038212815) --> + <skip /> <string name="battery" msgid="7498329822413202973">"बॅटरी"</string> <string name="clock" msgid="7416090374234785905">"घड्याळ"</string> <string name="headset" msgid="4534219457597457353">"हेडसेट"</string> @@ -875,17 +898,8 @@ <string name="open_saver_setting_action" msgid="8314624730997322529">"सेटिंग्ज"</string> <string name="auto_saver_okay_action" msgid="2701221740227683650">"समजले"</string> <string name="heap_dump_tile_name" msgid="9141031328971226374">"SysUI हीप डंप करा"</string> - <plurals name="ongoing_privacy_chip_multiple_apps" formatted="false" msgid="1406406529558080714"> - <item quantity="one"><xliff:g id="NUM_APPS_2">%d</xliff:g> अॅप</item> - <item quantity="other"><xliff:g id="NUM_APPS_2">%d</xliff:g> अॅप्स</item> - </plurals> <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> तुमचे <xliff:g id="TYPES_LIST">%2$s</xliff:g> वापरत आहे."</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"अॅप्लिकेशन्स तुमचे <xliff:g id="TYPES_LIST">%s</xliff:g> वापरत आहे."</string> - <string name="ongoing_privacy_chip_in_use" msgid="5174331553211609272">"वापरात:"</string> - <plurals name="ongoing_privacy_chip_content_multiple_apps_single_op" formatted="false" msgid="4871926099254314088"> - <item quantity="one"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> अॅप्लिकेशन तुमचे <xliff:g id="TYPE_5">%2$s</xliff:g> वापरत आहे.</item> - <item quantity="other"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> अॅप्लिकेशन तुमचे <xliff:g id="TYPE_5">%2$s</xliff:g> वापरत आहेत.</item> - </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"समजले"</string> <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"गोपनीयता सेटिंग्ज"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"अॅप तुमचे <xliff:g id="TYPES_LIST">%s</xliff:g> वापरत आहे"</string> @@ -895,16 +909,33 @@ <string name="privacy_type_camera" msgid="1676604631892420333">"कॅमेरा"</string> <string name="privacy_type_location" msgid="6435497989657286700">"स्थान"</string> <string name="privacy_type_microphone" msgid="4153045784928554506">"मायक्रोफोन"</string> - <plurals name="ongoing_privacy_dialog_overflow_text" formatted="false" msgid="3441296594927649172"> - <item quantity="one">इतर <xliff:g id="NUM_APPS_1">%d</xliff:g> अॅप</item> - <item quantity="other">इतर <xliff:g id="NUM_APPS_1">%d</xliff:g> अॅप्स</item> - </plurals> <string name="sensor_privacy_mode" msgid="8982771253020769598">"सेन्सर बंद आहेत"</string> <string name="device_services" msgid="1191212554435440592">"डिव्हाइस सेवा"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"शीर्षक नाही"</string> + <!-- no translation found for restart_button_description (2035077840254950187) --> + <skip /> <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"<xliff:g id="APP_NAME">%1$s</xliff:g> उघडा"</string> - <string name="bubbles_settings_button_description" msgid="1940331766151865776">"<xliff:g id="APP_NAME">%1$s</xliff:g>साठी सूचना सेटिंग्ज उघडा"</string> - <string name="bubbles_prompt" msgid="2684301469286150276">"या अॅपवरील बबलना अनुमती द्यायची आहे का?"</string> - <string name="no_bubbles" msgid="7173621233904687258">"ब्लॉक करा"</string> + <!-- no translation found for bubbles_settings_button_description (2970630476657287189) --> + <skip /> + <!-- no translation found for bubbles_prompt (8807968030159469710) --> + <skip /> + <!-- no translation found for no_bubbles (337101288173078247) --> + <skip /> <string name="yes_bubbles" msgid="668809525728633841">"अनुमती द्या"</string> + <!-- no translation found for ask_me_later_bubbles (2147688438402939029) --> + <skip /> + <!-- no translation found for bubble_content_description_single (1184462974339387516) --> + <skip /> + <!-- no translation found for bubble_content_description_stack (8666349184095622232) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move (1794879742234803840) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_left (104736832249802724) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_right (1671844272347036806) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_left (206369104473183217) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_right (8705660152384312329) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index b5c23431837e..58011629d9c5 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -108,12 +108,13 @@ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Desbloquear sem utilizar a sua impressão digital"</string> <string name="accessibility_scanning_face" msgid="769545173211758586">"A analisar o rosto…"</string> <string name="accessibility_send_smart_reply" msgid="7766727839703044493">"Enviar"</string> + <!-- no translation found for accessibility_manage_notification (2026361503393549753) --> + <skip /> <string name="unlock_label" msgid="8779712358041029439">"desbloquear"</string> <string name="phone_label" msgid="2320074140205331708">"abrir telemóvel"</string> <string name="voice_assist_label" msgid="3956854378310019854">"abrir assistente de voz"</string> <string name="camera_label" msgid="7261107956054836961">"abrir câmara"</string> <string name="cancel" msgid="6442560571259935130">"Cancelar"</string> - <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Área da mensagem de ajuda"</string> <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Confirmar"</string> <string name="biometric_dialog_try_again" msgid="1900185172633183201">"Tentar novamente"</string> <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Toque no sensor de impressões digitais."</string> @@ -179,6 +180,8 @@ <string name="accessibility_cell_data" msgid="5326139158682385073">"Dados móveis"</string> <string name="accessibility_cell_data_on" msgid="5927098403452994422">"Dados móveis ativados"</string> <string name="cell_data_off_content_description" msgid="4356113230238585072">"Dados móveis desativados"</string> + <!-- no translation found for not_default_data_content_description (9194667237765917844) --> + <skip /> <string name="cell_data_off" msgid="1051264981229902873">"Desativado"</string> <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Ligação Bluetooth via telemóvel."</string> <string name="accessibility_airplane_mode" msgid="834748999790763092">"Modo de avião"</string> @@ -220,9 +223,12 @@ <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"Modo de avião ligado."</string> <string name="accessibility_quick_settings_dnd_none_on" msgid="2960643943620637020">"silêncio total"</string> <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3357131899365865386">"apenas alarmes"</string> - <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"Não incomodar."</string> - <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"Não incomodar desligado."</string> - <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"Não incomodar ligado."</string> + <!-- no translation found for accessibility_quick_settings_dnd (5555155552520665891) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_off (2757071272328547807) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_on (6808220653747701059) --> + <skip /> <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"Bluetooth."</string> <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"Bluetooth desligado."</string> <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"Bluetooth ligado."</string> @@ -269,7 +275,6 @@ <string name="accessibility_location_active" msgid="2427290146138169014">"Pedidos de localização ativos"</string> <string name="accessibility_clear_all" msgid="5235938559247164925">"Limpar todas as notificações."</string> <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string> - <string name="notification_group_overflow_indicator_ambient" msgid="879560382990377886">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>, +<xliff:g id="OVERFLOW">%2$s</xliff:g>"</string> <plurals name="notification_group_overflow_description" formatted="false" msgid="4579313201268495404"> <item quantity="other">Mais <xliff:g id="NUMBER_1">%s</xliff:g> notificações no grupo.</item> <item quantity="one">Mais <xliff:g id="NUMBER_0">%s</xliff:g> notificação no grupo.</item> @@ -286,7 +291,8 @@ <string name="start_dreams" msgid="5640361424498338327">"Proteção de ecrã"</string> <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string> <string name="quick_settings_header_onboarding_text" msgid="8030309023792936283">"Toque sem soltar nos ícones para obter mais opções."</string> - <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Não incomodar"</string> + <!-- no translation found for quick_settings_dnd_label (7112342227663678739) --> + <skip /> <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Apenas prioridade"</string> <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Apenas alarmes"</string> <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Silêncio total"</string> @@ -437,8 +443,10 @@ <string name="battery_saver_notification_title" msgid="8614079794522291840">"Poupança de bateria ativada"</string> <string name="battery_saver_notification_text" msgid="820318788126672692">"Reduz o desempenho e os dados de segundo plano"</string> <string name="battery_saver_notification_action_text" msgid="132118784269455533">"Desativar a Poupança de bateria"</string> - <string name="media_projection_dialog_text" msgid="1443042478990422751">"O(a) <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> irá começar a captar tudo o que é apresentado no ecrã, incluindo notificações, palavras-passe, fotos, mensagens e informações de pagamento."</string> - <string name="media_projection_dialog_title" msgid="7574971526813630219">"Pretende permitir que o(a) <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> grave ou transmita o seu ecrã?"</string> + <!-- no translation found for media_projection_dialog_text (5751657130671431216) --> + <skip /> + <!-- no translation found for media_projection_dialog_title (8124184308671641248) --> + <skip /> <string name="media_projection_remember_text" msgid="3103510882172746752">"Não mostrar de novo"</string> <string name="clear_all_notifications_text" msgid="814192889771462828">"Limpar tudo"</string> <string name="manage_notifications_text" msgid="2386728145475108753">"Gerir"</string> @@ -513,6 +521,10 @@ <string name="accessibility_volume_settings" msgid="4915364006817819212">"Definições de som"</string> <string name="accessibility_volume_expand" msgid="5946812790999244205">"Expandir"</string> <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Reduzir"</string> + <!-- no translation found for volume_odi_captions_tip (1193653197906918269) --> + <skip /> + <!-- no translation found for accessibility_volume_close_odi_captions_tip (1163987066404128967) --> + <skip /> <string name="accessibility_output_chooser" msgid="8185317493017988680">"Mudar de dispositivo de saída"</string> <string name="screen_pinning_title" msgid="3273740381976175811">"O ecrã está fixado"</string> <string name="screen_pinning_description" msgid="8909878447196419623">"Esta opção mantém o item visível até o soltar. Toque sem soltar em Anterior e em Vista geral para soltar."</string> @@ -613,6 +625,8 @@ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"Estas notificações irão alertá-lo."</string> <string name="inline_blocking_helper" msgid="3055064577771478591">"Normalmente, ignora estas notificações. \nPretende continuar a mostrá-las?"</string> <string name="inline_done_button" msgid="492513001558716452">"Concluído"</string> + <!-- no translation found for inline_ok_button (966006867967928987) --> + <skip /> <string name="inline_keep_showing" msgid="8945102997083836858">"Pretende continuar a ver estas notificações?"</string> <string name="inline_stop_button" msgid="4172980096860941033">"Parar notificações"</string> <string name="inline_deliver_silently_button" msgid="7756289895745629140">"Publicar silenciosamente"</string> @@ -621,9 +635,16 @@ <string name="inline_minimize_button" msgid="966233327974702195">"Minimizar"</string> <string name="inline_silent_button_silent" msgid="4411510650503783646">"Mostrar silenciosamente"</string> <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Continuar sem som"</string> - <string name="inline_silent_button_alert" msgid="7961887853830826523">"Alertar-me"</string> + <!-- no translation found for inline_silent_button_alert (2273030946176140380) --> + <skip /> <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Continuar a alertar"</string> <string name="inline_keep_showing_app" msgid="1723113469580031041">"Pretende continuar a ver notificações desta aplicação?"</string> + <!-- no translation found for hint_text_block (3554459167504485284) --> + <skip /> + <!-- no translation found for hint_text_silent (859468056340177016) --> + <skip /> + <!-- no translation found for hint_text_alert (428122667751463119) --> + <skip /> <string name="notification_unblockable_desc" msgid="1037434112919403708">"Não é possível desativar estas notificações."</string> <string name="notification_delegate_header" msgid="9167022191405284627">"através da aplicação <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="appops_camera" msgid="8100147441602585776">"Esta aplicação está a utilizar a câmara."</string> @@ -703,9 +724,11 @@ <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendário"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Mostrar com controlos de volume"</string> - <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Não incomodar"</string> + <!-- no translation found for volume_and_do_not_disturb (1750270820297253561) --> + <skip /> <string name="volume_dnd_silent" msgid="4363882330723050727">"Atalho dos botões de volume"</string> - <string name="volume_up_silent" msgid="7141255269783588286">"Desativar Não incomodar ao aumentar o volume"</string> + <!-- no translation found for volume_up_silent (7545869833038212815) --> + <skip /> <string name="battery" msgid="7498329822413202973">"Bateria"</string> <string name="clock" msgid="7416090374234785905">"Relógio"</string> <string name="headset" msgid="4534219457597457353">"Ausc. com microfone integrado"</string> @@ -875,17 +898,8 @@ <string name="open_saver_setting_action" msgid="8314624730997322529">"Definições"</string> <string name="auto_saver_okay_action" msgid="2701221740227683650">"Compreendi"</string> <string name="heap_dump_tile_name" msgid="9141031328971226374">"Cp ár. di. da. SysUI"</string> - <plurals name="ongoing_privacy_chip_multiple_apps" formatted="false" msgid="1406406529558080714"> - <item quantity="other"><xliff:g id="NUM_APPS_2">%d</xliff:g> aplic.</item> - <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> aplicação</item> - </plurals> <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"A aplicação <xliff:g id="APP">%1$s</xliff:g> está a utilizar o(a) <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"As aplicações estão a utilizar o(a) <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> - <string name="ongoing_privacy_chip_in_use" msgid="5174331553211609272">"Em util.:"</string> - <plurals name="ongoing_privacy_chip_content_multiple_apps_single_op" formatted="false" msgid="4871926099254314088"> - <item quantity="other"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> aplicações estão a utilizar o(a) <xliff:g id="TYPE_5">%2$s</xliff:g>.</item> - <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> aplicação está a utilizar o(a) <xliff:g id="TYPE_1">%2$s</xliff:g>.</item> - </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Compreendi"</string> <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Def. de privacidade"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Aplicações que utilizam o(a) <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> @@ -895,16 +909,33 @@ <string name="privacy_type_camera" msgid="1676604631892420333">"câmara"</string> <string name="privacy_type_location" msgid="6435497989657286700">"localização"</string> <string name="privacy_type_microphone" msgid="4153045784928554506">"microfone"</string> - <plurals name="ongoing_privacy_dialog_overflow_text" formatted="false" msgid="3441296594927649172"> - <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> outras aplicações</item> - <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> outra aplicação</item> - </plurals> <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensores desativados"</string> <string name="device_services" msgid="1191212554435440592">"Serviços do dispositivo"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Sem título"</string> + <!-- no translation found for restart_button_description (2035077840254950187) --> + <skip /> <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Abrir a aplicação <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> - <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Abrir as definições de notificação da aplicação <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> - <string name="bubbles_prompt" msgid="2684301469286150276">"Pretende permitir balões desta aplicação?"</string> - <string name="no_bubbles" msgid="7173621233904687258">"Bloquear"</string> + <!-- no translation found for bubbles_settings_button_description (2970630476657287189) --> + <skip /> + <!-- no translation found for bubbles_prompt (8807968030159469710) --> + <skip /> + <!-- no translation found for no_bubbles (337101288173078247) --> + <skip /> <string name="yes_bubbles" msgid="668809525728633841">"Permitir"</string> + <!-- no translation found for ask_me_later_bubbles (2147688438402939029) --> + <skip /> + <!-- no translation found for bubble_content_description_single (1184462974339387516) --> + <skip /> + <!-- no translation found for bubble_content_description_stack (8666349184095622232) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move (1794879742234803840) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_left (104736832249802724) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_right (1671844272347036806) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_left (206369104473183217) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_right (8705660152384312329) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index c1b80b197a20..adb0b1d1bd66 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -108,12 +108,13 @@ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Odomknúť bez použitia odtlačku"</string> <string name="accessibility_scanning_face" msgid="769545173211758586">"Skenovanie tváre"</string> <string name="accessibility_send_smart_reply" msgid="7766727839703044493">"Odoslať"</string> + <!-- no translation found for accessibility_manage_notification (2026361503393549753) --> + <skip /> <string name="unlock_label" msgid="8779712358041029439">"odomknúť"</string> <string name="phone_label" msgid="2320074140205331708">"otvoriť telefón"</string> <string name="voice_assist_label" msgid="3956854378310019854">"otvoriť hlasového asistenta"</string> <string name="camera_label" msgid="7261107956054836961">"spustiť fotoaparát"</string> <string name="cancel" msgid="6442560571259935130">"Zrušiť"</string> - <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Oblasť správy pomocníka"</string> <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Potvrdiť"</string> <string name="biometric_dialog_try_again" msgid="1900185172633183201">"Skúsiť znova"</string> <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Klepnite na senzor odtlačkov prstov"</string> @@ -179,6 +180,8 @@ <string name="accessibility_cell_data" msgid="5326139158682385073">"Mobilné dáta"</string> <string name="accessibility_cell_data_on" msgid="5927098403452994422">"Mobilné dáta sú zapnuté"</string> <string name="cell_data_off_content_description" msgid="4356113230238585072">"Mobilné dáta sú vypnuté"</string> + <!-- no translation found for not_default_data_content_description (9194667237765917844) --> + <skip /> <string name="cell_data_off" msgid="1051264981229902873">"Vypnuté"</string> <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Pripojenie cez Bluetooth."</string> <string name="accessibility_airplane_mode" msgid="834748999790763092">"Režim v lietadle."</string> @@ -220,9 +223,12 @@ <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"Režim v lietadle je zapnutý."</string> <string name="accessibility_quick_settings_dnd_none_on" msgid="2960643943620637020">"úplné ticho"</string> <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3357131899365865386">"iba budíky"</string> - <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"Režim bez vyrušení"</string> - <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"Režim bez vyrušení je vypnutý."</string> - <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"Režim bez vyrušení je zapnutý."</string> + <!-- no translation found for accessibility_quick_settings_dnd (5555155552520665891) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_off (2757071272328547807) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_on (6808220653747701059) --> + <skip /> <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"Bluetooth"</string> <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"Rozhranie Bluetooth je vypnuté."</string> <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"Rozhranie Bluetooth je zapnuté."</string> @@ -269,7 +275,6 @@ <string name="accessibility_location_active" msgid="2427290146138169014">"Žiadosti o polohu sú aktívne"</string> <string name="accessibility_clear_all" msgid="5235938559247164925">"Vymazať všetky upozornenia."</string> <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string> - <string name="notification_group_overflow_indicator_ambient" msgid="879560382990377886">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>, +<xliff:g id="OVERFLOW">%2$s</xliff:g>"</string> <plurals name="notification_group_overflow_description" formatted="false" msgid="4579313201268495404"> <item quantity="few">Skupina obsahuje ešte <xliff:g id="NUMBER_1">%s</xliff:g> upozornenia.</item> <item quantity="many">Skupina obsahuje ešte <xliff:g id="NUMBER_1">%s</xliff:g> upozornenia.</item> @@ -288,7 +293,8 @@ <string name="start_dreams" msgid="5640361424498338327">"Šetrič obrazovky"</string> <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string> <string name="quick_settings_header_onboarding_text" msgid="8030309023792936283">"Pridržaním ikon zobrazíte ďalšie možnosti"</string> - <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Režim bez vyrušení"</string> + <!-- no translation found for quick_settings_dnd_label (7112342227663678739) --> + <skip /> <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Iba prioritné"</string> <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Iba budíky"</string> <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Úplné ticho"</string> @@ -443,8 +449,10 @@ <string name="battery_saver_notification_title" msgid="8614079794522291840">"Šetrič batérie je zapnutý"</string> <string name="battery_saver_notification_text" msgid="820318788126672692">"Obmedzí výkonnosť a prenos údajov na pozadí"</string> <string name="battery_saver_notification_action_text" msgid="132118784269455533">"Vypnúť šetrič batérie"</string> - <string name="media_projection_dialog_text" msgid="1443042478990422751">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> začne snímať všetok obsah obrazovky vrátane upozornení, hesiel, fotiek, správ a platobných údajov."</string> - <string name="media_projection_dialog_title" msgid="7574971526813630219">"Chcete povoliť aplikácii <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> zaznamenať alebo prenášať vašu obrazovku?"</string> + <!-- no translation found for media_projection_dialog_text (5751657130671431216) --> + <skip /> + <!-- no translation found for media_projection_dialog_title (8124184308671641248) --> + <skip /> <string name="media_projection_remember_text" msgid="3103510882172746752">"Nabudúce nezobrazovať"</string> <string name="clear_all_notifications_text" msgid="814192889771462828">"Vymazať všetko"</string> <string name="manage_notifications_text" msgid="2386728145475108753">"Spravovať"</string> @@ -519,6 +527,10 @@ <string name="accessibility_volume_settings" msgid="4915364006817819212">"Nastavenia zvuku"</string> <string name="accessibility_volume_expand" msgid="5946812790999244205">"Rozbaliť"</string> <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Zbaliť"</string> + <!-- no translation found for volume_odi_captions_tip (1193653197906918269) --> + <skip /> + <!-- no translation found for accessibility_volume_close_odi_captions_tip (1163987066404128967) --> + <skip /> <string name="accessibility_output_chooser" msgid="8185317493017988680">"Prepnúť výstupné zariadenie"</string> <string name="screen_pinning_title" msgid="3273740381976175811">"Obrazovka je pripnutá"</string> <string name="screen_pinning_description" msgid="8909878447196419623">"Obsah bude pripnutý v zobrazení, dokým ho neuvoľníte. Uvoľníte ho stlačením a podržaním tlačidiel Späť a Prehľad."</string> @@ -619,6 +631,8 @@ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"Tieto upozornenia vás upozornia"</string> <string name="inline_blocking_helper" msgid="3055064577771478591">"Tieto upozornenia zvyčajne odmietate. \nChcete ich naďalej zobrazovať?"</string> <string name="inline_done_button" msgid="492513001558716452">"Hotovo"</string> + <!-- no translation found for inline_ok_button (966006867967928987) --> + <skip /> <string name="inline_keep_showing" msgid="8945102997083836858">"Majú sa tieto upozornenia naďalej zobrazovať?"</string> <string name="inline_stop_button" msgid="4172980096860941033">"Prestať zobrazovať upozornenia"</string> <string name="inline_deliver_silently_button" msgid="7756289895745629140">"Poskytovať bez zvukov"</string> @@ -627,9 +641,16 @@ <string name="inline_minimize_button" msgid="966233327974702195">"Minimalizovať"</string> <string name="inline_silent_button_silent" msgid="4411510650503783646">"Zobraziť potichu"</string> <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Naďalej upozorňovať potichu"</string> - <string name="inline_silent_button_alert" msgid="7961887853830826523">"Upozorniť ma"</string> + <!-- no translation found for inline_silent_button_alert (2273030946176140380) --> + <skip /> <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Naďalej upozorňovať"</string> <string name="inline_keep_showing_app" msgid="1723113469580031041">"Majú sa upozornenia z tejto aplikácie naďalej zobrazovať?"</string> + <!-- no translation found for hint_text_block (3554459167504485284) --> + <skip /> + <!-- no translation found for hint_text_silent (859468056340177016) --> + <skip /> + <!-- no translation found for hint_text_alert (428122667751463119) --> + <skip /> <string name="notification_unblockable_desc" msgid="1037434112919403708">"Tieto upozornenia sa nedajú vypnúť"</string> <string name="notification_delegate_header" msgid="9167022191405284627">"prostredníctvom aplikácie <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="appops_camera" msgid="8100147441602585776">"Táto aplikácia používa fotoaparát."</string> @@ -713,9 +734,11 @@ <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalendár"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Zobrazovať s ovládacími prvkami hlasitosti"</string> - <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Režim bez vyrušení"</string> + <!-- no translation found for volume_and_do_not_disturb (1750270820297253561) --> + <skip /> <string name="volume_dnd_silent" msgid="4363882330723050727">"Skratka tlačidiel hlasitosti"</string> - <string name="volume_up_silent" msgid="7141255269783588286">"Pri zvýšení hlasitosti ukončiť režim bez vyrušení"</string> + <!-- no translation found for volume_up_silent (7545869833038212815) --> + <skip /> <string name="battery" msgid="7498329822413202973">"Batéria"</string> <string name="clock" msgid="7416090374234785905">"Hodiny"</string> <string name="headset" msgid="4534219457597457353">"Náhlavná súprava"</string> @@ -885,21 +908,8 @@ <string name="open_saver_setting_action" msgid="8314624730997322529">"Nastavenia"</string> <string name="auto_saver_okay_action" msgid="2701221740227683650">"Dobre"</string> <string name="heap_dump_tile_name" msgid="9141031328971226374">"Výpis haldy SysUI"</string> - <plurals name="ongoing_privacy_chip_multiple_apps" formatted="false" msgid="1406406529558080714"> - <item quantity="few"><xliff:g id="NUM_APPS_1">%d</xliff:g> aplikácie</item> - <item quantity="many"><xliff:g id="NUM_APPS_2">%d</xliff:g> apps</item> - <item quantity="other"><xliff:g id="NUM_APPS_2">%d</xliff:g> aplikácií</item> - <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> aplikácia</item> - </plurals> <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> používa zoznam <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Aplikácie používajú zoznam <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> - <string name="ongoing_privacy_chip_in_use" msgid="5174331553211609272">"Používa sa:"</string> - <plurals name="ongoing_privacy_chip_content_multiple_apps_single_op" formatted="false" msgid="4871926099254314088"> - <item quantity="few"><xliff:g id="TYPE_3">%2$s</xliff:g> používajú <xliff:g id="NUM_APPS_2">%1$d</xliff:g> aplikácie</item> - <item quantity="many"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> applications are using your <xliff:g id="TYPE_5">%2$s</xliff:g>.</item> - <item quantity="other"><xliff:g id="TYPE_5">%2$s</xliff:g> používa <xliff:g id="NUM_APPS_4">%1$d</xliff:g> aplikácií</item> - <item quantity="one"><xliff:g id="TYPE_1">%2$s</xliff:g> používa <xliff:g id="NUM_APPS_0">%1$d</xliff:g> aplikácia.</item> - </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Dobre"</string> <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Nastavenia ochrany súkromia"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Aplikácia používajúca <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> @@ -909,18 +919,33 @@ <string name="privacy_type_camera" msgid="1676604631892420333">"fotoaparát"</string> <string name="privacy_type_location" msgid="6435497989657286700">"poloha"</string> <string name="privacy_type_microphone" msgid="4153045784928554506">"mikrofón"</string> - <plurals name="ongoing_privacy_dialog_overflow_text" formatted="false" msgid="3441296594927649172"> - <item quantity="few"><xliff:g id="NUM_APPS_1">%d</xliff:g> ďalšie aplikácie</item> - <item quantity="many"><xliff:g id="NUM_APPS_1">%d</xliff:g> other apps</item> - <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> ďalších aplikácií</item> - <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> ďalšia aplikácia</item> - </plurals> <string name="sensor_privacy_mode" msgid="8982771253020769598">"Senzory sú vypnuté"</string> <string name="device_services" msgid="1191212554435440592">"Služby zariadenia"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Bez názvu"</string> + <!-- no translation found for restart_button_description (2035077840254950187) --> + <skip /> <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Otvoriť <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> - <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Otvoriť nastavenia upozornení pre <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> - <string name="bubbles_prompt" msgid="2684301469286150276">"Chcete povoliť bubliny z tejto aplikácie?"</string> - <string name="no_bubbles" msgid="7173621233904687258">"Blokovať"</string> + <!-- no translation found for bubbles_settings_button_description (2970630476657287189) --> + <skip /> + <!-- no translation found for bubbles_prompt (8807968030159469710) --> + <skip /> + <!-- no translation found for no_bubbles (337101288173078247) --> + <skip /> <string name="yes_bubbles" msgid="668809525728633841">"Povoliť"</string> + <!-- no translation found for ask_me_later_bubbles (2147688438402939029) --> + <skip /> + <!-- no translation found for bubble_content_description_single (1184462974339387516) --> + <skip /> + <!-- no translation found for bubble_content_description_stack (8666349184095622232) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move (1794879742234803840) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_left (104736832249802724) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_right (1671844272347036806) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_left (206369104473183217) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_right (8705660152384312329) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index e5fd95387eaa..c67b6f3b0443 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -108,12 +108,13 @@ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"உங்கள் கைரேகையைப் பயன்படுத்தாமல் திறக்கவும்"</string> <string name="accessibility_scanning_face" msgid="769545173211758586">"முகத்தை ஸ்கேன் செய்கிறது"</string> <string name="accessibility_send_smart_reply" msgid="7766727839703044493">"அனுப்பு"</string> + <!-- no translation found for accessibility_manage_notification (2026361503393549753) --> + <skip /> <string name="unlock_label" msgid="8779712358041029439">"திற"</string> <string name="phone_label" msgid="2320074140205331708">"ஃபோனைத் திற"</string> <string name="voice_assist_label" msgid="3956854378310019854">"குரல் உதவியைத் திற"</string> <string name="camera_label" msgid="7261107956054836961">"கேமராவைத் திற"</string> <string name="cancel" msgid="6442560571259935130">"ரத்துசெய்"</string> - <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"உதவிச் செய்திக்கான பகுதி"</string> <string name="biometric_dialog_confirm" msgid="6468457350041712674">"உறுதிப்படுத்துக"</string> <string name="biometric_dialog_try_again" msgid="1900185172633183201">"மீண்டும் முயல்க"</string> <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"கைரேகை சென்சாரைத் தொடவும்"</string> @@ -179,6 +180,8 @@ <string name="accessibility_cell_data" msgid="5326139158682385073">"மொபைல் டேட்டா"</string> <string name="accessibility_cell_data_on" msgid="5927098403452994422">"மொபைல் டேட்டா இயக்கப்பட்டது"</string> <string name="cell_data_off_content_description" msgid="4356113230238585072">"மொபைல் டேட்டா ஆஃப் செய்யப்பட்டது"</string> + <!-- no translation found for not_default_data_content_description (9194667237765917844) --> + <skip /> <string name="cell_data_off" msgid="1051264981229902873">"ஆஃப்"</string> <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"புளூடூத் டெதெரிங்."</string> <string name="accessibility_airplane_mode" msgid="834748999790763092">"விமானப் பயன்முறை."</string> @@ -220,9 +223,12 @@ <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"விமானப் பயன்முறை இயக்கப்பட்டது."</string> <string name="accessibility_quick_settings_dnd_none_on" msgid="2960643943620637020">"முழு அமைதி"</string> <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3357131899365865386">"அலாரங்கள் மட்டும்"</string> - <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"தொந்தரவு செய்யாதே."</string> - <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"தொந்தரவு செய்ய வேண்டாம் என்பது முடக்கப்பட்டது."</string> - <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"தொந்தரவு செய்ய வேண்டாம் என்பது இயக்கப்பட்டது."</string> + <!-- no translation found for accessibility_quick_settings_dnd (5555155552520665891) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_off (2757071272328547807) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_on (6808220653747701059) --> + <skip /> <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"புளூடூத்."</string> <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"புளூடூத் முடக்கத்தில்."</string> <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"புளூடூத் இயக்கத்தில்."</string> @@ -269,7 +275,6 @@ <string name="accessibility_location_active" msgid="2427290146138169014">"இருப்பிடக் கோரிக்கைகள் இயக்கப்பட்டன"</string> <string name="accessibility_clear_all" msgid="5235938559247164925">"எல்லா அறிவிப்புகளையும் அழி."</string> <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string> - <string name="notification_group_overflow_indicator_ambient" msgid="879560382990377886">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>, +<xliff:g id="OVERFLOW">%2$s</xliff:g>"</string> <plurals name="notification_group_overflow_description" formatted="false" msgid="4579313201268495404"> <item quantity="other">உள்ளே மேலும் <xliff:g id="NUMBER_1">%s</xliff:g> அறிவிப்புகள் உள்ளன.</item> <item quantity="one">உள்ளே மேலும் <xliff:g id="NUMBER_0">%s</xliff:g> அறிவிப்பு உள்ளது.</item> @@ -286,7 +291,8 @@ <string name="start_dreams" msgid="5640361424498338327">"ஸ்கிரீன் சேவர்"</string> <string name="ethernet_label" msgid="7967563676324087464">"ஈதர்நெட்"</string> <string name="quick_settings_header_onboarding_text" msgid="8030309023792936283">"மேலும் விருப்பங்களைக் காண, ஐகான்களைத் தொட்டுப் பிடிக்கவும்"</string> - <string name="quick_settings_dnd_label" msgid="8735855737575028208">"தொந்தரவு செய்யாதே"</string> + <!-- no translation found for quick_settings_dnd_label (7112342227663678739) --> + <skip /> <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"முதன்மை மட்டும்"</string> <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"அலாரங்கள் மட்டும்"</string> <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"அறிவிப்புகள் வேண்டாம்"</string> @@ -437,8 +443,10 @@ <string name="battery_saver_notification_title" msgid="8614079794522291840">"பேட்டரி சேமிப்பான் ஆன் செய்யப்பட்டுள்ளது"</string> <string name="battery_saver_notification_text" msgid="820318788126672692">"செயல்திறனையும் பின்புல டேட்டா உபயோகத்தையும் குறைக்கிறது"</string> <string name="battery_saver_notification_action_text" msgid="132118784269455533">"பேட்டரி சேமிப்பானை ஆஃப் செய்"</string> - <string name="media_projection_dialog_text" msgid="1443042478990422751">"உங்கள் திரையில் தோன்றும் அறிவிப்புகள், கடவுச்சொற்கள், படங்கள், மெசேஜ்கள் மற்றும் கட்டணத் தகவல் போன்ற அனைத்தையும் <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> காட்டத் தொடங்கும்."</string> - <string name="media_projection_dialog_title" msgid="7574971526813630219">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> உங்கள் திரையை ரெக்கார்டு செய்யவோ அலைபரப்பவோ அனுமதிக்கவா?"</string> + <!-- no translation found for media_projection_dialog_text (5751657130671431216) --> + <skip /> + <!-- no translation found for media_projection_dialog_title (8124184308671641248) --> + <skip /> <string name="media_projection_remember_text" msgid="3103510882172746752">"மீண்டும் காட்டாதே"</string> <string name="clear_all_notifications_text" msgid="814192889771462828">"எல்லாவற்றையும் அழி"</string> <string name="manage_notifications_text" msgid="2386728145475108753">"அறிவிப்புகளை நிர்வகி"</string> @@ -513,6 +521,10 @@ <string name="accessibility_volume_settings" msgid="4915364006817819212">"ஒலி அமைப்புகள்"</string> <string name="accessibility_volume_expand" msgid="5946812790999244205">"விரிவாக்கு"</string> <string name="accessibility_volume_collapse" msgid="3609549593031810875">"சுருக்கு"</string> + <!-- no translation found for volume_odi_captions_tip (1193653197906918269) --> + <skip /> + <!-- no translation found for accessibility_volume_close_odi_captions_tip (1163987066404128967) --> + <skip /> <string name="accessibility_output_chooser" msgid="8185317493017988680">"வெளியீட்டுச் சாதனத்தை மாற்றுதல்"</string> <string name="screen_pinning_title" msgid="3273740381976175811">"திரை பொருத்தப்பட்டது"</string> <string name="screen_pinning_description" msgid="8909878447196419623">"பொருத்தியதை அகற்றும் வரை இதைக் காட்சியில் வைக்கும். அகற்ற, முந்தையது மற்றும் மேலோட்டப் பார்வையைத் தொட்டுப் பிடிக்கவும்."</string> @@ -613,6 +625,8 @@ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"இந்த அறிவிப்புகள் விழிப்பூட்டலாக அமையும்"</string> <string name="inline_blocking_helper" msgid="3055064577771478591">"வழக்கமாக, இந்த அறிவிப்புகளை நிராகரிக்கிறீர்கள். \nதொடர்ந்து இவற்றைக் காட்டலாமா?"</string> <string name="inline_done_button" msgid="492513001558716452">"முடிந்தது"</string> + <!-- no translation found for inline_ok_button (966006867967928987) --> + <skip /> <string name="inline_keep_showing" msgid="8945102997083836858">"இந்த அறிவிப்புகளைத் தொடர்ந்து காட்டவா?"</string> <string name="inline_stop_button" msgid="4172980096860941033">"அறிவிப்புகளை நிறுத்து"</string> <string name="inline_deliver_silently_button" msgid="7756289895745629140">"ஒலியின்றி அறிவிப்புகளை வழங்கு"</string> @@ -621,9 +635,16 @@ <string name="inline_minimize_button" msgid="966233327974702195">"சிறிதாக்கு"</string> <string name="inline_silent_button_silent" msgid="4411510650503783646">"ஒலிக்காமல் காட்டு"</string> <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"அறிவிப்புகளை ஒலியின்றிக் காட்டு"</string> - <string name="inline_silent_button_alert" msgid="7961887853830826523">"எனக்கு விழிப்பூட்டலை அனுப்பு"</string> + <!-- no translation found for inline_silent_button_alert (2273030946176140380) --> + <skip /> <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"தொடர்ந்து விழிப்பூட்டு"</string> <string name="inline_keep_showing_app" msgid="1723113469580031041">"இந்தப் பயன்பாட்டின் அறிவிப்புகளைத் தொடர்ந்து காட்டவா?"</string> + <!-- no translation found for hint_text_block (3554459167504485284) --> + <skip /> + <!-- no translation found for hint_text_silent (859468056340177016) --> + <skip /> + <!-- no translation found for hint_text_alert (428122667751463119) --> + <skip /> <string name="notification_unblockable_desc" msgid="1037434112919403708">"இந்த அறிவிப்புகளை ஆஃப் செய்ய முடியாது"</string> <string name="notification_delegate_header" msgid="9167022191405284627">"<xliff:g id="APP_NAME">%1$s</xliff:g> மூலமாக"</string> <string name="appops_camera" msgid="8100147441602585776">"இந்த ஆப்ஸானது கேமராவை உபயோகிக்கிறது."</string> @@ -703,9 +724,11 @@ <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"கேலெண்டர்"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"ஒலிக் கட்டுப்பாடுகளுடன் காட்டு"</string> - <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"தொந்தரவு செய்யாதே"</string> + <!-- no translation found for volume_and_do_not_disturb (1750270820297253561) --> + <skip /> <string name="volume_dnd_silent" msgid="4363882330723050727">"ஒலியளவுப் பொத்தான்களுக்கான ஷார்ட்கட்"</string> - <string name="volume_up_silent" msgid="7141255269783588286">"ஒலியைக் கூட்டும் போது தொந்தரவு செய்ய வேண்டாம் என்பதை முடக்கு"</string> + <!-- no translation found for volume_up_silent (7545869833038212815) --> + <skip /> <string name="battery" msgid="7498329822413202973">"பேட்டரி"</string> <string name="clock" msgid="7416090374234785905">"கடிகாரம்"</string> <string name="headset" msgid="4534219457597457353">"ஹெட்செட்"</string> @@ -875,17 +898,8 @@ <string name="open_saver_setting_action" msgid="8314624730997322529">"அமைப்புகள்"</string> <string name="auto_saver_okay_action" msgid="2701221740227683650">"சரி"</string> <string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string> - <plurals name="ongoing_privacy_chip_multiple_apps" formatted="false" msgid="1406406529558080714"> - <item quantity="other"><xliff:g id="NUM_APPS_2">%d</xliff:g> ஆப்ஸ்</item> - <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> ஆப்ஸ்</item> - </plurals> <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"உங்கள் <xliff:g id="TYPES_LIST">%2$s</xliff:g>ஐ <xliff:g id="APP">%1$s</xliff:g> ஆப்ஸ் பயன்படுத்துகிறது."</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"உங்கள் <xliff:g id="TYPES_LIST">%s</xliff:g> ஆகியவற்றை ஆப்ஸ் பயன்படுத்துகின்றன."</string> - <string name="ongoing_privacy_chip_in_use" msgid="5174331553211609272">"செயலில்:"</string> - <plurals name="ongoing_privacy_chip_content_multiple_apps_single_op" formatted="false" msgid="4871926099254314088"> - <item quantity="other"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> ஆப்ஸால் உங்கள் <xliff:g id="TYPE_5">%2$s</xliff:g> பயன்படுத்தப் படுகிறது.</item> - <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> ஆப்ஸால் உங்கள் <xliff:g id="TYPE_1">%2$s</xliff:g> பயன்படுத்தப் படுகிறது.</item> - </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"சரி"</string> <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"தனியுரிமை அமைப்புகள்"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"உங்கள் <xliff:g id="TYPES_LIST">%s</xliff:g> ஆகியவற்றைப் பயன்படுத்தும் ஆப்ஸ்"</string> @@ -895,16 +909,33 @@ <string name="privacy_type_camera" msgid="1676604631892420333">"கேமரா"</string> <string name="privacy_type_location" msgid="6435497989657286700">"இருப்பிடம்"</string> <string name="privacy_type_microphone" msgid="4153045784928554506">"மைக்ரோஃபோன்"</string> - <plurals name="ongoing_privacy_dialog_overflow_text" formatted="false" msgid="3441296594927649172"> - <item quantity="other">வேறு <xliff:g id="NUM_APPS_1">%d</xliff:g> ஆப்ஸ்</item> - <item quantity="one">வேறு <xliff:g id="NUM_APPS_0">%d</xliff:g> ஆப்ஸ்</item> - </plurals> <string name="sensor_privacy_mode" msgid="8982771253020769598">"சென்சார்களை ஆஃப் செய்தல்"</string> <string name="device_services" msgid="1191212554435440592">"சாதன சேவைகள்"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"தலைப்பு இல்லை"</string> + <!-- no translation found for restart_button_description (2035077840254950187) --> + <skip /> <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸைத் திறக்கும்"</string> - <string name="bubbles_settings_button_description" msgid="1940331766151865776">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸிற்கான அறிவிப்பு அமைப்புகளைத் திறக்கும்"</string> - <string name="bubbles_prompt" msgid="2684301469286150276">"இந்த ஆப்ஸிற்குக் குமிழை அனுமதிக்கவா?"</string> - <string name="no_bubbles" msgid="7173621233904687258">"வேண்டாம்"</string> + <!-- no translation found for bubbles_settings_button_description (2970630476657287189) --> + <skip /> + <!-- no translation found for bubbles_prompt (8807968030159469710) --> + <skip /> + <!-- no translation found for no_bubbles (337101288173078247) --> + <skip /> <string name="yes_bubbles" msgid="668809525728633841">"அனுமதி"</string> + <!-- no translation found for ask_me_later_bubbles (2147688438402939029) --> + <skip /> + <!-- no translation found for bubble_content_description_single (1184462974339387516) --> + <skip /> + <!-- no translation found for bubble_content_description_stack (8666349184095622232) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move (1794879742234803840) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_left (104736832249802724) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_right (1671844272347036806) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_left (206369104473183217) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_right (8705660152384312329) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 67970eb3ea91..a353286c535c 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -108,12 +108,13 @@ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Mở khóa không dùng vân tay của bạn"</string> <string name="accessibility_scanning_face" msgid="769545173211758586">"Quét tìm khuôn mặt"</string> <string name="accessibility_send_smart_reply" msgid="7766727839703044493">"Gửi"</string> + <!-- no translation found for accessibility_manage_notification (2026361503393549753) --> + <skip /> <string name="unlock_label" msgid="8779712358041029439">"mở khóa"</string> <string name="phone_label" msgid="2320074140205331708">"mở điện thoại"</string> <string name="voice_assist_label" msgid="3956854378310019854">"mở trợ lý thoại"</string> <string name="camera_label" msgid="7261107956054836961">"mở máy ảnh"</string> <string name="cancel" msgid="6442560571259935130">"Hủy"</string> - <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Vùng thông báo trợ giúp"</string> <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Xác nhận"</string> <string name="biometric_dialog_try_again" msgid="1900185172633183201">"Thử lại"</string> <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Chạm vào cảm biến vân tay"</string> @@ -179,6 +180,8 @@ <string name="accessibility_cell_data" msgid="5326139158682385073">"Dữ liệu di động"</string> <string name="accessibility_cell_data_on" msgid="5927098403452994422">"Dữ liệu di động đang bật"</string> <string name="cell_data_off_content_description" msgid="4356113230238585072">"Đã tắt dữ liệu di động"</string> + <!-- no translation found for not_default_data_content_description (9194667237765917844) --> + <skip /> <string name="cell_data_off" msgid="1051264981229902873">"Tắt"</string> <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Chia sẻ kết nối Internet qua Bluetooth"</string> <string name="accessibility_airplane_mode" msgid="834748999790763092">"Chế độ trên máy bay."</string> @@ -220,9 +223,12 @@ <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"Đã bật chế độ trên máy bay."</string> <string name="accessibility_quick_settings_dnd_none_on" msgid="2960643943620637020">"hoàn toàn tắt tiếng"</string> <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3357131899365865386">"chỉ báo thức"</string> - <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"Không làm phiền."</string> - <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"Đã tắt tính năng không làm phiền."</string> - <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"Đã bật tính năng không làm phiền."</string> + <!-- no translation found for accessibility_quick_settings_dnd (5555155552520665891) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_off (2757071272328547807) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_dnd_changed_on (6808220653747701059) --> + <skip /> <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"Bluetooth."</string> <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"Bluetooth tắt."</string> <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"Bluetooth bật."</string> @@ -269,7 +275,6 @@ <string name="accessibility_location_active" msgid="2427290146138169014">"Yêu cầu về thông tin vị trí đang hoạt động"</string> <string name="accessibility_clear_all" msgid="5235938559247164925">"Xóa tất cả thông báo."</string> <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string> - <string name="notification_group_overflow_indicator_ambient" msgid="879560382990377886">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>, +<xliff:g id="OVERFLOW">%2$s</xliff:g>"</string> <plurals name="notification_group_overflow_description" formatted="false" msgid="4579313201268495404"> <item quantity="other">Còn <xliff:g id="NUMBER_1">%s</xliff:g> thông báo nữa bên trong.</item> <item quantity="one">Còn <xliff:g id="NUMBER_0">%s</xliff:g> thông báo nữa bên trong.</item> @@ -286,7 +291,8 @@ <string name="start_dreams" msgid="5640361424498338327">"Trình bảo vệ m.hình"</string> <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string> <string name="quick_settings_header_onboarding_text" msgid="8030309023792936283">"Chạm và giữ các biểu tượng để xem thêm tùy chọn khác"</string> - <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Không làm phiền"</string> + <!-- no translation found for quick_settings_dnd_label (7112342227663678739) --> + <skip /> <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Chỉ ưu tiên"</string> <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Chỉ báo thức"</string> <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Hoàn toàn tắt tiếng"</string> @@ -437,8 +443,10 @@ <string name="battery_saver_notification_title" msgid="8614079794522291840">"Trình tiết kiệm pin đang bật"</string> <string name="battery_saver_notification_text" msgid="820318788126672692">"Giảm hiệu suất và dữ liệu nền"</string> <string name="battery_saver_notification_action_text" msgid="132118784269455533">"Tắt trình tiết kiệm pin"</string> - <string name="media_projection_dialog_text" msgid="1443042478990422751">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sẽ bắt đầu chụp mọi thứ trên màn hình của bạn, bao gồm cả thông báo, mật khẩu, ảnh, tin nhắn và thông tin thanh toán."</string> - <string name="media_projection_dialog_title" msgid="7574971526813630219">"Bạn có muốn cho phép <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ghi hoặc truyền màn hình của bạn không?"</string> + <!-- no translation found for media_projection_dialog_text (5751657130671431216) --> + <skip /> + <!-- no translation found for media_projection_dialog_title (8124184308671641248) --> + <skip /> <string name="media_projection_remember_text" msgid="3103510882172746752">"Không hiển thị lại"</string> <string name="clear_all_notifications_text" msgid="814192889771462828">"Xóa tất cả"</string> <string name="manage_notifications_text" msgid="2386728145475108753">"Quản lý"</string> @@ -513,6 +521,10 @@ <string name="accessibility_volume_settings" msgid="4915364006817819212">"Cài đặt âm thanh"</string> <string name="accessibility_volume_expand" msgid="5946812790999244205">"Mở rộng"</string> <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Thu gọn"</string> + <!-- no translation found for volume_odi_captions_tip (1193653197906918269) --> + <skip /> + <!-- no translation found for accessibility_volume_close_odi_captions_tip (1163987066404128967) --> + <skip /> <string name="accessibility_output_chooser" msgid="8185317493017988680">"Chuyển đổi thiết bị đầu ra"</string> <string name="screen_pinning_title" msgid="3273740381976175811">"Màn hình được ghim"</string> <string name="screen_pinning_description" msgid="8909878447196419623">"Thao tác này sẽ duy trì hiển thị màn hình cho đến khi bạn bỏ ghim. Hãy chạm và giữ Quay lại và Tổng quan để bỏ ghim."</string> @@ -613,6 +625,8 @@ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"Các thông báo này sẽ phát âm báo cho bạn"</string> <string name="inline_blocking_helper" msgid="3055064577771478591">"Bạn thường bỏ qua những thông báo này. \nTiếp tục hiển thị thông báo?"</string> <string name="inline_done_button" msgid="492513001558716452">"Xong"</string> + <!-- no translation found for inline_ok_button (966006867967928987) --> + <skip /> <string name="inline_keep_showing" msgid="8945102997083836858">"Tiếp tục hiển thị các thông báo này?"</string> <string name="inline_stop_button" msgid="4172980096860941033">"Dừng thông báo"</string> <string name="inline_deliver_silently_button" msgid="7756289895745629140">"Gửi mà không phát âm báo"</string> @@ -621,9 +635,16 @@ <string name="inline_minimize_button" msgid="966233327974702195">"Thu nhỏ"</string> <string name="inline_silent_button_silent" msgid="4411510650503783646">"Hiển thị không phát âm báo"</string> <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Tiếp tục chế độ im lặng"</string> - <string name="inline_silent_button_alert" msgid="7961887853830826523">"Cảnh báo cho tôi"</string> + <!-- no translation found for inline_silent_button_alert (2273030946176140380) --> + <skip /> <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Tiếp tục cảnh báo"</string> <string name="inline_keep_showing_app" msgid="1723113469580031041">"Tiếp tục hiển thị các thông báo từ ứng dụng này?"</string> + <!-- no translation found for hint_text_block (3554459167504485284) --> + <skip /> + <!-- no translation found for hint_text_silent (859468056340177016) --> + <skip /> + <!-- no translation found for hint_text_alert (428122667751463119) --> + <skip /> <string name="notification_unblockable_desc" msgid="1037434112919403708">"Không thể tắt các thông báo này"</string> <string name="notification_delegate_header" msgid="9167022191405284627">"thông qua <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="appops_camera" msgid="8100147441602585776">"Ứng dụng này đang sử dụng máy ảnh."</string> @@ -703,9 +724,11 @@ <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Lịch"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Hiển thị với các điều khiển âm lượng"</string> - <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Không làm phiền"</string> + <!-- no translation found for volume_and_do_not_disturb (1750270820297253561) --> + <skip /> <string name="volume_dnd_silent" msgid="4363882330723050727">"Phím tắt các nút âm lượng"</string> - <string name="volume_up_silent" msgid="7141255269783588286">"Thoát không làm phiền khi tăng âm lượng"</string> + <!-- no translation found for volume_up_silent (7545869833038212815) --> + <skip /> <string name="battery" msgid="7498329822413202973">"Pin"</string> <string name="clock" msgid="7416090374234785905">"Đồng hồ"</string> <string name="headset" msgid="4534219457597457353">"Tai nghe"</string> @@ -875,17 +898,8 @@ <string name="open_saver_setting_action" msgid="8314624730997322529">"Cài đặt"</string> <string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string> <string name="heap_dump_tile_name" msgid="9141031328971226374">"Trích xuất bộ nhớ SysUI"</string> - <plurals name="ongoing_privacy_chip_multiple_apps" formatted="false" msgid="1406406529558080714"> - <item quantity="other"><xliff:g id="NUM_APPS_2">%d</xliff:g> ứng dụng</item> - <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> ứng dụng</item> - </plurals> <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> đang dùng <xliff:g id="TYPES_LIST">%2$s</xliff:g> của bạn."</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Các ứng dụng đang dùng <xliff:g id="TYPES_LIST">%s</xliff:g> của bạn."</string> - <string name="ongoing_privacy_chip_in_use" msgid="5174331553211609272">"Đang dùng:"</string> - <plurals name="ongoing_privacy_chip_content_multiple_apps_single_op" formatted="false" msgid="4871926099254314088"> - <item quantity="other"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> ứng dụng đang dùng <xliff:g id="TYPE_5">%2$s</xliff:g> của bạn.</item> - <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> ứng dụng đang dùng <xliff:g id="TYPE_1">%2$s</xliff:g> của bạn.</item> - </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"OK"</string> <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Cài đặt quyền riêng tư"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Ứng dụng đang sử dụng <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> @@ -895,16 +909,33 @@ <string name="privacy_type_camera" msgid="1676604631892420333">"máy ảnh"</string> <string name="privacy_type_location" msgid="6435497989657286700">"vị trí"</string> <string name="privacy_type_microphone" msgid="4153045784928554506">"micrô"</string> - <plurals name="ongoing_privacy_dialog_overflow_text" formatted="false" msgid="3441296594927649172"> - <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> ứng dụng khác</item> - <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> ứng dụng khác</item> - </plurals> <string name="sensor_privacy_mode" msgid="8982771253020769598">"Tắt cảm biến"</string> <string name="device_services" msgid="1191212554435440592">"Dịch vụ cho thiết bị"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Không có tiêu đề"</string> + <!-- no translation found for restart_button_description (2035077840254950187) --> + <skip /> <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Mở <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> - <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Mở mục cài đặt thông báo dành cho <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> - <string name="bubbles_prompt" msgid="2684301469286150276">"Bạn có muốn bật bong bóng từ ứng dụng này không?"</string> - <string name="no_bubbles" msgid="7173621233904687258">"Chặn"</string> + <!-- no translation found for bubbles_settings_button_description (2970630476657287189) --> + <skip /> + <!-- no translation found for bubbles_prompt (8807968030159469710) --> + <skip /> + <!-- no translation found for no_bubbles (337101288173078247) --> + <skip /> <string name="yes_bubbles" msgid="668809525728633841">"Cho phép"</string> + <!-- no translation found for ask_me_later_bubbles (2147688438402939029) --> + <skip /> + <!-- no translation found for bubble_content_description_single (1184462974339387516) --> + <skip /> + <!-- no translation found for bubble_content_description_stack (8666349184095622232) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move (1794879742234803840) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_left (104736832249802724) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_top_right (1671844272347036806) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_left (206369104473183217) --> + <skip /> + <!-- no translation found for bubble_accessibility_action_move_bottom_right (8705660152384312329) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml index 27d2bcdc05b4..e0bcf2435948 100644 --- a/packages/SystemUI/res/values/attrs.xml +++ b/packages/SystemUI/res/values/attrs.xml @@ -146,5 +146,9 @@ <attr name="showAirplaneMode" format="boolean" /> </declare-styleable> + <declare-styleable name="CaptionsToggleImageButton"> + <attr name="optedOut" format="boolean" /> + </declare-styleable> + </resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 27cebcc112ac..1da1405f469a 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -206,10 +206,10 @@ <dimen name="status_bar_icon_padding">0dp</dimen> <!-- the padding on the start of the statusbar --> - <dimen name="status_bar_padding_start">6dp</dimen> + <dimen name="status_bar_padding_start">8dp</dimen> <!-- the padding on the end of the statusbar --> - <dimen name="status_bar_padding_end">6dp</dimen> + <dimen name="status_bar_padding_end">8dp</dimen> <!-- the radius of the overflow dot in the status bar --> <dimen name="overflow_dot_radius">2dp</dimen> @@ -433,7 +433,7 @@ <dimen name="qs_detail_item_icon_marginEnd">20dp</dimen> <dimen name="qs_header_tooltip_height">18dp</dimen> <dimen name="qs_header_alarm_icon_size">18dp</dimen> - <dimen name="qs_header_mobile_icon_size">18dp</dimen> + <dimen name="qs_header_mobile_icon_size">@dimen/status_bar_icon_drawing_size</dimen> <dimen name="qs_header_alarm_text_margin_start">6dp</dimen> <dimen name="qs_header_separator_width">8dp</dimen> <dimen name="qs_header_carrier_separator_width">6dp</dimen> @@ -442,7 +442,8 @@ <dimen name="qs_footer_padding_start">16dp</dimen> <dimen name="qs_footer_padding_end">16dp</dimen> <dimen name="qs_footer_icon_size">16dp</dimen> - <dimen name="qs_paged_tile_layout_padding_bottom">16dp</dimen> + <dimen name="qs_paged_tile_layout_padding_bottom">0dp</dimen> + <dimen name="qs_header_top_margin">12dp</dimen> <dimen name="qs_notif_collapsed_space">64dp</dimen> diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml index 05cf040a3772..501b1b56a848 100644 --- a/packages/SystemUI/res/values/ids.xml +++ b/packages/SystemUI/res/values/ids.xml @@ -111,13 +111,14 @@ <!-- Optional cancel button on Keyguard --> <item type="id" name="cancel_button"/> - <!-- For saving DynamicAnimation physics animations as view tags. --> + <!-- For saving PhysicsAnimationLayout animations/animators as view tags. --> <item type="id" name="translation_x_dynamicanimation_tag"/> <item type="id" name="translation_y_dynamicanimation_tag"/> <item type="id" name="translation_z_dynamicanimation_tag"/> <item type="id" name="alpha_dynamicanimation_tag"/> <item type="id" name="scale_x_dynamicanimation_tag"/> <item type="id" name="scale_y_dynamicanimation_tag"/> + <item type="id" name="physics_animator_tag"/> <!-- Global Actions Menu --> <item type="id" name="global_actions_view" /> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index f8bec4a309b8..aca99e3cfae1 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -165,6 +165,12 @@ <!-- Message of USB contaminant presence dialog [CHAR LIMIT=NONE] --> <string name="usb_contaminant_message">To protect your device from liquid or debris, the USB port is disabled and won\u2019t detect any accessories.\n\nYou\u2019ll be notified when it\u2019s safe to use the USB port again.</string> + <!-- Toast for enabling ports from USB contaminant dialog [CHAR LIMIT=NONE] --> + <string name="usb_port_enabled">USB port enabled to detect chargers and accessories</string> + + <!-- Button text to disable contaminant detection [CHAR LIMIT=NONE] --> + <string name="usb_disable_contaminant_detection">Enable USB</string> + <!-- Checkbox label for application compatibility mode ON (zooming app to look like it's running on a phone). [CHAR LIMIT=25] --> <string name="compat_mode_on">Zoom to fill screen</string> @@ -279,8 +285,6 @@ <!-- Button name for "Cancel". [CHAR LIMIT=NONE] --> <string name="cancel">Cancel</string> - <!-- Content description for the error/help message are when the system-provided fingerprint dialog is showing, for accessibility (not shown on the screen). [CHAR LIMIT=NONE] --> - <string name="accessibility_biometric_dialog_help_area">Help message area</string> <!-- Message shown when a biometric is authenticated, asking the user to confirm authentication [CHAR LIMIT=30] --> <string name="biometric_dialog_confirm">Confirm</string> <!-- Button name on BiometricPrompt shown when a biometric is detected but not authenticated. Tapping the button resumes authentication [CHAR_LIMIT=30] --> @@ -551,11 +555,11 @@ <!-- Content description of the do not disturb tile in quick settings when on in alarms only (not shown on the screen). [CHAR LIMIT=NONE] --> <string name="accessibility_quick_settings_dnd_alarms_on">alarms only</string> <!-- Content description of the do not disturb tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] --> - <string name="accessibility_quick_settings_dnd">Do not disturb.</string> + <string name="accessibility_quick_settings_dnd">Do Not Disturb.</string> <!-- Announcement made when do not disturb changes to off (not shown on the screen). [CHAR LIMIT=NONE] --> - <string name="accessibility_quick_settings_dnd_changed_off">Do not disturb turned off.</string> + <string name="accessibility_quick_settings_dnd_changed_off">Do Not Disturb turned off.</string> <!-- Announcement made when do not disturb changes to on (not shown on the screen). [CHAR LIMIT=NONE] --> - <string name="accessibility_quick_settings_dnd_changed_on">Do not disturb turned on.</string> + <string name="accessibility_quick_settings_dnd_changed_on">Do Not Disturb turned on.</string> <!-- Content description of the bluetooth tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] --> <string name="accessibility_quick_settings_bluetooth">Bluetooth.</string> <!-- Content description of the bluetooth tile in quick settings when off (not shown on the screen). [CHAR LIMIT=NONE] --> @@ -701,7 +705,7 @@ <!-- QuickSettings: Onboarding text that introduces users to long press on an option in order to view the option's menu in Settings [CHAR LIMIT=NONE] --> <string name="quick_settings_header_onboarding_text">Touch & hold icons for more options</string> <!-- QuickSettings: Do not disturb [CHAR LIMIT=NONE] --> - <string name="quick_settings_dnd_label">Do not disturb</string> + <string name="quick_settings_dnd_label">Do Not Disturb</string> <!-- QuickSettings: Do not disturb - Priority only [CHAR LIMIT=NONE] --> <string name="quick_settings_dnd_priority_label">Priority only</string> <!-- QuickSettings: Do not disturb - Alarms only [CHAR LIMIT=NONE] --> @@ -1816,14 +1820,14 @@ <string name="tuner_full_zen_title">Show with volume controls</string> <!-- SysUI Tuner: Label for screen about do not disturb settings [CHAR LIMIT=60] --> - <string name="volume_and_do_not_disturb">Do not disturb</string> + <string name="volume_and_do_not_disturb">Do Not Disturb</string> <!-- SysUI Tuner: Switch to control whether volume buttons enter/exit do not disturb [CHAR LIMIT=60] --> <string name="volume_dnd_silent">Volume buttons shortcut</string> <!-- SysUI Tuner: Switch to control volume up behavior [CHAR LIMIT=60] --> - <string name="volume_up_silent">Exit do not disturb on volume up</string> + <string name="volume_up_silent">Exit Do Not Disturb on volume up</string> <!-- Name of the battery icon in status bar [CHAR LIMIT=30] --> <string name="battery">Battery</string> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 1c13750a1340..a6a6e6b6fea2 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -353,13 +353,13 @@ <style name="AutoSizingList"> <item name="enableAutoSizing">true</item> </style> - <style name="Theme.AlertDialogHost" parent="android:Theme.DeviceDefault"> + <style name="Theme.MediaProjectionAlertDialog" parent="android:Theme.DeviceDefault"> <item name="android:windowIsTranslucent">true</item> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowContentOverlay">@null</item> <item name="android:windowNoTitle">true</item> <item name="android:windowIsFloating">true</item> - <item name="android:backgroundDimEnabled">false</item> + <item name="android:backgroundDimEnabled">true</item> <item name="android:alertDialogTheme">@style/Theme.SystemUI.Dialog.Alert</item> </style> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java index b363b4a242e1..8d6f830c6d8e 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java @@ -21,12 +21,8 @@ import android.annotation.IntDef; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -/** - * TODO: Remove this class - */ public class NavigationBarCompat extends QuickStepContract { - @Retention(RetentionPolicy.SOURCE) @IntDef({HIT_TARGET_NONE, HIT_TARGET_BACK, HIT_TARGET_HOME, HIT_TARGET_OVERVIEW}) public @interface HitTarget{} @@ -59,4 +55,6 @@ public class NavigationBarCompat extends QuickStepContract { * Interaction type: show/hide the overview button while this service is connected to launcher */ public static final int FLAG_SHOW_OVERVIEW_BUTTON = 0x4; + + } diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java index 6d7abd089861..46f4c8689196 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java @@ -16,7 +16,13 @@ package com.android.systemui.shared.system; +import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON; +import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON; +import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL; + +import android.content.Context; import android.content.res.Resources; +import android.view.WindowManagerPolicyConstants; /** * Various shared constants between Launcher and SysUI as part of quickstep @@ -28,6 +34,13 @@ public class QuickStepContract { public static final String KEY_EXTRA_WINDOW_CORNER_RADIUS = "extra_window_corner_radius"; public static final String KEY_EXTRA_SUPPORTS_WINDOW_CORNERS = "extra_supports_window_corners"; + public static final String NAV_BAR_MODE_2BUTTON_OVERLAY = + WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON_OVERLAY; + public static final String NAV_BAR_MODE_3BUTTON_OVERLAY = + WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY; + public static final String NAV_BAR_MODE_GESTURAL_OVERLAY = + WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY; + /** * Touch slopes and thresholds for quick step operations. Drag slop is the point where the * home button press/long press over are ignored and will start to drag when exceeded and the @@ -49,4 +62,54 @@ public class QuickStepContract { private static int convertDpToPixel(float dp) { return (int) (dp * Resources.getSystem().getDisplayMetrics().density); } + + /** + * @return whether this nav bar mode is edge to edge + */ + public static boolean isGesturalMode(int mode) { + return mode == NAV_BAR_MODE_GESTURAL; + } + + /** + * @return whether the current nav bar mode is gestural + */ + public static boolean isGesturalMode(Context context) { + return isGesturalMode(getCurrentInteractionMode(context)); + } + + /** + * @return whether this nav bar mode is swipe up + */ + public static boolean isSwipeUpMode(int mode) { + return mode == NAV_BAR_MODE_2BUTTON; + } + + /** + * @return whether the current nav bar mode is swipe up + */ + public static boolean isSwipeUpMode(Context context) { + return isSwipeUpMode(getCurrentInteractionMode(context)); + } + + /** + * @return whether this nav bar mode is 3 button + */ + public static boolean isLegacyMode(int mode) { + return mode == NAV_BAR_MODE_3BUTTON; + } + + /** + * @return whether this nav bar mode is 3 button + */ + public static boolean isLegacyMode(Context context) { + return isLegacyMode(getCurrentInteractionMode(context)); + } + + /** + * @return the current nav bar interaction mode + */ + public static int getCurrentInteractionMode(Context context) { + return context.getResources().getInteger( + com.android.internal.R.integer.config_navBarInteractionMode); + } } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java index ce65b5a3a3a3..fd92e9e72d2e 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java @@ -1,5 +1,7 @@ package com.android.keyguard; +import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT; + import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; @@ -24,8 +26,8 @@ import android.widget.TextClock; import androidx.annotation.VisibleForTesting; import com.android.internal.colorextraction.ColorExtractor; +import com.android.internal.colorextraction.ColorExtractor.OnColorsChangedListener; import com.android.keyguard.clock.ClockManager; -import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.plugins.ClockPlugin; @@ -37,37 +39,65 @@ import java.io.PrintWriter; import java.util.Arrays; import java.util.TimeZone; +import javax.inject.Inject; +import javax.inject.Named; + /** * Switch to show plugin clock when plugin is connected, otherwise it will show default clock. */ public class KeyguardClockSwitch extends RelativeLayout { + /** + * Controller used to track StatusBar state to know when to show the big_clock_container. + */ + private final StatusBarStateController mStatusBarStateController; + + /** + * Color extractor used to apply colors from wallpaper to custom clock faces. + */ + private final SysuiColorExtractor mSysuiColorExtractor; + + /** + * Manager used to know when to show a custom clock face. + */ + private final ClockManager mClockManager; + + /** + * Layout transition that scales the default clock face. + */ private final Transition mTransition; + /** * Optional/alternative clock injected via plugin. */ private ClockPlugin mClockPlugin; + /** * Default clock. */ private TextClock mClockView; + /** * Frame for default and custom clock. */ private FrameLayout mSmallClockFrame; + /** * Container for big custom clock. */ private ViewGroup mBigClockContainer; + /** * Status area (date and other stuff) shown below the clock. Plugin can decide whether or not to * show it below the alternate clock. */ private View mKeyguardStatusArea; + /** * Maintain state so that a newly connected plugin can be initialized. */ private float mDarkAmount; + /** * If the Keyguard Slice has a header (big center-aligned text.) */ @@ -96,22 +126,20 @@ public class KeyguardClockSwitch extends RelativeLayout { * * The color palette changes when the wallpaper is changed. */ - private SysuiColorExtractor.OnColorsChangedListener mColorsListener = (extractor, which) -> { + private final OnColorsChangedListener mColorsListener = (extractor, which) -> { if ((which & WallpaperManager.FLAG_LOCK) != 0) { - if (extractor instanceof SysuiColorExtractor) { - updateColors((SysuiColorExtractor) extractor); - } else { - updateColors(Dependency.get(SysuiColorExtractor.class)); - } + updateColors(); } }; - public KeyguardClockSwitch(Context context) { - this(context, null); - } - - public KeyguardClockSwitch(Context context, AttributeSet attrs) { + @Inject + public KeyguardClockSwitch(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs, + StatusBarStateController statusBarStateController, SysuiColorExtractor colorExtractor, + ClockManager clockManager) { super(context, attrs); + mStatusBarStateController = statusBarStateController; + mSysuiColorExtractor = colorExtractor; + mClockManager = clockManager; mTransition = new ClockBoundsTransition(); } @@ -133,22 +161,18 @@ public class KeyguardClockSwitch extends RelativeLayout { @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); - Dependency.get(ClockManager.class).addOnClockChangedListener(mClockChangedListener); - StatusBarStateController stateController = Dependency.get(StatusBarStateController.class); - stateController.addCallback(mStateListener); - mStateListener.onStateChanged(stateController.getState()); - SysuiColorExtractor colorExtractor = Dependency.get(SysuiColorExtractor.class); - colorExtractor.addOnColorsChangedListener(mColorsListener); - updateColors(colorExtractor); + mClockManager.addOnClockChangedListener(mClockChangedListener); + mStatusBarStateController.addCallback(mStateListener); + mSysuiColorExtractor.addOnColorsChangedListener(mColorsListener); + updateColors(); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); - Dependency.get(ClockManager.class).removeOnClockChangedListener(mClockChangedListener); - Dependency.get(StatusBarStateController.class).removeCallback(mStateListener); - Dependency.get(SysuiColorExtractor.class) - .removeOnColorsChangedListener(mColorsListener); + mClockManager.removeOnClockChangedListener(mClockChangedListener); + mStatusBarStateController.removeCallback(mStateListener); + mSysuiColorExtractor.removeOnColorsChangedListener(mColorsListener); setClockPlugin(null); } @@ -271,14 +295,11 @@ public class KeyguardClockSwitch extends RelativeLayout { return mClockView.getTextSize(); } - public void refresh() { - mClockView.refresh(); - } - /** - * Notifies that time tick alarm from doze service fired. + * Refresh the time of the clock, due to either time tick broadcast or doze time tick alarm. */ - public void dozeTimeTick() { + public void refresh() { + mClockView.refresh(); if (mClockPlugin != null) { mClockPlugin.onTimeTick(); } @@ -293,9 +314,9 @@ public class KeyguardClockSwitch extends RelativeLayout { } } - private void updateColors(SysuiColorExtractor colorExtractor) { - ColorExtractor.GradientColors colors = colorExtractor.getColors(WallpaperManager.FLAG_LOCK, - true); + private void updateColors() { + ColorExtractor.GradientColors colors = mSysuiColorExtractor.getColors( + WallpaperManager.FLAG_LOCK, true); mSupportsDarkText = colors.supportsDarkText(); mColorPalette = colors.getColorPalette(); if (mClockPlugin != null) { diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java index 9dd97170437d..ae8bc528ab6a 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java @@ -28,9 +28,12 @@ import android.util.Log; import android.util.SparseArray; import android.view.Display; import android.view.DisplayInfo; +import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; +import com.android.systemui.util.InjectionInflationController; + // TODO(multi-display): Support multiple external displays public class KeyguardDisplayManager { protected static final String TAG = "KeyguardDisplayManager"; @@ -38,6 +41,7 @@ public class KeyguardDisplayManager { private final MediaRouter mMediaRouter; private final DisplayManager mDisplayService; + private final InjectionInflationController mInjectableInflater; private final Context mContext; private boolean mShowing; @@ -75,8 +79,10 @@ public class KeyguardDisplayManager { } }; - public KeyguardDisplayManager(Context context) { + public KeyguardDisplayManager(Context context, + InjectionInflationController injectableInflater) { mContext = context; + mInjectableInflater = injectableInflater; mMediaRouter = mContext.getSystemService(MediaRouter.class); mDisplayService = mContext.getSystemService(DisplayManager.class); mDisplayService.registerDisplayListener(mDisplayListener, null /* handler */); @@ -110,7 +116,7 @@ public class KeyguardDisplayManager { final int displayId = display.getDisplayId(); Presentation presentation = mPresentations.get(displayId); if (presentation == null) { - presentation = new KeyguardPresentation(mContext, display); + presentation = new KeyguardPresentation(mContext, display, mInjectableInflater); presentation.setOnDismissListener(dialog -> { if (null != mPresentations.get(displayId)) { mPresentations.remove(displayId); @@ -201,6 +207,7 @@ public class KeyguardDisplayManager { private final static class KeyguardPresentation extends Presentation { private static final int VIDEO_SAFE_REGION = 80; // Percentage of display width & height private static final int MOVE_CLOCK_TIMEOUT = 10000; // 10s + private final InjectionInflationController mInjectableInflater; private View mClock; private int mUsableWidth; private int mUsableHeight; @@ -217,8 +224,10 @@ public class KeyguardDisplayManager { } }; - KeyguardPresentation(Context context, Display display) { + KeyguardPresentation(Context context, Display display, + InjectionInflationController injectionInflater) { super(context, display, R.style.keyguard_presentation_theme); + mInjectableInflater = injectionInflater; getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); setCancelable(false); } @@ -239,7 +248,9 @@ public class KeyguardDisplayManager { mMarginLeft = (100 - VIDEO_SAFE_REGION) * p.x / 200; mMarginTop = (100 - VIDEO_SAFE_REGION) * p.y / 200; - setContentView(R.layout.keyguard_presentation); + LayoutInflater inflater = mInjectableInflater.injectable( + LayoutInflater.from(getContext())); + setContentView(inflater.inflate(R.layout.keyguard_presentation, null)); mClock = findViewById(R.id.clock); // Avoid screen burn in diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java index e87b31397626..52b766de5ec4 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java @@ -47,6 +47,17 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe private static final int USER_TYPE_WORK_PROFILE = 2; private static final int USER_TYPE_SECONDARY_USER = 3; + // Bouncer is dismissed due to no security. + private static final int BOUNCER_DISMISS_NONE_SECURITY = 0; + // Bouncer is dismissed due to pin, password or pattern entered. + private static final int BOUNCER_DISMISS_PASSWORD = 1; + // Bouncer is dismissed due to biometric (face, fingerprint or iris) authenticated. + private static final int BOUNCER_DISMISS_BIOMETRIC = 2; + // Bouncer is dismissed due to extended access granted. + private static final int BOUNCER_DISMISS_EXTENDED_ACCESS = 3; + // Bouncer is dismissed due to sim card unlock code entered. + private static final int BOUNCER_DISMISS_SIM = 4; + private KeyguardSecurityModel mSecurityModel; private LockPatternUtils mLockPatternUtils; @@ -328,12 +339,18 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe if (DEBUG) Log.d(TAG, "showNextSecurityScreenOrFinish(" + authenticated + ")"); boolean finish = false; boolean strongAuth = false; - if (mUpdateMonitor.getUserCanSkipBouncer(targetUserId)) { + int eventSubtype = -1; + if (mUpdateMonitor.getUserHasTrust(targetUserId)) { + finish = true; + eventSubtype = BOUNCER_DISMISS_EXTENDED_ACCESS; + } else if (mUpdateMonitor.getUserUnlockedWithBiometric(targetUserId)) { finish = true; + eventSubtype = BOUNCER_DISMISS_BIOMETRIC; } else if (SecurityMode.None == mCurrentSecuritySelection) { SecurityMode securityMode = mSecurityModel.getSecurityMode(targetUserId); if (SecurityMode.None == securityMode) { finish = true; // no security required + eventSubtype = BOUNCER_DISMISS_NONE_SECURITY; } else { showSecurityScreen(securityMode); // switch to the alternate security view } @@ -344,6 +361,7 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe case PIN: strongAuth = true; finish = true; + eventSubtype = BOUNCER_DISMISS_PASSWORD; break; case SimPin: @@ -353,6 +371,7 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe if (securityMode == SecurityMode.None || mLockPatternUtils.isLockScreenDisabled( KeyguardUpdateMonitor.getCurrentUser())) { finish = true; + eventSubtype = BOUNCER_DISMISS_SIM; } else { showSecurityScreen(securityMode); } @@ -364,6 +383,10 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe break; } } + if (eventSubtype != -1) { + mMetricsLogger.write(new LogMaker(MetricsEvent.BOUNCER) + .setType(MetricsEvent.TYPE_DISMISS).setSubtype(eventSubtype)); + } if (finish) { mSecurityCallback.finish(strongAuth, targetUserId); } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java index 808e264258da..0369e4c0aea6 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java @@ -214,7 +214,6 @@ public class KeyguardStatusView extends GridLayout implements public void dozeTimeTick() { refreshTime(); mKeyguardSlice.refresh(); - mClockView.dozeTimeTick(); } private void refreshTime() { diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 63f8cd6d2025..fa39ccd28ff1 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -886,15 +886,22 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { public boolean getUserCanSkipBouncer(int userId) { - boolean fingerprintOrFace = mUserFingerprintAuthenticated.get(userId) - || mUserFaceAuthenticated.get(userId); - return getUserHasTrust(userId) || (fingerprintOrFace && isUnlockingWithBiometricAllowed()); + return getUserHasTrust(userId) || getUserUnlockedWithBiometric(userId); } public boolean getUserHasTrust(int userId) { return !isTrustDisabled(userId) && mUserHasTrust.get(userId); } + /** + * Returns whether the user is unlocked with biometrics. + */ + public boolean getUserUnlockedWithBiometric(int userId) { + boolean fingerprintOrFace = mUserFingerprintAuthenticated.get(userId) + || mUserFaceAuthenticated.get(userId); + return fingerprintOrFace && isUnlockingWithBiometricAllowed(); + } + public boolean getUserTrustIsManaged(int userId) { return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId); } diff --git a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java index 870ac8778f76..32c1242b695d 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java @@ -141,6 +141,8 @@ public class BubbleClockController implements ClockPlugin { @Override public void onTimeTick() { mAnalogClock.onTimeChanged(); + mDigitalClock.refresh(); + mLockClock.refresh(); } @Override diff --git a/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java index 7401819fde4d..34b2fd86f648 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java @@ -136,6 +136,8 @@ public class StretchAnalogClockController implements ClockPlugin { @Override public void onTimeTick() { mAnalogClock.onTimeChanged(); + mDigitalClock.refresh(); + mLockClock.refresh(); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/ActivityIntentHelper.java b/packages/SystemUI/src/com/android/systemui/ActivityIntentHelper.java new file mode 100644 index 000000000000..2b62e040b1fd --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/ActivityIntentHelper.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui; + +import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; + +import java.util.List; + +/** + * Contains useful methods for querying properties of an Activity Intent. + */ +public class ActivityIntentHelper { + + private final Context mContext; + + public ActivityIntentHelper(Context context) { + mContext = context; + } + + /** + * Determines if sending the given intent would result in starting an Intent resolver activity, + * instead of resolving to a specific component. + * + * @param intent the intent + * @param currentUserId the id for the user to resolve as + * @return true if the intent would launch a resolver activity + */ + public boolean wouldLaunchResolverActivity(Intent intent, int currentUserId) { + ActivityInfo targetActivityInfo = getTargetActivityInfo(intent, currentUserId, + false /* onlyDirectBootAware */); + return targetActivityInfo == null; + } + + /** + * Returns info about the target Activity of a given intent, or null if the intent does not + * resolve to a specific component meeting the requirements. + * + * @param onlyDirectBootAware a boolean indicating whether the matched activity packages must + * be direct boot aware when in direct boot mode if false, all packages are considered + * a match even if they are not aware. + * @return the target activity info of the intent it resolves to a specific package or + * {@code null} if it resolved to the resolver activity + */ + public ActivityInfo getTargetActivityInfo(Intent intent, int currentUserId, + boolean onlyDirectBootAware) { + PackageManager packageManager = mContext.getPackageManager(); + int flags = PackageManager.MATCH_DEFAULT_ONLY; + if (!onlyDirectBootAware) { + flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE; + } + final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser( + intent, flags, currentUserId); + if (appList.size() == 0) { + return null; + } + ResolveInfo resolved = packageManager.resolveActivityAsUser(intent, + flags | PackageManager.GET_META_DATA, currentUserId); + if (resolved == null || wouldLaunchResolverActivity(resolved, appList)) { + return null; + } else { + return resolved.activityInfo; + } + } + + /** + * Determines if the given intent resolves to an Activity which is allowed to appear above + * the lock screen. + * + * @param intent the intent to resolve + * @return true if the launched Activity would appear above the lock screen + */ + public boolean wouldShowOverLockscreen(Intent intent, int currentUserId) { + ActivityInfo targetActivityInfo = getTargetActivityInfo(intent, + currentUserId, false /* onlyDirectBootAware */); + return targetActivityInfo != null + && (targetActivityInfo.flags & (ActivityInfo.FLAG_SHOW_WHEN_LOCKED + | ActivityInfo.FLAG_SHOW_FOR_ALL_USERS)) > 0; + } + + /** + * Determines if sending the given intent would result in starting an Intent resolver activity, + * instead of resolving to a specific component. + * + * @param resolved the resolveInfo for the intent as returned by resolveActivityAsUser + * @param appList a list of resolveInfo as returned by queryIntentActivitiesAsUser + * @return true if the intent would launch a resolver activity + */ + public boolean wouldLaunchResolverActivity(ResolveInfo resolved, List<ResolveInfo> appList) { + // If the list contains the above resolved activity, then it can't be + // ResolverActivity itself. + for (int i = 0; i < appList.size(); i++) { + ResolveInfo tmp = appList.get(i); + if (tmp.activityInfo.name.equals(resolved.activityInfo.name) + && tmp.activityInfo.packageName.equals(resolved.activityInfo.packageName)) { + return false; + } + } + return true; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java index b7d19007cac2..70f2ccee7d60 100644 --- a/packages/SystemUI/src/com/android/systemui/Dependency.java +++ b/packages/SystemUI/src/com/android/systemui/Dependency.java @@ -97,6 +97,7 @@ import com.android.systemui.statusbar.policy.NextAlarmController; import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler; import com.android.systemui.statusbar.policy.RotationLockController; import com.android.systemui.statusbar.policy.SecurityController; +import com.android.systemui.statusbar.policy.SensorPrivacyController; import com.android.systemui.statusbar.policy.SmartReplyConstants; import com.android.systemui.statusbar.policy.UserInfoController; import com.android.systemui.statusbar.policy.UserSwitcherController; @@ -291,6 +292,7 @@ public class Dependency extends SystemUI { @Inject Lazy<ActivityManagerWrapper> mActivityManagerWrapper; @Inject Lazy<DevicePolicyManagerWrapper> mDevicePolicyManagerWrapper; @Inject Lazy<PackageManagerWrapper> mPackageManagerWrapper; + @Inject Lazy<SensorPrivacyController> mSensorPrivacyController; @Inject public Dependency() { @@ -461,6 +463,7 @@ public class Dependency extends SystemUI { mProviders.put(ActivityManagerWrapper.class, mActivityManagerWrapper::get); mProviders.put(DevicePolicyManagerWrapper.class, mDevicePolicyManagerWrapper::get); mProviders.put(PackageManagerWrapper.class, mPackageManagerWrapper::get); + mProviders.put(SensorPrivacyController.class, mSensorPrivacyController::get); // TODO(b/118592525): to support multi-display , we start to add something which is diff --git a/packages/SystemUI/src/com/android/systemui/DependencyBinder.java b/packages/SystemUI/src/com/android/systemui/DependencyBinder.java index 3c6f081d0373..53050bf2dc3e 100644 --- a/packages/SystemUI/src/com/android/systemui/DependencyBinder.java +++ b/packages/SystemUI/src/com/android/systemui/DependencyBinder.java @@ -60,6 +60,8 @@ import com.android.systemui.statusbar.policy.RotationLockController; import com.android.systemui.statusbar.policy.RotationLockControllerImpl; import com.android.systemui.statusbar.policy.SecurityController; import com.android.systemui.statusbar.policy.SecurityControllerImpl; +import com.android.systemui.statusbar.policy.SensorPrivacyController; +import com.android.systemui.statusbar.policy.SensorPrivacyControllerImpl; import com.android.systemui.statusbar.policy.UserInfoController; import com.android.systemui.statusbar.policy.UserInfoControllerImpl; import com.android.systemui.statusbar.policy.ZenModeController; @@ -225,5 +227,11 @@ public abstract class DependencyBinder { /** */ @Binds + public abstract SensorPrivacyController provideSensorPrivacyControllerImpl( + SensorPrivacyControllerImpl controllerImpl); + + /** + */ + @Binds public abstract QSHost provideQsHost(QSTileHost controllerImpl); } diff --git a/packages/SystemUI/src/com/android/systemui/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/DependencyProvider.java index 895f9b9a1cdf..f649976ccf01 100644 --- a/packages/SystemUI/src/com/android/systemui/DependencyProvider.java +++ b/packages/SystemUI/src/com/android/systemui/DependencyProvider.java @@ -155,8 +155,9 @@ public class DependencyProvider { @Singleton @Provides - public NightDisplayListener provideNightDisplayListener(Context context) { - return new NightDisplayListener(context); + public NightDisplayListener provideNightDisplayListener(Context context, + @Named(BG_HANDLER_NAME) Handler bgHandler) { + return new NightDisplayListener(context, bgHandler); } @Singleton diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java index 14e910f41cab..8e3afd8bcae0 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java @@ -43,6 +43,7 @@ import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.ShapeDrawable; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.UserHandle; import android.provider.Settings; import android.service.notification.StatusBarNotification; import android.util.AttributeSet; @@ -457,30 +458,38 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList void updateHeight() { if (usingActivityView()) { Notification.BubbleMetadata data = mEntry.getBubbleMetadata(); - int desiredHeight; + float desiredHeight; if (data == null) { // This is a contentIntent based bubble, lets allow it to be the max height // as it was forced into this mode and not prepared to be small desiredHeight = mStackView.getMaxExpandedHeight(); } else { - desiredHeight = data.getDesiredHeight() > 0 - ? data.getDesiredHeight() - : mMinHeight; + boolean useRes = data.getDesiredHeightResId() != 0; + float desiredPx; + if (useRes) { + desiredPx = getDimenForPackageUser(data.getDesiredHeightResId(), + mEntry.notification.getPackageName(), + mEntry.notification.getUser().getIdentifier()); + } else { + desiredPx = data.getDesiredHeight() + * getContext().getResources().getDisplayMetrics().density; + } + desiredHeight = desiredPx > 0 ? desiredPx : mMinHeight; } int chromeHeight = mPermissionView.getVisibility() != View.VISIBLE ? mHeaderHeight : mPermissionHeight; int max = mStackView.getMaxExpandedHeight() - chromeHeight - mPointerView.getHeight() - mPointerMargin; - int height = Math.min(desiredHeight, max); + float height = Math.min(desiredHeight, max); height = Math.max(height, mMinHeight); LayoutParams lp = (LayoutParams) mActivityView.getLayoutParams(); mNeedsNewHeight = lp.height != height; if (!mKeyboardVisible) { // If the keyboard is visible... don't adjust the height because that will cause // a configuration change and the keyboard will be lost. - lp.height = height; - mBubbleHeight = height; + lp.height = (int) height; + mBubbleHeight = (int) height; mActivityView.setLayoutParams(lp); mNeedsNewHeight = false; } @@ -712,4 +721,23 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList mStackView.getNormalizedXPosition(), mStackView.getNormalizedYPosition()); } + + private int getDimenForPackageUser(int resId, String pkg, int userId) { + Resources r; + if (pkg != null) { + try { + if (userId == UserHandle.USER_ALL) { + userId = UserHandle.USER_SYSTEM; + } + r = mPm.getResourcesForApplicationAsUser(pkg, userId); + return r.getDimensionPixelSize(resId); + } catch (PackageManager.NameNotFoundException ex) { + // Uninstalled, don't care + } catch (Resources.NotFoundException e) { + // Invalid res id, return 0 and user our default + Log.e(TAG, "Couldn't find desired height res id", e); + } + } + return 0; + } } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java index 40e08bed8352..d601e633137d 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java @@ -104,16 +104,23 @@ public class ExpandedAnimationController * @return The y-value to which the bubbles were expanded, in case that's useful. */ public float expandFromStack(PointF collapseTo, Runnable after) { - mCollapseToPoint = collapseTo; + animationsForChildrenFromIndex( + 0, /* startIndex */ + new ChildAnimationConfigurator() { + // How much to translate the next bubble, so that it is not overlapping the + // previous one. + float mTranslateNextBubbleXBy = mBubblePaddingPx; - // How much to translate the next bubble, so that it is not overlapping the previous one. - float translateNextBubbleXBy = mBubblePaddingPx; - for (int i = 0; i < mLayout.getChildCount(); i++) { - mLayout.animatePositionForChildAtIndex(i, translateNextBubbleXBy, getExpandedY()); - translateNextBubbleXBy += mBubbleSizePx + mBubblePaddingPx; - } + @Override + public void configureAnimationForChildAtIndex( + int index, PhysicsAnimationLayout.PhysicsPropertyAnimator animation) { + animation.position(mTranslateNextBubbleXBy, getExpandedY()); + mTranslateNextBubbleXBy += mBubbleSizePx + mBubblePaddingPx; + } + }) + .startAll(after); - runAfterTranslationsEnd(after); + mCollapseToPoint = collapseTo; return getExpandedY(); } @@ -121,13 +128,14 @@ public class ExpandedAnimationController public void collapseBackToStack(Runnable after) { // Stack to the left if we're going to the left, or right if not. final float sideMultiplier = mLayout.isFirstChildXLeftOfCenter(mCollapseToPoint.x) ? -1 : 1; - for (int i = 0; i < mLayout.getChildCount(); i++) { - mLayout.animatePositionForChildAtIndex( - i, - mCollapseToPoint.x + (sideMultiplier * i * mStackOffsetPx), mCollapseToPoint.y); - } - runAfterTranslationsEnd(after); + animationsForChildrenFromIndex( + 0, /* startIndex */ + (index, animation) -> + animation.position( + mCollapseToPoint.x + (sideMultiplier * index * mStackOffsetPx), + mCollapseToPoint.y)) + .startAll(after /* endAction */); } /** Prepares the given bubble to be dragged out. */ @@ -164,20 +172,10 @@ public class ExpandedAnimationController public void snapBubbleBack(View bubbleView, float velX, float velY) { final int index = mLayout.indexOfChild(bubbleView); - // Snap the bubble back, respecting its current velocity. - mLayout.animateValueForChildAtIndex( - DynamicAnimation.TRANSLATION_X, index, getXForChildAtIndex(index), velX); - mLayout.animateValueForChildAtIndex( - DynamicAnimation.TRANSLATION_Y, index, getExpandedY(), velY); - mLayout.setEndListenerForProperties( - mLayout.new OneTimeMultiplePropertyEndListener() { - @Override - void onAllAnimationsForPropertiesEnd() { - // Reset Z translation once the bubble is done snapping back. - bubbleView.setTranslationZ(0f); - } - }, - DynamicAnimation.TRANSLATION_X, DynamicAnimation.TRANSLATION_Y); + animationForChildAtIndex(index) + .position(getXForChildAtIndex(index), getExpandedY()) + .withPositionStartVelocities(velX, velY) + .start(() -> bubbleView.setTranslationZ(0f) /* after */); animateStackByBubbleWidthsStartingFrom( /* numBubbleWidths */ 0, /* startIndex */ index + 1); @@ -202,12 +200,8 @@ public class ExpandedAnimationController */ public void updateYPosition(Runnable after) { if (mLayout == null) return; - - for (int i = 0; i < mLayout.getChildCount(); i++) { - boolean isLast = i == mLayout.getChildCount() - 1; - mLayout.animateValueForChildAtIndex(DynamicAnimation.TRANSLATION_Y, i, - getExpandedY(), isLast ? after : null); - } + animationsForChildrenFromIndex( + 0, (i, anim) -> anim.translationY(getExpandedY())).startAll(after); } /** @@ -216,12 +210,11 @@ public class ExpandedAnimationController * positions. */ private void animateStackByBubbleWidthsStartingFrom(int numBubbleWidths, int startIndex) { - for (int i = startIndex; i < mLayout.getChildCount(); i++) { - mLayout.animateValueForChildAtIndex( - DynamicAnimation.TRANSLATION_X, - i, - getXForChildAtIndex(i + numBubbleWidths)); - } + animationsForChildrenFromIndex( + startIndex, + (index, animation) -> + animation.translationX(getXForChildAtIndex(index + numBubbleWidths))) + .startAll(); } /** The Y value of the row of expanded bubbles. */ @@ -248,21 +241,6 @@ public class ExpandedAnimationController } } - /** Runs the given Runnable after all translation-related animations have ended. */ - private void runAfterTranslationsEnd(Runnable after) { - DynamicAnimation.OnAnimationEndListener allEndedListener = - (animation, canceled, value, velocity) -> { - if (!mLayout.arePropertiesAnimating( - DynamicAnimation.TRANSLATION_X, - DynamicAnimation.TRANSLATION_Y)) { - after.run(); - } - }; - - mLayout.setEndListenerForProperty(allEndedListener, DynamicAnimation.TRANSLATION_X); - mLayout.setEndListenerForProperty(allEndedListener, DynamicAnimation.TRANSLATION_Y); - } - @Override Set<DynamicAnimation.ViewProperty> getAnimatedProperties() { return Sets.newHashSet( @@ -295,8 +273,12 @@ public class ExpandedAnimationController // Pop in from the top. // TODO: Reverse this when bubbles are at the bottom. child.setTranslationX(getXForChildAtIndex(index)); - child.setTranslationY(getExpandedY() - mBubbleSizePx * ANIMATE_TRANSLATION_FACTOR); - mLayout.animateValueForChild(DynamicAnimation.TRANSLATION_Y, child, getExpandedY()); + + animationForChild(child) + .translationY( + getExpandedY() - mBubbleSizePx * ANIMATE_TRANSLATION_FACTOR, /* from */ + getExpandedY() /* to */) + .start(); animateBubblesAfterIndexToCorrectX(index); } @@ -304,36 +286,26 @@ public class ExpandedAnimationController void onChildRemoved(View child, int index, Runnable finishRemoval) { // Bubble pops out to the top. // TODO: Reverse this when bubbles are at the bottom. - mLayout.animateValueForChild( - DynamicAnimation.ALPHA, child, 0f, finishRemoval); + + final PhysicsAnimationLayout.PhysicsPropertyAnimator animator = animationForChild(child); + animator.alpha(0f, finishRemoval /* endAction */); // If we're removing the dragged-out bubble, that means it got dismissed. if (child.equals(mBubbleDraggingOut)) { - // Throw it to the bottom of the screen, towards the center horizontally. - mLayout.animateValueForChild( - DynamicAnimation.TRANSLATION_X, - child, - mLayout.getWidth() / 2f - mBubbleSizePx / 2f, - mBubbleDraggingOutVelX); - mLayout.animateValueForChild( - DynamicAnimation.TRANSLATION_Y, - child, - mLayout.getHeight() + mBubbleSizePx, - mBubbleDraggingOutVelY); - - // Scale it down a bit so it looks like it's disappearing. - mLayout.animateValueForChild(DynamicAnimation.SCALE_X, child, ANIMATE_SCALE_PERCENT); - mLayout.animateValueForChild(DynamicAnimation.SCALE_Y, child, ANIMATE_SCALE_PERCENT); + animator.position( + mLayout.getWidth() / 2f - mBubbleSizePx / 2f, + mLayout.getHeight() + mBubbleSizePx) + .withPositionStartVelocities(mBubbleDraggingOutVelX, mBubbleDraggingOutVelY) + .scaleX(ANIMATE_SCALE_PERCENT) + .scaleY(ANIMATE_SCALE_PERCENT); mBubbleDraggingOut = null; } else { - // If we're removing some random bubble just throw it off the top. - mLayout.animateValueForChild( - DynamicAnimation.TRANSLATION_Y, - child, - getExpandedY() - mBubbleSizePx * ANIMATE_TRANSLATION_FACTOR); + animator.translationY(getExpandedY() - mBubbleSizePx * ANIMATE_TRANSLATION_FACTOR); } + animator.start(); + // Animate all the other bubbles to their new positions sans this bubble. animateBubblesAfterIndexToCorrectX(index); } @@ -346,12 +318,9 @@ public class ExpandedAnimationController child.setVisibility(View.VISIBLE); } - // Fade in. - mLayout.animateValueForChild( - DynamicAnimation.ALPHA, - child, - /* value */ visibility == View.GONE ? 0f : 1f, - () -> super.setChildVisibility(child, index, visibility)); + animationForChild(child) + .alpha(visibility == View.GONE ? 0f : 1f) + .start(() -> super.setChildVisibility(child, index, visibility) /* after */); } /** @@ -365,8 +334,9 @@ public class ExpandedAnimationController // Don't animate the dragging out bubble, or it'll jump around while being dragged. It // will be snapped to the correct X value after the drag (if it's not dismissed). if (!bubble.equals(mBubbleDraggingOut)) { - mLayout.animateValueForChild( - DynamicAnimation.TRANSLATION_X, bubble, getXForChildAtIndex(i)); + animationForChild(bubble) + .translationX(getXForChildAtIndex(i)) + .start(); } } } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java index dfdcfc9f3b74..8731b6b9767c 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java @@ -27,8 +27,11 @@ import androidx.dynamicanimation.animation.SpringForce; import com.android.systemui.R; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.List; +import java.util.Map; import java.util.Set; /** @@ -46,6 +49,35 @@ public class PhysicsAnimationLayout extends FrameLayout { */ abstract static class PhysicsAnimationController { + /** Configures a given {@link PhysicsPropertyAnimator} for a view at the given index. */ + interface ChildAnimationConfigurator { + + /** + * Called to configure the animator for the view at the given index. + * + * This method should make use of methods such as + * {@link PhysicsPropertyAnimator#translationX} and + * {@link PhysicsPropertyAnimator#withStartDelay} to configure the animation. + * + * Implementations should not call {@link PhysicsPropertyAnimator#start}, this will + * happen elsewhere after configuration is complete. + */ + void configureAnimationForChildAtIndex(int index, PhysicsPropertyAnimator animation); + } + + /** + * Returned by {@link #animationsForChildrenFromIndex} to allow starting multiple animations + * on multiple child views at the same time. + */ + interface MultiAnimationStarter { + + /** + * Start all animations and call the given end actions once all animations have + * completed. + */ + void startAll(Runnable... endActions); + } + /** * Constant to return from {@link #getNextAnimationInChain} if the animation should not be * chained at all. @@ -98,7 +130,7 @@ public class PhysicsAnimationLayout extends FrameLayout { * by getChildAt() and getChildCount(). * * The controller can perform animations on the child (either manually, or by using - * {@link #animateValueForChild}), and then call finishRemoval when complete. + * {@link #animationForChild(View)}), and then call finishRemoval when complete. * * finishRemoval must be called by implementations of this method, or transient views will * never be removed. @@ -125,17 +157,74 @@ public class PhysicsAnimationLayout extends FrameLayout { protected void setChildVisibility(View child, int index, int visibility) { child.setVisibility(visibility); } + + /** + * Returns a {@link PhysicsPropertyAnimator} instance for the given child view. + */ + protected PhysicsPropertyAnimator animationForChild(View child) { + PhysicsPropertyAnimator animator = + (PhysicsPropertyAnimator) child.getTag(R.id.physics_animator_tag); + + if (animator == null) { + animator = mLayout.new PhysicsPropertyAnimator(child); + child.setTag(R.id.physics_animator_tag, animator); + } + + return animator; + } + + /** Returns a {@link PhysicsPropertyAnimator} instance for child at the given index. */ + protected PhysicsPropertyAnimator animationForChildAtIndex(int index) { + return animationForChild(mLayout.getChildAt(index)); + } + + /** + * Returns a {@link MultiAnimationStarter} whose startAll method will start the physics + * animations for all children from startIndex onward. The provided configurator will be + * called with each child's {@link PhysicsPropertyAnimator}, where it can set up each + * animation appropriately. + */ + protected MultiAnimationStarter animationsForChildrenFromIndex( + int startIndex, ChildAnimationConfigurator configurator) { + final Set<DynamicAnimation.ViewProperty> allAnimatedProperties = new HashSet<>(); + final List<PhysicsPropertyAnimator> allChildAnims = new ArrayList<>(); + + // Retrieve the animator for each child, ask the configurator to configure it, then save + // it and the properties it chose to animate. + for (int i = startIndex; i < mLayout.getChildCount(); i++) { + final PhysicsPropertyAnimator anim = animationForChildAtIndex(i); + configurator.configureAnimationForChildAtIndex(i, anim); + allAnimatedProperties.addAll(anim.getAnimatedProperties()); + allChildAnims.add(anim); + } + + // Return a MultiAnimationStarter that will start all of the child animations, and also + // add a multiple property end listener to the layout that will call the end action + // provided to startAll() once all animations on the animated properties complete. + return (endActions) -> { + if (endActions != null) { + mLayout.setEndActionForMultipleProperties( + () -> { + for (Runnable action : endActions) { + action.run(); + } + }, + allAnimatedProperties.toArray( + new DynamicAnimation.ViewProperty[0])); + } + + for (PhysicsPropertyAnimator childAnim : allChildAnims) { + childAnim.start(); + } + }; + } } /** - * End listeners that are called when every child's animation of the given property has - * finished. + * End actions that are called when every child's animation of the given property has finished. */ - protected final HashMap<DynamicAnimation.ViewProperty, DynamicAnimation.OnAnimationEndListener> - mEndListenerForProperty = new HashMap<>(); - - /** Set of currently rendered transient views. */ - private final Set<View> mTransientViews = new HashSet<>(); + protected final HashMap<DynamicAnimation.ViewProperty, Runnable> mEndActionForProperty = + new HashMap<>(); /** The currently active animation controller. */ private PhysicsAnimationController mController; @@ -165,7 +254,7 @@ public class PhysicsAnimationLayout extends FrameLayout { */ public void setController(PhysicsAnimationController controller) { cancelAllAnimations(); - mEndListenerForProperty.clear(); + mEndActionForProperty.clear(); this.mController = controller; mController.setLayout(this); @@ -177,26 +266,27 @@ public class PhysicsAnimationLayout extends FrameLayout { } /** - * Sets an end listener that will be called when all child animations for a given property have + * Sets an end action that will be run when all child animations for a given property have * stopped running. */ - public void setEndListenerForProperty( - DynamicAnimation.OnAnimationEndListener listener, - DynamicAnimation.ViewProperty property) { - mEndListenerForProperty.put(property, listener); + public void setEndActionForProperty(Runnable action, DynamicAnimation.ViewProperty property) { + mEndActionForProperty.put(property, action); } /** - * Sets an end listener that will be called whenever any of the given properties' animations - * end. For example, setting a listener for TRANSLATION_X and TRANSLATION_Y will result in that - * listener being called twice - once when all TRANSLATION_X animations end, and again when all - * TRANSLATION_Y animations end. + * Sets an end action that will be run when all child animations for all of the given properties + * have stopped running. */ - public void setEndListenerForProperties( - DynamicAnimation.OnAnimationEndListener endListener, - DynamicAnimation.ViewProperty... properties) { + public void setEndActionForMultipleProperties( + Runnable action, DynamicAnimation.ViewProperty... properties) { + final Runnable checkIfAllFinished = () -> { + if (!arePropertiesAnimating(properties)) { + action.run(); + } + }; + for (DynamicAnimation.ViewProperty property : properties) { - setEndListenerForProperty(endListener, property); + setEndActionForProperty(checkIfAllFinished, property); } } @@ -204,8 +294,8 @@ public class PhysicsAnimationLayout extends FrameLayout { * Removes the end listener that would have been called when all child animations for a given * property stopped running. */ - public void removeEndListenerForProperty(DynamicAnimation.ViewProperty property) { - mEndListenerForProperty.remove(property); + public void removeEndActionForProperty(DynamicAnimation.ViewProperty property) { + mEndActionForProperty.remove(property); } @Override @@ -231,15 +321,8 @@ public class PhysicsAnimationLayout extends FrameLayout { } @Override - public void addTransientView(View view, int index) { - super.addTransientView(view, index); - mTransientViews.add(view); - } - - @Override - public void removeTransientView(View view) { - super.removeTransientView(view); - mTransientViews.remove(view); + public void removeViewAt(int index) { + removeView(getChildAt(index)); } /** Immediately moves the view from wherever it currently is, to the given index. */ @@ -265,7 +348,9 @@ public class PhysicsAnimationLayout extends FrameLayout { // Tell the controller to animate this view out, and call the callback when it's // finished. mController.onChildRemoved(view, index, () -> { - // Done animating, remove the transient view. + // The controller says it's done with the transient view, cancel animations in case + // any are still running and then remove it. + cancelAnimationsOnView(view); removeTransientView(view); if (callback != null) { @@ -304,7 +389,10 @@ public class PhysicsAnimationLayout extends FrameLayout { for (int i = 0; i < getChildCount(); i++) { for (DynamicAnimation.ViewProperty property : mController.getAnimatedProperties()) { - getAnimationAtIndex(property, i).cancel(); + final DynamicAnimation anim = getAnimationAtIndex(property, i); + if (anim != null) { + anim.cancel(); + } } } } @@ -316,107 +404,6 @@ public class PhysicsAnimationLayout extends FrameLayout { } } - /** - * Animates the property of the given child view, then runs the callback provided when the - * animation ends. - */ - protected void animateValueForChild( - DynamicAnimation.ViewProperty property, - View view, - float value, - float startVel, - Runnable after) { - if (view != null) { - final SpringAnimation animation = - (SpringAnimation) view.getTag(getTagIdForProperty(property)); - if (after != null) { - animation.addEndListener(new OneTimeEndListener() { - @Override - public void onAnimationEnd(DynamicAnimation animation, boolean canceled, - float value, float velocity) { - super.onAnimationEnd(animation, canceled, value, velocity); - after.run(); - } - }); - } - - // Set the start velocity if it's something other than the not-set value. - if (startVel != Float.MAX_VALUE) { - animation.setStartVelocity(startVel); - } - - animation.animateToFinalPosition(value); - } - } - - protected void animateValueForChild( - DynamicAnimation.ViewProperty property, - View view, - float value, - Runnable after) { - animateValueForChild(property, view, value, Float.MAX_VALUE, after); - } - - protected void animateValueForChild( - DynamicAnimation.ViewProperty property, - View view, - float value) { - animateValueForChild(property, view, value, Float.MAX_VALUE, /* after */ null); - } - - protected void animateValueForChild( - DynamicAnimation.ViewProperty property, - View view, - float value, - float startVel) { - animateValueForChild(property, view, value, startVel, /* after */ null); - } - - /** - * Animates the property of the child at the given index to the given value, then runs the - * callback provided when the animation ends. - */ - protected void animateValueForChildAtIndex( - DynamicAnimation.ViewProperty property, - int index, - float value, - float startVel, - Runnable after) { - animateValueForChild(property, getChildAt(index), value, startVel, after); - } - - /** Shortcut to animate a value with a callback, but no start velocity. */ - protected void animateValueForChildAtIndex( - DynamicAnimation.ViewProperty property, - int index, - float value, - Runnable after) { - animateValueForChildAtIndex(property, index, value, Float.MAX_VALUE, after); - } - - /** Shortcut to animate a value with a start velocity, but no callback. */ - protected void animateValueForChildAtIndex( - DynamicAnimation.ViewProperty property, - int index, - float value, - float startVel) { - animateValueForChildAtIndex(property, index, value, startVel, /* callback */ null); - } - - /** Shortcut to animate a value without changing the velocity or providing a callback. */ - protected void animateValueForChildAtIndex( - DynamicAnimation.ViewProperty property, - int index, - float value) { - animateValueForChildAtIndex(property, index, value, Float.MAX_VALUE, /* callback */ null); - } - - /** Shortcut to animate a child view's TRANSLATION_X and TRANSLATION_Y values. */ - protected void animatePositionForChildAtIndex(int index, float x, float y) { - animateValueForChildAtIndex(DynamicAnimation.TRANSLATION_X, index, x); - animateValueForChildAtIndex(DynamicAnimation.TRANSLATION_Y, index, y); - } - /** Whether the first child would be left of center if translated to the given x value. */ protected boolean isFirstChildXLeftOfCenter(float x) { if (getChildCount() > 0) { @@ -470,13 +457,11 @@ public class PhysicsAnimationLayout extends FrameLayout { DynamicAnimation.ViewProperty property, View child, int index) { SpringAnimation newAnim = new SpringAnimation(child, property); newAnim.addUpdateListener((animation, value, velocity) -> { + final int indexOfChild = indexOfChild(child); final int nextAnimInChain = - mController.getNextAnimationInChain(property, indexOfChild(child)); + mController.getNextAnimationInChain(property, indexOfChild); - // If the controller doesn't want us to chain, or if we're a transient view in the - // process of being removed, don't chain. - if (nextAnimInChain == PhysicsAnimationController.NONE - || mTransientViews.contains(child)) { + if (nextAnimInChain == PhysicsAnimationController.NONE || indexOfChild < 0) { return; } @@ -562,40 +547,256 @@ public class PhysicsAnimationLayout extends FrameLayout { public void onAnimationEnd( DynamicAnimation anim, boolean canceled, float value, float velocity) { if (!arePropertiesAnimating(mProperty)) { - if (mEndListenerForProperty.containsKey(mProperty)) { - mEndListenerForProperty.get(mProperty).onAnimationEnd(anim, canceled, value, - velocity); + if (mEndActionForProperty.containsKey(mProperty)) { + mEndActionForProperty.get(mProperty).run(); } } } } /** - * One time end listener that waits for every animation on every given property to finish. At - * that point, it calls {@link #onAllAnimationsForPropertiesEnd} and then removes itself as an - * end listener from each property. + * Animator class returned by {@link PhysicsAnimationController#animationForChild}, to allow + * controllers to animate child views using physics animations. + * + * See docs/physics-animation-layout.md for documentation and examples. */ - public abstract class OneTimeMultiplePropertyEndListener - implements DynamicAnimation.OnAnimationEndListener { - final DynamicAnimation.ViewProperty[] mViewProperties; + protected class PhysicsPropertyAnimator { + /** The view whose properties this animator animates. */ + private View mView; - OneTimeMultiplePropertyEndListener(DynamicAnimation.ViewProperty... properties) { - mViewProperties = properties; + /** Start velocity to use for all property animations. */ + private float mDefaultStartVelocity = 0f; + + /** Start delay to use when start is called. */ + private long mStartDelay = 0; + + /** End actions to call when animations for the given property complete. */ + private Map<DynamicAnimation.ViewProperty, Runnable[]> mEndActionsForProperty = + new HashMap<>(); + + /** + * Start velocities to use for TRANSLATION_X and TRANSLATION_Y, since these are often + * provided by VelocityTrackers and differ from each other. + */ + private Map<DynamicAnimation.ViewProperty, Float> mPositionStartVelocities = + new HashMap<>(); + + /** + * End actions to call when both TRANSLATION_X and TRANSLATION_Y animations have completed, + * if {@link #position} was used to animate TRANSLATION_X and TRANSLATION_Y simultaneously. + */ + private Runnable[] mPositionEndActions; + + /** + * All of the properties that have been set and will animate when {@link #start} is called. + */ + private Map<DynamicAnimation.ViewProperty, Float> mAnimatedProperties = new HashMap<>(); + + protected PhysicsPropertyAnimator(View view) { + this.mView = view; } - @Override - public void onAnimationEnd(DynamicAnimation animation, boolean canceled, float value, - float velocity) { - if (!arePropertiesAnimating(mViewProperties)) { - onAllAnimationsForPropertiesEnd(); + /** Animate a property to the given value, then call the optional end actions. */ + public PhysicsPropertyAnimator property( + DynamicAnimation.ViewProperty property, float value, Runnable... endActions) { + mAnimatedProperties.put(property, value); + mEndActionsForProperty.put(property, endActions); + return this; + } + + /** Animate the view's alpha value to the provided value. */ + public PhysicsPropertyAnimator alpha(float alpha, Runnable... endActions) { + return property(DynamicAnimation.ALPHA, alpha, endActions); + } + + /** Set the view's alpha value to 'from', then animate it to the given value. */ + public PhysicsPropertyAnimator alpha(float from, float to, Runnable... endActions) { + mView.setAlpha(from); + return alpha(to, endActions); + } + + /** Animate the view's translationX value to the provided value. */ + public PhysicsPropertyAnimator translationX(float translationX, Runnable... endActions) { + return property(DynamicAnimation.TRANSLATION_X, translationX, endActions); + } + + /** Set the view's translationX value to 'from', then animate it to the given value. */ + public PhysicsPropertyAnimator translationX( + float from, float to, Runnable... endActions) { + mView.setTranslationX(from); + return translationX(to, endActions); + } + + /** Animate the view's translationY value to the provided value. */ + public PhysicsPropertyAnimator translationY(float translationY, Runnable... endActions) { + return property(DynamicAnimation.TRANSLATION_Y, translationY, endActions); + } + + /** Set the view's translationY value to 'from', then animate it to the given value. */ + public PhysicsPropertyAnimator translationY( + float from, float to, Runnable... endActions) { + mView.setTranslationY(from); + return translationY(to, endActions); + } + + /** + * Animate the view's translationX and translationY values, and call the end actions only + * once both TRANSLATION_X and TRANSLATION_Y animations have completed. + */ + public PhysicsPropertyAnimator position( + float translationX, float translationY, Runnable... endActions) { + mPositionEndActions = endActions; + translationX(translationX); + return translationY(translationY); + } + + /** Animate the view's scaleX value to the provided value. */ + public PhysicsPropertyAnimator scaleX(float scaleX, Runnable... endActions) { + return property(DynamicAnimation.SCALE_X, scaleX, endActions); + } + + /** Set the view's scaleX value to 'from', then animate it to the given value. */ + public PhysicsPropertyAnimator scaleX(float from, float to, Runnable... endActions) { + mView.setScaleX(from); + return scaleX(to, endActions); + } + + /** Animate the view's scaleY value to the provided value. */ + public PhysicsPropertyAnimator scaleY(float scaleY, Runnable... endActions) { + return property(DynamicAnimation.SCALE_Y, scaleY, endActions); + } + + /** Set the view's scaleY value to 'from', then animate it to the given value. */ + public PhysicsPropertyAnimator scaleY(float from, float to, Runnable... endActions) { + mView.setScaleY(from); + return scaleY(to, endActions); + } + + /** Set the start velocity to use for all property animations. */ + public PhysicsPropertyAnimator withStartVelocity(float startVel) { + mDefaultStartVelocity = startVel; + return this; + } + + /** + * Set the start velocities to use for TRANSLATION_X and TRANSLATION_Y animations. This + * overrides any value set via {@link #withStartVelocity(float)} for those properties. + */ + public PhysicsPropertyAnimator withPositionStartVelocities(float velX, float velY) { + mPositionStartVelocities.put(DynamicAnimation.TRANSLATION_X, velX); + mPositionStartVelocities.put(DynamicAnimation.TRANSLATION_Y, velY); + return this; + } + + /** Set a delay, in milliseconds, before kicking off the animations. */ + public PhysicsPropertyAnimator withStartDelay(long startDelay) { + mStartDelay = startDelay; + return this; + } - for (DynamicAnimation.ViewProperty property : mViewProperties) { - removeEndListenerForProperty(property); + /** + * Start the animations, and call the optional end actions once all animations for every + * animated property on every child (including chained animations) have ended. + */ + public void start(Runnable... after) { + final Set<DynamicAnimation.ViewProperty> properties = getAnimatedProperties(); + + // If there are end actions, set an end listener on the layout for all the properties + // we're about to animate. + if (after != null) { + final DynamicAnimation.ViewProperty[] propertiesArray = + properties.toArray(new DynamicAnimation.ViewProperty[0]); + for (Runnable callback : after) { + setEndActionForMultipleProperties(callback, propertiesArray); } } + + // If we used position-specific end actions, we'll need to listen for both TRANSLATION_X + // and TRANSLATION_Y animations ending, and call them once both have finished. + if (mPositionEndActions != null) { + final SpringAnimation translationXAnim = + getAnimationFromView(DynamicAnimation.TRANSLATION_X, mView); + final SpringAnimation translationYAnim = + getAnimationFromView(DynamicAnimation.TRANSLATION_Y, mView); + final Runnable waitForBothXAndY = () -> { + if (!translationXAnim.isRunning() && !translationYAnim.isRunning()) { + if (mPositionEndActions != null) { + for (Runnable callback : mPositionEndActions) { + callback.run(); + } + } + + mPositionEndActions = null; + } + }; + + mEndActionsForProperty.put(DynamicAnimation.TRANSLATION_X, + new Runnable[]{waitForBothXAndY}); + mEndActionsForProperty.put(DynamicAnimation.TRANSLATION_Y, + new Runnable[]{waitForBothXAndY}); + } + + // Actually start the animations. + for (DynamicAnimation.ViewProperty property : properties) { + animateValueForChild( + property, + mView, + mAnimatedProperties.get(property), + mPositionStartVelocities.getOrDefault(property, mDefaultStartVelocity), + mStartDelay, + mEndActionsForProperty.get(property)); + } + + // Clear out the animator. + mAnimatedProperties.clear(); + mPositionStartVelocities.clear(); + mDefaultStartVelocity = 0; + mStartDelay = 0; + mEndActionsForProperty.clear(); } - /** Called when every animation for every property has finished. */ - abstract void onAllAnimationsForPropertiesEnd(); + /** Returns the set of properties that will animate once {@link #start} is called. */ + protected Set<DynamicAnimation.ViewProperty> getAnimatedProperties() { + return mAnimatedProperties.keySet(); + } + + /** + * Animates the property of the given child view, then runs the callback provided when the + * animation ends. + */ + protected void animateValueForChild( + DynamicAnimation.ViewProperty property, + View view, + float value, + float startVel, + long startDelay, + Runnable[] afterCallbacks) { + if (view != null) { + final SpringAnimation animation = + (SpringAnimation) view.getTag(getTagIdForProperty(property)); + if (afterCallbacks != null) { + animation.addEndListener(new OneTimeEndListener() { + @Override + public void onAnimationEnd(DynamicAnimation animation, boolean canceled, + float value, float velocity) { + super.onAnimationEnd(animation, canceled, value, velocity); + for (Runnable runnable : afterCallbacks) { + runnable.run(); + } + } + }); + } + + if (startVel > 0) { + animation.setStartVelocity(startVel); + } + + if (startDelay > 0) { + postDelayed(() -> animation.animateToFinalPosition(value), startDelay); + } else { + animation.animateToFinalPosition(value); + } + } + } } } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java index 3c4bc7259a62..c39503129454 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java @@ -206,12 +206,12 @@ public class StackAnimationController extends .setDampingRatio(SPRING_DAMPING_RATIO), /* destination */ null); - mLayout.setEndListenerForProperties( - (animation, canceled, value, velocity) -> { + mLayout.setEndActionForMultipleProperties( + () -> { mRestingStackPosition = new PointF(); mRestingStackPosition.set(mStackPosition); - mLayout.removeEndListenerForProperty(DynamicAnimation.TRANSLATION_X); - mLayout.removeEndListenerForProperty(DynamicAnimation.TRANSLATION_Y); + mLayout.removeEndActionForProperty(DynamicAnimation.TRANSLATION_X); + mLayout.removeEndActionForProperty(DynamicAnimation.TRANSLATION_Y); }, DynamicAnimation.TRANSLATION_X, DynamicAnimation.TRANSLATION_Y); } @@ -292,8 +292,8 @@ public class StackAnimationController extends cancelStackPositionAnimation(DynamicAnimation.TRANSLATION_X); cancelStackPositionAnimation(DynamicAnimation.TRANSLATION_Y); - mLayout.removeEndListenerForProperty(DynamicAnimation.TRANSLATION_X); - mLayout.removeEndListenerForProperty(DynamicAnimation.TRANSLATION_Y); + mLayout.removeEndActionForProperty(DynamicAnimation.TRANSLATION_X); + mLayout.removeEndActionForProperty(DynamicAnimation.TRANSLATION_Y); } /** @@ -441,19 +441,18 @@ public class StackAnimationController extends @Override void onChildRemoved(View child, int index, Runnable finishRemoval) { - // Animate the child out, actually removing it once its alpha is zero. - mLayout.animateValueForChild(DynamicAnimation.ALPHA, child, 0f, finishRemoval); - mLayout.animateValueForChild(DynamicAnimation.SCALE_X, child, ANIMATE_IN_STARTING_SCALE); - mLayout.animateValueForChild(DynamicAnimation.SCALE_Y, child, ANIMATE_IN_STARTING_SCALE); - // Animate the removing view in the opposite direction of the stack. final float xOffset = getOffsetForChainedPropertyAnimation(DynamicAnimation.TRANSLATION_X); - mLayout.animateValueForChild(DynamicAnimation.TRANSLATION_X, child, - mStackPosition.x - (-xOffset * ANIMATE_TRANSLATION_FACTOR)); + animationForChild(child) + .alpha(0f, finishRemoval /* after */) + .scaleX(ANIMATE_IN_STARTING_SCALE) + .scaleY(ANIMATE_IN_STARTING_SCALE) + .translationX(mStackPosition.x - (-xOffset * ANIMATE_TRANSLATION_FACTOR)) + .start(); - // Pull the top of the stack to the correct position, the chained animations will instruct - // any children that are out of place to animate to the correct position. - mLayout.animateValueForChildAtIndex(DynamicAnimation.TRANSLATION_X, 0, mStackPosition.x); + if (mLayout.getChildCount() > 0) { + animationForChildAtIndex(0).translationX(mStackPosition.x).start(); + } } /** Moves the stack, without any animation, to the starting position. */ @@ -486,10 +485,12 @@ public class StackAnimationController extends if (mLayout.getChildCount() > 0) { property.setValue(mLayout.getChildAt(0), value); - mLayout.animateValueForChildAtIndex( - property, - /* index */ 1, - value + getOffsetForChainedPropertyAnimation(property)); + + if (mLayout.getChildCount() > 1) { + animationForChildAtIndex(1) + .property(property, value + getOffsetForChainedPropertyAnimation(property)) + .start(); + } } } @@ -520,23 +521,15 @@ public class StackAnimationController extends private void animateInBubble(View child) { child.setTranslationY(mStackPosition.y); - // Pop in the new bubble. - child.setScaleX(ANIMATE_IN_STARTING_SCALE); - child.setScaleY(ANIMATE_IN_STARTING_SCALE); - mLayout.animateValueForChildAtIndex(DynamicAnimation.SCALE_X, 0, 1f); - mLayout.animateValueForChildAtIndex(DynamicAnimation.SCALE_Y, 0, 1f); - - // Fade in the new bubble. - child.setAlpha(0); - mLayout.animateValueForChildAtIndex(DynamicAnimation.ALPHA, 0, 1f); - - // Start the new bubble 4x the normal offset distance in the opposite direction. We'll - // animate in from this position. Since the animations are chained, when the new bubble - // flies in from the side, it will push the other ones out of the way. float xOffset = getOffsetForChainedPropertyAnimation(DynamicAnimation.TRANSLATION_X); - child.setTranslationX(mStackPosition.x - ANIMATE_TRANSLATION_FACTOR * xOffset); - mLayout.animateValueForChildAtIndex( - DynamicAnimation.TRANSLATION_X, 0, mStackPosition.x); + animationForChild(child) + .scaleX(ANIMATE_IN_STARTING_SCALE /* from */, 1f /* to */) + .scaleY(ANIMATE_IN_STARTING_SCALE /* from */, 1f /* to */) + .alpha(0f /* from */, 1f /* to */) + .translationX( + mStackPosition.x - ANIMATE_TRANSLATION_FACTOR * xOffset /* from */, + mStackPosition.x /* to */) + .start(); } /** diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java index 6c4be0617043..c243899c6bc9 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java @@ -211,7 +211,7 @@ public class DozeMachine { mDozeService.requestWakeUp(); } - private boolean isExecutingTransition() { + public boolean isExecutingTransition() { return !mQueuedRequests.isEmpty(); } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java index 031f56266ea4..7189a48fed1f 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java @@ -198,6 +198,14 @@ public class DozeTriggers implements DozeMachine.Part { } private void onProximityFar(boolean far) { + // Proximity checks are asynchronous and the user might have interacted with the phone + // when a new event is arriving. This means that a state transition might have happened + // and the proximity check is now obsolete. + if (mMachine.isExecutingTransition()) { + Log.w(TAG, "onProximityFar called during transition. Ignoring sensor response."); + return; + } + final boolean near = !far; final DozeMachine.State state = mMachine.getState(); final boolean paused = (state == DozeMachine.State.DOZE_AOD_PAUSED); diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java index 477e7d7ebf72..d1939d0fddb0 100644 --- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java +++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java @@ -85,7 +85,9 @@ class ImageProcessHelper { Bitmap bitmap = bitmaps[0]; if (bitmap != null) { int[] histogram = processHistogram(bitmap); - return computePercentile85(bitmap, histogram); + Float val = computePercentile85(bitmap, histogram); + bitmaps[0] = null; + return val; } Log.e(TAG, "Per85ComputeTask: Can't get bitmap"); return DEFAULT_PER85; diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 676e59428075..d70d0d80c681 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -90,6 +90,7 @@ import com.android.systemui.statusbar.phone.BiometricUnlockController; import com.android.systemui.statusbar.phone.NotificationPanelView; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; +import com.android.systemui.util.InjectionInflationController; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -710,7 +711,10 @@ public class KeyguardViewMediator extends SystemUI { mContext.registerReceiver(mDelayedLockBroadcastReceiver, delayedActionFilter, SYSTEMUI_PERMISSION, null /* scheduler */); - mKeyguardDisplayManager = new KeyguardDisplayManager(mContext); + InjectionInflationController injectionInflationController = + new InjectionInflationController(SystemUIFactory.getInstance().getRootComponent()); + mKeyguardDisplayManager = new KeyguardDisplayManager(mContext, + injectionInflationController); mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java index 9f0f53e0d508..3a0534d24f59 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java +++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java @@ -38,8 +38,10 @@ import android.text.TextPaint; import android.text.TextUtils; import android.text.style.StyleSpan; import android.util.Log; +import android.view.View; import android.view.Window; import android.view.WindowManager; +import android.widget.TextView; import com.android.systemui.R; @@ -133,9 +135,12 @@ public class MediaProjectionPermissionActivity extends Activity String dialogTitle = getString(R.string.media_projection_dialog_title, appName); + View dialogTitleView = View.inflate(this, R.layout.media_projection_dialog_title, null); + TextView titleText = (TextView) dialogTitleView.findViewById(R.id.dialog_title); + titleText.setText(dialogTitle); + mDialog = new AlertDialog.Builder(this) - .setTitle(dialogTitle) - .setIcon(R.drawable.ic_media_projection_permission) + .setCustomTitle(dialogTitleView) .setMessage(message) .setPositiveButton(R.string.media_projection_action_text, this) .setNegativeButton(android.R.string.cancel, this) diff --git a/packages/SystemUI/src/com/android/systemui/media/OWNERS b/packages/SystemUI/src/com/android/systemui/media/OWNERS new file mode 100644 index 000000000000..69ea57bfd397 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/media/OWNERS @@ -0,0 +1 @@ +per-file MediaProjectionPermissionActivity.java = michaelwr@google.com diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java index 0ae8f6c9de5b..10eacbaefd9a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java @@ -87,7 +87,6 @@ public class QSFooterImpl extends FrameLayout implements QSFooter, private boolean mListening; - private View mDivider; protected MultiUserSwitch mMultiUserSwitch; private ImageView mMultiUserAvatar; @@ -133,7 +132,6 @@ public class QSFooterImpl extends FrameLayout implements QSFooter, @Override protected void onFinishInflate() { super.onFinishInflate(); - mDivider = findViewById(R.id.qs_footer_divider); mEdit = findViewById(android.R.id.edit); mEdit.setOnClickListener(view -> mActivityStarter.postQSRunnableDismissingKeyguard(() -> @@ -218,7 +216,6 @@ public class QSFooterImpl extends FrameLayout implements QSFooter, @Nullable private TouchAnimator createFooterAnimator() { return new TouchAnimator.Builder() - .addFloat(mDivider, "alpha", 0, 1) .addFloat(mActionsContainer, "alpha", 0, 1) .addFloat(mEditContainer, "alpha", 0, 1) .addFloat(mDragHandle, "alpha", 1, 0, 0) diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java index c897b9c3b467..d78982183db9 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java @@ -395,14 +395,13 @@ public class QuickStatusBarHeader extends RelativeLayout implements private void updateStatusIconAlphaAnimator() { mStatusIconsAlphaAnimator = new TouchAnimator.Builder() - .addFloat(mQuickQsStatusIcons, "alpha", 1, 0) + .addFloat(mQuickQsStatusIcons, "alpha", 1, 0, 0) .build(); } private void updateHeaderTextContainerAlphaAnimator() { mHeaderTextContainerAlphaAnimator = new TouchAnimator.Builder() - .addFloat(mHeaderTextContainerView, "alpha", 0, 1) - .setStartDelay(.5f) + .addFloat(mHeaderTextContainerView, "alpha", 0, 0, 1) .build(); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java index d26cee982b64..2956ad0600a7 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java @@ -41,7 +41,6 @@ import com.android.systemui.qs.tiles.LocationTile; import com.android.systemui.qs.tiles.NfcTile; import com.android.systemui.qs.tiles.NightDisplayTile; import com.android.systemui.qs.tiles.RotationLockTile; -import com.android.systemui.qs.tiles.SensorPrivacyTile; import com.android.systemui.qs.tiles.UserTile; import com.android.systemui.qs.tiles.WifiTile; import com.android.systemui.qs.tiles.WorkModeTile; @@ -73,7 +72,6 @@ public class QSFactoryImpl implements QSFactory { private final Provider<DataSaverTile> mDataSaverTileProvider; private final Provider<NightDisplayTile> mNightDisplayTileProvider; private final Provider<NfcTile> mNfcTileProvider; - private final Provider<SensorPrivacyTile> mSensorPrivacyTileProvider; private final Provider<GarbageMonitor.MemoryTile> mMemoryTileProvider; private QSTileHost mHost; @@ -96,7 +94,6 @@ public class QSFactoryImpl implements QSFactory { Provider<DataSaverTile> dataSaverTileProvider, Provider<NightDisplayTile> nightDisplayTileProvider, Provider<NfcTile> nfcTileProvider, - Provider<SensorPrivacyTile> sensorPrivacyTileProvider, Provider<GarbageMonitor.MemoryTile> memoryTileProvider) { mWifiTileProvider = wifiTileProvider; mBluetoothTileProvider = bluetoothTileProvider; @@ -115,7 +112,6 @@ public class QSFactoryImpl implements QSFactory { mDataSaverTileProvider = dataSaverTileProvider; mNightDisplayTileProvider = nightDisplayTileProvider; mNfcTileProvider = nfcTileProvider; - mSensorPrivacyTileProvider = sensorPrivacyTileProvider; mMemoryTileProvider = memoryTileProvider; } @@ -168,8 +164,6 @@ public class QSFactoryImpl implements QSFactory { return mNightDisplayTileProvider.get(); case "nfc": return mNfcTileProvider.get(); - case "sensorprivacy": - return mSensorPrivacyTileProvider.get(); } // Intent tiles. 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 effa935c5c20..241b375ffeaa 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java @@ -19,11 +19,12 @@ package com.android.systemui.qs.tiles; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_QS_MODE; import android.annotation.Nullable; -import android.app.ActivityManager; import android.content.Intent; import android.hardware.display.ColorDisplayManager; import android.hardware.display.NightDisplayListener; import android.metrics.LogMaker; +import android.os.Handler; +import android.os.Looper; import android.provider.Settings; import android.service.quicksettings.Tile; import android.text.TextUtils; @@ -66,7 +67,7 @@ public class NightDisplayTile extends QSTileImpl<BooleanState> implements public NightDisplayTile(QSHost host) { super(host); mManager = mContext.getSystemService(ColorDisplayManager.class); - mListener = new NightDisplayListener(mContext, ActivityManager.getCurrentUser()); + mListener = new NightDisplayListener(mContext, new Handler(Looper.myLooper())); } @Override @@ -102,7 +103,7 @@ public class NightDisplayTile extends QSTileImpl<BooleanState> implements } // Make a new controller for the new user. - mListener = new NightDisplayListener(mContext, newUserId); + mListener = new NightDisplayListener(mContext, newUserId, new Handler(Looper.myLooper())); if (mIsListening) { mListener.setCallback(this); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyTile.java deleted file mode 100644 index 7ee37d567a55..000000000000 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyTile.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2018 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.tiles; - -import android.content.Intent; -import android.hardware.SensorPrivacyManager; -import android.service.quicksettings.Tile; -import android.widget.Switch; - -import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.R; -import com.android.systemui.plugins.ActivityStarter; -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.KeyguardMonitor; - -import javax.inject.Inject; - -/** Quick settings tile: SensorPrivacy mode **/ -public class SensorPrivacyTile extends QSTileImpl<BooleanState> implements - SensorPrivacyManager.OnSensorPrivacyChangedListener { - private static final String TAG = "SensorPrivacy"; - private final Icon mIcon = - ResourceIcon.get(R.drawable.ic_signal_sensors); - private final KeyguardMonitor mKeyguard; - private final SensorPrivacyManager mSensorPrivacyManager; - private final ActivityStarter mActivityStarter; - - @Inject - public SensorPrivacyTile(QSHost host, SensorPrivacyManager sensorPrivacyManager, - KeyguardMonitor keyguardMonitor, ActivityStarter activityStarter) { - super(host); - - mSensorPrivacyManager = sensorPrivacyManager; - mKeyguard = keyguardMonitor; - mActivityStarter = activityStarter; - } - - @Override - public BooleanState newTileState() { - return new BooleanState(); - } - - @Override - public void handleClick() { - final boolean wasEnabled = mState.value; - // Don't allow disabling from the lockscreen. - if (wasEnabled && mKeyguard.isSecure() && mKeyguard.isShowing()) { - mActivityStarter.postQSRunnableDismissingKeyguard(() -> { - MetricsLogger.action(mContext, getMetricsCategory(), !wasEnabled); - setEnabled(!wasEnabled); - }); - return; - } - - MetricsLogger.action(mContext, getMetricsCategory(), !wasEnabled); - setEnabled(!wasEnabled); - } - - private void setEnabled(boolean enabled) { - mSensorPrivacyManager.setSensorPrivacy(enabled); - } - - @Override - public CharSequence getTileLabel() { - return mContext.getString(R.string.sensor_privacy_mode); - } - - @Override - public Intent getLongClickIntent() { - return new Intent(); - } - - @Override - protected void handleUpdateState(BooleanState state, Object arg) { - final boolean enabled = arg instanceof Boolean ? (Boolean) arg - : mSensorPrivacyManager.isSensorPrivacyEnabled(); - state.value = enabled; - state.label = mContext.getString(R.string.sensor_privacy_mode); - state.icon = mIcon; - state.state = enabled ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE; - state.contentDescription = state.label; - state.expandedAccessibilityClassName = Switch.class.getName(); - } - - @Override - public int getMetricsCategory() { - return MetricsEvent.QS_SENSOR_PRIVACY; - } - - @Override - protected String composeChangeAnnouncement() { - if (mState.value) { - return mContext - .getString(R.string.accessibility_quick_settings_sensor_privacy_changed_on); - } else { - return mContext - .getString(R.string.accessibility_quick_settings_sensor_privacy_changed_off); - } - } - - @Override - protected void handleSetListening(boolean listening) { - if (listening) { - mSensorPrivacyManager.addSensorPrivacyListener(this); - } else { - mSensorPrivacyManager.removeSensorPrivacyListener(this); - } - } - - @Override - public void onSensorPrivacyChanged(boolean enabled) { - refreshState(enabled); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java index 92195942ca06..494e6cde5a1c 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java +++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java @@ -46,7 +46,6 @@ import android.os.Looper; import android.os.PatternMatcher; import android.os.RemoteException; import android.os.UserHandle; -import android.provider.Settings; import android.util.Log; import android.view.InputChannel; import android.view.MotionEvent; @@ -60,6 +59,7 @@ import com.android.systemui.shared.recents.IOverviewProxy; import com.android.systemui.shared.recents.ISystemUiProxy; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.InputChannelCompat.InputEventDispatcher; +import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.stackdivider.Divider; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.CallbackController; @@ -589,11 +589,9 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis private int getDefaultInteractionFlags() { // If there is no settings available use device default or get it from settings - final boolean defaultState = getSwipeUpDefaultValue(); - final boolean swipeUpEnabled = getSwipeUpSettingAvailable() - ? getSwipeUpEnabledFromSettings(defaultState) - : defaultState; - return swipeUpEnabled ? 0 : DEFAULT_DISABLE_SWIPE_UP_STATE; + return QuickStepContract.isLegacyMode(mContext) + ? DEFAULT_DISABLE_SWIPE_UP_STATE + : 0; } private void notifyBackButtonAlphaChanged(float alpha, boolean animate) { @@ -638,21 +636,6 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis ActivityManagerWrapper.getInstance().getCurrentUserId()) != null; } - private boolean getSwipeUpDefaultValue() { - return mContext.getResources() - .getBoolean(com.android.internal.R.bool.config_swipe_up_gesture_default); - } - - private boolean getSwipeUpSettingAvailable() { - return mContext.getResources() - .getBoolean(com.android.internal.R.bool.config_swipe_up_gesture_setting_available); - } - - private boolean getSwipeUpEnabledFromSettings(boolean defaultValue) { - return Settings.Secure.getInt(mContext.getContentResolver(), - Settings.Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED, defaultValue ? 1 : 0) == 1; - } - @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println(TAG_OPS + " state:"); @@ -665,11 +648,8 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis pw.print(" quickStepIntent="); pw.println(mQuickStepIntent); pw.print(" quickStepIntentResolved="); pw.println(isEnabled()); - - final boolean swipeUpDefaultValue = getSwipeUpDefaultValue(); - final boolean swipeUpEnabled = getSwipeUpEnabledFromSettings(swipeUpDefaultValue); - pw.print(" swipeUpSetting="); pw.println(swipeUpEnabled); - pw.print(" swipeUpSettingDefault="); pw.println(swipeUpDefaultValue); + pw.print(" navBarMode="); + pw.println(QuickStepContract.getCurrentInteractionMode(mContext)); } public interface OverviewProxyListener { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java index be63bad47d4a..aeaceb0c11e5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java @@ -79,7 +79,7 @@ public class NotificationListener extends NotificationListenerWithPlugins { } }); NotificationManager noMan = mContext.getSystemService(NotificationManager.class); - onStatusBarIconsBehaviorChanged(noMan.shouldHideSilentStatusBarIcons()); + onSilentStatusBarIconsVisibilityChanged(noMan.shouldHideSilentStatusBarIcons()); } @Override @@ -144,7 +144,7 @@ public class NotificationListener extends NotificationListenerWithPlugins { } @Override - public void onStatusBarIconsBehaviorChanged(boolean hideSilentStatusIcons) { + public void onSilentStatusBarIconsVisibilityChanged(boolean hideSilentStatusIcons) { for (NotificationSettingsListener listener : mSettingsListeners) { listener.onStatusBarIconsBehaviorChanged(hideSilentStatusIcons); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index 813faa9ee4ed..520df9797cc3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -36,6 +36,7 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.Outline; import android.graphics.Paint; import android.graphics.PointF; import android.graphics.PorterDuff; @@ -58,6 +59,7 @@ import android.view.VelocityTracker; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; +import android.view.ViewOutlineProvider; import android.view.ViewTreeObserver; import android.view.WindowInsets; import android.view.accessibility.AccessibilityEvent; @@ -394,6 +396,16 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd } } }; + private final ViewOutlineProvider mOutlineProvider = new ViewOutlineProvider() { + @Override + public void getOutline(View view, Outline outline) { + if (mAmbientState.isDarkAtAll() && !mAmbientState.isFullyDark()) { + outline.setRoundRect(mBackgroundAnimationRect, mCornerRadius); + } else { + ViewOutlineProvider.BACKGROUND.getOutline(view, outline); + } + } + }; private PorterDuffXfermode mSrcMode = new PorterDuffXfermode(PorterDuff.Mode.SRC); private boolean mPulsing; private boolean mGroupExpandedForMeasure; @@ -520,6 +532,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd mRoundnessManager.setAnimatedChildren(mChildrenToAddAnimated); mRoundnessManager.setOnRoundingChangedCallback(this::invalidate); addOnExpandedHeightListener(mRoundnessManager::setExpanded); + setOutlineProvider(mOutlineProvider); // Blocking helper manager wants to know the expanded state, update as well. NotificationBlockingHelperManager blockingHelperManager = @@ -1298,6 +1311,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd public void updateClipping() { boolean clipped = mRequestedClipBounds != null && !mInHeadsUpPinnedMode && !mHeadsUpAnimatingAway; + boolean clipToOutline = false; if (mIsClipped != clipped) { mIsClipped = clipped; } @@ -1306,12 +1320,15 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd && mAmbientState.isFullyDark() && mShowDarkShelf) { setClipBounds(null); } else if (mAmbientState.isDarkAtAll()) { - setClipBounds(mBackgroundAnimationRect); + clipToOutline = true; + invalidateOutline(); } else if (clipped) { setClipBounds(mRequestedClipBounds); } else { setClipBounds(null); } + + setClipToOutline(clipToOutline); } /** @@ -4805,6 +4822,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd if (!wasDarkAtAll && nowDarkAtAll) { resetExposedMenuView(true /* animate */, true /* animate */); } + if (nowFullyDark != wasFullyDark || wasDarkAtAll != nowDarkAtAll) { + invalidateOutline(); + } updateAlgorithmHeightAndPadding(); updateBackgroundDimming(); updatePanelTranslation(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java index 5a7df1f21bbd..ca452093eb20 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.phone; import android.content.Context; import android.hardware.biometrics.BiometricSourceType; +import android.metrics.LogMaker; import android.os.Handler; import android.os.PowerManager; import android.os.SystemClock; @@ -26,6 +27,8 @@ import android.provider.Settings; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.logging.MetricsLogger; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.LatencyTracker; import com.android.keyguard.KeyguardConstants; import com.android.keyguard.KeyguardUpdateMonitor; @@ -140,6 +143,8 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback { } }; + private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class); + public BiometricUnlockController(Context context, DozeScrimController dozeScrimController, KeyguardViewMediator keyguardViewMediator, @@ -253,6 +258,8 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback { Trace.endSection(); return; } + mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH) + .setType(MetricsEvent.TYPE_SUCCESS).setSubtype(toSubtype(biometricSourceType))); startWakeAndUnlock(calculateMode(biometricSourceType)); } @@ -420,12 +427,16 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback { @Override public void onBiometricAuthFailed(BiometricSourceType biometricSourceType) { + mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH) + .setType(MetricsEvent.TYPE_FAILURE).setSubtype(toSubtype(biometricSourceType))); cleanup(); } @Override public void onBiometricError(int msgId, String errString, BiometricSourceType biometricSourceType) { + mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH) + .setType(MetricsEvent.TYPE_ERROR).setSubtype(toSubtype(biometricSourceType))); cleanup(); } @@ -501,4 +512,20 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback { public boolean isBiometricUnlock() { return isWakeAndUnlock() || mMode == MODE_UNLOCK; } + + /** + * Translates biometric source type for logging purpose. + */ + private int toSubtype(BiometricSourceType biometricSourceType) { + switch (biometricSourceType) { + case FINGERPRINT: + return 0; + case FACE: + return 1; + case IRIS: + return 2; + default: + return 3; + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java index 847f3ff9f24d..800ae5801016 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -67,6 +67,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; +import com.android.systemui.ActivityIntentHelper; import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; @@ -170,6 +171,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL private boolean mDozing; private int mIndicationBottomMargin; private float mDarkAmount; + private ActivityIntentHelper mActivityIntentHelper; public KeyguardBottomAreaView(Context context) { this(context, null); @@ -235,6 +237,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL protected void onFinishInflate() { super.onFinishInflate(); mLockPatternUtils = new LockPatternUtils(mContext); + mPreviewInflater = new PreviewInflater(mContext, new LockPatternUtils(mContext), + new ActivityIntentHelper(mContext)); mPreviewContainer = findViewById(R.id.preview_container); mOverlayContainer = findViewById(R.id.overlay_container); mRightAffordanceView = findViewById(R.id.camera_button); @@ -254,7 +258,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL mLockIcon.update(); setClipChildren(false); setClipToPadding(false); - mPreviewInflater = new PreviewInflater(mContext, new LockPatternUtils(mContext)); inflateCameraPreview(); mLockIcon.setOnClickListener(this); mLockIcon.setOnLongClickListener(this); @@ -266,6 +269,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL mAccessibilityController = Dependency.get(AccessibilityController.class); mAssistManager = Dependency.get(AssistManager.class); mLockIcon.setAccessibilityController(mAccessibilityController); + mActivityIntentHelper = new ActivityIntentHelper(getContext()); updateLeftAffordance(); } @@ -459,7 +463,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL public void bindCameraPrewarmService() { Intent intent = getCameraIntent(); - ActivityInfo targetInfo = PreviewInflater.getTargetActivityInfo(mContext, intent, + ActivityInfo targetInfo = mActivityIntentHelper.getTargetActivityInfo(intent, KeyguardUpdateMonitor.getCurrentUser(), true /* onlyDirectBootAware */); if (targetInfo != null && targetInfo.metaData != null) { String clazz = targetInfo.metaData.getString( @@ -500,8 +504,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL public void launchCamera(String source) { final Intent intent = getCameraIntent(); intent.putExtra(EXTRA_CAMERA_LAUNCH_SOURCE, source); - boolean wouldLaunchResolverActivity = PreviewInflater.wouldLaunchResolverActivity( - mContext, intent, KeyguardUpdateMonitor.getCurrentUser()); + boolean wouldLaunchResolverActivity = mActivityIntentHelper.wouldLaunchResolverActivity( + intent, KeyguardUpdateMonitor.getCurrentUser()); if (intent == SECURE_CAMERA_INTENT && !wouldLaunchResolverActivity) { AsyncTask.execute(new Runnable() { @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java index c8ce39230da8..4c50d07aa6ea 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java @@ -468,6 +468,11 @@ public class KeyguardStatusBarView extends RelativeLayout } @Override + public void onDensityOrFontScaleChanged() { + loadDimens(); + } + + @Override public void onOverlayChanged() { mCarrierLabel.setTextAppearance( Utils.getThemeAttr(mContext, com.android.internal.R.attr.textAppearanceSmall)); @@ -514,6 +519,8 @@ public class KeyguardStatusBarView extends RelativeLayout return; } mDozing = dozing; + setClipChildren(!dozing); + setClipToPadding(!dozing); updateVisibilities(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java index 2d54970cdfa8..9cfb1aa192b1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java @@ -21,10 +21,11 @@ import static android.view.Display.DEFAULT_DISPLAY; import android.content.Context; import android.graphics.Rect; import android.os.Handler; -import android.provider.Settings; import android.view.CompositionSamplingListener; import android.view.View; +import com.android.systemui.shared.system.QuickStepContract; + import java.io.PrintWriter; /** @@ -166,9 +167,6 @@ public class NavBarTintController implements View.OnAttachStateChangeListener, public static boolean isEnabled(Context context) { return context.getDisplayId() == DEFAULT_DISPLAY - && Settings.Global.getInt(context.getContentResolver(), - NavigationPrototypeController.NAV_COLOR_ADAPT_ENABLE_SETTING, 0) == 1 - && Settings.Global.getInt(context.getContentResolver(), - NavigationPrototypeController.SHOW_HOME_HANDLE_SETTING, 0) == 1; + && QuickStepContract.isGesturalMode(context); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java index 1478a0780eb7..c77b16b23e67 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java @@ -71,7 +71,7 @@ public class NavigationBackAction extends NavigationGestureAction { @Override protected void onGestureStart(MotionEvent event) { - if (!QuickStepController.shouldhideBackButton(getContext())) { + if (!QuickStepController.shouldHideBackButton(getContext())) { mNavigationBarView.getBackButton().setAlpha(0 /* alpha */, true /* animate */, BACK_BUTTON_FADE_OUT_ALPHA); } @@ -85,7 +85,7 @@ public class NavigationBackAction extends NavigationGestureAction { @Override protected void onGestureEnd() { mHandler.removeCallbacks(mExecuteBackRunnable); - if (!QuickStepController.shouldhideBackButton(getContext())) { + if (!QuickStepController.shouldHideBackButton(getContext())) { mNavigationBarView.getBackButton().setAlpha( mProxySender.getBackButtonAlpha(), true /* animate */); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java index ea30451175d4..cbb5d5430e8d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java @@ -201,7 +201,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback @Override public void onBackButtonAlphaChanged(float alpha, boolean animate) { final ButtonDispatcher backButton = mNavigationBarView.getBackButton(); - if (QuickStepController.shouldhideBackButton(getContext())) { + if (QuickStepController.shouldHideBackButton(getContext())) { // If property was changed to hide/show back button, going home will trigger // launcher to to change the back button alpha to reflect property change backButton.setVisibility(View.GONE); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java index faa2ab105816..26aa617db167 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java @@ -38,6 +38,7 @@ import com.android.systemui.plugins.PluginListener; import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.shared.plugins.PluginManager; +import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.statusbar.phone.ReverseLinearLayout.ReverseRelativeLayout; import com.android.systemui.statusbar.policy.KeyButtonView; import com.android.systemui.tuner.TunerService; @@ -136,10 +137,12 @@ public class NavigationBarInflaterView extends FrameLayout } protected String getDefaultLayout() { - final int defaultResource = mOverviewProxyService.shouldShowSwipeUpUI() - ? R.string.config_navBarLayoutQuickstep - : R.string.config_navBarLayout; - return mContext.getString(defaultResource); + final int defaultResource = QuickStepContract.isGesturalMode(getContext()) + ? R.string.config_navBarLayoutHandle + : mOverviewProxyService.shouldShowSwipeUpUI() + ? R.string.config_navBarLayoutQuickstep + : R.string.config_navBarLayout; + return getContext().getString(defaultResource); } @Override 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 18612c359dae..f809b62c2b24 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.phone; +import static android.content.Intent.ACTION_OVERLAY_CHANGED; import static android.view.MotionEvent.ACTION_DOWN; import static android.view.WindowManagerPolicyConstants.NAV_BAR_INVALID; import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT; @@ -41,7 +42,10 @@ import android.annotation.DrawableRes; import android.annotation.IntDef; import android.annotation.SuppressLint; import android.app.StatusBarManager; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; import android.content.pm.ParceledListSlice; import android.content.res.Configuration; import android.graphics.Canvas; @@ -50,8 +54,6 @@ import android.graphics.Rect; import android.graphics.Region; import android.graphics.Region.Op; import android.os.Bundle; -import android.os.Handler; -import android.os.Message; import android.os.RemoteException; import android.os.SystemProperties; import android.util.AttributeSet; @@ -90,6 +92,7 @@ import com.android.systemui.recents.RecentsOnboarding; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.NavigationBarCompat; +import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.WindowManagerWrapper; import com.android.systemui.statusbar.phone.NavigationPrototypeController.GestureAction; import com.android.systemui.statusbar.phone.NavigationPrototypeController.OnPrototypeChangedListener; @@ -150,10 +153,6 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav private final NavigationBarTransitions mBarTransitions; private final OverviewProxyService mOverviewProxyService; - // workaround for LayoutTransitions leaving the nav buttons in a weird state (bug 5549288) - final static boolean WORKAROUND_INVALID_LAYOUT = true; - final static int MSG_CHECK_INVALID_LAYOUT = 8686; - // performs manual animation in sync with layout transitions private final NavTransitionListener mTransitionListener = new NavTransitionListener(); @@ -182,7 +181,6 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav private NavigationBackAction mBackAction; private QuickSwitchAction mQuickSwitchAction; private NavigationAssistantAction mAssistantAction; - private NavigationNotificationPanelAction mNotificationPanelAction; private NavigationBarEdgePanel mLeftEdgePanel; private NavigationBarEdgePanel mRightEdgePanel; @@ -261,29 +259,6 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav } }; - private class H extends Handler { - public void handleMessage(Message m) { - switch (m.what) { - case MSG_CHECK_INVALID_LAYOUT: - final String how = "" + m.obj; - final int w = getWidth(); - final int h = getHeight(); - final int vw = getCurrentView().getWidth(); - final int vh = getCurrentView().getHeight(); - - if (h != vh || w != vw) { - Log.w(TAG, String.format( - "*** Invalid layout in navigation bar (%s this=%dx%d cur=%dx%d)", - how, w, h, vw, vh)); - if (WORKAROUND_INVALID_LAYOUT) { - requestLayout(); - } - } - break; - } - } - } - private final AccessibilityDelegate mQuickStepAccessibilityDelegate = new AccessibilityDelegate() { private AccessibilityAction mToggleOverviewAction; @@ -310,6 +285,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav } }; + // TODO(b/112934365): To be removed private OnPrototypeChangedListener mPrototypeListener = new OnPrototypeChangedListener() { @Override public void onGestureRemap(int[] actions) { @@ -319,13 +295,15 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav @Override public void onBackButtonVisibilityChanged(boolean visible) { if (!inScreenPinning()) { - getBackButton().setVisibility(visible ? VISIBLE : GONE); + getBackButton().setVisibility(QuickStepController.shouldHideBackButton(getContext()) + ? GONE : VISIBLE); } } @Override public void onHomeButtonVisibilityChanged(boolean visible) { - getHomeButton().setVisibility(visible ? VISIBLE : GONE); + getHomeButton().setVisibility(QuickStepController.shouldHideHomeButton(getContext()) + ? GONE : VISIBLE); } @Override @@ -349,7 +327,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav @Override public void onHomeHandleVisiblilityChanged(boolean visible) { - showHomeHandle(visible); + showHomeHandle(QuickStepController.showHomeHandle(getContext())); } @Override @@ -398,6 +376,13 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav } }; + private BroadcastReceiver mOverlaysChangedReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + showHomeHandle(QuickStepController.showHomeHandle(getContext())); + } + }; + public NavigationBarView(Context context, AttributeSet attrs) { super(context, attrs); @@ -451,10 +436,14 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav mQuickScrubAction, null /* swipeLeftEdgeAction */, null /* swipeRightEdgeAction */ }; - mPrototypeController = new NavigationPrototypeController(mHandler, mContext); + mPrototypeController = new NavigationPrototypeController(context); mPrototypeController.register(); mPrototypeController.setOnPrototypeChangedListener(mPrototypeListener); mColorAdaptionController = new NavBarTintController(this, getLightTransitionsController()); + + IntentFilter filter = new IntentFilter(ACTION_OVERLAY_CHANGED); + filter.addDataScheme("package"); + context.registerReceiver(mOverlaysChangedReceiver, filter); } public NavBarTintController getColorAdaptionController() { @@ -475,10 +464,6 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav mAssistantAction = new NavigationAssistantAction(this, mOverviewProxyService, assistManager); } - if (mNotificationPanelAction == null) { - mNotificationPanelAction = new NavigationNotificationPanelAction(this, - mOverviewProxyService, panel); - } if (mGestureHelper instanceof QuickStepController) { ((QuickStepController) mGestureHelper).setComponents(this); updateNavigationGestures(); @@ -493,7 +478,12 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav private void updateNavigationGestures() { if (mGestureHelper instanceof QuickStepController) { - final int[] assignedMap = mPrototypeController.getGestureActionMap(); + // TODO: Clarify this when we remove the prototype controller + final int[] gesturalMap = {0, 7, 1, 1, 3, 3}; + final int[] normalMap = {0, 0, 0, 0, 0, 0}; + final int[] assignedMap = QuickStepContract.isGesturalMode(getContext()) + ? gesturalMap + : normalMap; ((QuickStepController) mGestureHelper).setGestureActions( getNavigationActionFromType(assignedMap[0], mDefaultGestureMap[0]), getNavigationActionFromType(assignedMap[1], mDefaultGestureMap[1]), @@ -517,8 +507,6 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav return mQuickSwitchAction; case NavigationPrototypeController.ACTION_ASSISTANT: return mAssistantAction; - case NavigationPrototypeController.ACTION_EXPAND_NOTIFICATION: - return mNotificationPanelAction; case NavigationPrototypeController.ACTION_NOTHING: return null; default: @@ -598,8 +586,6 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav getHomeButton().abortCurrentGesture(); } - private H mHandler = new H(); - public View getCurrentView() { return mCurrentView; } @@ -654,6 +640,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav } public boolean isQuickScrubEnabled() { + // TODO(b/112934365): Remove this sys prop flag return SystemProperties.getBoolean("persist.quickstep.scrub.enabled", true) && mOverviewProxyService.isEnabled() && isOverviewEnabled() && ((mOverviewProxyService.getInteractionFlags() & FLAG_DISABLE_QUICK_SCRUB) == 0); @@ -800,17 +787,17 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav mBarTransitions.reapplyDarkIntensity(); - boolean disableHome = ((mDisabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0); + boolean disableHome = QuickStepController.shouldHideHomeButton(getContext()) + || ((mDisabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0); // TODO(b/113914868): investigation log for disappearing home button Log.i(TAG, "updateNavButtonIcons (b/113914868): home disabled=" + disableHome + " mDisabledFlags=" + mDisabledFlags); - disableHome |= mPrototypeController.hideHomeButton(); // Always disable recents when alternate car mode UI is active and for secondary displays. boolean disableRecent = isRecentsButtonDisabled(); - boolean disableBack = QuickStepController.shouldhideBackButton(getContext()) + boolean disableBack = QuickStepController.shouldHideBackButton(getContext()) || (((mDisabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0) && !useAltBack); // When screen pinning, don't hide back and home when connected service or back and @@ -829,7 +816,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav disableBack = disableRecent = false; } - ViewGroup navButtons = (ViewGroup) getCurrentView().findViewById(R.id.nav_buttons); + ViewGroup navButtons = getCurrentView().findViewById(R.id.nav_buttons); if (navButtons != null) { LayoutTransition lt = navButtons.getLayoutTransition(); if (lt != null) { @@ -984,8 +971,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav } private void showHomeHandle(boolean visible) { - mNavigationInflaterView.onTuningChanged(NAV_BAR_VIEWS, - visible ? getContext().getString(R.string.config_navBarLayoutHandle) : null); + mNavigationInflaterView.onTuningChanged(NAV_BAR_VIEWS, null); // Color adaption is tied with showing home handle, only avaliable if visible if (visible) { @@ -1002,7 +988,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav // TODO(b/112934365): move this back to NavigationBarFragment when prototype is removed private void updateAssistantAvailability() { - boolean available = mAssistantAvailable && mPrototypeController.isAssistantGestureEnabled(); + boolean available = mAssistantAvailable && QuickStepContract.isGesturalMode(getContext()); if (mOverviewProxyService.getProxy() != null) { try { mOverviewProxyService.getProxy().onAssistantAvailable(available); @@ -1200,23 +1186,23 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav } @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int w = MeasureSpec.getSize(widthMeasureSpec); + int h = MeasureSpec.getSize(heightMeasureSpec); if (DEBUG) Log.d(TAG, String.format( - "onSizeChanged: (%dx%d) old: (%dx%d)", w, h, oldw, oldh)); + "onMeasure: (%dx%d) old: (%dx%d)", w, h, getMeasuredWidth(), getMeasuredHeight())); final boolean newVertical = w > 0 && h > w; if (newVertical != mIsVertical) { mIsVertical = newVertical; if (DEBUG) { - Log.d(TAG, String.format("onSizeChanged: h=%d, w=%d, vert=%s", h, w, + Log.d(TAG, String.format("onMeasure: h=%d, w=%d, vert=%s", h, w, mIsVertical ? "y" : "n")); } reorient(); notifyVerticalChangedListener(newVertical); } - - postCheckForInvalidLayout("sizeChanged"); - super.onSizeChanged(w, h, oldw, oldh); + super.onMeasure(widthMeasureSpec, heightMeasureSpec); } private void notifyVerticalChangedListener(boolean newVertical) { @@ -1271,28 +1257,6 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav return uiCarModeChanged; } - /* - @Override - protected void onLayout (boolean changed, int left, int top, int right, int bottom) { - if (DEBUG) Log.d(TAG, String.format( - "onLayout: %s (%d,%d,%d,%d)", - changed?"changed":"notchanged", left, top, right, bottom)); - super.onLayout(changed, left, top, right, bottom); - } - - // uncomment this for extra defensiveness in WORKAROUND_INVALID_LAYOUT situations: if all else - // fails, any touch on the display will fix the layout. - @Override - public boolean onInterceptTouchEvent(MotionEvent ev) { - if (DEBUG) Log.d(TAG, "onInterceptTouchEvent: " + ev.toString()); - if (ev.getAction() == MotionEvent.ACTION_DOWN) { - postCheckForInvalidLayout("touch"); - } - return super.onInterceptTouchEvent(ev); - } - */ - - private String getResourceName(int resId) { if (resId != 0) { final android.content.res.Resources res = getContext().getResources(); @@ -1306,10 +1270,6 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav } } - private void postCheckForInvalidLayout(final String how) { - mHandler.obtainMessage(MSG_CHECK_INVALID_LAYOUT, 0, 0, how).sendToTarget(); - } - private static String visibilityToString(int vis) { switch (vis) { case View.INVISIBLE: @@ -1331,7 +1291,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav NavGesture.class, false /* Only one */); setUpSwipeUpOnboarding(isQuickStepSwipeUpEnabled()); - if (mPrototypeController.isEnabled()) { + if (QuickStepContract.isGesturalMode(getContext())) { WindowManager wm = (WindowManager) getContext() .getSystemService(Context.WINDOW_SERVICE); int width = mPrototypeController.getEdgeSensitivityWidth(); @@ -1362,6 +1322,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav mGestureHelper.destroy(); } mPrototypeController.unregister(); + getContext().unregisterReceiver(mOverlaysChangedReceiver); setUpSwipeUpOnboarding(false); for (int i = 0; i < mButtonDispatchers.size(); ++i) { mButtonDispatchers.valueAt(i).onDestroy(); @@ -1478,7 +1439,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav void onVerticalChanged(boolean isVertical); } - private final Consumer<Boolean> mDockedListener = exists -> mHandler.post(() -> { + private final Consumer<Boolean> mDockedListener = exists -> post(() -> { mDockedStackExists = exists; updateRecentsIcon(); }); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationNotificationPanelAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationNotificationPanelAction.java deleted file mode 100644 index 6c7870dccd27..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationNotificationPanelAction.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.statusbar.phone; - -import android.annotation.NonNull; -import android.view.MotionEvent; - -import com.android.systemui.recents.OverviewProxyService; - -/** - * Triggers notification panel to be expanded when executed - */ -public class NavigationNotificationPanelAction extends NavigationGestureAction { - private final NotificationPanelView mPanelView; - - public NavigationNotificationPanelAction(@NonNull NavigationBarView navigationBarView, - @NonNull OverviewProxyService service, @NonNull NotificationPanelView panelView) { - super(navigationBarView, service); - mPanelView = panelView; - } - - @Override - public boolean isEnabled() { - return true; - } - - @Override - public boolean disableProxyEvents() { - return true; - } - - @Override - public void onGestureStart(MotionEvent event) { - mPanelView.expand(true); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java index 31579c26bbd0..7ea72c79501d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java @@ -47,7 +47,7 @@ public class NavigationPrototypeController extends ContentObserver { @Retention(RetentionPolicy.SOURCE) @IntDef({ACTION_DEFAULT, ACTION_QUICKSTEP, ACTION_QUICKSCRUB, ACTION_BACK, - ACTION_QUICKSWITCH, ACTION_NOTHING, ACTION_ASSISTANT, ACTION_EXPAND_NOTIFICATION}) + ACTION_QUICKSWITCH, ACTION_NOTHING, ACTION_ASSISTANT}) @interface GestureAction {} static final int ACTION_DEFAULT = 0; static final int ACTION_QUICKSTEP = 1; @@ -56,7 +56,6 @@ public class NavigationPrototypeController extends ContentObserver { static final int ACTION_QUICKSWITCH = 4; static final int ACTION_NOTHING = 5; static final int ACTION_ASSISTANT = 6; - static final int ACTION_EXPAND_NOTIFICATION = 7; private OnPrototypeChangedListener mListener; @@ -68,8 +67,8 @@ public class NavigationPrototypeController extends ContentObserver { private final Context mContext; - public NavigationPrototypeController(Handler handler, Context context) { - super(handler); + public NavigationPrototypeController(Context context) { + super(new Handler()); mContext = context; updateSwipeLTRBackSetting(); } @@ -131,7 +130,8 @@ public class NavigationPrototypeController extends ContentObserver { * @return the width for edge swipe */ public int getEdgeSensitivityWidth() { - return convertDpToPixel(getGlobalInt(EDGE_SENSITIVITY_WIDTH_SETTING, 0)); + // TODO: Move into resource + return convertDpToPixel(getGlobalInt(EDGE_SENSITIVITY_WIDTH_SETTING, 48)); } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java index 253bdfb1a206..b902e43bbac6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -92,6 +92,7 @@ import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.KeyguardUserSwitcher; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; import com.android.systemui.statusbar.policy.ZenModeController; +import com.android.systemui.util.InjectionInflationController; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -141,6 +142,7 @@ public class NotificationPanelView extends PanelView implements private static final AnimationProperties CLOCK_ANIMATION_PROPERTIES = new AnimationProperties() .setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD); + private final InjectionInflationController mInjectionInflationController; private final PowerManager mPowerManager; private final AccessibilityManager mAccessibilityManager; private final NotificationWakeUpCoordinator mWakeUpCoordinator; @@ -336,10 +338,12 @@ public class NotificationPanelView extends PanelView implements @Inject public NotificationPanelView(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs, + InjectionInflationController injectionInflationController, NotificationWakeUpCoordinator coordinator, PulseExpansionHandler pulseExpansionHandler) { super(context, attrs); setWillNotDraw(!DEBUG); + mInjectionInflationController = injectionInflationController; mFalsingManager = FalsingManager.getInstance(context); mPowerManager = context.getSystemService(PowerManager.class); mWakeUpCoordinator = coordinator; @@ -475,10 +479,11 @@ public class NotificationPanelView extends PanelView implements // Re-inflate the status view group. int index = indexOfChild(mKeyguardStatusView); removeView(mKeyguardStatusView); - mKeyguardStatusView = (KeyguardStatusView) LayoutInflater.from(mContext).inflate( - R.layout.keyguard_status_view, - this, - false); + mKeyguardStatusView = (KeyguardStatusView) mInjectionInflationController + .injectable(LayoutInflater.from(mContext)).inflate( + R.layout.keyguard_status_view, + this, + false); addView(mKeyguardStatusView, index); // Re-associate the clock container with the keyguard clock switch. @@ -490,10 +495,11 @@ public class NotificationPanelView extends PanelView implements index = indexOfChild(mKeyguardBottomArea); removeView(mKeyguardBottomArea); KeyguardBottomAreaView oldBottomArea = mKeyguardBottomArea; - mKeyguardBottomArea = (KeyguardBottomAreaView) LayoutInflater.from(mContext).inflate( - R.layout.keyguard_bottom_area, - this, - false); + mKeyguardBottomArea = (KeyguardBottomAreaView) mInjectionInflationController + .injectable(LayoutInflater.from(mContext)).inflate( + R.layout.keyguard_bottom_area, + this, + false); mKeyguardBottomArea.initFrom(oldBottomArea); addView(mKeyguardBottomArea, index); initBottomArea(); 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 4a86484393a9..b7a78738828e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -60,6 +60,7 @@ import com.android.systemui.statusbar.policy.LocationController; import com.android.systemui.statusbar.policy.NextAlarmController; import com.android.systemui.statusbar.policy.RotationLockController; import com.android.systemui.statusbar.policy.RotationLockController.RotationLockControllerCallback; +import com.android.systemui.statusbar.policy.SensorPrivacyController; import com.android.systemui.statusbar.policy.UserInfoController; import com.android.systemui.statusbar.policy.ZenModeController; @@ -100,6 +101,7 @@ public class PhoneStatusBarPolicy private final String mSlotLocation; private final String mSlotMicrophone; private final String mSlotCamera; + private final String mSlotSensorsOff; private final Context mContext; private final Handler mHandler = new Handler(); @@ -118,6 +120,7 @@ public class PhoneStatusBarPolicy private final LocationController mLocationController; private final PrivacyItemController mPrivacyItemController; private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class); + private final SensorPrivacyController mSensorPrivacyController; // Assume it's all good unless we hear otherwise. We don't always seem // to get broadcasts that it *is* there. @@ -149,6 +152,7 @@ public class PhoneStatusBarPolicy mKeyguardMonitor = Dependency.get(KeyguardMonitor.class); mLocationController = Dependency.get(LocationController.class); mPrivacyItemController = Dependency.get(PrivacyItemController.class); + mSensorPrivacyController = Dependency.get(SensorPrivacyController.class); mSlotCast = context.getString(com.android.internal.R.string.status_bar_cast); mSlotHotspot = context.getString(com.android.internal.R.string.status_bar_hotspot); @@ -165,6 +169,7 @@ public class PhoneStatusBarPolicy mSlotLocation = context.getString(com.android.internal.R.string.status_bar_location); mSlotMicrophone = context.getString(com.android.internal.R.string.status_bar_microphone); mSlotCamera = context.getString(com.android.internal.R.string.status_bar_camera); + mSlotSensorsOff = context.getString(com.android.internal.R.string.status_bar_sensors_off); // listen for broadcasts IntentFilter filter = new IntentFilter(); @@ -232,6 +237,11 @@ public class PhoneStatusBarPolicy mContext.getString(R.string.accessibility_location_active)); mIconController.setIconVisibility(mSlotLocation, false); + // sensors off + mIconController.setIcon(mSlotSensorsOff, R.drawable.stat_sys_sensors_off, null); + mIconController.setIconVisibility(mSlotSensorsOff, + mSensorPrivacyController.isSensorPrivacyEnabled()); + mRotationLockController.addCallback(this); mBluetooth.addCallback(this); mProvisionedController.addCallback(this); @@ -242,6 +252,7 @@ public class PhoneStatusBarPolicy mDataSaver.addCallback(this); mKeyguardMonitor.addCallback(this); mPrivacyItemController.addCallback(this); + mSensorPrivacyController.addCallback(mSensorPrivacyListener); SysUiServiceProvider.getComponent(mContext, CommandQueue.class).addCallback(this); } @@ -514,6 +525,16 @@ public class PhoneStatusBarPolicy } }; + private final SensorPrivacyController.OnSensorPrivacyChangedListener mSensorPrivacyListener = + new SensorPrivacyController.OnSensorPrivacyChangedListener() { + @Override + public void onSensorPrivacyChanged(boolean enabled) { + mHandler.post(() -> { + mIconController.setIconVisibility(mSlotSensorsOff, enabled); + }); + } + }; + @Override public void appTransitionStarting(int displayId, long startTime, long duration, boolean forced) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java index 3398fd34c921..25cb7d0573da 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java @@ -58,6 +58,7 @@ import com.android.systemui.shared.recents.IOverviewProxy; import com.android.systemui.shared.recents.utilities.Utilities; import com.android.systemui.shared.system.InputChannelCompat.InputEventDispatcher; import com.android.systemui.shared.system.NavigationBarCompat; +import com.android.systemui.shared.system.QuickStepContract; import java.io.PrintWriter; @@ -72,6 +73,7 @@ public class QuickStepController implements GestureHelper { /** Experiment to swipe home button left to execute a back key press */ private static final String HIDE_BACK_BUTTON_PROP = "quickstepcontroller_hideback"; + private static final String HIDE_HOME_BUTTON_PROP = "quickstepcontroller_hidehome"; private static final String ENABLE_CLICK_THROUGH_NAV_PROP = "quickstepcontroller_clickthrough"; private static final String GESTURE_REGION_THRESHOLD_SETTING = "gesture_region_threshold"; private static final long BACK_BUTTON_FADE_IN_ALPHA = 150; @@ -148,7 +150,7 @@ public class QuickStepController implements GestureHelper { public void setComponents(NavigationBarView navigationBarView) { mNavigationBarView = navigationBarView; - mNavigationBarView.getBackButton().setVisibility(shouldhideBackButton(mContext) + mNavigationBarView.getBackButton().setVisibility(shouldHideBackButton(mContext) ? View.GONE : View.VISIBLE); } @@ -355,7 +357,7 @@ public class QuickStepController implements GestureHelper { if (mCurrentAction != null) { mCurrentAction.endGesture(); } - } else if (getBoolGlobalSetting(mContext, ENABLE_CLICK_THROUGH_NAV_PROP) + } else if (QuickStepContract.isGesturalMode(mContext) && !mClickThroughPressed) { // Enable click through functionality where no gesture has been detected and // not passed the drag slop so inject a touch event at the same location @@ -700,6 +702,8 @@ public class QuickStepController implements GestureHelper { return (int) (dp * Resources.getSystem().getDisplayMetrics().density); } + // TODO(112934365): Clean up following methods when cleaning up nav bar experiments + static boolean getBoolGlobalSetting(Context context, String key) { return Settings.Global.getInt(context.getContentResolver(), key, 0) != 0; } @@ -708,7 +712,24 @@ public class QuickStepController implements GestureHelper { return Settings.Global.getInt(context.getContentResolver(), key, defaultValue); } - public static boolean shouldhideBackButton(Context context) { - return getBoolGlobalSetting(context, HIDE_BACK_BUTTON_PROP); + /** + * @return whether to hide the back button. + */ + public static boolean shouldHideBackButton(Context context) { + return QuickStepContract.isGesturalMode(context); + } + + /** + * @return whether to hide the home button. + */ + public static boolean shouldHideHomeButton(Context context) { + return QuickStepContract.isGesturalMode(context); + } + + /** + * @return whether to show the home handle. + */ + public static boolean showHomeHandle(Context context) { + return QuickStepContract.isGesturalMode(context); } } 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 319a504c17a5..5d52359480e6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -25,6 +25,7 @@ import static android.app.StatusBarManager.WindowVisibleState; import static android.app.StatusBarManager.windowStateToString; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY; +import static com.android.systemui.Dependency.MAIN_HANDLER; import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP; import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE; import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_WAKING; @@ -126,6 +127,7 @@ import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.keyguard.ViewMediatorCallback; +import com.android.systemui.ActivityIntentHelper; import com.android.systemui.ActivityStarterDelegate; import com.android.systemui.AutoReinflateContainer; import com.android.systemui.DemoMode; @@ -219,7 +221,6 @@ import com.android.systemui.statusbar.policy.KeyguardMonitor; import com.android.systemui.statusbar.policy.KeyguardUserSwitcher; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; -import com.android.systemui.statusbar.policy.PreviewInflater; import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler; import com.android.systemui.statusbar.policy.UserInfoController; import com.android.systemui.statusbar.policy.UserInfoControllerImpl; @@ -586,11 +587,12 @@ public class StatusBar extends SystemUI implements DemoMode, mEntryManager.updateNotifications(); updateScrimController(); }; + private ActivityIntentHelper mActivityIntentHelper; @Override public void onActiveStateChanged(int code, int uid, String packageName, boolean active) { mForegroundServiceController.onAppOpChanged(code, uid, packageName, active); - Dependency.get(Dependency.MAIN_HANDLER).post(() -> { + Dependency.get(MAIN_HANDLER).post(() -> { mNotificationListController.updateNotificationsForAppOp(code, uid, packageName, active); }); } @@ -635,6 +637,7 @@ public class StatusBar extends SystemUI implements DemoMode, mNavigationBarController = Dependency.get(NavigationBarController.class); mBubbleController = Dependency.get(BubbleController.class); mBubbleController.setExpandListener(mBubbleExpandListener); + mActivityIntentHelper = new ActivityIntentHelper(mContext); KeyguardSliceProvider sliceProvider = KeyguardSliceProvider.getAttachedInstance(); if (sliceProvider != null) { sliceProvider.initDependencies(mMediaManager, mStatusBarStateController); @@ -1069,7 +1072,8 @@ public class StatusBar extends SystemUI implements DemoMode, mRemoteInputManager, mStatusBarRemoteInputCallback, mGroupManager, mLockscreenUserManager, shadeController, mKeyguardMonitor, mNotificationInterruptionStateProvider, mMetricsLogger, - new LockPatternUtils(mContext)); + new LockPatternUtils(mContext), Dependency.get(MAIN_HANDLER), + mActivityIntentHelper); mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter); @@ -2449,8 +2453,8 @@ public class StatusBar extends SystemUI implements DemoMode, final Callback callback, int flags) { if (onlyProvisioned && !mDeviceProvisionedController.isDeviceProvisioned()) return; - final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity( - mContext, intent, mLockscreenUserManager.getCurrentUserId()); + final boolean afterKeyguardGone = mActivityIntentHelper.wouldLaunchResolverActivity( + intent, mLockscreenUserManager.getCurrentUserId()); Runnable runnable = () -> { mAssistManager.hideAssist(); intent.setFlags( @@ -4315,7 +4319,7 @@ public class StatusBar extends SystemUI implements DemoMode, public void startPendingIntentDismissingKeyguard( final PendingIntent intent, @Nullable final Runnable intentSentUiThreadCallback) { final boolean afterKeyguardGone = intent.isActivity() - && PreviewInflater.wouldLaunchResolverActivity(mContext, intent.getIntent(), + && mActivityIntentHelper.wouldLaunchResolverActivity(intent.getIntent(), mLockscreenUserManager.getCurrentUserId()); executeActionDismissingKeyguard(() -> { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java index 7e45507b4985..215f5c4dfc5b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java @@ -16,7 +16,6 @@ package com.android.systemui.statusbar.phone; -import static com.android.systemui.Dependency.MAIN_HANDLER; import static com.android.systemui.statusbar.phone.StatusBar.getActivityOptions; import android.app.ActivityManager; @@ -29,6 +28,7 @@ import android.app.TaskStackBuilder; import android.content.Context; import android.content.Intent; import android.os.AsyncTask; +import android.os.Handler; import android.os.Looper; import android.os.RemoteException; import android.os.UserHandle; @@ -43,6 +43,7 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.NotificationVisibility; import com.android.internal.widget.LockPatternUtils; +import com.android.systemui.ActivityIntentHelper; import com.android.systemui.Dependency; import com.android.systemui.EventLogTags; import com.android.systemui.UiOffloadThread; @@ -65,7 +66,6 @@ import com.android.systemui.statusbar.notification.logging.NotificationLogger; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.policy.HeadsUpUtil; import com.android.systemui.statusbar.policy.KeyguardMonitor; -import com.android.systemui.statusbar.policy.PreviewInflater; /** * Status bar implementation of {@link NotificationActivityStarter}. @@ -97,6 +97,8 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit private final IStatusBarService mBarService; private final CommandQueue mCommandQueue; private final IDreamManager mDreamManager; + private final Handler mMainThreadHandler; + private final ActivityIntentHelper mActivityIntentHelper; private boolean mIsCollapsingToShowActivityOverLockscreen; @@ -121,7 +123,9 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit KeyguardMonitor keyguardMonitor, NotificationInterruptionStateProvider notificationInterruptionStateProvider, MetricsLogger metricsLogger, - LockPatternUtils lockPatternUtils) { + LockPatternUtils lockPatternUtils, + Handler mainThreadHandler, + ActivityIntentHelper activityIntentHelper) { mContext = context; mNotificationPanel = panel; mPresenter = presenter; @@ -150,6 +154,8 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit } }); mStatusBarRemoteInputCallback = remoteInputCallback; + mMainThreadHandler = mainThreadHandler; + mActivityIntentHelper = activityIntentHelper; } /** @@ -176,12 +182,11 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit boolean isActivityIntent = intent.isActivity(); final boolean afterKeyguardGone = isActivityIntent - && PreviewInflater.wouldLaunchResolverActivity(mContext, intent.getIntent(), + && mActivityIntentHelper.wouldLaunchResolverActivity(intent.getIntent(), mLockscreenUserManager.getCurrentUserId()); final boolean wasOccluded = mShadeController.isOccluded(); boolean showOverLockscreen = mKeyguardMonitor.isShowing() - && PreviewInflater.wouldShowOverLockscreen(mContext, - intent.getIntent(), + && mActivityIntentHelper.wouldShowOverLockscreen(intent.getIntent(), mLockscreenUserManager.getCurrentUserId()); ActivityStarter.OnDismissAction postKeyguardAction = () -> handleNotificationClickAfterKeyguardDismissed( @@ -358,7 +363,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit mActivityLaunchAnimator.setLaunchResult(launchResult, true /* isActivityIntent */); if (shouldCollapse()) { // Putting it back on the main thread, since we're touching views - Dependency.get(MAIN_HANDLER).post(() -> mCommandQueue.animateCollapsePanels( + mMainThreadHandler.post(() -> mCommandQueue.animateCollapsePanels( CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */)); } }); @@ -425,7 +430,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit if (Looper.getMainLooper().isCurrentThread()) { mShadeController.collapsePanel(); } else { - Dependency.get(MAIN_HANDLER).post(mShadeController::collapsePanel); + mMainThreadHandler.post(mShadeController::collapsePanel); } } @@ -444,7 +449,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit private void removeNotification(StatusBarNotification notification) { // We have to post it to the UI thread for synchronization - Dependency.get(MAIN_HANDLER).post(() -> { + mMainThreadHandler.post(() -> { Runnable removeRunnable = () -> mEntryManager.performRemoveNotification(notification); if (mPresenter.isCollapsing()) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java index 21d9dcc6897d..471d5113a502 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java @@ -33,6 +33,7 @@ import android.os.UserHandle; import android.view.View; import android.view.ViewParent; +import com.android.systemui.ActivityIntentHelper; import com.android.systemui.Dependency; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.statusbar.StatusBarStateController; @@ -46,7 +47,6 @@ import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.policy.KeyguardMonitor; -import com.android.systemui.statusbar.policy.PreviewInflater; import javax.inject.Inject; import javax.inject.Singleton; @@ -64,6 +64,7 @@ public class StatusBarRemoteInputCallback implements Callback, Callbacks, Dependency.get(NotificationLockscreenUserManager.class); private final ActivityStarter mActivityStarter = Dependency.get(ActivityStarter.class); private final Context mContext; + private final ActivityIntentHelper mActivityIntentHelper; private View mPendingWorkRemoteInputView; private View mPendingRemoteInputView; private final ShadeController mShadeController = Dependency.get(ShadeController.class); @@ -83,6 +84,7 @@ public class StatusBarRemoteInputCallback implements Callback, Callbacks, mKeyguardManager = context.getSystemService(KeyguardManager.class); mCommandQueue = getComponent(context, CommandQueue.class); mCommandQueue.addCallback(this); + mActivityIntentHelper = new ActivityIntentHelper(mContext); } @Override @@ -220,8 +222,8 @@ public class StatusBarRemoteInputCallback implements Callback, Callbacks, NotificationRemoteInputManager.ClickHandler defaultHandler) { final boolean isActivity = pendingIntent.isActivity(); if (isActivity) { - final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity( - mContext, pendingIntent.getIntent(), mLockscreenUserManager.getCurrentUserId()); + final boolean afterKeyguardGone = mActivityIntentHelper.wouldLaunchResolverActivity( + pendingIntent.getIntent(), mLockscreenUserManager.getCurrentUserId()); mActivityStarter.dismissKeyguardThenExecute(() -> { try { ActivityManager.getService().resumeAppSwitches(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java index a8ae5f65a2a0..96090571685e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java @@ -114,17 +114,19 @@ public class StatusBarWindowView extends FrameLayout { if (mSingleTapEnabled) { mService.wakeUpIfDozing(SystemClock.uptimeMillis(), StatusBarWindowView.this, "SINGLE_TAP"); + return true; } - return mSingleTapEnabled; + return false; } @Override public boolean onDoubleTap(MotionEvent e) { - if (mDoubleTapEnabled) { + if (mDoubleTapEnabled || mSingleTapEnabled) { mService.wakeUpIfDozing(SystemClock.uptimeMillis(), StatusBarWindowView.this, "DOUBLE_TAP"); + return true; } - return mDoubleTapEnabled; + return false; } }; private final TunerService.Tunable mTunable = (key, newValue) -> { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java index 3c8ed6ebf279..b53ff0e45cea 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java @@ -16,9 +16,11 @@ package com.android.systemui.statusbar.policy; +import android.annotation.NonNull; import android.app.ActivityManager; import android.content.Context; +import com.android.internal.util.Preconditions; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.settings.CurrentUserTracker; @@ -69,7 +71,8 @@ public class KeyguardMonitorImpl extends KeyguardUpdateMonitorCallback } @Override - public void addCallback(Callback callback) { + public void addCallback(@NonNull Callback callback) { + Preconditions.checkNotNull(callback, "Callback must not be null. b/128895449"); mCallbacks.add(callback); if (mCallbacks.size() != 0 && !mListening) { mListening = true; @@ -81,7 +84,8 @@ public class KeyguardMonitorImpl extends KeyguardUpdateMonitorCallback } @Override - public void removeCallback(Callback callback) { + public void removeCallback(@NonNull Callback callback) { + Preconditions.checkNotNull(callback, "Callback must not be null. b/128895449"); if (mCallbacks.remove(callback) && mCallbacks.size() == 0 && mListening) { mListening = false; mKeyguardUpdateMonitor.removeCallback(this); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java index 92034b2be0ed..3d317143eb51 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java @@ -19,7 +19,6 @@ package com.android.systemui.statusbar.policy; import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; @@ -29,6 +28,7 @@ import android.view.View; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.systemui.ActivityIntentHelper; import com.android.systemui.statusbar.phone.KeyguardPreviewContainer; import java.util.List; @@ -41,13 +41,16 @@ public class PreviewInflater { private static final String TAG = "PreviewInflater"; private static final String META_DATA_KEYGUARD_LAYOUT = "com.android.keyguard.layout"; + private final ActivityIntentHelper mActivityIntentHelper; private Context mContext; private LockPatternUtils mLockPatternUtils; - public PreviewInflater(Context context, LockPatternUtils lockPatternUtils) { + public PreviewInflater(Context context, LockPatternUtils lockPatternUtils, + ActivityIntentHelper activityIntentHelper) { mContext = context; mLockPatternUtils = lockPatternUtils; + mActivityIntentHelper = activityIntentHelper; } public View inflatePreview(Intent intent) { @@ -130,7 +133,7 @@ public class PreviewInflater { ResolveInfo resolved = packageManager.resolveActivityAsUser(intent, flags | PackageManager.GET_META_DATA, KeyguardUpdateMonitor.getCurrentUser()); - if (wouldLaunchResolverActivity(resolved, appList)) { + if (mActivityIntentHelper.wouldLaunchResolverActivity(resolved, appList)) { return null; } if (resolved == null || resolved.activityInfo == null) { @@ -140,63 +143,6 @@ public class PreviewInflater { resolved.activityInfo.metaData); } - public static boolean wouldLaunchResolverActivity(Context ctx, Intent intent, - int currentUserId) { - return getTargetActivityInfo(ctx, intent, currentUserId, false /* onlyDirectBootAware */) - == null; - } - - public static boolean wouldShowOverLockscreen(Context ctx, Intent intent, int currentUserId) { - ActivityInfo targetActivityInfo = getTargetActivityInfo(ctx, intent, currentUserId, - false /* onlyDirectBootAware */); - return targetActivityInfo != null - && (targetActivityInfo.flags & (ActivityInfo.FLAG_SHOW_WHEN_LOCKED - | ActivityInfo.FLAG_SHOW_FOR_ALL_USERS)) > 0; - } - - /** - * @param onlyDirectBootAware a boolean indicating whether the matched activity packages must - * be direct boot aware when in direct boot mode if false, all - * packages are considered a match even if they are not aware. - * @return the target activity info of the intent it resolves to a specific package or - * {@code null} if it resolved to the resolver activity - */ - public static ActivityInfo getTargetActivityInfo(Context ctx, Intent intent, - int currentUserId, boolean onlyDirectBootAware) { - PackageManager packageManager = ctx.getPackageManager(); - int flags = PackageManager.MATCH_DEFAULT_ONLY; - if (!onlyDirectBootAware) { - flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE - | PackageManager.MATCH_DIRECT_BOOT_UNAWARE; - } - final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser( - intent, flags, currentUserId); - if (appList.size() == 0) { - return null; - } - ResolveInfo resolved = packageManager.resolveActivityAsUser(intent, - flags | PackageManager.GET_META_DATA, currentUserId); - if (resolved == null || wouldLaunchResolverActivity(resolved, appList)) { - return null; - } else { - return resolved.activityInfo; - } - } - - private static boolean wouldLaunchResolverActivity( - ResolveInfo resolved, List<ResolveInfo> appList) { - // If the list contains the above resolved activity, then it can't be - // ResolverActivity itself. - for (int i = 0; i < appList.size(); i++) { - ResolveInfo tmp = appList.get(i); - if (tmp.activityInfo.name.equals(resolved.activityInfo.name) - && tmp.activityInfo.packageName.equals(resolved.activityInfo.packageName)) { - return false; - } - } - return true; - } - private static class WidgetInfo { String contextPackage; int layoutId; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensorPrivacyController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensorPrivacyController.java new file mode 100644 index 000000000000..6d5ce60ef621 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensorPrivacyController.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.policy; + +/** + * Interface for classes to control sensor privacy state and notification. + */ +public interface SensorPrivacyController extends + CallbackController<SensorPrivacyController.OnSensorPrivacyChangedListener> { + + /** + * Returns whether sensor privacy is enabled. + */ + boolean isSensorPrivacyEnabled(); + + /** + * Interface for classes to receive callbacks when sensor privacy state changes. + */ + interface OnSensorPrivacyChangedListener { + void onSensorPrivacyChanged(boolean enabled); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensorPrivacyControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensorPrivacyControllerImpl.java new file mode 100644 index 000000000000..5db66932d3c1 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensorPrivacyControllerImpl.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.policy; + +import android.content.Context; +import android.hardware.SensorPrivacyManager; + +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * Controls sensor privacy state and notification. + */ +@Singleton +public class SensorPrivacyControllerImpl implements SensorPrivacyController, + SensorPrivacyManager.OnSensorPrivacyChangedListener { + private SensorPrivacyManager mSensorPrivacyManager; + private final List<OnSensorPrivacyChangedListener> mListeners; + private Object mLock = new Object(); + private boolean mSensorPrivacyEnabled; + + /** + * Public constructor. + */ + @Inject + public SensorPrivacyControllerImpl(Context context) { + mSensorPrivacyManager = (SensorPrivacyManager) context.getSystemService( + Context.SENSOR_PRIVACY_SERVICE); + mSensorPrivacyEnabled = mSensorPrivacyManager.isSensorPrivacyEnabled(); + mSensorPrivacyManager.addSensorPrivacyListener(this); + mListeners = new ArrayList<>(1); + } + + /** + * Returns whether sensor privacy is enabled. + */ + public boolean isSensorPrivacyEnabled() { + synchronized (mLock) { + return mSensorPrivacyEnabled; + } + } + + /** + * Adds the provided listener for callbacks when sensor privacy state changes. + */ + public void addCallback(OnSensorPrivacyChangedListener listener) { + synchronized (mLock) { + mListeners.add(listener); + notifyListenerLocked(listener); + } + } + + /** + * Removes the provided listener from callbacks when sensor privacy state changes. + */ + public void removeCallback(OnSensorPrivacyChangedListener listener) { + synchronized (mLock) { + mListeners.remove(listener); + } + } + + /** + * Callback invoked by the SensorPrivacyService when sensor privacy state changes. + */ + public void onSensorPrivacyChanged(boolean enabled) { + synchronized (mLock) { + mSensorPrivacyEnabled = enabled; + for (OnSensorPrivacyChangedListener listener : mListeners) { + notifyListenerLocked(listener); + } + } + } + + private void notifyListenerLocked(OnSensorPrivacyChangedListener listener) { + listener.onSensorPrivacyChanged(mSensorPrivacyEnabled); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java index 72f4fc7820a5..e57cff789a23 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java @@ -118,7 +118,8 @@ public final class SmartReplyConstants { mRequiresTargetingP = readDeviceConfigBooleanOrDefaultIfEmpty( SystemUiDeviceConfigFlags.SSIN_REQUIRES_TARGETING_P, mDefaultRequiresP); - mMaxSqueezeRemeasureAttempts = readDeviceConfigIntegerOrDefaultIfEmpty( + mMaxSqueezeRemeasureAttempts = DeviceConfig.getInt( + DeviceConfig.NAMESPACE_SYSTEMUI, SystemUiDeviceConfigFlags.SSIN_MAX_SQUEEZE_REMEASURE_ATTEMPTS, mDefaultMaxSqueezeRemeasureAttempts); mEditChoicesBeforeSending = readDeviceConfigBooleanOrDefaultIfEmpty( @@ -127,10 +128,12 @@ public final class SmartReplyConstants { mShowInHeadsUp = readDeviceConfigBooleanOrDefaultIfEmpty( SystemUiDeviceConfigFlags.SSIN_SHOW_IN_HEADS_UP, mDefaultShowInHeadsUp); - mMinNumSystemGeneratedReplies = readDeviceConfigIntegerOrDefaultIfEmpty( + mMinNumSystemGeneratedReplies = DeviceConfig.getInt( + DeviceConfig.NAMESPACE_SYSTEMUI, SystemUiDeviceConfigFlags.SSIN_MIN_NUM_SYSTEM_GENERATED_REPLIES, mDefaultMinNumSystemGeneratedReplies); - mMaxNumActions = readDeviceConfigIntegerOrDefaultIfEmpty( + mMaxNumActions = DeviceConfig.getInt( + DeviceConfig.NAMESPACE_SYSTEMUI, SystemUiDeviceConfigFlags.SSIN_MAX_NUM_ACTIONS, mDefaultMaxNumActions); } @@ -152,21 +155,6 @@ public final class SmartReplyConstants { return defaultValue; } - private static int readDeviceConfigIntegerOrDefaultIfEmpty(String propertyName, - int defaultValue) { - String value = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_SYSTEMUI, propertyName); - if (TextUtils.isEmpty(value)) { - return defaultValue; - } - try { - return Integer.parseInt(value); - } catch (NumberFormatException e) { - Log.e(TAG, "Tried to read an integer flag, property name=" - + propertyName + ", value=" + value); - return defaultValue; - } - } - /** Returns whether smart replies in notifications are enabled. */ public boolean isEnabled() { return mEnabled; diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbContaminantActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbContaminantActivity.java index fa4b3fe4be18..ecf608beb91c 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/UsbContaminantActivity.java +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbContaminantActivity.java @@ -16,14 +16,17 @@ package com.android.systemui.usb; +import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.hardware.usb.ParcelableUsbPort; import android.hardware.usb.UsbManager; import android.hardware.usb.UsbPort; import android.os.Bundle; +import android.util.Log; import android.view.Window; import android.view.WindowManager; +import android.widget.Toast; import com.android.internal.app.AlertActivity; import com.android.internal.app.AlertController; @@ -36,7 +39,6 @@ public class UsbContaminantActivity extends AlertActivity implements DialogInterface.OnClickListener { private static final String TAG = "UsbContaminantActivity"; - private UsbDisconnectedReceiver mDisconnectedReceiver; private UsbPort mUsbPort; @Override @@ -55,8 +57,10 @@ public class UsbContaminantActivity extends AlertActivity final AlertController.AlertParams ap = mAlertParams; ap.mTitle = getString(R.string.usb_contaminant_title); ap.mMessage = getString(R.string.usb_contaminant_message); - ap.mPositiveButtonText = getString(android.R.string.ok); - ap.mPositiveButtonListener = this; + ap.mNegativeButtonText = getString(android.R.string.ok); + ap.mNeutralButtonText = getString(R.string.usb_disable_contaminant_detection); + ap.mNegativeButtonListener = this; + ap.mNeutralButtonListener = this; setupAlert(); } @@ -68,6 +72,15 @@ public class UsbContaminantActivity extends AlertActivity @Override public void onClick(DialogInterface dialog, int which) { + if (which == AlertDialog.BUTTON_NEUTRAL) { + try { + mUsbPort.enableContaminantDetection(false); + Toast.makeText(this, R.string.usb_port_enabled, + Toast.LENGTH_SHORT).show(); + } catch (Exception e) { + Log.e(TAG, "Unable to notify Usb service", e); + } + } finish(); } } diff --git a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java index e6b6672d3544..7705e4ecfaea 100644 --- a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java +++ b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java @@ -23,6 +23,7 @@ import android.view.InflateException; import android.view.LayoutInflater; import android.view.View; +import com.android.keyguard.KeyguardClockSwitch; import com.android.systemui.SystemUIFactory; import com.android.systemui.qs.QSCarrierGroup; import com.android.systemui.qs.QSFooterImpl; @@ -130,6 +131,11 @@ public class InjectionInflationController { * Creates the QSCarrierGroup */ QSCarrierGroup createQSCarrierGroup(); + + /** + * Creates the KeyguardClockSwitch. + */ + KeyguardClockSwitch createKeyguardClockSwitch(); } /** diff --git a/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java b/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java new file mode 100644 index 000000000000..8ec66e4bcc30 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.volume; + +import android.content.Context; +import android.util.AttributeSet; + +import com.android.keyguard.AlphaOptimizedImageButton; +import com.android.systemui.R; + +/** Toggle button in Volume Dialog that allows extra state for when streams are opted-out */ +public class CaptionsToggleImageButton extends AlphaOptimizedImageButton { + + private static final int[] OPTED_OUT_STATE = new int[] { R.attr.optedOut }; + + private boolean mComponentEnabled = false; + private boolean mOptedOut = false; + + public CaptionsToggleImageButton(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + public int[] onCreateDrawableState(int extraSpace) { + int[] state = super.onCreateDrawableState(extraSpace + 1); + if (mOptedOut) { + mergeDrawableStates(state, OPTED_OUT_STATE); + } + return state; + } + + Runnable setComponentEnabled(boolean isComponentEnabled) { + this.mComponentEnabled = isComponentEnabled; + + return this.setImageResourceAsync(this.mComponentEnabled + ? R.drawable.ic_volume_odi_captions + : R.drawable.ic_volume_odi_captions_disabled); + } + + boolean getComponentEnabled() { + return this.mComponentEnabled; + } + + /** Sets whether or not the current stream has opted out of captions */ + void setOptedOut(boolean isOptedOut) { + this.mOptedOut = isOptedOut; + refreshDrawableState(); + } + + boolean getOptedOut() { + return this.mOptedOut; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java index 2fa8889a02f9..a3db533bb7d0 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java @@ -282,6 +282,13 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa Settings.Secure.ODI_CAPTIONS_ENABLED, isEnabled ? 1 : 0); } + @Override + public boolean isCaptionStreamOptedOut() { + int currentValue = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.ODI_CAPTIONS_OPTED_OUT, 0); + return currentValue == 1; + } + public void getCaptionsComponentState(boolean fromTooltip) { if (mDestroyed) return; mWorker.obtainMessage(W.GET_CAPTIONS_COMPONENT_STATE, fromTooltip).sendToTarget(); diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java index cdda216c5220..bd7824df1d24 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java @@ -133,7 +133,7 @@ public class VolumeDialogImpl implements VolumeDialog { private ViewGroup mRinger; private ImageButton mRingerIcon; private ViewGroup mODICaptionsView; - private ImageButton mODICaptionsIcon; + private CaptionsToggleImageButton mODICaptionsIcon; private View mSettingsView; private ImageButton mSettingsIcon; private FrameLayout mZenIcon; @@ -587,11 +587,15 @@ public class VolumeDialogImpl implements VolumeDialog { } private void updateCaptionsIcon() { - mHandler.post( - mODICaptionsIcon.setImageResourceAsync( - mController.areCaptionsEnabled() - ? R.drawable.ic_volume_odi_captions - : R.drawable.ic_volume_odi_captions_disabled)); + boolean componentEnabled = mController.areCaptionsEnabled(); + if (mODICaptionsIcon.getComponentEnabled() != componentEnabled) { + mHandler.post(mODICaptionsIcon.setComponentEnabled(componentEnabled)); + } + + boolean isOptedOut = mController.isCaptionStreamOptedOut(); + if (mODICaptionsIcon.getOptedOut() != isOptedOut) { + mHandler.post(() -> mODICaptionsIcon.setOptedOut(isOptedOut)); + } } private void onCaptionIconClicked() { @@ -952,7 +956,7 @@ public class VolumeDialogImpl implements VolumeDialog { } private void updateVolumeRowH(VolumeRow row) { - if (D.BUG) Log.d(TAG, "updateVolumeRowH s=" + row.stream); + if (D.BUG) Log.i(TAG, "updateVolumeRowH s=" + row.stream); if (mState == null) return; final StreamState ss = mState.states.get(row.stream); if (ss == null) return; diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java index 29505a2046bb..632b0c05e2c2 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java @@ -39,10 +39,12 @@ import android.widget.FrameLayout; import android.widget.TextClock; import com.android.keyguard.clock.ClockManager; +import com.android.systemui.SystemUIFactory; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.ClockPlugin; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.StatusBarState; +import com.android.systemui.util.InjectionInflationController; import org.junit.Before; import org.junit.Test; @@ -70,7 +72,10 @@ public class KeyguardClockSwitchTest extends SysuiTestCase { @Before public void setUp() { - LayoutInflater layoutInflater = LayoutInflater.from(getContext()); + InjectionInflationController inflationController = new InjectionInflationController( + SystemUIFactory.getInstance().getRootComponent()); + LayoutInflater layoutInflater = inflationController + .injectable(LayoutInflater.from(getContext())); mKeyguardClockSwitch = (KeyguardClockSwitch) layoutInflater.inflate(R.layout.keyguard_clock_switch, null); mClockContainer = mKeyguardClockSwitch.findViewById(R.id.clock_view); diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java index 3582ab010413..31ea39cedf3b 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java @@ -24,8 +24,10 @@ import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; import android.view.LayoutInflater; +import com.android.systemui.SystemUIFactory; import com.android.systemui.SysuiTestCase; import com.android.systemui.util.Assert; +import com.android.systemui.util.InjectionInflationController; import org.junit.Before; import org.junit.Test; @@ -48,7 +50,10 @@ public class KeyguardStatusViewTest extends SysuiTestCase { @Before public void setUp() { Assert.sMainLooper = TestableLooper.get(this).getLooper(); - LayoutInflater layoutInflater = LayoutInflater.from(getContext()); + InjectionInflationController inflationController = new InjectionInflationController( + SystemUIFactory.getInstance().getRootComponent()); + LayoutInflater layoutInflater = inflationController + .injectable(LayoutInflater.from(getContext())); mKeyguardStatusView = (KeyguardStatusView) layoutInflater.inflate(R.layout.keyguard_status_view, null); org.mockito.MockitoAnnotations.initMocks(this); diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java index 63b66732c02e..c9b550cd6e64 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java @@ -35,6 +35,7 @@ import android.widget.FrameLayout; import androidx.test.filters.SmallTest; +import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.NotificationTestHelper; import com.android.systemui.statusbar.notification.NotificationEntryListener; @@ -89,6 +90,8 @@ public class BubbleControllerTest extends SysuiTestCase { private BubbleController.BubbleStateChangeListener mBubbleStateChangeListener; @Mock private BubbleController.BubbleExpandListener mBubbleExpandListener; + @Mock + NotificationVisibility mNotificationVisibility; @Mock private PendingIntent mDeleteIntent; diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java index b8add89243ce..cd8480505c04 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java @@ -43,7 +43,6 @@ public class ExpandedAnimationControllerTest extends PhysicsAnimationLayoutTestC @Spy private ExpandedAnimationController mExpandedController = new ExpandedAnimationController(new Point(500, 1000) /* displaySize */); - private int mStackOffset; private float mBubblePadding; private float mBubbleSize; diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTest.java index a50919b22a6a..38a90f7a52d2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTest.java @@ -20,12 +20,11 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; import android.os.SystemClock; import android.testing.AndroidTestingRunner; @@ -68,7 +67,8 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { // offset, and don't actually remove views immediately (since most implementations will wait // to animate child views out before actually removing them). mTestableController.setAnimatedProperties(Sets.newHashSet( - DynamicAnimation.TRANSLATION_X, DynamicAnimation.TRANSLATION_Y)); + DynamicAnimation.TRANSLATION_X, + DynamicAnimation.TRANSLATION_Y)); mTestableController.setChainedProperties(Sets.newHashSet(DynamicAnimation.TRANSLATION_X)); mTestableController.setOffsetForProperty( DynamicAnimation.TRANSLATION_X, TEST_TRANSLATION_X_OFFSET); @@ -126,11 +126,11 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { // Animate the first child's translation X. final CountDownLatch animLatch = new CountDownLatch(1); - mLayout.animateValueForChildAtIndex( - DynamicAnimation.TRANSLATION_X, - 0, - 100, - animLatch::countDown); + + mTestableController + .animationForChildAtIndex(0) + .translationX(100) + .start(animLatch::countDown); animLatch.await(1, TimeUnit.SECONDS); // Ensure that the first view has been translated, but not the second one. @@ -140,60 +140,50 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { @Test public void testUpdateValueXChained() throws InterruptedException { - mLayout.setController(mTestableController); - addOneMoreThanRenderLimitBubbles(); testChainedTranslationAnimations(); } @Test - public void testSetEndListeners() throws InterruptedException { + public void testSetEndActions() throws InterruptedException { mLayout.setController(mTestableController); addOneMoreThanRenderLimitBubbles(); mTestableController.setChainedProperties(Sets.newHashSet()); final CountDownLatch xLatch = new CountDownLatch(1); - OneTimeEndListener xEndListener = Mockito.spy(new OneTimeEndListener() { + Runnable xEndAction = Mockito.spy(new Runnable() { + @Override - public void onAnimationEnd(DynamicAnimation animation, boolean canceled, float value, - float velocity) { - super.onAnimationEnd(animation, canceled, value, velocity); + public void run() { xLatch.countDown(); } }); final CountDownLatch yLatch = new CountDownLatch(1); - final OneTimeEndListener yEndListener = Mockito.spy(new OneTimeEndListener() { + Runnable yEndAction = Mockito.spy(new Runnable() { + @Override - public void onAnimationEnd(DynamicAnimation animation, boolean canceled, float value, - float velocity) { - super.onAnimationEnd(animation, canceled, value, velocity); + public void run() { yLatch.countDown(); } }); // Set end listeners for both x and y. - mLayout.setEndListenerForProperty(xEndListener, DynamicAnimation.TRANSLATION_X); - mLayout.setEndListenerForProperty(yEndListener, DynamicAnimation.TRANSLATION_Y); + mLayout.setEndActionForProperty(xEndAction, DynamicAnimation.TRANSLATION_X); + mLayout.setEndActionForProperty(yEndAction, DynamicAnimation.TRANSLATION_Y); // Animate x, and wait for it to finish. - mLayout.animateValueForChildAtIndex( - DynamicAnimation.TRANSLATION_X, - 0, - 100); + mTestableController.animationForChildAtIndex(0) + .translationX(100) + .start(); + xLatch.await(); yLatch.await(1, TimeUnit.SECONDS); // Make sure the x end listener was called only one time, and the y listener was never // called since we didn't animate y. Wait 1 second after the original animation end trigger // to make sure it doesn't get called again. - Mockito.verify(xEndListener, Mockito.after(1000).times(1)) - .onAnimationEnd( - any(), - eq(false), - eq(100f), - anyFloat()); - Mockito.verify(yEndListener, Mockito.after(1000).never()) - .onAnimationEnd(any(), anyBoolean(), anyFloat(), anyFloat()); + Mockito.verify(xEndAction, Mockito.after(1000).times(1)).run(); + Mockito.verify(yEndAction, Mockito.after(1000).never()).run(); } @Test @@ -203,39 +193,31 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { mTestableController.setChainedProperties(Sets.newHashSet()); final CountDownLatch xLatch = new CountDownLatch(1); - OneTimeEndListener xEndListener = Mockito.spy(new OneTimeEndListener() { + Runnable xEndListener = Mockito.spy(new Runnable() { + @Override - public void onAnimationEnd(DynamicAnimation animation, boolean canceled, float value, - float velocity) { - super.onAnimationEnd(animation, canceled, value, velocity); + public void run() { xLatch.countDown(); } }); // Set the end listener. - mLayout.setEndListenerForProperty(xEndListener, DynamicAnimation.TRANSLATION_X); + mLayout.setEndActionForProperty(xEndListener, DynamicAnimation.TRANSLATION_X); // Animate x, and wait for it to finish. - mLayout.animateValueForChildAtIndex( - DynamicAnimation.TRANSLATION_X, - 0, - 100); + mTestableController.animationForChildAtIndex(0) + .translationX(100) + .start(); xLatch.await(); InOrder endListenerCalls = inOrder(xEndListener); - endListenerCalls.verify(xEndListener, Mockito.times(1)) - .onAnimationEnd( - any(), - eq(false), - eq(100f), - anyFloat()); + endListenerCalls.verify(xEndListener, Mockito.times(1)).run(); // Animate X again, remove the end listener. - mLayout.animateValueForChildAtIndex( - DynamicAnimation.TRANSLATION_X, - 0, - 1000); - mLayout.removeEndListenerForProperty(DynamicAnimation.TRANSLATION_X); + mTestableController.animationForChildAtIndex(0) + .translationX(1000) + .start(); + mLayout.removeEndActionForProperty(DynamicAnimation.TRANSLATION_X); xLatch.await(1, TimeUnit.SECONDS); // Make sure the end listener was not called. @@ -261,10 +243,9 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { secondController.setRemoveImmediately(true); mLayout.setController(secondController); - mLayout.animateValueForChildAtIndex( - DynamicAnimation.SCALE_X, - 0, - 1.5f); + mTestableController.animationForChildAtIndex(0) + .scaleX(1.5f) + .start(); waitForPropertyAnimations(DynamicAnimation.SCALE_X); @@ -285,10 +266,9 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { .getOffsetForChainedPropertyAnimation(eq(DynamicAnimation.SCALE_X)); mLayout.setController(mTestableController); - mLayout.animateValueForChildAtIndex( - DynamicAnimation.TRANSLATION_X, - 0, - 100f); + mTestableController.animationForChildAtIndex(0) + .translationX(100f) + .start(); waitForPropertyAnimations(DynamicAnimation.TRANSLATION_X); @@ -308,10 +288,9 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { assertFalse(mLayout.arePropertiesAnimating( DynamicAnimation.TRANSLATION_X, DynamicAnimation.TRANSLATION_Y)); - mLayout.animateValueForChildAtIndex( - DynamicAnimation.TRANSLATION_X, - 0, - 100); + mTestableController.animationForChildAtIndex(0) + .translationX(100f) + .start(); // Wait for the animations to get underway. SystemClock.sleep(50); @@ -330,14 +309,9 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { mLayout.setController(mTestableController); addOneMoreThanRenderLimitBubbles(); - mLayout.animateValueForChildAtIndex( - DynamicAnimation.TRANSLATION_X, - 0, - 1000); - mLayout.animateValueForChildAtIndex( - DynamicAnimation.TRANSLATION_Y, - 0, - 1000); + mTestableController.animationForChildAtIndex(0) + .position(1000, 1000) + .start(); mLayout.cancelAllAnimations(); @@ -367,13 +341,15 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { /** Standard test of chained translation animations. */ private void testChainedTranslationAnimations() throws InterruptedException { + mLayout.setController(mTestableController); + addOneMoreThanRenderLimitBubbles(); + assertEquals(0, mLayout.getChildAt(0).getTranslationX(), .1f); assertEquals(0, mLayout.getChildAt(1).getTranslationX(), .1f); - mLayout.animateValueForChildAtIndex( - DynamicAnimation.TRANSLATION_X, - 0, - 100); + mTestableController.animationForChildAtIndex(0) + .translationX(100f) + .start(); waitForPropertyAnimations(DynamicAnimation.TRANSLATION_X); @@ -392,10 +368,9 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { assertEquals(0, mLayout.getChildAt(1).getTranslationY(), .1f); // Animate the first child's Y translation. - mLayout.animateValueForChildAtIndex( - DynamicAnimation.TRANSLATION_Y, - 0, - 100); + mTestableController.animationForChildAtIndex(0) + .translationY(100f) + .start(); waitForPropertyAnimations(DynamicAnimation.TRANSLATION_Y); @@ -405,6 +380,75 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { assertEquals(0, mLayout.getChildAt(1).getTranslationY(), .1f); } + @Test + public void testPhysicsAnimator() throws InterruptedException { + mLayout.setController(mTestableController); + addOneMoreThanRenderLimitBubbles(); + + Runnable afterAll = Mockito.mock(Runnable.class); + Runnable after = Mockito.spy(new Runnable() { + int mCallCount = 0; + + @Override + public void run() { + // Make sure that if only one of the animations has finished, we didn't already call + // afterAll. + if (mCallCount == 1) { + Mockito.verifyNoMoreInteractions(afterAll); + } + } + }); + + // Animate from x = 7 to x = 100, and from y = 100 to 7 = 200, calling 'after' after each + // property's animation completes, then call afterAll when they're all complete. + mTestableController.animationForChildAtIndex(0) + .translationX(7, 100, after) + .translationY(100, 200, after) + .start(afterAll); + + // We should have immediately set the 'from' values. + assertEquals(7, mViews.get(0).getTranslationX(), .01f); + assertEquals(100, mViews.get(0).getTranslationY(), .01f); + + waitForPropertyAnimations( + DynamicAnimation.TRANSLATION_X, + DynamicAnimation.TRANSLATION_Y); + + // We should have called the after callback twice, and afterAll once. We verify in the + // mocked callback that afterAll isn't called before both finish. + Mockito.verify(after, times(2)).run(); + Mockito.verify(afterAll).run(); + + // Make sure we actually animated the views. + assertEquals(100, mViews.get(0).getTranslationX(), .01f); + assertEquals(200, mViews.get(0).getTranslationY(), .01f); + } + + @Test + public void testAnimationsForChildrenFromIndex() throws InterruptedException { + // Don't chain since we're going to invoke each animation independently. + mTestableController.setChainedProperties(new HashSet<>()); + + mLayout.setController(mTestableController); + + addOneMoreThanRenderLimitBubbles(); + + Runnable allEnd = Mockito.mock(Runnable.class); + + mTestableController.animationsForChildrenFromIndex( + 1, (index, animation) -> animation.translationX((index - 1) * 50)) + .startAll(allEnd); + + waitForPropertyAnimations(DynamicAnimation.TRANSLATION_X); + + assertEquals(0, mViews.get(0).getTranslationX(), .1f); + assertEquals(0, mViews.get(1).getTranslationX(), .1f); + assertEquals(50, mViews.get(2).getTranslationX(), .1f); + assertEquals(100, mViews.get(3).getTranslationX(), .1f); + + Mockito.verify(allEnd, times(1)).run(); + } + /** * Animation controller with configuration methods whose return values can be set by individual * tests. diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTestCase.java index d94b6694c7fa..9fce092ef7ce 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTestCase.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTestCase.java @@ -28,6 +28,7 @@ import android.view.WindowInsets; import android.widget.FrameLayout; import androidx.dynamicanimation.animation.DynamicAnimation; +import androidx.dynamicanimation.animation.SpringForce; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; @@ -38,6 +39,7 @@ import org.mockito.MockitoAnnotations; import java.util.ArrayList; import java.util.List; +import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -113,25 +115,17 @@ public class PhysicsAnimationLayoutTestCase extends SysuiTestCase { throws InterruptedException { final CountDownLatch animLatch = new CountDownLatch(properties.length); for (DynamicAnimation.ViewProperty property : properties) { - mLayout.setTestEndListenerForProperty(new OneTimeEndListener() { - @Override - public void onAnimationEnd(DynamicAnimation animation, boolean canceled, - float value, - float velocity) { - super.onAnimationEnd(animation, canceled, value, velocity); - animLatch.countDown(); - } - }, property); + mLayout.setTestEndActionForProperty(animLatch::countDown, property); } - animLatch.await(1, TimeUnit.SECONDS); + + animLatch.await(2, TimeUnit.SECONDS); } - /** Uses a latch to wait for the message queue to finish. */ + /** Uses a latch to wait for the main thread message queue to finish. */ void waitForLayoutMessageQueue() throws InterruptedException { - // Wait for layout, then the view should be actually removed. CountDownLatch layoutLatch = new CountDownLatch(1); mMainThreadHandler.post(layoutLatch::countDown); - layoutLatch.await(1, TimeUnit.SECONDS); + layoutLatch.await(2, TimeUnit.SECONDS); } /** @@ -145,8 +139,9 @@ public class PhysicsAnimationLayoutTestCase extends SysuiTestCase { @Override public void setController(PhysicsAnimationController controller) { - mMainThreadHandler.post(() -> super.setController(controller)); - waitForMessageQueueAndIgnoreIfInterrupted(); + runOnMainThreadAndBlock( + () -> super.setController( + new MainThreadAnimationControllerWrapper(controller))); } @Override @@ -160,59 +155,139 @@ public class PhysicsAnimationLayoutTestCase extends SysuiTestCase { } @Override - protected void animateValueForChildAtIndex(DynamicAnimation.ViewProperty property, - int index, float value, float startVel, Runnable after) { - mMainThreadHandler.post(() -> - super.animateValueForChildAtIndex(property, index, value, startVel, after)); - } - - @Override public WindowInsets getRootWindowInsets() { return mWindowInsets; } @Override - public void removeView(View view) { - mMainThreadHandler.post(() -> - super.removeView(view)); - waitForMessageQueueAndIgnoreIfInterrupted(); + public void addView(View child, int index) { + child.setTag(R.id.physics_animator_tag, new TestablePhysicsPropertyAnimator(child)); + super.addView(child, index); } @Override public void addView(View child, int index, ViewGroup.LayoutParams params) { - mMainThreadHandler.post(() -> - super.addView(child, index, params)); - waitForMessageQueueAndIgnoreIfInterrupted(); + child.setTag(R.id.physics_animator_tag, new TestablePhysicsPropertyAnimator(child)); + super.addView(child, index, params); } /** - * Wait for the queue but just catch and print the exception if interrupted, since we can't - * just add the exception to the overridden methods' signatures. + * Sets an end action that will be called after the 'real' end action that was already set. */ - private void waitForMessageQueueAndIgnoreIfInterrupted() { - try { - waitForLayoutMessageQueue(); - } catch (InterruptedException e) { - e.printStackTrace(); + private void setTestEndActionForProperty( + Runnable action, DynamicAnimation.ViewProperty property) { + final Runnable realEndAction = mEndActionForProperty.get(property); + + setEndActionForProperty(() -> { + if (realEndAction != null) { + realEndAction.run(); + } + + action.run(); + }, property); + } + + /** PhysicsPropertyAnimator that posts its animations to the main thread. */ + protected class TestablePhysicsPropertyAnimator extends PhysicsPropertyAnimator { + public TestablePhysicsPropertyAnimator(View view) { + super(view); + } + + @Override + protected void animateValueForChild(DynamicAnimation.ViewProperty property, View view, + float value, float startVel, long startDelay, Runnable[] afterCallbacks) { + mMainThreadHandler.post(() -> super.animateValueForChild( + property, view, value, startVel, startDelay, afterCallbacks)); } } /** - * Sets an end listener that will be called after the 'real' end listener that was already - * set. + * Wrapper around an animation controller that dispatches methods that could start + * animations to the main thread. */ - private void setTestEndListenerForProperty(DynamicAnimation.OnAnimationEndListener listener, - DynamicAnimation.ViewProperty property) { - final DynamicAnimation.OnAnimationEndListener realEndListener = - mEndListenerForProperty.get(property); - - setEndListenerForProperty((animation, canceled, value, velocity) -> { - if (realEndListener != null) { - realEndListener.onAnimationEnd(animation, canceled, value, velocity); + protected class MainThreadAnimationControllerWrapper extends PhysicsAnimationController { + + private final PhysicsAnimationController mWrappedController; + + protected MainThreadAnimationControllerWrapper(PhysicsAnimationController controller) { + mWrappedController = controller; + } + + @Override + protected void setLayout(PhysicsAnimationLayout layout) { + mWrappedController.setLayout(layout); + } + + @Override + protected PhysicsAnimationLayout getLayout() { + return mWrappedController.getLayout(); + } + + @Override + Set<DynamicAnimation.ViewProperty> getAnimatedProperties() { + return mWrappedController.getAnimatedProperties(); + } + + @Override + int getNextAnimationInChain(DynamicAnimation.ViewProperty property, int index) { + return mWrappedController.getNextAnimationInChain(property, index); + } + + @Override + float getOffsetForChainedPropertyAnimation(DynamicAnimation.ViewProperty property) { + return mWrappedController.getOffsetForChainedPropertyAnimation(property); + } + + @Override + SpringForce getSpringForce(DynamicAnimation.ViewProperty property, View view) { + return mWrappedController.getSpringForce(property, view); + } + + @Override + void onChildAdded(View child, int index) { + runOnMainThreadAndBlock(() -> mWrappedController.onChildAdded(child, index)); + } + + @Override + void onChildRemoved(View child, int index, Runnable finishRemoval) { + runOnMainThreadAndBlock( + () -> mWrappedController.onChildRemoved(child, index, finishRemoval)); + } + + @Override + protected void setChildVisibility(View child, int index, int visibility) { + mWrappedController.setChildVisibility(child, index, visibility); + } + + @Override + protected PhysicsPropertyAnimator animationForChild(View child) { + PhysicsPropertyAnimator animator = + (PhysicsPropertyAnimator) child.getTag(R.id.physics_animator_tag); + + if (!(animator instanceof TestablePhysicsPropertyAnimator)) { + animator = new TestablePhysicsPropertyAnimator(child); + child.setTag(R.id.physics_animator_tag, animator); } - listener.onAnimationEnd(animation, canceled, value, velocity); - }, property); + return animator; + } + } + } + + /** + * Posts the given Runnable on the main thread, and blocks the calling thread until it's run. + */ + private void runOnMainThreadAndBlock(Runnable action) { + final CountDownLatch latch = new CountDownLatch(1); + mMainThreadHandler.post(() -> { + action.run(); + latch.countDown(); + }); + + try { + latch.await(5, TimeUnit.SECONDS); + } catch (InterruptedException e) { + e.printStackTrace(); } } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java index 2ee73f30ea5a..096f205e7a56 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java @@ -209,6 +209,9 @@ public class StackAnimationControllerTest extends PhysicsAnimationLayoutTestCase final PointF prevStackPos = mStackController.getStackPosition(); mLayout.removeAllViews(); + + waitForLayoutMessageQueue(); + mLayout.addView(new FrameLayout(getContext())); waitForLayoutMessageQueue(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/SensorPrivacyTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/SensorPrivacyTileTest.java deleted file mode 100644 index 6386c4cd6331..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/SensorPrivacyTileTest.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2018 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.tiles; - -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.hardware.SensorPrivacyManager; -import android.testing.AndroidTestingRunner; -import android.testing.TestableLooper; - -import androidx.test.filters.SmallTest; - -import com.android.systemui.Dependency; -import com.android.systemui.SysuiTestCase; -import com.android.systemui.plugins.ActivityStarter; -import com.android.systemui.qs.QSTileHost; -import com.android.systemui.statusbar.policy.KeyguardMonitor; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@RunWith(AndroidTestingRunner.class) -@TestableLooper.RunWithLooper -@SmallTest -public class SensorPrivacyTileTest extends SysuiTestCase { - - @Mock - private KeyguardMonitor mKeyguard; - @Mock - private QSTileHost mHost; - @Mock - SensorPrivacyManager mSensorPrivacyManager; - - private TestableLooper mTestableLooper; - - private SensorPrivacyTile mSensorPrivacyTile; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - - mTestableLooper = TestableLooper.get(this); - mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper()); - mKeyguard = mDependency.injectMockDependency(KeyguardMonitor.class); - - mSensorPrivacyManager = mDependency.injectMockDependency(SensorPrivacyManager.class); - - when(mHost.getContext()).thenReturn(mContext); - - mSensorPrivacyTile = new SensorPrivacyTile(mHost, mSensorPrivacyManager, mKeyguard, - mock(ActivityStarter.class)); - } - - @Test - public void testSensorPrivacyListenerAdded_handleListeningTrue() { - // To prevent access to privacy related features from apps with WRITE_SECURE_SETTINGS the - // sensor privacy state is not stored in Settings; to receive notification apps must add - // themselves as a listener with the SensorPrivacyManager. This test verifies when - // setListening is called with a value of true the tile adds itself as a listener. - mSensorPrivacyTile.handleSetListening(true); - mTestableLooper.processAllMessages(); - verify(mSensorPrivacyManager).addSensorPrivacyListener(mSensorPrivacyTile); - } - - @Test - public void testSensorPrivacyListenerRemoved_handleListeningFalse() { - // Similar to the test above verifies that the tile removes itself as a listener when - // setListening is called with a value of false. - mSensorPrivacyTile.handleSetListening(false); - mTestableLooper.processAllMessages(); - verify(mSensorPrivacyManager).removeSensorPrivacyListener((mSensorPrivacyTile)); - } - - @Test - public void testSensorPrivacyEnabled_handleClick() { - // Verifies when the SensorPrivacy tile is clicked it invokes the SensorPrivacyManager to - // set sensor privacy. - mSensorPrivacyTile.getState().value = false; - mSensorPrivacyTile.handleClick(); - mTestableLooper.processAllMessages(); - verify(mSensorPrivacyManager).setSensorPrivacy(true); - - mSensorPrivacyTile.getState().value = true; - mSensorPrivacyTile.handleClick(); - mTestableLooper.processAllMessages(); - verify(mSensorPrivacyManager).setSensorPrivacy(false); - } - - @Test - public void testSensorPrivacyNotDisabled_keyguard() { - // Verifies when the device is locked that sensor privacy cannot be disabled - when(mKeyguard.isSecure()).thenReturn(true); - when(mKeyguard.isShowing()).thenReturn(true); - mSensorPrivacyTile.getState().value = true; - mSensorPrivacyTile.handleClick(); - mTestableLooper.processAllMessages(); - verify(mSensorPrivacyManager, never()).setSensorPrivacy(false); - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java index 2a013560bcd3..1a1acdf4590c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java @@ -129,7 +129,7 @@ public class NotificationListenerTest extends SysuiTestCase { mock(NotificationListener.NotificationSettingsListener.class); mListener.addNotificationSettingsListener(settingsListener); - mListener.onStatusBarIconsBehaviorChanged(true); + mListener.onSilentStatusBarIconsVisibilityChanged(true); verify(settingsListener).onStatusBarIconsBehaviorChanged(true); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java index 5a1f24a44b2f..1bcf8803b5cf 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java @@ -312,7 +312,6 @@ public class NotificationTestHelper { return new BubbleMetadata.Builder() .setIntent(bubbleIntent) .setDeleteIntent(deleteIntent) - .setTitle("bubble title") .setIcon(Icon.createWithResource(mContext, R.drawable.android)) .setDesiredHeight(314) .build(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardPresentationTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardPresentationTest.java index eec836fde7f5..dfe2913e4ea3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardPresentationTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardPresentationTest.java @@ -23,7 +23,9 @@ import android.view.LayoutInflater; import androidx.test.filters.SmallTest; import com.android.systemui.R; +import com.android.systemui.SystemUIFactory; import com.android.systemui.SysuiTestCase; +import com.android.systemui.util.InjectionInflationController; import org.junit.Test; import org.junit.runner.RunWith; @@ -35,7 +37,10 @@ public class KeyguardPresentationTest extends SysuiTestCase { @Test public void testInflation_doesntCrash() { com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper(); - LayoutInflater inflater = LayoutInflater.from(getContext()); + InjectionInflationController inflationController = new InjectionInflationController( + SystemUIFactory.getInstance().getRootComponent()); + LayoutInflater inflater = inflationController + .injectable(LayoutInflater.from(getContext())); inflater.inflate(R.layout.keyguard_presentation, null); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java index 6889c57d74df..232c6a25a708 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java @@ -27,6 +27,7 @@ import android.testing.TestableLooper; import androidx.test.filters.SmallTest; import com.android.keyguard.KeyguardStatusView; +import com.android.systemui.SystemUIFactory; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.AmbientPulseManager; @@ -38,6 +39,7 @@ import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ZenModeController; +import com.android.systemui.util.InjectionInflationController; import org.junit.Before; import org.junit.Test; @@ -104,7 +106,10 @@ public class NotificationPanelViewTest extends SysuiTestCase { private class TestableNotificationPanelView extends NotificationPanelView { TestableNotificationPanelView(NotificationWakeUpCoordinator coordinator, PulseExpansionHandler expansionHandler) { - super(NotificationPanelViewTest.this.mContext, null, coordinator, expansionHandler); + super(NotificationPanelViewTest.this.mContext, null, + new InjectionInflationController( + SystemUIFactory.getInstance().getRootComponent()), + coordinator, expansionHandler); mNotificationStackScroller = mNotificationStackScrollLayout; mKeyguardStatusView = NotificationPanelViewTest.this.mKeyguardStatusView; mKeyguardStatusBar = NotificationPanelViewTest.this.mKeyguardStatusBar; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java new file mode 100644 index 000000000000..20af1ac5a42f --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.phone; + +import static org.mockito.AdditionalAnswers.answerVoid; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.app.KeyguardManager; +import android.app.Notification; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.os.Handler; +import android.os.RemoteException; +import android.os.UserHandle; +import android.service.dreams.IDreamManager; +import android.service.notification.StatusBarNotification; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; + +import androidx.test.filters.SmallTest; + +import com.android.internal.logging.MetricsLogger; +import com.android.internal.statusbar.IStatusBarService; +import com.android.internal.statusbar.NotificationVisibility; +import com.android.internal.widget.LockPatternUtils; +import com.android.systemui.ActivityIntentHelper; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.assist.AssistManager; +import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.statusbar.NotificationLockscreenUserManager; +import com.android.systemui.statusbar.NotificationPresenter; +import com.android.systemui.statusbar.NotificationRemoteInputManager; +import com.android.systemui.statusbar.NotificationTestHelper; +import com.android.systemui.statusbar.RemoteInputController; +import com.android.systemui.statusbar.StatusBarState; +import com.android.systemui.statusbar.notification.ActivityLaunchAnimator; +import com.android.systemui.statusbar.notification.NotificationActivityStarter; +import com.android.systemui.statusbar.notification.NotificationEntryManager; +import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider; +import com.android.systemui.statusbar.notification.collection.NotificationData; +import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; +import com.android.systemui.statusbar.policy.KeyguardMonitor; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.stubbing.Answer; + +import java.util.ArrayList; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper(setAsMainLooper = true) +public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { + + @Mock + private AssistManager mAssistManager; + @Mock + private NotificationEntryManager mEntryManager; + @Mock + private ActivityStarter mActivityStarter; + @Mock + private IStatusBarService mStatusBarService; + @Mock + private StatusBarStateController mStatusBarStateController; + @Mock + private NotificationRemoteInputManager mRemoteInputManager; + @Mock + private RemoteInputController mRemoteInputController; + @Mock + private ShadeController mShadeController; + @Mock + private KeyguardMonitor mKeyguardMonitor; + @Mock + private Handler mHandler; + + @Mock + private ActivityIntentHelper mActivityIntentHelper; + @Mock + private PendingIntent mContentIntent; + @Mock + private NotificationData mNotificationData; + @Mock + private NotificationEntry mNotificationEntry; + @Mock + private NotificationEntry mBubbleEntry; + + private NotificationActivityStarter mNotificationActivityStarter; + + private NotificationTestHelper mNotificationTestHelper; + ExpandableNotificationRow mNotificationRow; + + private final Answer<Void> mCallOnDismiss = answerVoid( + (ActivityStarter.OnDismissAction dismissAction, Runnable cancel, + Boolean afterKeyguardGone) -> dismissAction.onDismiss()); + private ArrayList<NotificationEntry> mActiveNotifications; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController); + when(mEntryManager.getNotificationData()).thenReturn(mNotificationData); + + mActiveNotifications = new ArrayList<>(); + mActiveNotifications.add(mNotificationEntry); + mActiveNotifications.add(mBubbleEntry); + when(mNotificationData.getActiveNotifications()).thenReturn(mActiveNotifications); + when(mNotificationEntry.getRow()).thenReturn(mNotificationRow); + + mNotificationTestHelper = new NotificationTestHelper(mContext); + mNotificationRow = mNotificationTestHelper.createRow(); + + mNotificationActivityStarter = new StatusBarNotificationActivityStarter(getContext(), + mock(CommandQueue.class), mAssistManager, mock(NotificationPanelView.class), + mock(NotificationPresenter.class), mEntryManager, mock(HeadsUpManagerPhone.class), + mActivityStarter, mock(ActivityLaunchAnimator.class), mStatusBarService, + mock(StatusBarStateController.class), mock(KeyguardManager.class), + mock(IDreamManager.class), mRemoteInputManager, + mock(StatusBarRemoteInputCallback.class), mock(NotificationGroupManager.class), + mock(NotificationLockscreenUserManager.class), mShadeController, mKeyguardMonitor, + mock(NotificationInterruptionStateProvider.class), mock(MetricsLogger.class), + mock(LockPatternUtils.class), mHandler, mActivityIntentHelper); + + + when(mContentIntent.isActivity()).thenReturn(true); + when(mContentIntent.getCreatorUserHandle()).thenReturn(UserHandle.of(1)); + + // SBNActivityStarter expects contentIntent or fullScreenIntent to be set + mNotificationRow.getEntry().notification.getNotification().contentIntent = mContentIntent; + + when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE); + + // set up dismissKeyguardThenExecute to synchronously invoke the OnDismissAction arg + doAnswer(mCallOnDismiss).when(mActivityStarter).dismissKeyguardThenExecute( + any(ActivityStarter.OnDismissAction.class), any(), anyBoolean()); + + // set up addAfterKeyguardGoneRunnable to synchronously invoke the Runnable arg + doAnswer(answerVoid(Runnable::run)) + .when(mShadeController).addAfterKeyguardGoneRunnable(any(Runnable.class)); + + // set up addPostCollapseAction to synchronously invoke the Runnable arg + doAnswer(answerVoid(Runnable::run)) + .when(mShadeController).addPostCollapseAction(any(Runnable.class)); + + // set up Handler to synchronously invoke the Runnable arg + doAnswer(answerVoid(Runnable::run)) + .when(mHandler).post(any(Runnable.class)); + } + + @Test + public void testOnNotificationClicked_whileKeyguardVisible() + throws PendingIntent.CanceledException, RemoteException { + // Given + when(mKeyguardMonitor.isShowing()).thenReturn(true); + when(mShadeController.isOccluded()).thenReturn(true); + when(mContentIntent.isActivity()).thenReturn(true); + when(mActivityIntentHelper.wouldShowOverLockscreen(any(Intent.class), anyInt())) + .thenReturn(false); + when(mActivityIntentHelper.wouldLaunchResolverActivity(any(Intent.class), anyInt())) + .thenReturn(false); + + StatusBarNotification statusBarNotification = mNotificationRow.getEntry().notification; + statusBarNotification.getNotification().flags |= Notification.FLAG_AUTO_CANCEL; + + // When + mNotificationActivityStarter.onNotificationClicked(statusBarNotification, + mNotificationRow); + + // Then + verify(mActivityStarter).dismissKeyguardThenExecute( + any(ActivityStarter.OnDismissAction.class), + any() /* cancel */, + anyBoolean() /* afterKeyguardGone */); + + verify(mShadeController, atLeastOnce()).collapsePanel(); + + verify(mContentIntent).sendAndReturnResult( + any(Context.class), + anyInt() /* code */, + any() /* fillInIntent */, + any() /* PendingIntent.OnFinished */, + any() /* Handler */, + any() /* requiredPermission */, + any() /* Bundle options */); + + verify(mAssistManager).hideAssist(); + + verify(mStatusBarService).onNotificationClick( + eq(mNotificationRow.getEntry().key), any(NotificationVisibility.class)); + + // Notification is removed due to FLAG_AUTO_CANCEL + verify(mEntryManager).performRemoveNotification(eq(statusBarNotification)); + } +} diff --git a/packages/overlays/Android.mk b/packages/overlays/Android.mk index a15e89c8bcdb..c57d4e9f1395 100644 --- a/packages/overlays/Android.mk +++ b/packages/overlays/Android.mk @@ -39,20 +39,15 @@ LOCAL_REQUIRED_MODULES := \ IconShapeRoundedRectOverlay \ IconShapeSquareOverlay \ IconShapeSquircleOverlay \ - IconShapeTeardropOverlay + IconShapeTeardropOverlay \ + NavigationBarMode3ButtonOverlay \ + NavigationBarMode2ButtonOverlay \ + NavigationBarModeGesturalOverlay include $(BUILD_PHONY_PACKAGE) include $(CLEAR_VARS) LOCAL_MODULE := frameworks-base-overlays-debug -LOCAL_REQUIRED_MODULES := \ - ExperimentNavigationBarFloatingOverlay \ - ExperimentNavigationBarVisualInsetOverlay \ - ExperimentNavigationBarDefaultOverlay \ - ExperimentNavigationBarSlimOverlay32 \ - ExperimentNavigationBarSlimOverlay40 \ - ExperimentNavigationBarLargeOverlay56 \ - ExperimentNavigationBarLargeOverlay64 include $(BUILD_PHONY_PACKAGE) include $(call first-makefiles-under,$(LOCAL_PATH)) diff --git a/packages/overlays/NavigationBarMode2ButtonOverlay/Android.mk b/packages/overlays/NavigationBarMode2ButtonOverlay/Android.mk new file mode 100644 index 000000000000..410d6d87c61d --- /dev/null +++ b/packages/overlays/NavigationBarMode2ButtonOverlay/Android.mk @@ -0,0 +1,30 @@ +# +# Copyright 2018, 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. +# + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_RRO_THEME := NavigationBarMode2Button +LOCAL_CERTIFICATE := platform + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res + +LOCAL_PACKAGE_NAME := NavigationBarMode2ButtonOverlay +LOCAL_SDK_VERSION := current + +include $(BUILD_RRO_PACKAGE)
\ No newline at end of file diff --git a/packages/overlays/NavigationBarMode2ButtonOverlay/AndroidManifest.xml b/packages/overlays/NavigationBarMode2ButtonOverlay/AndroidManifest.xml new file mode 100644 index 000000000000..970380f070e9 --- /dev/null +++ b/packages/overlays/NavigationBarMode2ButtonOverlay/AndroidManifest.xml @@ -0,0 +1,27 @@ +<!-- +/** + * Copyright (c) 2018, 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. + */ +--> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.internal.systemui.navbar.twobutton" + android:versionCode="1" + android:versionName="1.0"> + <overlay android:targetPackage="android" + android:category="com.android.internal.navigation_bar_mode" + android:priority="1"/> + + <application android:label="@string/navigation_bar_mode_title" android:hasCode="false"/> +</manifest>
\ No newline at end of file diff --git a/packages/overlays/NavigationBarMode2ButtonOverlay/res/values/config.xml b/packages/overlays/NavigationBarMode2ButtonOverlay/res/values/config.xml new file mode 100644 index 000000000000..b353322aed9c --- /dev/null +++ b/packages/overlays/NavigationBarMode2ButtonOverlay/res/values/config.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources> + <!-- Controls the navigation bar interaction mode: + 0: 3 button mode (back, home, overview buttons) + 1: 2 button mode (back, home buttons + swipe up for overview) + 2: gestures only for back, home and overview --> + <integer name="config_navBarInteractionMode">1</integer> +</resources>
\ No newline at end of file diff --git a/packages/overlays/NavigationBarMode2ButtonOverlay/res/values/strings.xml b/packages/overlays/NavigationBarMode2ButtonOverlay/res/values/strings.xml new file mode 100644 index 000000000000..1696ecfea4e4 --- /dev/null +++ b/packages/overlays/NavigationBarMode2ButtonOverlay/res/values/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2018, 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. + */ +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- Name of overlay [CHAR LIMIT=64] --> + <string name="navigation_bar_mode_title" translatable="false">2 Button Navigation Bar</string> +</resources>
\ No newline at end of file diff --git a/packages/overlays/NavigationBarMode3ButtonOverlay/Android.mk b/packages/overlays/NavigationBarMode3ButtonOverlay/Android.mk new file mode 100644 index 000000000000..2bc9a6aea9eb --- /dev/null +++ b/packages/overlays/NavigationBarMode3ButtonOverlay/Android.mk @@ -0,0 +1,30 @@ +# +# Copyright 2018, 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. +# + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_RRO_THEME := NavigationBarMode3Button +LOCAL_CERTIFICATE := platform + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res + +LOCAL_PACKAGE_NAME := NavigationBarMode3ButtonOverlay +LOCAL_SDK_VERSION := current + +include $(BUILD_RRO_PACKAGE)
\ No newline at end of file diff --git a/packages/overlays/NavigationBarMode3ButtonOverlay/AndroidManifest.xml b/packages/overlays/NavigationBarMode3ButtonOverlay/AndroidManifest.xml new file mode 100644 index 000000000000..628fc1dd3aa7 --- /dev/null +++ b/packages/overlays/NavigationBarMode3ButtonOverlay/AndroidManifest.xml @@ -0,0 +1,27 @@ +<!-- +/** + * Copyright (c) 2018, 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. + */ +--> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.internal.systemui.navbar.threebutton" + android:versionCode="1" + android:versionName="1.0"> + <overlay android:targetPackage="android" + android:category="com.android.internal.navigation_bar_mode" + android:priority="1"/> + + <application android:label="@string/navigation_bar_mode_title" android:hasCode="false"/> +</manifest>
\ No newline at end of file diff --git a/packages/overlays/NavigationBarMode3ButtonOverlay/res/values/config.xml b/packages/overlays/NavigationBarMode3ButtonOverlay/res/values/config.xml new file mode 100644 index 000000000000..7bd0a140bb1c --- /dev/null +++ b/packages/overlays/NavigationBarMode3ButtonOverlay/res/values/config.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources> + <!-- Controls the navigation bar interaction mode: + 0: 3 button mode (back, home, overview buttons) + 1: 2 button mode (back, home buttons + swipe up for overview) + 2: gestures only for back, home and overview --> + <integer name="config_navBarInteractionMode">0</integer> +</resources>
\ No newline at end of file diff --git a/packages/overlays/NavigationBarMode3ButtonOverlay/res/values/strings.xml b/packages/overlays/NavigationBarMode3ButtonOverlay/res/values/strings.xml new file mode 100644 index 000000000000..201b9e94cfbc --- /dev/null +++ b/packages/overlays/NavigationBarMode3ButtonOverlay/res/values/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2018, 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. + */ +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- Name of overlay [CHAR LIMIT=64] --> + <string name="navigation_bar_mode_title" translatable="false">3 Button Navigation Bar</string> +</resources>
\ No newline at end of file diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/Android.mk b/packages/overlays/NavigationBarModeGesturalOverlay/Android.mk new file mode 100644 index 000000000000..5f7e0eb62a46 --- /dev/null +++ b/packages/overlays/NavigationBarModeGesturalOverlay/Android.mk @@ -0,0 +1,30 @@ +# +# Copyright 2018, 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. +# + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_RRO_THEME := NavigationBarModeGestural +LOCAL_CERTIFICATE := platform + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res + +LOCAL_PACKAGE_NAME := NavigationBarModeGesturalOverlay +LOCAL_SDK_VERSION := current + +include $(BUILD_RRO_PACKAGE)
\ No newline at end of file diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/AndroidManifest.xml b/packages/overlays/NavigationBarModeGesturalOverlay/AndroidManifest.xml new file mode 100644 index 000000000000..aff82d836ae5 --- /dev/null +++ b/packages/overlays/NavigationBarModeGesturalOverlay/AndroidManifest.xml @@ -0,0 +1,27 @@ +<!-- +/** + * Copyright (c) 2018, 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. + */ +--> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.internal.systemui.navbar.gestural" + android:versionCode="1" + android:versionName="1.0"> + <overlay android:targetPackage="android" + android:category="com.android.internal.navigation_bar_mode" + android:priority="1"/> + + <application android:label="@string/navigation_bar_mode_title" android:hasCode="false"/> +</manifest>
\ No newline at end of file diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml new file mode 100644 index 000000000000..48c37695d4a1 --- /dev/null +++ b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources> + <!-- Controls the navigation bar interaction mode: + 0: 3 button mode (back, home, overview buttons) + 1: 2 button mode (back, home buttons + swipe up for overview) + 2: gestures only for back, home and overview --> + <integer name="config_navBarInteractionMode">2</integer> +</resources>
\ No newline at end of file diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml new file mode 100644 index 000000000000..721d11be8cb5 --- /dev/null +++ b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources> + <!-- Height of the bottom navigation / system bar. --> + <dimen name="navigation_bar_height">16dp</dimen> + <!-- Width of the navigation bar when it is placed vertically on the screen --> + <dimen name="navigation_bar_width">16dp</dimen> + <!-- Height of the bottom navigation / system bar. --> + <dimen name="navigation_bar_frame_height">48dp</dimen> + <!-- Width of the navigation bar when it is placed vertically on the screen --> + <dimen name="navigation_bar_frame_width">48dp</dimen> +</resources>
\ No newline at end of file diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/strings.xml b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/strings.xml new file mode 100644 index 000000000000..8d38916a0541 --- /dev/null +++ b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2018, 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. + */ +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- Name of overlay [CHAR LIMIT=64] --> + <string name="navigation_bar_mode_title" translatable="false">Gestural Navigation Bar</string> +</resources>
\ No newline at end of file diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto index 7447331b113d..95abd05ff011 100644 --- a/proto/src/metrics_constants/metrics_constants.proto +++ b/proto/src/metrics_constants/metrics_constants.proto @@ -74,6 +74,9 @@ message MetricsEvent { // The view switched to summary mode (most relevant for notifications) TYPE_COLLAPSE = 14; + // The action results an error. + TYPE_ERROR = 15; + // The notification was adjusted by the assistant. Enum value is // out of sequence due to b/122737498. TYPE_NOTIFICATION_ASSISTANT_ADJUSTMENT = 1573; @@ -7138,6 +7141,14 @@ message MetricsEvent { // OS: Q DISPLAY_POLICY = 1696; + // Biometric authentication. + // TYPE: SUCCESS, FAILURE or ERROR + // SUBTYPE: 0 is fingerprint, 1 is face, 2 is iris and 3 is unknown. + // OS: Q + BIOMETRIC_AUTH = 1697; + + // Settings > Display > Theme + DARK_UI_SETTINGS = 1698; // ---- End Q Constants, all Q constants go above this line ---- // Add new aosp constants above this line. // END OF AOSP CONSTANTS diff --git a/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java b/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java index 833eaa06d759..6bb537041668 100644 --- a/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java +++ b/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java @@ -94,10 +94,10 @@ public class AppPredictionManagerService extends } @Override - public void notifyLocationShown(@NonNull AppPredictionSessionId sessionId, + public void notifyLaunchLocationShown(@NonNull AppPredictionSessionId sessionId, @NonNull String launchLocation, @NonNull ParceledListSlice targetIds) { runForUserLocked((service) -> - service.notifyLocationShownLocked(sessionId, launchLocation, targetIds)); + service.notifyLaunchLocationShownLocked(sessionId, launchLocation, targetIds)); } @Override diff --git a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java index 24d592c38afb..430abf5c479d 100644 --- a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java +++ b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java @@ -111,11 +111,11 @@ public class AppPredictionPerUserService extends * Records when a launch location is shown. */ @GuardedBy("mLock") - public void notifyLocationShownLocked(@NonNull AppPredictionSessionId sessionId, + public void notifyLaunchLocationShownLocked(@NonNull AppPredictionSessionId sessionId, @NonNull String launchLocation, @NonNull ParceledListSlice targetIds) { final RemoteAppPredictionService service = getRemoteServiceLocked(); if (service != null) { - service.notifyLocationShown(sessionId, launchLocation, targetIds); + service.notifyLaunchLocationShown(sessionId, launchLocation, targetIds); } } diff --git a/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java b/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java index 922b3271e20c..21088e442212 100644 --- a/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java +++ b/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java @@ -85,9 +85,10 @@ public class RemoteAppPredictionService extends /** * Records when a launch location is shown. */ - public void notifyLocationShown(@NonNull AppPredictionSessionId sessionId, + public void notifyLaunchLocationShown(@NonNull AppPredictionSessionId sessionId, @NonNull String launchLocation, @NonNull ParceledListSlice targetIds) { - scheduleAsyncRequest((s) -> s.notifyLocationShown(sessionId, launchLocation, targetIds)); + scheduleAsyncRequest((s) + -> s.notifyLaunchLocationShown(sessionId, launchLocation, targetIds)); } /** diff --git a/services/art-profile b/services/art-profile index 6368c632d5a0..f0b9234ff4a6 100644 --- a/services/art-profile +++ b/services/art-profile @@ -1136,7 +1136,7 @@ Lcom/android/server/DropBoxManagerService$4; Lcom/android/server/DropBoxManagerService$EntryFile; Lcom/android/server/DropBoxManagerService$FileList; Lcom/android/server/DropBoxManagerService; -Lcom/android/server/DynamicAndroidService; +Lcom/android/server/DynamicSystemService; Lcom/android/server/EntropyMixer$1; Lcom/android/server/EntropyMixer$2; Lcom/android/server/EntropyMixer; @@ -4769,9 +4769,9 @@ PLcom/android/server/DropBoxManagerService$2;->getNextEntry(Ljava/lang/String;JL PLcom/android/server/DropBoxManagerService$EntryFile;->getFile(Ljava/io/File;)Ljava/io/File; PLcom/android/server/DropBoxManagerService;->checkPermission(ILjava/lang/String;)Z PLcom/android/server/DropBoxManagerService;->getNextEntry(Ljava/lang/String;JLjava/lang/String;)Landroid/os/DropBoxManager$Entry; -PLcom/android/server/DynamicAndroidService;->connect(Landroid/os/IBinder$DeathRecipient;)Landroid/gsi/IGsiService; -PLcom/android/server/DynamicAndroidService;->getGsiService()Landroid/gsi/IGsiService; -PLcom/android/server/DynamicAndroidService;->isInUse()Z +PLcom/android/server/DynamicSystemService;->connect(Landroid/os/IBinder$DeathRecipient;)Landroid/gsi/IGsiService; +PLcom/android/server/DynamicSystemService;->getGsiService()Landroid/gsi/IGsiService; +PLcom/android/server/DynamicSystemService;->isInUse()Z PLcom/android/server/EntropyMixer$1;->handleMessage(Landroid/os/Message;)V PLcom/android/server/EntropyMixer$2;->onReceive(Landroid/content/Context;Landroid/content/Intent;)V PLcom/android/server/EventLogTags;->writeBatterySaverMode(IIIIILjava/lang/String;I)V @@ -15043,7 +15043,7 @@ SPLcom/android/server/DropBoxManagerService;->isTagEnabled(Ljava/lang/String;)Z SPLcom/android/server/DropBoxManagerService;->onBootPhase(I)V SPLcom/android/server/DropBoxManagerService;->onStart()V SPLcom/android/server/DropBoxManagerService;->trimToFit()J -SPLcom/android/server/DynamicAndroidService;-><init>(Landroid/content/Context;)V +SPLcom/android/server/DynamicSystemService;-><init>(Landroid/content/Context;)V SPLcom/android/server/EntropyMixer;-><init>(Landroid/content/Context;)V SPLcom/android/server/EntropyMixer;-><init>(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V SPLcom/android/server/EntropyMixer;->addDeviceSpecificEntropy()V diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java index c1c125da1f69..87a265cf38d4 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java @@ -80,6 +80,7 @@ import com.android.server.FgThread; import com.android.server.LocalServices; import com.android.server.autofill.ui.AutoFillUI; import com.android.server.infra.AbstractMasterSystemService; +import com.android.server.infra.FrameworkResourcesServiceNameResolver; import com.android.server.infra.SecureSettingsServiceNameResolver; import java.io.FileDescriptor; @@ -132,6 +133,12 @@ public final class AutofillManagerService @GuardedBy("sLock") private static int sVisibleDatasetsMaxCount = 0; + /** + * Object used to set the name of the augmented autofill service. + */ + @NonNull + final FrameworkResourcesServiceNameResolver mAugmentedAutofillResolver; + private final AutoFillUI mUi; private final LocalLog mRequestsHistory = new LocalLog(20); @@ -200,6 +207,11 @@ public final class AutofillManagerService getServiceForUserLocked(userId); } } + + mAugmentedAutofillResolver = new FrameworkResourcesServiceNameResolver(getContext(), + com.android.internal.R.string.config_defaultAugmentedAutofillService); + mAugmentedAutofillResolver.setOnTemporaryServiceNameChangedCallback( + (u, s) -> getServiceForUserLocked(u).updateRemoteAugmentedAutofillService()); } @Override // from AbstractMasterSystemService @@ -521,7 +533,7 @@ public final class AutofillManagerService new FieldClassificationStrategy(getContext(), UserHandle.USER_CURRENT); strategy.calculateScores(callback, Arrays.asList(AutofillValue.forText(value1)), - new String[] { value2 }, null, algorithmName, null, null, null); + new String[] { value2 }, new String[] { null }, algorithmName, null, null, null); } // Called by Shell command. @@ -549,37 +561,19 @@ public final class AutofillManagerService + MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS + " (called with " + durationMs + ")"); } - synchronized (mLock) { - final AutofillManagerServiceImpl service = getServiceForUserLocked(userId); - if (service != null) { - service.mAugmentedAutofillResolver.setTemporaryService(userId, serviceName, - durationMs); - } - } + mAugmentedAutofillResolver.setTemporaryService(userId, serviceName, durationMs); } // Called by Shell command void resetTemporaryAugmentedAutofillService(@UserIdInt int userId) { enforceCallingPermissionForManagement(); - synchronized (mLock) { - final AutofillManagerServiceImpl service = getServiceForUserLocked(userId); - if (service != null) { - service.mAugmentedAutofillResolver.resetTemporaryService(userId); - } - } + mAugmentedAutofillResolver.resetTemporaryService(userId); } // Called by Shell command boolean isDefaultAugmentedServiceEnabled(@UserIdInt int userId) { enforceCallingPermissionForManagement(); - - synchronized (mLock) { - final AutofillManagerServiceImpl service = getServiceForUserLocked(userId); - if (service != null) { - return service.mAugmentedAutofillResolver.isDefaultServiceEnabled(userId); - } - } - return false; + return mAugmentedAutofillResolver.isDefaultServiceEnabled(userId); } // Called by Shell command @@ -590,7 +584,7 @@ public final class AutofillManagerService synchronized (mLock) { final AutofillManagerServiceImpl service = getServiceForUserLocked(userId); if (service != null) { - final boolean changed = service.mAugmentedAutofillResolver + final boolean changed = mAugmentedAutofillResolver .setDefaultServiceEnabled(userId, enabled); if (changed) { service.updateRemoteAugmentedAutofillService(); @@ -942,12 +936,14 @@ public final class AutofillManagerService final class AutoFillManagerServiceStub extends IAutoFillManager.Stub { @Override - public void addClient(IAutoFillManagerClient client, int userId, - @NonNull IResultReceiver receiver) { + public void addClient(IAutoFillManagerClient client, ComponentName componentName, + int userId, IResultReceiver receiver) { int flags = 0; synchronized (mLock) { - if (getServiceForUserLocked(userId).addClientLocked(client)) { - flags |= AutofillManager.FLAG_ADD_CLIENT_ENABLED; + final int enabledFlags = getServiceForUserLocked(userId).addClientLocked(client, + componentName); + if (enabledFlags != 0) { + flags |= enabledFlags; } if (sDebug) { flags |= AutofillManager.FLAG_ADD_CLIENT_DEBUG; @@ -1346,6 +1342,7 @@ public final class AutofillManagerService pw.print(" sVerbose: "); pw.println(realVerbose); // Dump per-user services dumpLocked("", pw); + mAugmentedAutofillResolver.dumpShort(pw); pw.println(); pw.print("Max partitions per session: "); pw.println(sPartitionMaxCount); pw.print("Max visible datasets: "); pw.println(sVisibleDatasetsMaxCount); if (sFullScreenMode != null) { diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java index 720d319b12f8..ff284dcabfd0 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java @@ -18,6 +18,8 @@ package com.android.server.autofill; import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST; import static android.view.autofill.AutofillManager.ACTION_START_SESSION; +import static android.view.autofill.AutofillManager.FLAG_ADD_CLIENT_ENABLED; +import static android.view.autofill.AutofillManager.FLAG_ADD_CLIENT_ENABLED_FOR_AUGMENTED_AUTOFILL_ONLY; import static android.view.autofill.AutofillManager.FLAG_SESSION_FOR_AUGMENTED_AUTOFILL_ONLY; import static android.view.autofill.AutofillManager.NO_SESSION; @@ -38,6 +40,7 @@ import android.graphics.Rect; import android.metrics.LogMaker; import android.os.AsyncTask; import android.os.Binder; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -54,7 +57,6 @@ import android.service.autofill.FieldClassification; import android.service.autofill.FieldClassification.Match; import android.service.autofill.FillEventHistory; import android.service.autofill.FillEventHistory.Event; -import android.service.autofill.FillRequest; import android.service.autofill.FillResponse; import android.service.autofill.IAutoFillService; import android.service.autofill.UserData; @@ -82,7 +84,6 @@ import com.android.server.autofill.AutofillManagerService.AutofillCompatState; import com.android.server.autofill.RemoteAugmentedAutofillService.RemoteAugmentedAutofillServiceCallbacks; import com.android.server.autofill.ui.AutoFillUI; import com.android.server.infra.AbstractPerUserSystemService; -import com.android.server.infra.FrameworkResourcesServiceNameResolver; import java.io.PrintWriter; import java.util.ArrayList; @@ -158,13 +159,6 @@ final class AutofillManagerServiceImpl /** When was {@link PruneTask} last executed? */ private long mLastPrune = 0; - // TODO(b/128911469): move to AutofillManagerService - /** - * Object used to set the name of the augmented autofill service. - */ - @NonNull - final FrameworkResourcesServiceNameResolver mAugmentedAutofillResolver; - /** * Reference to the {@link RemoteAugmentedAutofillService}, is set on demand. */ @@ -194,11 +188,6 @@ final class AutofillManagerServiceImpl mFieldClassificationStrategy = new FieldClassificationStrategy(getContext(), userId); mAutofillCompatState = autofillCompatState; - mAugmentedAutofillResolver = new FrameworkResourcesServiceNameResolver(master.getContext(), - com.android.internal.R.string.config_defaultAugmentedAutofillService); - mAugmentedAutofillResolver.setOnTemporaryServiceNameChangedCallback( - (u, s) -> updateRemoteAugmentedAutofillService()); - updateLocked(disabled); } @@ -242,13 +231,28 @@ final class AutofillManagerServiceImpl return mAutofillCompatState.getUrlBarResourceIds(packageName, mUserId); } + /** + * Adds the client and return the proper flags + * + * @return {@code 0} if disabled, {@code FLAG_ADD_CLIENT_ENABLED} if enabled (it might be + * OR'ed with {@code FLAG_AUGMENTED_AUTOFILL_REQUEST}). + */ @GuardedBy("mLock") - boolean addClientLocked(IAutoFillManagerClient client) { + int addClientLocked(IAutoFillManagerClient client, ComponentName componentName) { if (mClients == null) { mClients = new RemoteCallbackList<>(); } mClients.register(client); - return isEnabledLocked(); + + if (isEnabledLocked()) return FLAG_ADD_CLIENT_ENABLED; + + // Check if it's enabled for augmented autofill + if (isSetupCompletedLocked() && isWhitelistedForAugmentedAutofillLocked(componentName)) { + return FLAG_ADD_CLIENT_ENABLED_FOR_AUGMENTED_AUTOFILL_ONLY; + } + + // No flags / disabled + return 0; } @GuardedBy("mLock") @@ -286,7 +290,7 @@ final class AutofillManagerServiceImpl * * @return {@code long} whose right-most 32 bits represent the session id (which is always * non-negative), and the left-most contains extra flags (currently either {@code 0} or - * {@link FillRequest#FLAG_SESSION_FOR_AUGMENTED_AUTOFILL_ONLY}). + * {@link AutofillManager#FLAG_SESSION_FOR_AUGMENTED_AUTOFILL_ONLY}). */ @GuardedBy("mLock") long startSessionLocked(@NonNull IBinder activityToken, int taskId, int uid, @@ -294,26 +298,27 @@ final class AutofillManagerServiceImpl @NonNull Rect virtualBounds, @Nullable AutofillValue value, boolean hasCallback, @NonNull ComponentName componentName, boolean compatMode, boolean bindInstantServiceAllowed, int flags) { - if (!isEnabledLocked()) { + // FLAG_AUGMENTED_AUTOFILL_REQUEST is set in the flags when standard autofill is disabled + // but the package is whitelisted for augmented autofill + boolean forAugmentedAutofillOnly = (flags + & FLAG_ADD_CLIENT_ENABLED_FOR_AUGMENTED_AUTOFILL_ONLY) != 0; + if (!isEnabledLocked() && !forAugmentedAutofillOnly) { return 0; } - final String shortComponentName = componentName.toShortString(); - boolean forAugmentedAutofillOnly = false; - - if (isAutofillDisabledLocked(componentName)) { - // Service disabled autofill; that means no session, unless the activity is whitelisted - // for augmented autofill + if (!forAugmentedAutofillOnly && isAutofillDisabledLocked(componentName)) { + // Standard autofill is enabled, but service disabled autofill for this activity; that + // means no session, unless the activity is whitelisted for augmented autofill if (isWhitelistedForAugmentedAutofillLocked(componentName)) { if (sDebug) { - Slog.d(TAG, "startSession(" + shortComponentName + "): disabled by service but " + Slog.d(TAG, "startSession(" + componentName + "): disabled by service but " + "whitelisted for augmented autofill"); } forAugmentedAutofillOnly = true; } else { if (sDebug) { - Slog.d(TAG, "startSession(" + shortComponentName + "): ignored because " + Slog.d(TAG, "startSession(" + componentName + "): ignored because " + "disabled by service and not whitelisted for augmented autofill"); } final IAutoFillManagerClient client = IAutoFillManagerClient.Stub @@ -323,7 +328,7 @@ final class AutofillManagerServiceImpl /* autofillableIds= */ null); } catch (RemoteException e) { Slog.w(TAG, - "Could not notify " + shortComponentName + " that it's disabled: " + e); + "Could not notify " + componentName + " that it's disabled: " + e); } return NO_SESSION; @@ -345,9 +350,11 @@ final class AutofillManagerServiceImpl return NO_SESSION; } + // Service can be null when it's only for augmented autofill + String servicePackageName = mInfo == null ? null : mInfo.getServiceInfo().packageName; final String historyItem = - "id=" + newSession.id + " uid=" + uid + " a=" + shortComponentName - + " s=" + mInfo.getServiceInfo().packageName + "id=" + newSession.id + " uid=" + uid + " a=" + componentName.toShortString() + + " s=" + servicePackageName + " u=" + mUserId + " i=" + autofillId + " b=" + virtualBounds + " hc=" + hasCallback + " f=" + flags + " aa=" + forAugmentedAutofillOnly; mMaster.logRequestLocked(historyItem); @@ -485,9 +492,12 @@ final class AutofillManagerServiceImpl assertCallerLocked(componentName, compatMode); + // It's null when the session is just for augmented autofill + final ComponentName serviceComponentName = mInfo == null ? null + : mInfo.getServiceInfo().getComponentName(); final Session newSession = new Session(this, mUi, getContext(), mHandler, mUserId, mLock, sessionId, taskId, uid, activityToken, appCallbackToken, hasCallback, - mUiLatencyHistory, mWtfHistory, mInfo.getServiceInfo().getComponentName(), + mUiLatencyHistory, mWtfHistory, serviceComponentName, componentName, compatMode, bindInstantServiceAllowed, forAugmentedAutofillOnly, flags); mSessions.put(newSession.id, newSession); @@ -929,8 +939,7 @@ final class AutofillManagerServiceImpl .getString(R.string.config_defaultAutofillService)); pw.print(prefix); pw.println("mAugmentedAutofillNamer: "); - pw.print(prefix2); mAugmentedAutofillResolver.dumpShort(pw); pw.println(); - pw.print(prefix2); mAugmentedAutofillResolver.dumpShort(pw, mUserId); pw.println(); + pw.print(prefix2); mMaster.mAugmentedAutofillResolver.dumpShort(pw, mUserId); pw.println(); if (mRemoteAugmentedAutofillService != null) { pw.print(prefix); pw.println("RemoteAugmentedAutofillService: "); @@ -1087,7 +1096,7 @@ final class AutofillManagerServiceImpl @GuardedBy("mLock") @Nullable RemoteAugmentedAutofillService getRemoteAugmentedAutofillServiceLocked() { if (mRemoteAugmentedAutofillService == null) { - final String serviceName = mAugmentedAutofillResolver.getServiceName(mUserId); + final String serviceName = mMaster.mAugmentedAutofillResolver.getServiceName(mUserId); if (serviceName == null) { if (mMaster.verbose) { Slog.v(TAG, "getRemoteAugmentedAutofillServiceLocked(): not set"); @@ -1095,8 +1104,8 @@ final class AutofillManagerServiceImpl return null; } final Pair<ServiceInfo, ComponentName> pair = RemoteAugmentedAutofillService - .getComponentName( - serviceName, mUserId, mAugmentedAutofillResolver.isTemporary(mUserId)); + .getComponentName(serviceName, mUserId, + mMaster.mAugmentedAutofillResolver.isTemporary(mUserId)); if (pair == null) return null; mRemoteAugmentedAutofillServiceInfo = pair.first; @@ -1126,7 +1135,8 @@ final class AutofillManagerServiceImpl } /** - * Called when the {@link #mAugmentedAutofillResolver} changed (among other places). + * Called when the {@link AutofillManagerService#mAugmentedAutofillResolver} + * changed (among other places). */ void updateRemoteAugmentedAutofillService() { synchronized (mLock) { @@ -1203,6 +1213,18 @@ final class AutofillManagerServiceImpl @GuardedBy("mLock") boolean isWhitelistedForAugmentedAutofillLocked(@NonNull ComponentName componentName) { + if (Build.IS_USER && mMaster.mAugmentedAutofillResolver.isTemporary(mUserId)) { + final String serviceName = mMaster.mAugmentedAutofillResolver.getServiceName(mUserId); + final ComponentName component = ComponentName.unflattenFromString(serviceName); + final String servicePackage = component == null ? null : component.getPackageName(); + final String packageName = componentName.getPackageName(); + if (!packageName.equals(servicePackage)) { + Slog.w(TAG, "Ignoring package " + packageName + " for augmented autofill while " + + "using temporary service " + servicePackage); + return false; + } + } + return mAugmentedWhitelistHelper.isWhitelisted(componentName); } diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index f08bab3f60cb..c62794d3e3d2 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -185,6 +185,12 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState @GuardedBy("mLock") private DeathRecipient mClientVulture; + /** + * Reference to the remote service. + * + * <p>Only {@code null} when the session is for augmented autofill only. + */ + @Nullable private final RemoteFillService mRemoteFillService; @GuardedBy("mLock") @@ -293,6 +299,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState private final IAssistDataReceiver mAssistReceiver = new IAssistDataReceiver.Stub() { @Override public void onHandleAssistData(Bundle resultData) throws RemoteException { + if (mRemoteFillService == null) { + wtf(null, "onHandleAssistData() called without a remote service. " + + "mForAugmentedAutofillOnly: %s", mForAugmentedAutofillOnly); + return; + } final AssistStructure structure = resultData.getParcelable(ASSIST_KEY_STRUCTURE); if (structure == null) { Slog.e(TAG, "No assist structure - app might have crashed providing it"); @@ -527,6 +538,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState */ @GuardedBy("mLock") private void cancelCurrentRequestLocked() { + if (mRemoteFillService == null) { + wtf(null, "cancelCurrentRequestLocked() called without a remote service. " + + "mForAugmentedAutofillOnly: %s", mForAugmentedAutofillOnly); + return; + } final int canceledRequest = mRemoteFillService.cancelCurrentRequest(); // Remove the FillContext as there will never be a response for the service @@ -608,7 +624,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState @NonNull Context context, @NonNull Handler handler, int userId, @NonNull Object lock, int sessionId, int taskId, int uid, @NonNull IBinder activityToken, @NonNull IBinder client, boolean hasCallback, @NonNull LocalLog uiLatencyHistory, - @NonNull LocalLog wtfHistory, @NonNull ComponentName serviceComponentName, + @NonNull LocalLog wtfHistory, @Nullable ComponentName serviceComponentName, @NonNull ComponentName componentName, boolean compatMode, boolean bindInstantServiceAllowed, boolean forAugmentedAutofillOnly, int flags) { if (sessionId < 0) { @@ -623,8 +639,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mLock = lock; mUi = ui; mHandler = handler; - mRemoteFillService = new RemoteFillService(context, serviceComponentName, userId, this, - bindInstantServiceAllowed); + mRemoteFillService = serviceComponentName == null ? null + : new RemoteFillService(context, serviceComponentName, userId, this, + bindInstantServiceAllowed); mActivityToken = activityToken; mHasCallback = hasCallback; mUiLatencyHistory = uiLatencyHistory; @@ -2035,6 +2052,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState + id + " destroyed"); return; } + if (mRemoteFillService == null) { + wtf(null, "callSaveLocked() called without a remote service. " + + "mForAugmentedAutofillOnly: %s", mForAugmentedAutofillOnly); + return; + } if (sVerbose) Slog.v(TAG, "callSaveLocked(): mViewStates=" + mViewStates); @@ -2637,17 +2659,16 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mAugmentedAutofillDestroyer = triggerAugmentedAutofillLocked(); if (mAugmentedAutofillDestroyer == null) { if (sVerbose) { - Slog.v(TAG, "canceling session " + id + " when server returned null and there is no" - + " AugmentedAutofill for user. AutofillableIds: " + autofillableIds); + Slog.v(TAG, "canceling session " + id + " when service returned null and it cannot " + + "be augmented. AutofillableIds: " + autofillableIds); } // Nothing to be done, but need to notify client. notifyUnavailableToClient(AutofillManager.STATE_FINISHED, autofillableIds); removeSelf(); } else { if (sVerbose) { - Slog.v(TAG, "keeping session " + id + " when server returned null but " - + "there is an AugmentedAutofill for user. AutofillableIds: " - + autofillableIds); + Slog.v(TAG, "keeping session " + id + " when service returned null but " + + "it can be augmented. AutofillableIds: " + autofillableIds); } mAugmentedAutofillableIds = autofillableIds; } @@ -2665,7 +2686,10 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState // Check if Smart Suggestions is supported... final @SmartSuggestionMode int supportedModes = mService .getSupportedSmartSuggestionModesLocked(); - if (supportedModes == 0) return null; + if (supportedModes == 0) { + if (sVerbose) Slog.v(TAG, "triggerAugmentedAutofillLocked(): no supported modes"); + return null; + } // ...then if the service is set for the user @@ -2690,14 +2714,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState return null; } - if (sVerbose) { - Slog.v(TAG, "calling Augmented Autofill Service (" - + remoteService.getComponentName().toShortString() + ") on view " - + mCurrentViewId + " using suggestion mode " - + getSmartSuggestionModeToString(mode) - + " when server returned null for session " + this.id); - } - final boolean isWhitelisted = mService .isWhitelistedForAugmentedAutofillLocked(mComponentName); @@ -2711,12 +2727,20 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState if (!isWhitelisted) { if (sVerbose) { - Slog.v(TAG, mComponentName.toShortString() + " is not whitelisted for " - + "augmented autofill"); + Slog.v(TAG, "triggerAugmentedAutofillLocked(): " + + ComponentName.flattenToShortString(mComponentName) + " not whitelisted "); } return null; } + if (sVerbose) { + Slog.v(TAG, "calling Augmented Autofill Service (" + + ComponentName.flattenToShortString(remoteService.getComponentName()) + + ") on view " + mCurrentViewId + " using suggestion mode " + + getSmartSuggestionModeToString(mode) + + " when server returned null for session " + this.id); + } + final ViewState viewState = mViewStates.get(mCurrentViewId); viewState.setState(ViewState.STATE_TRIGGERED_AUGMENTED_AUTOFILL); final AutofillValue currentValue = viewState.getCurrentValue(); @@ -3045,7 +3069,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState pw.print(prefix); pw.print("mAugmentedAutofillableIds: "); pw.println(mAugmentedAutofillableIds); } - mRemoteFillService.dump(prefix, pw); + if (mRemoteFillService != null) { + mRemoteFillService.dump(prefix, pw); + } } private static void dumpRequestLog(@NonNull PrintWriter pw, @NonNull LogMaker log) { diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java index 9995d8e4d893..b2760e037f44 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java +++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java @@ -18,6 +18,12 @@ package com.android.server.contentcapture; import static android.Manifest.permission.MANAGE_CONTENT_CAPTURE; import static android.content.Context.CONTENT_CAPTURE_MANAGER_SERVICE; +import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_FALSE; +import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_OK; +import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_SECURITY_EXCEPTION; +import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_TRUE; + +import static com.android.internal.util.SyncResultReceiver.bundleFor; import android.annotation.NonNull; import android.annotation.Nullable; @@ -57,7 +63,6 @@ import com.android.internal.infra.AbstractRemoteService; import com.android.internal.os.IResultReceiver; import com.android.internal.util.DumpUtils; import com.android.internal.util.Preconditions; -import com.android.internal.util.SyncResultReceiver; import com.android.server.LocalServices; import com.android.server.infra.AbstractMasterSystemService; import com.android.server.infra.FrameworkResourcesServiceNameResolver; @@ -167,6 +172,22 @@ public final class ContentCaptureManagerService extends } @Override // from AbstractMasterSystemService + protected void onServicePackageUpdatingLocked(int userId) { + final ContentCapturePerUserService service = getServiceForUserLocked(userId); + if (service != null) { + service.onPackageUpdatingLocked(); + } + } + + @Override // from AbstractMasterSystemService + protected void onServicePackageUpdatedLocked(@UserIdInt int userId) { + final ContentCapturePerUserService service = getServiceForUserLocked(userId); + if (service != null) { + service.onPackageUpdatedLocked(); + } + } + + @Override // from AbstractMasterSystemService protected void enforceCallingPermissionForManagement() { getContext().enforceCallingPermission(MANAGE_CONTENT_CAPTURE, mTag); } @@ -414,8 +435,7 @@ public final class ContentCaptureManagerService extends if (isService) return true; try { - result.send(ContentCaptureManager.RESULT_CODE_NOT_SERVICE, - /* resultData= */ null); + result.send(RESULT_CODE_SECURITY_EXCEPTION, /* resultData= */ null); } catch (RemoteException e) { Slog.w(mTag, "Unable to send isContentCaptureFeatureEnabled(): " + e); } @@ -518,8 +538,7 @@ public final class ContentCaptureManagerService extends connectedServiceComponentName = service.getServiceComponentName(); } try { - result.send(/* resultCode= */ 0, - SyncResultReceiver.bundleFor(connectedServiceComponentName)); + result.send(RESULT_CODE_OK, bundleFor(connectedServiceComponentName)); } catch (RemoteException e) { Slog.w(mTag, "Unable to send service component name: " + e); } @@ -547,14 +566,40 @@ public final class ContentCaptureManagerService extends enabled = !mDisabledByDeviceConfig && !isDisabledBySettingsLocked(userId); } try { - result.send(enabled ? ContentCaptureManager.RESULT_CODE_TRUE - : ContentCaptureManager.RESULT_CODE_FALSE, /* resultData= */null); + result.send(enabled ? RESULT_CODE_TRUE : RESULT_CODE_FALSE, /* resultData= */null); } catch (RemoteException e) { Slog.w(mTag, "Unable to send isContentCaptureFeatureEnabled(): " + e); } } @Override + public void getServiceSettingsActivity(@NonNull IResultReceiver result) { + try { + enforceCallingPermissionForManagement(); + } catch (SecurityException e) { + try { + result.send(RESULT_CODE_SECURITY_EXCEPTION, bundleFor(e.getMessage())); + } catch (RemoteException e2) { + Slog.w(mTag, "Unable to send getServiceSettingsIntent() exception: " + e2); + return; + } + } + + final int userId = UserHandle.getCallingUserId(); + final ComponentName componentName; + synchronized (mLock) { + final ContentCapturePerUserService service = getServiceForUserLocked(userId); + if (service == null) return; + componentName = service.getServiceSettingsActivityLocked(); + } + try { + result.send(RESULT_CODE_OK, bundleFor(componentName)); + } catch (RemoteException e) { + Slog.w(mTag, "Unable to send getServiceSettingsIntent(): " + e); + } + } + + @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpPermission(getContext(), mTag, pw)) return; diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java index d7d97b39959f..d9097369ba3b 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java +++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java @@ -40,6 +40,7 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ServiceInfo; import android.os.Binder; +import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.os.UserHandle; @@ -74,7 +75,7 @@ final class ContentCapturePerUserService AbstractPerUserSystemService<ContentCapturePerUserService, ContentCaptureManagerService> implements ContentCaptureServiceCallbacks { - private static final String TAG = ContentCaptureManagerService.class.getSimpleName(); + private static final String TAG = ContentCapturePerUserService.class.getSimpleName(); @GuardedBy("mLock") private final ArrayMap<String, ContentCaptureServerSession> mSessions = @@ -87,7 +88,8 @@ final class ContentCapturePerUserService * master's cache (for example, because a temporary service was set). */ @GuardedBy("mLock") - private RemoteContentCaptureService mRemoteService; + @Nullable + RemoteContentCaptureService mRemoteService; private final ContentCaptureServiceRemoteCallback mRemoteServiceCallback = new ContentCaptureServiceRemoteCallback(); @@ -135,6 +137,10 @@ final class ContentCapturePerUserService } if (!disabled) { + if (mMaster.debug) { + Slog.d(TAG, "updateRemoteService(): creating new remote service for " + + serviceComponentName); + } mRemoteService = new RemoteContentCaptureService(mMaster.getContext(), ContentCaptureService.SERVICE_INTERFACE, serviceComponentName, mRemoteServiceCallback, mUserId, this, mMaster.isBindInstantServiceAllowed(), @@ -182,20 +188,40 @@ final class ContentCapturePerUserService } mZombie = false; - final int numSessions = mSessions.size(); - if (mMaster.debug) { - Slog.d(TAG, "Ressurrecting remote service (" + mRemoteService + ") on " - + numSessions + " sessions"); - } - - for (int i = 0; i < numSessions; i++) { - final ContentCaptureServerSession session = mSessions.valueAt(i); - session.resurrectLocked(); - } + resurrectSessionsLocked(); } } } + private void resurrectSessionsLocked() { + final int numSessions = mSessions.size(); + if (mMaster.debug) { + Slog.d(TAG, "Ressurrecting remote service (" + mRemoteService + ") on " + + numSessions + " sessions"); + } + + for (int i = 0; i < numSessions; i++) { + final ContentCaptureServerSession session = mSessions.valueAt(i); + session.resurrectLocked(); + } + } + + void onPackageUpdatingLocked() { + final int numSessions = mSessions.size(); + if (mMaster.debug) { + Slog.d(TAG, "Pausing " + numSessions + " sessions while package is updating"); + } + for (int i = 0; i < numSessions; i++) { + final ContentCaptureServerSession session = mSessions.valueAt(i); + session.pauseLocked(); + } + } + + void onPackageUpdatedLocked() { + updateRemoteServiceLocked(!isEnabledLocked()); + resurrectSessionsLocked(); + } + // TODO(b/119613670): log metrics @GuardedBy("mLock") public void startSessionLocked(@NonNull IBinder activityToken, @@ -274,9 +300,12 @@ final class ContentCapturePerUserService return; } + // Make sure service is bound, just in case the initial connection failed somehow + mRemoteService.ensureBoundLocked(); + final ContentCaptureServerSession newSession = new ContentCaptureServerSession( - activityToken, this, mRemoteService, componentName, clientReceiver, taskId, - displayId, sessionId, uid, flags); + activityToken, this, componentName, clientReceiver, taskId, displayId, sessionId, + uid, flags); if (mMaster.verbose) { Slog.v(TAG, "startSession(): new session for " + ComponentName.flattenToShortString(componentName) + " and id " + sessionId); @@ -290,21 +319,6 @@ final class ContentCapturePerUserService return mWhitelistHelper.isWhitelisted(componentName); } - /** - * @throws IllegalArgumentException if packages or components are empty. - */ - private void setWhitelist(@Nullable List<String> packages, - @Nullable List<ComponentName> components) { - // TODO(b/122595322): add CTS test for when it's null - synchronized (mLock) { - if (mMaster.verbose) { - Slog.v(TAG, "whitelisting packages: " + packages + " and activities: " - + components); - } - mWhitelistHelper.setWhitelist(packages, components); - } - } - // TODO(b/119613670): log metrics @GuardedBy("mLock") public void finishSessionLocked(@NonNull String sessionId) { @@ -332,6 +346,18 @@ final class ContentCapturePerUserService mRemoteService.onUserDataRemovalRequest(request); } + @GuardedBy("mLock") + @Nullable + public ComponentName getServiceSettingsActivityLocked() { + if (mInfo == null) return null; + + final String activityName = mInfo.getSettingsActivity(); + if (activityName == null) return null; + + final String packageName = mInfo.getServiceInfo().packageName; + return new ComponentName(packageName, activityName); + } + /** * Asserts the component is owned by the caller. */ @@ -430,8 +456,13 @@ final class ContentCapturePerUserService } @GuardedBy("mLock") + @Nullable ContentCaptureOptions getOptionsForPackageLocked(@NonNull String packageName) { if (!mWhitelistHelper.isWhitelisted(packageName)) { + if (packageName.equals(getServicePackageName())) { + if (mMaster.verbose) Slog.v(mTag, "getOptionsForPackage() lite for " + packageName); + return new ContentCaptureOptions(mMaster.mDevCfgLoggingLevel); + } if (mMaster.verbose) { Slog.v(mTag, "getOptionsForPackage(" + packageName + "): not whitelisted"); } @@ -440,6 +471,14 @@ final class ContentCapturePerUserService final ArraySet<ComponentName> whitelistedComponents = mWhitelistHelper .getWhitelistedComponents(packageName); + if (Build.IS_USER && isTemporaryServiceSetLocked()) { + final String servicePackageName = getServicePackageName(); + if (!packageName.equals(servicePackageName)) { + Slog.w(mTag, "Ignoring package " + packageName + + " while using temporary service " + servicePackageName); + return null; + } + } ContentCaptureOptions options = new ContentCaptureOptions(mMaster.mDevCfgLoggingLevel, mMaster.mDevCfgMaxBufferSize, mMaster.mDevCfgIdleFlushingFrequencyMs, mMaster.mDevCfgTextChangeFlushingFrequencyMs, mMaster.mDevCfgLogHistorySize, @@ -518,12 +557,16 @@ final class ContentCapturePerUserService @Override public void setContentCaptureWhitelist(List<String> packages, List<ComponentName> activities) { + // TODO(b/122595322): add CTS test for when it's null if (mMaster.verbose) { - Slog.v(TAG, "setContentCaptureWhitelist(packages=" + packages + ", activities=" - + activities + ")"); + Slog.v(TAG, "setContentCaptureWhitelist(" + (packages == null + ? "null_packages" : packages.size() + " packages") + + ", " + (activities == null + ? "null_activities" : activities.size() + " activities") + ")"); + } + synchronized (mLock) { + mWhitelistHelper.setWhitelist(packages, activities); } - setWhitelist(packages, activities); - // TODO(b/119613670): log metrics } diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java index da198362f5cb..9b2c05f7fa79 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java +++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java @@ -15,6 +15,12 @@ */ package com.android.server.contentcapture; +import static android.service.contentcapture.ContentCaptureService.setClientState; +import static android.view.contentcapture.ContentCaptureSession.STATE_ACTIVE; +import static android.view.contentcapture.ContentCaptureSession.STATE_DISABLED; +import static android.view.contentcapture.ContentCaptureSession.STATE_SERVICE_RESURRECTED; +import static android.view.contentcapture.ContentCaptureSession.STATE_SERVICE_UPDATING; + import android.annotation.NonNull; import android.content.ComponentName; import android.os.IBinder; @@ -23,7 +29,6 @@ import android.service.contentcapture.SnapshotData; import android.util.LocalLog; import android.util.Slog; import android.view.contentcapture.ContentCaptureContext; -import android.view.contentcapture.ContentCaptureSession; import android.view.contentcapture.ContentCaptureSessionId; import com.android.internal.annotations.GuardedBy; @@ -38,7 +43,6 @@ final class ContentCaptureServerSession { final IBinder mActivityToken; private final ContentCapturePerUserService mService; - private final RemoteContentCaptureService mRemoteService; // NOTE: this is the "internal" context (like package and taskId), not the explicit content // set by apps - those are only send to the ContentCaptureService. @@ -61,15 +65,13 @@ final class ContentCaptureServerSession { private final int mUid; ContentCaptureServerSession(@NonNull IBinder activityToken, - @NonNull ContentCapturePerUserService service, - @NonNull RemoteContentCaptureService remoteService, - @NonNull ComponentName appComponentName, @NonNull IResultReceiver sessionStateReceiver, + @NonNull ContentCapturePerUserService service, @NonNull ComponentName appComponentName, + @NonNull IResultReceiver sessionStateReceiver, int taskId, int displayId, @NonNull String sessionId, int uid, int flags) { mActivityToken = activityToken; mService = service; mId = Preconditions.checkNotNull(sessionId); mUid = uid; - mRemoteService = remoteService; mContentCaptureContext = new ContentCaptureContext(/* clientContext= */ null, appComponentName, taskId, displayId, flags); mSessionStateReceiver = sessionStateReceiver; @@ -87,8 +89,12 @@ final class ContentCaptureServerSession { */ @GuardedBy("mLock") public void notifySessionStartedLocked(@NonNull IResultReceiver clientReceiver) { - mRemoteService.onSessionStarted(mContentCaptureContext, mId, mUid, clientReceiver, - ContentCaptureSession.STATE_ACTIVE); + if (mService.mRemoteService == null) { + Slog.w(TAG, "notifySessionStartedLocked(): no remote service"); + return; + } + mService.mRemoteService.onSessionStarted(mContentCaptureContext, mId, mUid, clientReceiver, + STATE_ACTIVE); } /** @@ -101,7 +107,11 @@ final class ContentCaptureServerSession { logHistory.log("snapshot: id=" + mId); } - mRemoteService.onActivitySnapshotRequest(mId, snapshotData); + if (mService.mRemoteService == null) { + Slog.w(TAG, "sendActivitySnapshotLocked(): no remote service"); + return; + } + mService.mRemoteService.onActivitySnapshotRequest(mId, snapshotData); } /** @@ -134,7 +144,11 @@ final class ContentCaptureServerSession { } // TODO(b/111276913): must call client to set session as FINISHED_BY_SERVER if (notifyRemoteService) { - mRemoteService.onSessionFinished(mId); + if (mService.mRemoteService == null) { + Slog.w(TAG, "destroyLocked(): no remote service"); + return; + } + mService.mRemoteService.onSessionFinished(mId); } } @@ -143,10 +157,27 @@ final class ContentCaptureServerSession { */ @GuardedBy("mLock") public void resurrectLocked() { - mRemoteService.onSessionStarted(new ContentCaptureContext(mContentCaptureContext, + final RemoteContentCaptureService remoteService = mService.mRemoteService; + if (remoteService == null) { + Slog.w(TAG, "destroyLocked(: no remote service"); + return; + } + if (mService.isVerbose()) { + Slog.v(TAG, "resurrecting " + mActivityToken + " on " + remoteService); + } + remoteService.onSessionStarted(new ContentCaptureContext(mContentCaptureContext, ContentCaptureContext.FLAG_RECONNECTED), mId, mUid, mSessionStateReceiver, - ContentCaptureSession.STATE_ACTIVE - | ContentCaptureSession.STATE_SERVICE_RESURRECTED); + STATE_ACTIVE | STATE_SERVICE_RESURRECTED); + } + + /** + * Called to pause the session while the service is being updated. + */ + @GuardedBy("mLock") + public void pauseLocked() { + if (mService.isVerbose()) Slog.v(TAG, "pausing " + mActivityToken); + setClientState(mSessionStateReceiver, STATE_DISABLED | STATE_SERVICE_UPDATING, + /* binder= */ null); } @GuardedBy("mLock") diff --git a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java index 2ce5059244a1..df9ccbc499ba 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java +++ b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java @@ -54,7 +54,7 @@ final class RemoteContentCaptureService mIdleUnbindTimeoutMs = idleUnbindTimeoutMs; // Bind right away, which will trigger a onConnected() on service's - scheduleBind(); + ensureBoundLocked(); } @Override // from AbstractRemoteService @@ -89,6 +89,10 @@ final class RemoteContentCaptureService } } + public void ensureBoundLocked() { + scheduleBind(); + } + /** * Called by {@link ContentCaptureServerSession} to generate a call to the * {@link RemoteContentCaptureService} to indicate the session was created. diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index ec5987e97ceb..2be92cde68ec 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -988,7 +988,7 @@ public class ConnectivityService extends IConnectivityManager.Stub mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); - mKeepaliveTracker = new KeepaliveTracker(mHandler); + mKeepaliveTracker = new KeepaliveTracker(mContext, mHandler); mNotifier = new NetworkNotificationManager(mContext, mTelephonyManager, mContext.getSystemService(NotificationManager.class)); @@ -2564,7 +2564,12 @@ public class ConnectivityService extends IConnectivityManager.Stub || (nai.networkMisc.acceptPartialConnectivity && nai.partialConnectivity); // Once a network is determined to have partial connectivity, it cannot - // go back to full connectivity without a disconnect. + // go back to full connectivity without a disconnect. This is because + // NetworkMonitor can only communicate either PARTIAL_CONNECTIVITY or VALID, + // but not both. + // TODO: Provide multi-testResult to improve the communication between + // ConnectivityService and NetworkMonitor, so that ConnectivityService could + // know the real status of network. final boolean partialConnectivityChanged = (partialConnectivity && !nai.partialConnectivity); @@ -3470,8 +3475,12 @@ public class ConnectivityService extends IConnectivityManager.Stub return mMultinetworkPolicyTracker.getAvoidBadWifi(); } - @Override - public boolean getAvoidBadWifi() { + /** + * Return whether the device should maintain continuous, working connectivity by switching away + * from WiFi networks having no connectivity. + * @see MultinetworkPolicyTracker#getAvoidBadWifi() + */ + public boolean shouldAvoidBadWifi() { if (!checkNetworkStackPermission()) { throw new SecurityException("avoidBadWifi requires NETWORK_STACK permission"); } @@ -3581,9 +3590,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // NetworkMonitor detects the network is partial connectivity. Need to change the design to // popup the notification immediately when the network is partial connectivity. if (nai.partialConnectivity) { - // Treat PARTIAL_CONNECTIVITY as NO_INTERNET temporary until Settings has been updated. - // TODO: Need to change back to PARTIAL_CONNECTIVITY when Settings part is merged. - showNetworkNotification(nai, NotificationType.NO_INTERNET); + showNetworkNotification(nai, NotificationType.PARTIAL_CONNECTIVITY); } else { showNetworkNotification(nai, NotificationType.NO_INTERNET); } @@ -6685,7 +6692,9 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public String getCaptivePortalServerUrl() { enforceConnectivityInternalPermission(); - return NetworkMonitorUtils.getCaptivePortalServerHttpUrl(mContext); + final String defaultUrl = mContext.getResources().getString( + R.string.config_networkDefaultCaptivePortalServerUrl); + return NetworkMonitorUtils.getCaptivePortalServerHttpUrl(mContext, defaultUrl); } @Override @@ -6693,7 +6702,7 @@ public class ConnectivityService extends IConnectivityManager.Stub ISocketKeepaliveCallback cb, String srcAddr, int srcPort, String dstAddr) { enforceKeepalivePermission(); mKeepaliveTracker.startNattKeepalive( - getNetworkAgentInfoForNetwork(network), + getNetworkAgentInfoForNetwork(network), null /* fd */, intervalSeconds, cb, srcAddr, srcPort, dstAddr, NattSocketKeepalive.NATT_PORT); } @@ -6702,7 +6711,6 @@ public class ConnectivityService extends IConnectivityManager.Stub public void startNattKeepaliveWithFd(Network network, FileDescriptor fd, int resourceId, int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr, String dstAddr) { - enforceKeepalivePermission(); mKeepaliveTracker.startNattKeepalive( getNetworkAgentInfoForNetwork(network), fd, resourceId, intervalSeconds, cb, diff --git a/services/core/java/com/android/server/DynamicAndroidService.java b/services/core/java/com/android/server/DynamicSystemService.java index b02bfb111727..f5bd11cea779 100644 --- a/services/core/java/com/android/server/DynamicAndroidService.java +++ b/services/core/java/com/android/server/DynamicSystemService.java @@ -22,25 +22,25 @@ import android.gsi.GsiProgress; import android.gsi.IGsiService; import android.os.IBinder; import android.os.IBinder.DeathRecipient; -import android.os.IDynamicAndroidService; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; +import android.os.image.IDynamicSystemService; import android.util.Slog; /** - * DynamicAndroidService implements IDynamicAndroidService. It provides permission check before + * DynamicSystemService implements IDynamicSystemService. It provides permission check before * passing requests to gsid */ -public class DynamicAndroidService extends IDynamicAndroidService.Stub implements DeathRecipient { - private static final String TAG = "DynamicAndroidService"; +public class DynamicSystemService extends IDynamicSystemService.Stub implements DeathRecipient { + private static final String TAG = "DynamicSystemService"; private static final String NO_SERVICE_ERROR = "no gsiservice"; private static final int GSID_ROUGH_TIMEOUT_MS = 8192; private Context mContext; private volatile IGsiService mGsiService; - DynamicAndroidService(Context context) { + DynamicSystemService(Context context) { mContext = context; } @@ -93,9 +93,9 @@ public class DynamicAndroidService extends IDynamicAndroidService.Stub implement private void checkPermission() { if (mContext.checkCallingOrSelfPermission( - android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) + android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) != PackageManager.PERMISSION_GRANTED) { - throw new SecurityException("Requires MANAGE_DYNAMIC_ANDROID permission"); + throw new SecurityException("Requires MANAGE_DYNAMIC_SYSTEM permission"); } } diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java index b89223b5cbda..f0244c303360 100644 --- a/services/core/java/com/android/server/LocationManagerService.java +++ b/services/core/java/com/android/server/LocationManagerService.java @@ -3597,10 +3597,18 @@ public class LocationManagerService extends ILocationManager.Stub { pw.println(" " + provider + ": " + location); } - mGeofenceManager.dump(pw); - - pw.append(" "); - mBlacklist.dump(pw); + if (mGeofenceManager != null) { + mGeofenceManager.dump(pw); + } else { + pw.println(" Geofences: null"); + } + + if (mBlacklist != null) { + pw.append(" "); + mBlacklist.dump(pw); + } else { + pw.println(" mBlacklist=null"); + } if (mLocationControllerExtraPackage != null) { pw.println(" Location controller extra package: " + mLocationControllerExtraPackage @@ -3614,8 +3622,12 @@ public class LocationManagerService extends ILocationManager.Stub { } } - pw.append(" fudger: "); - mLocationFudger.dump(fd, pw, args); + if (mLocationFudger != null) { + pw.append(" fudger: "); + mLocationFudger.dump(fd, pw, args); + } else { + pw.println(" fudger: null"); + } if (args.length > 0 && "short".equals(args[0])) { return; diff --git a/services/core/java/com/android/server/SensorPrivacyService.java b/services/core/java/com/android/server/SensorPrivacyService.java index 1cbcbe5a8bdb..edeb049c0802 100644 --- a/services/core/java/com/android/server/SensorPrivacyService.java +++ b/services/core/java/com/android/server/SensorPrivacyService.java @@ -18,20 +18,15 @@ package com.android.server; import static android.content.pm.PackageManager.PERMISSION_GRANTED; -import android.app.ActivityManager; import android.content.Context; import android.hardware.ISensorPrivacyListener; import android.hardware.ISensorPrivacyManager; -import android.location.LocationManager; -import android.net.ConnectivityManager; import android.os.Environment; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.RemoteCallbackList; import android.os.RemoteException; -import android.os.UserHandle; -import android.provider.Settings; import android.util.ArrayMap; import android.util.AtomicFile; import android.util.Log; @@ -277,8 +272,6 @@ public final class SensorPrivacyService extends SystemService { } } mListeners.finishBroadcast(); - // Handle the state of all sensors managed by this service. - SensorState.handleSensorPrivacyToggled(mContext, enabled); } } @@ -306,121 +299,4 @@ public final class SensorPrivacyService extends SystemService { } } } - - /** - * Maintains the state of the sensors when sensor privacy is enabled to return them to their - * original state when sensor privacy is disabled. - */ - private static final class SensorState { - - private static Object sLock = new Object(); - @GuardedBy("sLock") - private static SensorState sPreviousState; - - private boolean mAirplaneEnabled; - private boolean mLocationEnabled; - - SensorState(boolean airplaneEnabled, boolean locationEnabled) { - mAirplaneEnabled = airplaneEnabled; - mLocationEnabled = locationEnabled; - } - - public static void handleSensorPrivacyToggled(Context context, boolean enabled) { - synchronized (sLock) { - SensorState state; - if (enabled) { - // if sensor privacy is being enabled then obtain the current state of the - // sensors to be persisted and restored when sensor privacy is disabled. - state = getCurrentSensorState(context); - } else { - // else obtain the previous sensor state to be restored, first from the saved - // state if available, otherwise attempt to read it from Settings. - if (sPreviousState != null) { - state = sPreviousState; - } else { - state = getPersistedSensorState(context); - } - // if the previous state is not available then return without attempting to - // modify the sensor state. - if (state == null) { - return; - } - } - // The SensorState represents the state of the sensor before sensor privacy was - // enabled; if airplane mode was not enabled then the state of airplane mode should - // be the same as the state of sensor privacy. - if (!state.mAirplaneEnabled) { - setAirplaneMode(context, enabled); - } - // Similar to airplane mode the state of location should be the opposite of sensor - // privacy mode, if it was enabled when sensor privacy was enabled then it should be - // disabled. If location is disabled when sensor privacy is enabled then it will be - // left disabled when sensor privacy is disabled. - if (state.mLocationEnabled) { - setLocationEnabled(context, !enabled); - } - - // if sensor privacy is being enabled then persist the current state. - if (enabled) { - sPreviousState = state; - persistState(context, sPreviousState); - } - } - } - - public static SensorState getCurrentSensorState(Context context) { - LocationManager locationManager = (LocationManager) context.getSystemService( - Context.LOCATION_SERVICE); - boolean airplaneEnabled = Settings.Global.getInt(context.getContentResolver(), - Settings.Global.AIRPLANE_MODE_ON, 0) != 0; - boolean locationEnabled = locationManager.isLocationEnabled(); - return new SensorState(airplaneEnabled, locationEnabled); - } - - public static void persistState(Context context, SensorState state) { - StringBuilder stateValue = new StringBuilder(); - stateValue.append(state.mAirplaneEnabled - ? Settings.Secure.MAINTAIN_AIRPLANE_MODE_AFTER_SP_DISABLED - : Settings.Secure.DISABLE_AIRPLANE_MODE_AFTER_SP_DISABLED); - stateValue.append(","); - stateValue.append( - state.mLocationEnabled ? Settings.Secure.REENABLE_LOCATION_AFTER_SP_DISABLED - : Settings.Secure.MAINTAIN_LOCATION_AFTER_SP_DISABLED); - Settings.Secure.putString(context.getContentResolver(), - Settings.Secure.SENSOR_PRIVACY_SENSOR_STATE, stateValue.toString()); - } - - public static SensorState getPersistedSensorState(Context context) { - String persistedState = Settings.Secure.getString(context.getContentResolver(), - Settings.Secure.SENSOR_PRIVACY_SENSOR_STATE); - if (persistedState == null) { - Log.e(TAG, "The persisted sensor state could not be obtained from Settings"); - return null; - } - String[] sensorStates = persistedState.split(","); - if (sensorStates.length < 2) { - Log.e(TAG, "The persisted sensor state does not contain the expected values: " - + persistedState); - return null; - } - boolean airplaneEnabled = sensorStates[0].equals( - Settings.Secure.MAINTAIN_AIRPLANE_MODE_AFTER_SP_DISABLED); - boolean locationEnabled = sensorStates[1].equals( - Settings.Secure.REENABLE_LOCATION_AFTER_SP_DISABLED); - return new SensorState(airplaneEnabled, locationEnabled); - } - - private static void setAirplaneMode(Context context, boolean enable) { - ConnectivityManager connectivityManager = - (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - connectivityManager.setAirplaneMode(enable); - } - - private static void setLocationEnabled(Context context, boolean enable) { - LocationManager locationManager = (LocationManager) context.getSystemService( - Context.LOCATION_SERVICE); - locationManager.setLocationEnabledForUser(enable, - UserHandle.of(ActivityManager.getCurrentUser())); - } - } } diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 5bd0b89755d4..fd73e62669e2 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -3862,6 +3862,16 @@ class StorageManagerService extends IStorageManager.Stub case "jp.naver.line.android": // b/124767356 case "com.mxtech.videoplayer.ad": // b/124531483 case "com.whatsapp": // b/124766614 + case "com.maxmpz.audioplayer": // b/127886230 + case "com.estrongs.android.pop": // b/127926473 + case "com.roidapp.photogrid": // b/128269119 + case "com.cleanmaster.mguard": // b/128384413 + case "com.skype.raider": // b/128487044 + case "org.telegram.messenger": // b/128652960 + case "com.jrtstudio.AnotherMusicPlayer": // b/129084562 + case "ak.alizandro.smartaudiobookplayer": // b/129084042 + case "com.campmobile.snow": // b/128803870 + case "com.qnap.qfile": // b/126374406 return Zygote.MOUNT_EXTERNAL_LEGACY; } } diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index e357ce8ce929..1878d00ba9f9 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -1805,7 +1805,7 @@ public final class ActiveServices { || (callerApp.getCurProcState() <= ActivityManager.PROCESS_STATE_TOP && (flags & Context.BIND_TREAT_LIKE_ACTIVITY) != 0), b.client); - mAm.updateOomAdjLocked(s.app, true); + mAm.updateOomAdjLocked(); } if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bind " + s + " with " + b diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 97cc756e3924..a1f2ac630c04 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -5121,6 +5121,7 @@ public class ActivityManagerService extends IActivityManager.Stub String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) { synchronized (ActivityManagerService.this) { + mOomAdjuster.mAppCompact.compactAllSystem(); requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); } } @@ -8614,6 +8615,10 @@ public class ActivityManagerService extends IActivityManager.Stub synchronized (this) { final long now = SystemClock.uptimeMillis(); final long timeSinceLastIdle = now - mLastIdleTime; + + // Compact all non-zygote processes to freshen up the page cache. + mOomAdjuster.mAppCompact.compactAllSystem(); + final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); mLastIdleTime = now; mLowRamTimeSinceLastIdle = 0; diff --git a/services/core/java/com/android/server/am/AppCompactor.java b/services/core/java/com/android/server/am/AppCompactor.java index 9216343e05d8..f58fb95b1ec9 100644 --- a/services/core/java/com/android/server/am/AppCompactor.java +++ b/services/core/java/com/android/server/am/AppCompactor.java @@ -51,6 +51,8 @@ public final class AppCompactor { @VisibleForTesting static final String KEY_COMPACT_THROTTLE_2 = "compact_throttle_2"; @VisibleForTesting static final String KEY_COMPACT_THROTTLE_3 = "compact_throttle_3"; @VisibleForTesting static final String KEY_COMPACT_THROTTLE_4 = "compact_throttle_4"; + @VisibleForTesting static final String KEY_COMPACT_THROTTLE_5 = "compact_throttle_5"; + @VisibleForTesting static final String KEY_COMPACT_THROTTLE_6 = "compact_throttle_6"; @VisibleForTesting static final String KEY_COMPACT_STATSD_SAMPLE_RATE = "compact_statsd_sample_rate"; @@ -73,6 +75,8 @@ public final class AppCompactor { @VisibleForTesting static final long DEFAULT_COMPACT_THROTTLE_2 = 10_000; @VisibleForTesting static final long DEFAULT_COMPACT_THROTTLE_3 = 500; @VisibleForTesting static final long DEFAULT_COMPACT_THROTTLE_4 = 10_000; + @VisibleForTesting static final long DEFAULT_COMPACT_THROTTLE_5 = 10 * 60 * 1000; + @VisibleForTesting static final long DEFAULT_COMPACT_THROTTLE_6 = 10 * 60 * 1000; // The sampling rate to push app compaction events into statsd for upload. @VisibleForTesting static final float DEFAULT_STATSD_SAMPLE_RATE = 0.1f; @@ -85,7 +89,10 @@ public final class AppCompactor { // Handler constants. static final int COMPACT_PROCESS_SOME = 1; static final int COMPACT_PROCESS_FULL = 2; + static final int COMPACT_PROCESS_PERSISTENT = 3; + static final int COMPACT_PROCESS_BFGS = 4; static final int COMPACT_PROCESS_MSG = 1; + static final int COMPACT_SYSTEM_MSG = 2; /** * This thread must be moved to the system background cpuset. @@ -142,6 +149,10 @@ public final class AppCompactor { @GuardedBy("mPhenotypeFlagLock") @VisibleForTesting volatile long mCompactThrottleFullFull = DEFAULT_COMPACT_THROTTLE_4; @GuardedBy("mPhenotypeFlagLock") + @VisibleForTesting volatile long mCompactThrottleBFGS = DEFAULT_COMPACT_THROTTLE_5; + @GuardedBy("mPhenotypeFlagLock") + @VisibleForTesting volatile long mCompactThrottlePersistent = DEFAULT_COMPACT_THROTTLE_6; + @GuardedBy("mPhenotypeFlagLock") private volatile boolean mUseCompaction = DEFAULT_USE_COMPACTION; private final Random mRandom = new Random(); @@ -224,6 +235,46 @@ public final class AppCompactor { } + @GuardedBy("mAm") + void compactAppPersistent(ProcessRecord app) { + app.reqCompactAction = COMPACT_PROCESS_PERSISTENT; + mPendingCompactionProcesses.add(app); + mCompactionHandler.sendMessage( + mCompactionHandler.obtainMessage( + COMPACT_PROCESS_MSG, app.curAdj, app.setProcState)); + } + + @GuardedBy("mAm") + boolean shouldCompactPersistent(ProcessRecord app, long now) { + return (app.lastCompactTime == 0 + || (now - app.lastCompactTime) > mCompactThrottlePersistent); + } + + @GuardedBy("mAm") + void compactAppBfgs(ProcessRecord app) { + app.reqCompactAction = COMPACT_PROCESS_BFGS; + mPendingCompactionProcesses.add(app); + mCompactionHandler.sendMessage( + mCompactionHandler.obtainMessage( + COMPACT_PROCESS_MSG, app.curAdj, app.setProcState)); + } + + @GuardedBy("mAm") + boolean shouldCompactBFGS(ProcessRecord app, long now) { + return (app.lastCompactTime == 0 + || (now - app.lastCompactTime) > mCompactThrottleBFGS); + } + + @GuardedBy("mAm") + void compactAllSystem() { + if (mUseCompaction) { + mCompactionHandler.sendMessage(mCompactionHandler.obtainMessage( + COMPACT_SYSTEM_MSG)); + } + } + + private native void compactSystem(); + /** * Reads the flag value from DeviceConfig to determine whether app compaction * should be enabled, and starts/stops the compaction thread as needed. @@ -265,10 +316,18 @@ public final class AppCompactor { String throttleFullFullFlag = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, KEY_COMPACT_THROTTLE_4); + String throttleBFGSFlag = + DeviceConfig.getProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + KEY_COMPACT_THROTTLE_5); + String throttlePersistentFlag = + DeviceConfig.getProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + KEY_COMPACT_THROTTLE_6); if (TextUtils.isEmpty(throttleSomeSomeFlag) || TextUtils.isEmpty(throttleSomeFullFlag) || TextUtils.isEmpty(throttleFullSomeFlag) - || TextUtils.isEmpty(throttleFullFullFlag)) { + || TextUtils.isEmpty(throttleFullFullFlag) + || TextUtils.isEmpty(throttleBFGSFlag) + || TextUtils.isEmpty(throttlePersistentFlag)) { // Set defaults for all if any are not set. useThrottleDefaults = true; } else { @@ -277,6 +336,8 @@ public final class AppCompactor { mCompactThrottleSomeFull = Integer.parseInt(throttleSomeFullFlag); mCompactThrottleFullSome = Integer.parseInt(throttleFullSomeFlag); mCompactThrottleFullFull = Integer.parseInt(throttleFullFullFlag); + mCompactThrottleBFGS = Integer.parseInt(throttleBFGSFlag); + mCompactThrottlePersistent = Integer.parseInt(throttlePersistentFlag); } catch (NumberFormatException e) { useThrottleDefaults = true; } @@ -287,6 +348,8 @@ public final class AppCompactor { mCompactThrottleSomeFull = DEFAULT_COMPACT_THROTTLE_2; mCompactThrottleFullSome = DEFAULT_COMPACT_THROTTLE_3; mCompactThrottleFullFull = DEFAULT_COMPACT_THROTTLE_4; + mCompactThrottleBFGS = DEFAULT_COMPACT_THROTTLE_5; + mCompactThrottlePersistent = DEFAULT_COMPACT_THROTTLE_6; } } @@ -332,14 +395,19 @@ public final class AppCompactor { synchronized (mAm) { proc = mPendingCompactionProcesses.remove(0); + pendingAction = proc.reqCompactAction; + // don't compact if the process has returned to perceptible - if (proc.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { + // and this is only a cached/home/prev compaction + if ((pendingAction == COMPACT_PROCESS_SOME + || pendingAction == COMPACT_PROCESS_FULL) + && (proc.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ)) { return; } pid = proc.pid; name = proc.processName; - pendingAction = proc.reqCompactAction; + lastCompactAction = proc.lastCompactAction; lastCompactTime = proc.lastCompactTime; } @@ -356,31 +424,49 @@ public final class AppCompactor { // Note that we explicitly don't take mPhenotypeFlagLock here as the flags // should very seldom change, and taking the risk of using the wrong action is // preferable to taking the lock for every single compaction action. - if (pendingAction == COMPACT_PROCESS_SOME) { - if ((lastCompactAction == COMPACT_PROCESS_SOME - && (start - lastCompactTime < mCompactThrottleSomeSome)) - || (lastCompactAction == COMPACT_PROCESS_FULL - && (start - lastCompactTime - < mCompactThrottleSomeFull))) { - return; - } - } else { - if ((lastCompactAction == COMPACT_PROCESS_SOME - && (start - lastCompactTime < mCompactThrottleFullSome)) - || (lastCompactAction == COMPACT_PROCESS_FULL - && (start - lastCompactTime - < mCompactThrottleFullFull))) { - return; + if (lastCompactTime != 0) { + if (pendingAction == COMPACT_PROCESS_SOME) { + if ((lastCompactAction == COMPACT_PROCESS_SOME + && (start - lastCompactTime < mCompactThrottleSomeSome)) + || (lastCompactAction == COMPACT_PROCESS_FULL + && (start - lastCompactTime + < mCompactThrottleSomeFull))) { + return; + } + } else if (pendingAction == COMPACT_PROCESS_FULL) { + if ((lastCompactAction == COMPACT_PROCESS_SOME + && (start - lastCompactTime < mCompactThrottleFullSome)) + || (lastCompactAction == COMPACT_PROCESS_FULL + && (start - lastCompactTime + < mCompactThrottleFullFull))) { + return; + } + } else if (pendingAction == COMPACT_PROCESS_PERSISTENT) { + if (start - lastCompactTime < mCompactThrottlePersistent) { + return; + } + } else if (pendingAction == COMPACT_PROCESS_BFGS) { + if (start - lastCompactTime < mCompactThrottleBFGS) { + return; + } } } - - if (pendingAction == COMPACT_PROCESS_SOME) { - action = mCompactActionSome; - } else { - action = mCompactActionFull; + switch (pendingAction) { + case COMPACT_PROCESS_SOME: + action = mCompactActionSome; + break; + // For the time being, treat these as equivalent. + case COMPACT_PROCESS_FULL: + case COMPACT_PROCESS_PERSISTENT: + case COMPACT_PROCESS_BFGS: + action = mCompactActionFull; + break; + default: + action = COMPACT_ACTION_NONE; + break; } - if (action.equals(COMPACT_ACTION_NONE)) { + if (COMPACT_ACTION_NONE.equals(action)) { return; } @@ -422,6 +508,13 @@ public final class AppCompactor { // nothing to do, presumably the process died Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } + break; + } + case COMPACT_SYSTEM_MSG: { + Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "compactSystem"); + compactSystem(); + Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); + break; } } } diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 4d5cb8cb4473..f86ba278138c 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -754,7 +754,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub } public void noteStartAudio(int uid) { - enforceCallingPermission(); + enforceSelfOrCallingPermission(uid); synchronized (mStats) { mStats.noteAudioOnLocked(uid); StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, uid, null, @@ -763,7 +763,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub } public void noteStopAudio(int uid) { - enforceCallingPermission(); + enforceSelfOrCallingPermission(uid); synchronized (mStats) { mStats.noteAudioOffLocked(uid); StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, uid, null, @@ -772,7 +772,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub } public void noteStartVideo(int uid) { - enforceCallingPermission(); + enforceSelfOrCallingPermission(uid); synchronized (mStats) { mStats.noteVideoOnLocked(uid); StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_STATE_CHANGED, uid, null, @@ -781,7 +781,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub } public void noteStopVideo(int uid) { - enforceCallingPermission(); + enforceSelfOrCallingPermission(uid); synchronized (mStats) { mStats.noteVideoOffLocked(uid); StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_STATE_CHANGED, uid, @@ -1182,6 +1182,13 @@ public final class BatteryStatsService extends IBatteryStats.Stub Binder.getCallingPid(), Binder.getCallingUid(), null); } + private void enforceSelfOrCallingPermission(int uid) { + if (Binder.getCallingUid() == uid) { + return; + } + enforceCallingPermission(); + } + final class WakeupReasonThread extends Thread { private static final int MAX_REASON_SIZE = 512; private CharsetDecoder mDecoder; diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index aa03de1115b2..c1b9a20d143d 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -1686,9 +1686,10 @@ public final class OomAdjuster { int changes = 0; - if (app.curAdj != app.setAdj) { - // don't compact during bootup - if (mAppCompact.useCompaction() && mService.mBooted) { + // don't compact during bootup + if (mAppCompact.useCompaction() && mService.mBooted) { + // Cached and prev/home compaction + if (app.curAdj != app.setAdj) { // Perform a minor compaction when a perceptible app becomes the prev/home app // Perform a major compaction when any app enters cached // reminder: here, setAdj is previous state, curAdj is upcoming state @@ -1702,7 +1703,23 @@ public final class OomAdjuster { && app.curAdj <= ProcessList.CACHED_APP_MAX_ADJ) { mAppCompact.compactAppFull(app); } + } else if (mService.mWakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE + && app.setAdj < ProcessList.FOREGROUND_APP_ADJ + // Because these can fire independent of oom_adj/procstate changes, we need + // to throttle the actual dispatch of these requests in addition to the + // processing of the requests. As a result, there is throttling both here + // and in AppCompactor. + && mAppCompact.shouldCompactPersistent(app, now)) { + mAppCompact.compactAppPersistent(app); + } else if (mService.mWakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE + && app.getCurProcState() + == ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE + && mAppCompact.shouldCompactBFGS(app, now)) { + mAppCompact.compactAppBfgs(app); } + } + + if (app.curAdj != app.setAdj) { ProcessList.setOomAdj(app.pid, app.uid, app.curAdj); if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mService.mCurOomAdjUid == app.info.uid) { String msg = "Set " + app.pid + " " + app.processName + " adj " diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 10b67c1047cf..2e5dd3b0941e 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -1257,6 +1257,7 @@ public class AppOpsService extends IAppOpsService.Stub { } scheduleWriteLocked(); } + uidState.evalForegroundOps(mOpModeWatchers); } String[] uidPackageNames = getPackagesForUid(uid); @@ -2414,8 +2415,6 @@ public class AppOpsService extends IAppOpsService.Stub { private void commitUidPendingStateLocked(UidState uidState) { final boolean lastForeground = uidState.state <= UID_STATE_MAX_LAST_NON_RESTRICTED; final boolean nowForeground = uidState.pendingState <= UID_STATE_MAX_LAST_NON_RESTRICTED; - uidState.state = uidState.pendingState; - uidState.pendingStateCommitTime = 0; if (uidState.hasForegroundWatchers && lastForeground != nowForeground) { for (int fgi = uidState.foregroundOps.size() - 1; fgi >= 0; fgi--) { if (!uidState.foregroundOps.valueAt(fgi)) { @@ -2424,11 +2423,10 @@ public class AppOpsService extends IAppOpsService.Stub { final int code = uidState.foregroundOps.keyAt(fgi); // For location ops we consider fg state only if the fg service // is of location type, for all other ops any fg service will do. - final long resolvedLastRestrictedUidState = resolveFirstUnrestrictedUidState(code); - final boolean resolvedLastFg = uidState.state <= resolvedLastRestrictedUidState; - final boolean resolvedNowBg = uidState.pendingState - <= resolvedLastRestrictedUidState; - if (resolvedLastFg == resolvedNowBg) { + final long firstUnrestrictedUidState = resolveFirstUnrestrictedUidState(code); + final boolean resolvedLastFg = uidState.state <= firstUnrestrictedUidState; + final boolean resolvedNowFg = uidState.pendingState <= firstUnrestrictedUidState; + if (resolvedLastFg == resolvedNowFg) { continue; } final ArraySet<ModeCallback> callbacks = mOpModeWatchers.get(code); @@ -2460,6 +2458,8 @@ public class AppOpsService extends IAppOpsService.Stub { } } } + uidState.state = uidState.pendingState; + uidState.pendingStateCommitTime = 0; } private Ops getOpsRawLocked(int uid, String packageName, boolean edit, diff --git a/services/core/java/com/android/server/attention/AttentionManagerService.java b/services/core/java/com/android/server/attention/AttentionManagerService.java index a8e99da295c4..1681c5bc61d3 100644 --- a/services/core/java/com/android/server/attention/AttentionManagerService.java +++ b/services/core/java/com/android/server/attention/AttentionManagerService.java @@ -17,6 +17,8 @@ package com.android.server.attention; import static android.provider.DeviceConfig.NAMESPACE_ATTENTION_MANAGER_SERVICE; +import static android.provider.Settings.System.ADAPTIVE_SLEEP; +import static android.service.attention.AttentionService.ATTENTION_FAILURE_CANCELLED; import android.Manifest; import android.annotation.NonNull; @@ -45,6 +47,7 @@ import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; import android.provider.DeviceConfig; +import android.provider.Settings; import android.service.attention.AttentionService; import android.service.attention.AttentionService.AttentionFailureCodes; import android.service.attention.IAttentionCallback; @@ -154,9 +157,8 @@ public class AttentionManagerService extends SystemService { * * @return {@code true} if the framework was able to send the provided callback to the service */ - private boolean checkAttention(int requestCode, long timeout, - AttentionCallbackInternal callback) { - Preconditions.checkNotNull(callback); + private boolean checkAttention(long timeout, AttentionCallbackInternal callbackInternal) { + Preconditions.checkNotNull(callbackInternal); if (!isAttentionServiceSupported()) { Slog.w(LOG_TAG, "Trying to call checkAttention() on an unsupported device."); @@ -170,6 +172,7 @@ public class AttentionManagerService extends SystemService { synchronized (mLock) { final long now = SystemClock.uptimeMillis(); + // schedule shutting down the connection if no one resets this timer freeIfInactiveLocked(); final UserState userState = getOrCreateCurrentUserStateLocked(); @@ -182,46 +185,50 @@ public class AttentionManagerService extends SystemService { // make sure every callback is called back if (userState.mPendingAttentionCheck != null) { userState.mPendingAttentionCheck.cancel( - AttentionService.ATTENTION_FAILURE_UNKNOWN); + ATTENTION_FAILURE_CANCELLED); } - userState.mPendingAttentionCheck = new PendingAttentionCheck(requestCode, - callback, () -> checkAttention(requestCode, timeout, callback)); + // fire the check when the service is started + userState.mPendingAttentionCheck = new PendingAttentionCheck( + callbackInternal, () -> checkAttention(timeout, callbackInternal)); } else { try { // throttle frequent requests - final AttentionCheckCache attentionCheckCache = userState.mAttentionCheckCache; - if (attentionCheckCache != null && now - < attentionCheckCache.mLastComputed + STALE_AFTER_MILLIS) { - callback.onSuccess(requestCode, attentionCheckCache.mResult, - attentionCheckCache.mTimestamp); + final AttentionCheckCache cache = userState.mAttentionCheckCache; + if (cache != null && now < cache.mLastComputed + STALE_AFTER_MILLIS) { + callbackInternal.onSuccess(cache.mResult, cache.mTimestamp); return true; } + // schedule request cancellation if not returned by that point yet cancelAfterTimeoutLocked(timeout); - userState.mCurrentAttentionCheckRequestCode = requestCode; - userState.mService.checkAttention(requestCode, new IAttentionCallback.Stub() { - @Override - public void onSuccess(int requestCode, int result, long timestamp) { - callback.onSuccess(requestCode, result, timestamp); - synchronized (mLock) { - userState.mAttentionCheckCache = new AttentionCheckCache( - SystemClock.uptimeMillis(), result, - timestamp); - userState.mCurrentAttentionCheckIsFulfilled = true; - } - StatsLog.write(StatsLog.ATTENTION_MANAGER_SERVICE_RESULT_REPORTED, - result); - } - - @Override - public void onFailure(int requestCode, int error) { - callback.onFailure(requestCode, error); - userState.mCurrentAttentionCheckIsFulfilled = true; - StatsLog.write(StatsLog.ATTENTION_MANAGER_SERVICE_RESULT_REPORTED, - error); - } - }); + userState.mCurrentAttentionCheck = new AttentionCheck(callbackInternal, + new IAttentionCallback.Stub() { + @Override + public void onSuccess(int result, long timestamp) { + callbackInternal.onSuccess(result, timestamp); + synchronized (mLock) { + userState.mAttentionCheckCache = new AttentionCheckCache( + SystemClock.uptimeMillis(), result, + timestamp); + userState.mCurrentAttentionCheckIsFulfilled = true; + } + StatsLog.write( + StatsLog.ATTENTION_MANAGER_SERVICE_RESULT_REPORTED, + result); + } + + @Override + public void onFailure(int error) { + callbackInternal.onFailure(error); + userState.mCurrentAttentionCheckIsFulfilled = true; + StatsLog.write( + StatsLog.ATTENTION_MANAGER_SERVICE_RESULT_REPORTED, + error); + } + }); + userState.mService.checkAttention( + userState.mCurrentAttentionCheck.mIAttentionCallback); } catch (RemoteException e) { Slog.e(LOG_TAG, "Cannot call into the AttentionService"); return false; @@ -232,7 +239,7 @@ public class AttentionManagerService extends SystemService { } /** Cancels the specified attention check. */ - private void cancelAttentionCheck(int requestCode) { + private void cancelAttentionCheck(AttentionCallbackInternal callbackInternal) { synchronized (mLock) { final UserState userState = peekCurrentUserStateLocked(); if (userState == null) { @@ -240,19 +247,35 @@ public class AttentionManagerService extends SystemService { } if (userState.mService == null) { if (userState.mPendingAttentionCheck != null - && userState.mPendingAttentionCheck.mRequestCode == requestCode) { + && userState.mPendingAttentionCheck.mCallbackInternal.equals( + callbackInternal)) { userState.mPendingAttentionCheck = null; } return; } - try { - userState.mService.cancelAttentionCheck(requestCode); - } catch (RemoteException e) { - Slog.e(LOG_TAG, "Cannot call into the AttentionService"); + if (userState.mCurrentAttentionCheck.mCallbackInternal.equals(callbackInternal)) { + try { + userState.mService.cancelAttentionCheck( + userState.mCurrentAttentionCheck.mIAttentionCallback); + } catch (RemoteException e) { + Slog.e(LOG_TAG, "Cannot call into the AttentionService"); + } + } else { + Slog.e(LOG_TAG, "Cannot cancel a non-current request"); } } } + /** Disables service dependants. */ + private void disableSelf() { + final long identity = Binder.clearCallingIdentity(); + try { + Settings.System.putInt(mContext.getContentResolver(), ADAPTIVE_SLEEP, 0); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + @GuardedBy("mLock") private void freeIfInactiveLocked() { // If we are called here, it means someone used the API again - reset the timer then. @@ -375,14 +398,18 @@ public class AttentionManagerService extends SystemService { } @Override - public boolean checkAttention(int requestCode, long timeout, - AttentionCallbackInternal callback) { - return AttentionManagerService.this.checkAttention(requestCode, timeout, callback); + public boolean checkAttention(long timeout, AttentionCallbackInternal callbackInternal) { + return AttentionManagerService.this.checkAttention(timeout, callbackInternal); + } + + @Override + public void cancelAttentionCheck(AttentionCallbackInternal callbackInternal) { + AttentionManagerService.this.cancelAttentionCheck(callbackInternal); } @Override - public void cancelAttentionCheck(int requestCode) { - AttentionManagerService.this.cancelAttentionCheck(requestCode); + public void disableSelf() { + AttentionManagerService.this.disableSelf(); } } @@ -400,19 +427,17 @@ public class AttentionManagerService extends SystemService { } private static final class PendingAttentionCheck { - private final int mRequestCode; - private final AttentionCallbackInternal mCallback; + private final AttentionCallbackInternal mCallbackInternal; private final Runnable mRunnable; - PendingAttentionCheck(int requestCode, AttentionCallbackInternal callback, + PendingAttentionCheck(AttentionCallbackInternal callbackInternal, Runnable runnable) { - mRequestCode = requestCode; - mCallback = callback; + mCallbackInternal = callbackInternal; mRunnable = runnable; } void cancel(@AttentionFailureCodes int failureCode) { - mCallback.onFailure(mRequestCode, failureCode); + mCallbackInternal.onFailure(failureCode); } void run() { @@ -420,6 +445,17 @@ public class AttentionManagerService extends SystemService { } } + private static final class AttentionCheck { + private final AttentionCallbackInternal mCallbackInternal; + private final IAttentionCallback mIAttentionCallback; + + AttentionCheck(AttentionCallbackInternal callbackInternal, + IAttentionCallback iAttentionCallback) { + mCallbackInternal = callbackInternal; + mIAttentionCallback = iAttentionCallback; + } + } + private static final class UserState { final ComponentName mComponentName; final AttentionServiceConnection mConnection = new AttentionServiceConnection(); @@ -429,12 +465,12 @@ public class AttentionManagerService extends SystemService { @GuardedBy("mLock") boolean mBinding; @GuardedBy("mLock") - int mCurrentAttentionCheckRequestCode; + AttentionCheck mCurrentAttentionCheck; @GuardedBy("mLock") boolean mCurrentAttentionCheckIsFulfilled; + @GuardedBy("mLock") PendingAttentionCheck mPendingAttentionCheck; - @GuardedBy("mLock") AttentionCheckCache mAttentionCheckCache; @@ -552,8 +588,7 @@ public class AttentionManagerService extends SystemService { if (userState != null) { // If not called back already. if (!userState.mCurrentAttentionCheckIsFulfilled) { - cancel(userState, - AttentionService.ATTENTION_FAILURE_TIMED_OUT); + cancel(userState, AttentionService.ATTENTION_FAILURE_TIMED_OUT); } } @@ -571,13 +606,14 @@ public class AttentionManagerService extends SystemService { if (userState.mService != null) { try { userState.mService.cancelAttentionCheck( - userState.mCurrentAttentionCheckRequestCode); + userState.mCurrentAttentionCheck.mIAttentionCallback); } catch (RemoteException e) { Slog.e(LOG_TAG, "Unable to cancel attention check"); } if (userState.mPendingAttentionCheck != null) { userState.mPendingAttentionCheck.cancel(failureCode); + userState.mPendingAttentionCheck = null; } } } diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index a14a638395db..93f7831e8886 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -78,6 +78,8 @@ import android.media.IPlaybackConfigDispatcher; import android.media.IRecordingConfigDispatcher; import android.media.IRingtonePlayer; import android.media.IVolumeController; +import android.media.MediaExtractor; +import android.media.MediaFormat; import android.media.MediaPlayer; import android.media.MediaPlayer.OnCompletionListener; import android.media.MediaPlayer.OnErrorListener; @@ -94,6 +96,7 @@ import android.media.audiopolicy.AudioVolumeGroups; import android.media.audiopolicy.IAudioPolicyCallback; import android.media.projection.IMediaProjection; import android.media.projection.IMediaProjectionManager; +import android.net.Uri; import android.os.Binder; import android.os.Build; import android.os.Bundle; @@ -4146,6 +4149,26 @@ public class AudioService extends IAudioService.Stub } } + /** + * See AudioManager.hasHapticChannels(Uri). + */ + public boolean hasHapticChannels(Uri uri) { + MediaExtractor extractor = new MediaExtractor(); + try { + extractor.setDataSource(mContext, uri, null); + for (int i = 0; i < extractor.getTrackCount(); i++) { + MediaFormat format = extractor.getTrackFormat(i); + if (format.containsKey(MediaFormat.KEY_HAPTIC_CHANNEL_COUNT) + && format.getInteger(MediaFormat.KEY_HAPTIC_CHANNEL_COUNT) > 0) { + return true; + } + } + } catch (IOException e) { + Log.e(TAG, "hasHapticChannels failure:" + e); + } + return false; + } + /////////////////////////////////////////////////////////////////////////// // Inner classes /////////////////////////////////////////////////////////////////////////// @@ -6290,8 +6313,8 @@ public class AudioService extends IAudioService.Stub // Audio policy management //========================================================================================== public String registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb, - boolean hasFocusListener, boolean isFocusPolicy, boolean isVolumeController, - IMediaProjection projection) { + boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, + boolean isVolumeController, IMediaProjection projection) { AudioSystem.setDynamicPolicyCallback(mDynPolicyCallback); if (!isPolicyRegisterAllowed(policyConfig, projection)) { @@ -6312,7 +6335,7 @@ public class AudioService extends IAudioService.Stub return null; } AudioPolicyProxy app = new AudioPolicyProxy(policyConfig, pcb, hasFocusListener, - isFocusPolicy, isVolumeController); + isFocusPolicy, isTestFocusPolicy, isVolumeController); pcb.asBinder().linkToDeath(app, 0/*flags*/); regId = app.getRegistrationId(); mAudioPolicies.put(pcb.asBinder(), app); @@ -6730,9 +6753,11 @@ public class AudioService extends IAudioService.Stub */ int mFocusDuckBehavior = AudioPolicy.FOCUS_POLICY_DUCKING_DEFAULT; boolean mIsFocusPolicy = false; + boolean mIsTestFocusPolicy = false; AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token, - boolean hasFocusListener, boolean isFocusPolicy, boolean isVolumeController) { + boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, + boolean isVolumeController) { super(config); setRegistration(new String(config.hashCode() + ":ap:" + mAudioPolicyCounter++)); mPolicyCallback = token; @@ -6743,7 +6768,8 @@ public class AudioService extends IAudioService.Stub // can only ever be true if there is a focus listener if (isFocusPolicy) { mIsFocusPolicy = true; - mMediaFocusControl.setFocusPolicy(mPolicyCallback); + mIsTestFocusPolicy = isTestFocusPolicy; + mMediaFocusControl.setFocusPolicy(mPolicyCallback, mIsTestFocusPolicy); } } if (mIsVolumeController) { @@ -6771,7 +6797,7 @@ public class AudioService extends IAudioService.Stub void release() { if (mIsFocusPolicy) { - mMediaFocusControl.unsetFocusPolicy(mPolicyCallback); + mMediaFocusControl.unsetFocusPolicy(mPolicyCallback, mIsTestFocusPolicy); } if (mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) { mMediaFocusControl.setDuckingInExtPolicyAvailable(false); diff --git a/services/core/java/com/android/server/audio/MediaFocusControl.java b/services/core/java/com/android/server/audio/MediaFocusControl.java index d028e88fa160..1e58b454a15b 100644 --- a/services/core/java/com/android/server/audio/MediaFocusControl.java +++ b/services/core/java/com/android/server/audio/MediaFocusControl.java @@ -17,6 +17,7 @@ package com.android.server.audio; import android.annotation.NonNull; +import android.annotation.Nullable; import android.app.AppOpsManager; import android.content.Context; import android.media.AudioAttributes; @@ -458,7 +459,15 @@ public class MediaFocusControl implements PlayerFocusEnforcer { } } - private IAudioPolicyCallback mFocusPolicy = null; + /** The current audio focus policy */ + @GuardedBy("mAudioFocusLock") + @Nullable private IAudioPolicyCallback mFocusPolicy = null; + /** + * The audio focus policy that was registered before a test focus policy was registered + * during a test + */ + @GuardedBy("mAudioFocusLock") + @Nullable private IAudioPolicyCallback mPreviousFocusPolicy = null; // Since we don't have a stack of focus owners when using an external focus policy, we keep // track of all the focus requesters in this map, with their clientId as the key. This is @@ -466,22 +475,30 @@ public class MediaFocusControl implements PlayerFocusEnforcer { private HashMap<String, FocusRequester> mFocusOwnersForFocusPolicy = new HashMap<String, FocusRequester>(); - void setFocusPolicy(IAudioPolicyCallback policy) { + void setFocusPolicy(IAudioPolicyCallback policy, boolean isTestFocusPolicy) { if (policy == null) { return; } synchronized (mAudioFocusLock) { + if (isTestFocusPolicy) { + mPreviousFocusPolicy = mFocusPolicy; + } mFocusPolicy = policy; } } - void unsetFocusPolicy(IAudioPolicyCallback policy) { + void unsetFocusPolicy(IAudioPolicyCallback policy, boolean isTestFocusPolicy) { if (policy == null) { return; } synchronized (mAudioFocusLock) { if (mFocusPolicy == policy) { - mFocusPolicy = null; + if (isTestFocusPolicy) { + // restore the focus policy that was there before the focus policy test started + mFocusPolicy = mPreviousFocusPolicy; + } else { + mFocusPolicy = null; + } } } } diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java index 3e48445dfb36..c60dd6ca130a 100644 --- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java +++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java @@ -1251,8 +1251,6 @@ public abstract class BiometricServiceBase extends SystemService if (getCurrentClient() instanceof InternalRemovalClient || getCurrentClient() instanceof InternalEnumerateClient) { Slog.w(getTag(), "User switched while performing cleanup"); - removeClient(getCurrentClient()); - clearEnumerateState(); } updateActiveGroup(userId, null); doTemplateCleanupForUser(userId); diff --git a/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java index 4289a25e5b3a..54a4ad42fd99 100644 --- a/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java +++ b/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java @@ -16,7 +16,6 @@ package com.android.server.broadcastradio; -import android.annotation.NonNull; import android.Manifest; import android.content.Context; import android.content.pm.PackageManager; @@ -26,14 +25,13 @@ import android.hardware.radio.IRadioService; import android.hardware.radio.ITuner; import android.hardware.radio.ITunerCallback; import android.hardware.radio.RadioManager; -import android.os.ParcelableException; import android.os.RemoteException; import android.util.Slog; -import com.android.internal.util.Preconditions; import com.android.server.SystemService; import com.android.server.broadcastradio.hal2.AnnouncementAggregator; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -45,16 +43,20 @@ public class BroadcastRadioService extends SystemService { private final ServiceImpl mServiceImpl = new ServiceImpl(); - private final com.android.server.broadcastradio.hal1.BroadcastRadioService mHal1 = - new com.android.server.broadcastradio.hal1.BroadcastRadioService(); - private final com.android.server.broadcastradio.hal2.BroadcastRadioService mHal2 = - new com.android.server.broadcastradio.hal2.BroadcastRadioService(); + private final com.android.server.broadcastradio.hal1.BroadcastRadioService mHal1; + private final com.android.server.broadcastradio.hal2.BroadcastRadioService mHal2; private final Object mLock = new Object(); - private List<RadioManager.ModuleProperties> mModules = null; + private List<RadioManager.ModuleProperties> mV1Modules = null; public BroadcastRadioService(Context context) { super(context); + + mHal1 = new com.android.server.broadcastradio.hal1.BroadcastRadioService(); + mV1Modules = mHal1.loadModules(); + OptionalInt max = mV1Modules.stream().mapToInt(RadioManager.ModuleProperties::getId).max(); + mHal2 = new com.android.server.broadcastradio.hal2.BroadcastRadioService( + max.isPresent() ? max.getAsInt() + 1 : 0); } @Override @@ -62,14 +64,6 @@ public class BroadcastRadioService extends SystemService { publishBinderService(Context.RADIO_SERVICE, mServiceImpl); } - /** - * Finds next available index for newly loaded modules. - */ - private static int getNextId(@NonNull List<RadioManager.ModuleProperties> modules) { - OptionalInt max = modules.stream().mapToInt(RadioManager.ModuleProperties::getId).max(); - return max.isPresent() ? max.getAsInt() + 1 : 0; - } - private class ServiceImpl extends IRadioService.Stub { private void enforcePolicyAccess() { if (PackageManager.PERMISSION_GRANTED != getContext().checkCallingPermission( @@ -81,14 +75,10 @@ public class BroadcastRadioService extends SystemService { @Override public List<RadioManager.ModuleProperties> listModules() { enforcePolicyAccess(); - synchronized (mLock) { - if (mModules != null) return mModules; - - mModules = mHal1.loadModules(); - mModules.addAll(mHal2.loadModules(getNextId(mModules))); - - return mModules; - } + List<RadioManager.ModuleProperties> modules = new ArrayList<>(); + modules.addAll(mV1Modules); + modules.addAll(mHal2.listModules()); + return modules; } @Override diff --git a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java index 954c0013fbe4..b8810c8f379f 100644 --- a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java +++ b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java @@ -18,20 +18,22 @@ package com.android.server.broadcastradio.hal2; import android.annotation.NonNull; import android.annotation.Nullable; +import android.hardware.broadcastradio.V2_0.IBroadcastRadio; import android.hardware.radio.IAnnouncementListener; import android.hardware.radio.ICloseHandle; import android.hardware.radio.ITuner; import android.hardware.radio.ITunerCallback; import android.hardware.radio.RadioManager; -import android.hardware.broadcastradio.V2_0.IBroadcastRadio; import android.hidl.manager.V1_0.IServiceManager; +import android.hidl.manager.V1_0.IServiceNotification; +import android.os.IHwBinder.DeathRecipient; import android.os.RemoteException; import android.util.Slog; +import com.android.internal.annotations.GuardedBy; + import java.util.Collection; -import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; @@ -39,52 +41,104 @@ import java.util.stream.Collectors; public class BroadcastRadioService { private static final String TAG = "BcRadio2Srv"; + private final Object mLock = new Object(); + + @GuardedBy("mLock") + private int mNextModuleId = 0; + + @GuardedBy("mLock") + private final Map<String, Integer> mServiceNameToModuleIdMap = new HashMap<>(); + + @GuardedBy("mLock") private final Map<Integer, RadioModule> mModules = new HashMap<>(); - private static @NonNull List<String> listByInterface(@NonNull String fqName) { + private IServiceNotification.Stub mServiceListener = new IServiceNotification.Stub() { + @Override + public void onRegistration(String fqName, String serviceName, boolean preexisting) { + Slog.v(TAG, "onRegistration(" + fqName + ", " + serviceName + ", " + preexisting + ")"); + Integer moduleId; + synchronized (mLock) { + // If the service has been registered before, reuse its previous module ID. + moduleId = mServiceNameToModuleIdMap.get(serviceName); + boolean newService = false; + if (moduleId == null) { + newService = true; + moduleId = mNextModuleId; + } + + RadioModule module = RadioModule.tryLoadingModule(moduleId, serviceName); + if (module == null) { + return; + } + Slog.v(TAG, "loaded broadcast radio module " + moduleId + ": " + serviceName + + " (HAL 2.0)"); + mModules.put(moduleId, module); + + if (newService) { + mServiceNameToModuleIdMap.put(serviceName, moduleId); + mNextModuleId++; + } + + try { + module.getService().linkToDeath(mDeathRecipient, moduleId); + } catch (RemoteException ex) { + // Service has already died, so remove its entry from mModules. + mModules.remove(moduleId); + } + } + } + }; + + private DeathRecipient mDeathRecipient = new DeathRecipient() { + @Override + public void serviceDied(long cookie) { + Slog.v(TAG, "serviceDied(" + cookie + ")"); + synchronized (mLock) { + int moduleId = (int) cookie; + mModules.remove(moduleId); + + for (Map.Entry<String, Integer> entry : mServiceNameToModuleIdMap.entrySet()) { + if (entry.getValue() == moduleId) { + Slog.i(TAG, "service " + entry.getKey() + + " died; removed RadioModule with ID " + moduleId); + return; + } + } + } + } + }; + + public BroadcastRadioService(int nextModuleId) { + mNextModuleId = nextModuleId; try { IServiceManager manager = IServiceManager.getService(); if (manager == null) { - Slog.e(TAG, "Failed to get HIDL Service Manager"); - return Collections.emptyList(); - } - - List<String> list = manager.listByInterface(fqName); - if (list == null) { - Slog.e(TAG, "Didn't get interface list from HIDL Service Manager"); - return Collections.emptyList(); + Slog.e(TAG, "failed to get HIDL Service Manager"); + return; } - return list; + manager.registerForNotifications(IBroadcastRadio.kInterfaceName, "", mServiceListener); } catch (RemoteException ex) { - Slog.e(TAG, "Failed fetching interface list", ex); - return Collections.emptyList(); + Slog.e(TAG, "failed to register for service notifications: ", ex); } } - public @NonNull Collection<RadioManager.ModuleProperties> loadModules(int idx) { - Slog.v(TAG, "loadModules(" + idx + ")"); - - for (String serviceName : listByInterface(IBroadcastRadio.kInterfaceName)) { - Slog.v(TAG, "checking service: " + serviceName); - - RadioModule module = RadioModule.tryLoadingModule(idx, serviceName); - if (module != null) { - Slog.i(TAG, "loaded broadcast radio module " + idx + ": " + - serviceName + " (HAL 2.0)"); - mModules.put(idx++, module); - } + public @NonNull Collection<RadioManager.ModuleProperties> listModules() { + synchronized (mLock) { + return mModules.values().stream().map(module -> module.mProperties) + .collect(Collectors.toList()); } - - return mModules.values().stream().map(module -> module.mProperties). - collect(Collectors.toList()); } public boolean hasModule(int id) { - return mModules.containsKey(id); + synchronized (mLock) { + return mModules.containsKey(id); + } } public boolean hasAnyModules() { - return !mModules.isEmpty(); + synchronized (mLock) { + return !mModules.isEmpty(); + } } public ITuner openSession(int moduleId, @Nullable RadioManager.BandConfig legacyConfig, @@ -95,7 +149,10 @@ public class BroadcastRadioService { throw new IllegalArgumentException("Non-audio sessions not supported with HAL 2.x"); } - RadioModule module = mModules.get(moduleId); + RadioModule module = null; + synchronized (mLock) { + module = mModules.get(moduleId); + } if (module == null) { throw new IllegalArgumentException("Invalid module ID"); } @@ -111,12 +168,14 @@ public class BroadcastRadioService { @NonNull IAnnouncementListener listener) { AnnouncementAggregator aggregator = new AnnouncementAggregator(listener); boolean anySupported = false; - for (RadioModule module : mModules.values()) { - try { - aggregator.watchModule(module, enabledTypes); - anySupported = true; - } catch (UnsupportedOperationException ex) { - Slog.v(TAG, "Announcements not supported for this module", ex); + synchronized (mLock) { + for (RadioModule module : mModules.values()) { + try { + aggregator.watchModule(module, enabledTypes); + anySupported = true; + } catch (UnsupportedOperationException ex) { + Slog.v(TAG, "Announcements not supported for this module", ex); + } } } if (!anySupported) { diff --git a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java index 816ba0b51355..832f8e1c9205 100644 --- a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java +++ b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java @@ -20,8 +20,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Bitmap; import android.graphics.BitmapFactory; -import android.hardware.radio.ITuner; -import android.hardware.radio.RadioManager; import android.hardware.broadcastradio.V2_0.AmFmRegionConfig; import android.hardware.broadcastradio.V2_0.Announcement; import android.hardware.broadcastradio.V2_0.DabTableEntry; @@ -30,13 +28,12 @@ import android.hardware.broadcastradio.V2_0.IBroadcastRadio; import android.hardware.broadcastradio.V2_0.ICloseHandle; import android.hardware.broadcastradio.V2_0.ITunerSession; import android.hardware.broadcastradio.V2_0.Result; -import android.os.ParcelableException; +import android.hardware.radio.RadioManager; import android.os.RemoteException; import android.util.MutableInt; import android.util.Slog; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; @@ -78,6 +75,10 @@ class RadioModule { } } + public @NonNull IBroadcastRadio getService() { + return mService; + } + public @NonNull TunerSession openSession(@NonNull android.hardware.radio.ITunerCallback userCb) throws RemoteException { TunerCallback cb = new TunerCallback(Objects.requireNonNull(userCb)); diff --git a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java index 0e3d82c0a660..ce887eb4f0fe 100644 --- a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java +++ b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java @@ -16,6 +16,7 @@ package com.android.server.connectivity; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.net.NattSocketKeepalive.NATT_PORT; import static android.net.NetworkAgent.CMD_ADD_KEEPALIVE_PACKET_FILTER; import static android.net.NetworkAgent.CMD_REMOVE_KEEPALIVE_PACKET_FILTER; @@ -23,6 +24,7 @@ import static android.net.NetworkAgent.CMD_START_SOCKET_KEEPALIVE; import static android.net.NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE; import static android.net.SocketKeepalive.BINDER_DIED; import static android.net.SocketKeepalive.DATA_RECEIVED; +import static android.net.SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES; import static android.net.SocketKeepalive.ERROR_INVALID_INTERVAL; import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS; import static android.net.SocketKeepalive.ERROR_INVALID_NETWORK; @@ -34,6 +36,7 @@ import static android.net.SocketKeepalive.SUCCESS; import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.Context; import android.net.ISocketKeepaliveCallback; import android.net.KeepalivePacketData; import android.net.NattKeepalivePacketData; @@ -84,10 +87,13 @@ public class KeepaliveTracker { private final Handler mConnectivityServiceHandler; @NonNull private final TcpKeepaliveController mTcpController; + @NonNull + private final Context mContext; - public KeepaliveTracker(Handler handler) { + public KeepaliveTracker(Context context, Handler handler) { mConnectivityServiceHandler = handler; mTcpController = new TcpKeepaliveController(handler); + mContext = context; } /** @@ -101,6 +107,7 @@ public class KeepaliveTracker { private final ISocketKeepaliveCallback mCallback; private final int mUid; private final int mPid; + private final boolean mPrivileged; private final NetworkAgentInfo mNai; private final int mType; private final FileDescriptor mFd; @@ -108,6 +115,11 @@ public class KeepaliveTracker { public static final int TYPE_NATT = 1; public static final int TYPE_TCP = 2; + // Max allowed unprivileged keepalive slots per network. Caller's permission will be + // enforced if number of existing keepalives reach this limit. + // TODO: consider making this limit configurable via resources. + private static final int MAX_UNPRIVILEGED_SLOTS = 3; + // Keepalive slot. A small integer that identifies this keepalive among the ones handled // by this network. private int mSlot = NO_KEEPALIVE; @@ -127,16 +139,33 @@ public class KeepaliveTracker { @NonNull KeepalivePacketData packet, int interval, int type, - @NonNull FileDescriptor fd) { + @Nullable FileDescriptor fd) throws InvalidSocketException { mCallback = callback; mPid = Binder.getCallingPid(); mUid = Binder.getCallingUid(); + mPrivileged = (PERMISSION_GRANTED == mContext.checkPermission(PERMISSION, mPid, mUid)); mNai = nai; mPacket = packet; mInterval = interval; mType = type; - mFd = fd; + + // For SocketKeepalive, a dup of fd is kept in mFd so the source port from which the + // keepalives are sent cannot be reused by another app even if the fd gets closed by + // the user. A null is acceptable here for backward compatibility of PacketKeepalive + // API. + // TODO: don't accept null fd after legacy packetKeepalive API is removed. + try { + if (fd != null) { + mFd = Os.dup(fd); + } else { + Log.d(TAG, "uid/pid " + mUid + "/" + mPid + " calls with null fd"); + mFd = null; + } + } catch (ErrnoException e) { + Log.e(TAG, "Cannot dup fd: ", e); + throw new InvalidSocketException(ERROR_INVALID_SOCKET, e); + } try { mCallback.asBinder().linkToDeath(this, 0); @@ -167,7 +196,7 @@ public class KeepaliveTracker { + "->" + IpUtils.addressAndPortToString(mPacket.dstAddress, mPacket.dstPort) + " interval=" + mInterval - + " uid=" + mUid + " pid=" + mPid + + " uid=" + mUid + " pid=" + mPid + " privileged=" + mPrivileged + " packetData=" + HexDump.toHexString(mPacket.getPacket()) + " ]"; } @@ -207,9 +236,27 @@ public class KeepaliveTracker { return SUCCESS; } + private int checkPermission() { + final HashMap<Integer, KeepaliveInfo> networkKeepalives = mKeepalives.get(mNai); + int unprivilegedCount = 0; + if (networkKeepalives == null) { + return ERROR_INVALID_NETWORK; + } + for (KeepaliveInfo ki : networkKeepalives.values()) { + if (!ki.mPrivileged) { + unprivilegedCount++; + } + if (unprivilegedCount >= MAX_UNPRIVILEGED_SLOTS) { + return mPrivileged ? SUCCESS : ERROR_INSUFFICIENT_RESOURCES; + } + } + return SUCCESS; + } + private int isValid() { synchronized (mNai) { int error = checkInterval(); + if (error == SUCCESS) error = checkPermission(); if (error == SUCCESS) error = checkNetworkConnected(); if (error == SUCCESS) error = checkSourceAddress(); return error; @@ -272,6 +319,18 @@ public class KeepaliveTracker { } } + // Close the duplicated fd that maintains the lifecycle of socket whenever + // keepalive is running. + if (mFd != null) { + try { + Os.close(mFd); + } catch (ErrnoException e) { + // This should not happen since system server controls the lifecycle of fd when + // keepalive offload is running. + Log.wtf(TAG, "Error closing fd for keepalive " + mSlot + ": " + e); + } + } + if (reason == SUCCESS) { try { mCallback.onStopped(); @@ -355,8 +414,9 @@ public class KeepaliveTracker { return; } ki.stop(reason); - Log.d(TAG, "Stopped keepalive " + slot + " on " + networkName); networkKeepalives.remove(slot); + Log.d(TAG, "Stopped keepalive " + slot + " on " + networkName + ", " + + networkKeepalives.size() + " remains."); if (networkKeepalives.isEmpty()) { mKeepalives.remove(nai); } @@ -389,7 +449,8 @@ public class KeepaliveTracker { ki = mKeepalives.get(nai).get(slot); } catch(NullPointerException e) {} if (ki == null) { - Log.e(TAG, "Event for unknown keepalive " + slot + " on " + nai.name()); + Log.e(TAG, "Event " + message.what + " for unknown keepalive " + slot + " on " + + nai.name()); return; } @@ -437,6 +498,7 @@ public class KeepaliveTracker { * {@link android.net.SocketKeepalive}. **/ public void startNattKeepalive(@Nullable NetworkAgentInfo nai, + @Nullable FileDescriptor fd, int intervalSeconds, @NonNull ISocketKeepaliveCallback cb, @NonNull String srcAddrString, @@ -465,8 +527,14 @@ public class KeepaliveTracker { notifyErrorCallback(cb, e.error); return; } - KeepaliveInfo ki = new KeepaliveInfo(cb, nai, packet, intervalSeconds, - KeepaliveInfo.TYPE_NATT, null); + KeepaliveInfo ki = null; + try { + ki = new KeepaliveInfo(cb, nai, packet, intervalSeconds, + KeepaliveInfo.TYPE_NATT, fd); + } catch (InvalidSocketException e) { + notifyErrorCallback(cb, ERROR_INVALID_SOCKET); + return; + } Log.d(TAG, "Created keepalive: " + ki.toString()); mConnectivityServiceHandler.obtainMessage( NetworkAgent.CMD_START_SOCKET_KEEPALIVE, ki).sendToTarget(); @@ -498,9 +566,14 @@ public class KeepaliveTracker { notifyErrorCallback(cb, e.error); return; } - - KeepaliveInfo ki = new KeepaliveInfo(cb, nai, packet, intervalSeconds, - KeepaliveInfo.TYPE_TCP, fd); + KeepaliveInfo ki = null; + try { + ki = new KeepaliveInfo(cb, nai, packet, intervalSeconds, + KeepaliveInfo.TYPE_TCP, fd); + } catch (InvalidSocketException e) { + notifyErrorCallback(cb, ERROR_INVALID_SOCKET); + return; + } Log.d(TAG, "Created keepalive: " + ki.toString()); mConnectivityServiceHandler.obtainMessage(CMD_START_SOCKET_KEEPALIVE, ki).sendToTarget(); } @@ -535,7 +608,7 @@ public class KeepaliveTracker { } // Forward request to old API. - startNattKeepalive(nai, intervalSeconds, cb, srcAddrString, srcPort, + startNattKeepalive(nai, fd, intervalSeconds, cb, srcAddrString, srcPort, dstAddrString, dstPort); } diff --git a/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java b/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java index f4d9006a7068..e570ef1e9bf2 100644 --- a/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java +++ b/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java @@ -16,14 +16,17 @@ package com.android.server.connectivity; import static android.net.SocketKeepalive.DATA_RECEIVED; -import static android.net.SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED; import static android.net.SocketKeepalive.ERROR_INVALID_SOCKET; import static android.net.SocketKeepalive.ERROR_SOCKET_NOT_IDLE; +import static android.net.SocketKeepalive.ERROR_UNSUPPORTED; import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR; import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT; import static android.system.OsConstants.ENOPROTOOPT; import static android.system.OsConstants.FIONREAD; +import static android.system.OsConstants.IPPROTO_IP; import static android.system.OsConstants.IPPROTO_TCP; +import static android.system.OsConstants.IP_TOS; +import static android.system.OsConstants.IP_TTL; import static android.system.OsConstants.TIOCOUTQ; import android.annotation.NonNull; @@ -193,12 +196,18 @@ public class TcpKeepaliveController { trw = NetworkUtils.getTcpRepairWindow(fd); tcpDetails.rcvWnd = trw.rcvWnd; tcpDetails.rcvWndScale = trw.rcvWndScale; + if (tcpDetails.srcAddress.length == 4 /* V4 address length */) { + // Query TOS. + tcpDetails.tos = Os.getsockoptInt(fd, IPPROTO_IP, IP_TOS); + // Query TTL. + tcpDetails.ttl = Os.getsockoptInt(fd, IPPROTO_IP, IP_TTL); + } } catch (ErrnoException e) { Log.e(TAG, "Exception reading TCP state from socket", e); if (e.errno == ENOPROTOOPT) { // ENOPROTOOPT may happen in kernel version lower than 4.8. - // Treat it as ERROR_HARDWARE_UNSUPPORTED. - throw new InvalidSocketException(ERROR_HARDWARE_UNSUPPORTED, e); + // Treat it as ERROR_UNSUPPORTED. + throw new InvalidSocketException(ERROR_UNSUPPORTED, e); } else { throw new InvalidSocketException(ERROR_INVALID_SOCKET, e); } diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index 35704d404ff3..37fe3d094179 100644 --- a/services/core/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java @@ -247,7 +247,14 @@ public class Tethering extends BaseNetworkObserver { (Intent ignored) -> { mLog.log("OBSERVED default data subscription change"); updateConfiguration(); - mEntitlementMgr.reevaluateSimCardProvisioning(); + // To avoid launch unexpected provisioning checks, ignore re-provisioning when + // no CarrierConfig loaded yet. Assume reevaluateSimCardProvisioning() will be + // triggered again when CarrierConfig is loaded. + if (mEntitlementMgr.getCarrierConfig() != null) { + mEntitlementMgr.reevaluateSimCardProvisioning(); + } else { + mLog.log("IGNORED reevaluate provisioning due to no carrier config loaded"); + } }); mStateReceiver = new StateReceiver(); diff --git a/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java b/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java index 65cc51610e72..70ab38983446 100644 --- a/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java +++ b/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java @@ -158,6 +158,21 @@ public class EntitlementManager { } } + /** Get carrier configuration bundle. */ + public PersistableBundle getCarrierConfig() { + final CarrierConfigManager configManager = (CarrierConfigManager) mContext + .getSystemService(Context.CARRIER_CONFIG_SERVICE); + if (configManager == null) return null; + + final PersistableBundle carrierConfig = configManager.getConfig(); + + if (CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfig)) { + return carrierConfig; + } + + return null; + } + // The logic here is aimed solely at confirming that a CarrierConfig exists // and affirms that entitlement checks are not required. // @@ -165,11 +180,7 @@ public class EntitlementManager { // entirely so that this is more intuitive. private boolean carrierConfigAffirmsEntitlementCheckNotRequired() { // Check carrier config for entitlement checks - final CarrierConfigManager configManager = (CarrierConfigManager) mContext - .getSystemService(Context.CARRIER_CONFIG_SERVICE); - if (configManager == null) return false; - - final PersistableBundle carrierConfig = configManager.getConfig(); + final PersistableBundle carrierConfig = getCarrierConfig(); if (carrierConfig == null) return false; // A CarrierConfigManager was found and it has a config. diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 32f34b8378ce..3010324488b8 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -37,7 +37,6 @@ import android.content.pm.ParceledListSlice; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.ColorSpace; -import android.graphics.GraphicBuffer; import android.graphics.Point; import android.graphics.Rect; import android.hardware.SensorManager; @@ -1275,11 +1274,12 @@ public final class DisplayManagerService extends SystemService { if (token == null) { return false; } - final GraphicBuffer gb = SurfaceControl.screenshotToBufferWithSecureLayersUnsafe( - token, new Rect(), 0 /* width */, 0 /* height */, false /* useIdentityTransform */, - 0 /* rotation */); + final SurfaceControl.ScreenshotGraphicBuffer gb = + SurfaceControl.screenshotToBufferWithSecureLayersUnsafe( + token, new Rect(), 0 /* width */, 0 /* height */, + false /* useIdentityTransform */, 0 /* rotation */); try { - outSurface.attachAndQueueBuffer(gb); + outSurface.attachAndQueueBuffer(gb.getGraphicBuffer()); } catch (RuntimeException e) { Slog.w(TAG, "Failed to take screenshot - " + e.getMessage()); } diff --git a/services/core/java/com/android/server/display/color/ColorDisplayService.java b/services/core/java/com/android/server/display/color/ColorDisplayService.java index ed420b73e79b..45505c7a0bef 100644 --- a/services/core/java/com/android/server/display/color/ColorDisplayService.java +++ b/services/core/java/com/android/server/display/color/ColorDisplayService.java @@ -26,7 +26,6 @@ import static android.hardware.display.ColorDisplayManager.COLOR_MODE_SATURATED; import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_DISPLAY_WHITE_BALANCE; import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_NIGHT_DISPLAY; -import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_SATURATION; import android.Manifest; import android.animation.Animator; @@ -88,19 +87,13 @@ import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZoneId; import java.time.format.DateTimeParseException; -import java.util.Arrays; /** * Controls the display's color transforms. */ public final class ColorDisplayService extends SystemService { - private static final String TAG = "ColorDisplayService"; - - /** - * The transition time, in milliseconds, for Night Display to turn on/off. - */ - private static final long TRANSITION_DURATION = 3000L; + static final String TAG = "ColorDisplayService"; /** * The identity matrix, used if one of the given matrices is {@code null}. @@ -111,6 +104,11 @@ public final class ColorDisplayService extends SystemService { Matrix.setIdentityM(MATRIX_IDENTITY, 0); } + /** + * The transition time, in milliseconds, for Night Display to turn on/off. + */ + private static final long TRANSITION_DURATION = 3000L; + private static final int MSG_APPLY_NIGHT_DISPLAY_IMMEDIATE = 0; private static final int MSG_APPLY_NIGHT_DISPLAY_ANIMATED = 1; private static final int MSG_APPLY_GLOBAL_SATURATION = 2; @@ -133,59 +131,8 @@ public final class ColorDisplayService extends SystemService { final DisplayWhiteBalanceTintController mDisplayWhiteBalanceTintController = new DisplayWhiteBalanceTintController(); - private final TintController mGlobalSaturationTintController = new TintController() { - - private float[] mMatrixGlobalSaturation = new float[16]; - - @Override - public void setUp(Context context, boolean needsLinear) { - } - - @Override - public float[] getMatrix() { - return Arrays.copyOf(mMatrixGlobalSaturation, mMatrixGlobalSaturation.length); - } - - @Override - public void setMatrix(int saturationLevel) { - if (saturationLevel < 0) { - saturationLevel = 0; - } else if (saturationLevel > 100) { - saturationLevel = 100; - } - Slog.d(TAG, "Setting saturation level: " + saturationLevel); - - if (saturationLevel == 100) { - setActivated(false); - Matrix.setIdentityM(mMatrixGlobalSaturation, 0); - } else { - setActivated(true); - float saturation = saturationLevel * 0.1f; - float desaturation = 1.0f - saturation; - float[] luminance = {0.231f * desaturation, 0.715f * desaturation, - 0.072f * desaturation}; - mMatrixGlobalSaturation[0] = luminance[0] + saturation; - mMatrixGlobalSaturation[1] = luminance[0]; - mMatrixGlobalSaturation[2] = luminance[0]; - mMatrixGlobalSaturation[4] = luminance[1]; - mMatrixGlobalSaturation[5] = luminance[1] + saturation; - mMatrixGlobalSaturation[6] = luminance[1]; - mMatrixGlobalSaturation[8] = luminance[2]; - mMatrixGlobalSaturation[9] = luminance[2]; - mMatrixGlobalSaturation[10] = luminance[2] + saturation; - } - } - - @Override - public int getLevel() { - return LEVEL_COLOR_MATRIX_SATURATION; - } - - @Override - public boolean isAvailable(Context context) { - return ColorDisplayManager.isColorTransformAccelerated(context); - } - }; + private final TintController mGlobalSaturationTintController = + new GlobalSaturationTintController(); /** * Matrix and offset used for converting color to grayscale. @@ -1084,82 +1031,6 @@ public final class ColorDisplayService extends SystemService { } } - private abstract static class TintController { - - private ValueAnimator mAnimator; - private Boolean mIsActivated; - - public ValueAnimator getAnimator() { - return mAnimator; - } - - public void setAnimator(ValueAnimator animator) { - mAnimator = animator; - } - - /** - * Cancel the animator if it's still running. - */ - public void cancelAnimator() { - if (mAnimator != null) { - mAnimator.cancel(); - } - } - - /** - * End the animator if it's still running, jumping to the end state. - */ - public void endAnimator() { - if (mAnimator != null) { - mAnimator.end(); - mAnimator = null; - } - } - - public void setActivated(Boolean isActivated) { - mIsActivated = isActivated; - } - - public boolean isActivated() { - return mIsActivated != null && mIsActivated; - } - - public boolean isActivatedStateNotSet() { - return mIsActivated == null; - } - - /** - * Dump debug information. - */ - public void dump(PrintWriter pw) { - } - - /** - * Set up any constants needed for computing the matrix. - */ - public abstract void setUp(Context context, boolean needsLinear); - - /** - * Sets the 4x4 matrix to apply. - */ - public abstract void setMatrix(int value); - - /** - * Get the 4x4 matrix to apply. - */ - public abstract float[] getMatrix(); - - /** - * Get the color transform level to apply the matrix. - */ - public abstract int getLevel(); - - /** - * Returns whether or not this transform type is available on this device. - */ - public abstract boolean isAvailable(Context context); - } - private final class NightDisplayTintController extends TintController { private final float[] mMatrix = new float[16]; diff --git a/services/core/java/com/android/server/display/color/GlobalSaturationTintController.java b/services/core/java/com/android/server/display/color/GlobalSaturationTintController.java new file mode 100644 index 000000000000..71fdcc73a57e --- /dev/null +++ b/services/core/java/com/android/server/display/color/GlobalSaturationTintController.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.display.color; + +import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_SATURATION; + +import android.content.Context; +import android.hardware.display.ColorDisplayManager; +import android.opengl.Matrix; +import android.util.Slog; + +import java.util.Arrays; + +/** Control the color transform for global device saturation. */ +public class GlobalSaturationTintController extends TintController { + + private final float[] mMatrixGlobalSaturation = new float[16]; + + @Override + public void setUp(Context context, boolean needsLinear) { + } + + @Override + public float[] getMatrix() { + return Arrays.copyOf(mMatrixGlobalSaturation, mMatrixGlobalSaturation.length); + } + + @Override + public void setMatrix(int saturationLevel) { + if (saturationLevel < 0) { + saturationLevel = 0; + } else if (saturationLevel > 100) { + saturationLevel = 100; + } + Slog.d(ColorDisplayService.TAG, "Setting saturation level: " + saturationLevel); + + if (saturationLevel == 100) { + setActivated(false); + Matrix.setIdentityM(mMatrixGlobalSaturation, 0); + } else { + setActivated(true); + float saturation = saturationLevel * 0.01f; + float desaturation = 1.0f - saturation; + float[] luminance = {0.231f * desaturation, 0.715f * desaturation, + 0.072f * desaturation}; + mMatrixGlobalSaturation[0] = luminance[0] + saturation; + mMatrixGlobalSaturation[1] = luminance[0]; + mMatrixGlobalSaturation[2] = luminance[0]; + mMatrixGlobalSaturation[4] = luminance[1]; + mMatrixGlobalSaturation[5] = luminance[1] + saturation; + mMatrixGlobalSaturation[6] = luminance[1]; + mMatrixGlobalSaturation[8] = luminance[2]; + mMatrixGlobalSaturation[9] = luminance[2]; + mMatrixGlobalSaturation[10] = luminance[2] + saturation; + } + } + + @Override + public int getLevel() { + return LEVEL_COLOR_MATRIX_SATURATION; + } + + @Override + public boolean isAvailable(Context context) { + return ColorDisplayManager.isColorTransformAccelerated(context); + } +} diff --git a/services/core/java/com/android/server/display/color/TintController.java b/services/core/java/com/android/server/display/color/TintController.java new file mode 100644 index 000000000000..b291c645027a --- /dev/null +++ b/services/core/java/com/android/server/display/color/TintController.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.display.color; + +import android.animation.ValueAnimator; +import android.content.Context; + +import java.io.PrintWriter; + +abstract class TintController { + + private ValueAnimator mAnimator; + private Boolean mIsActivated; + + public ValueAnimator getAnimator() { + return mAnimator; + } + + public void setAnimator(ValueAnimator animator) { + mAnimator = animator; + } + + /** + * Cancel the animator if it's still running. + */ + public void cancelAnimator() { + if (mAnimator != null) { + mAnimator.cancel(); + } + } + + /** + * End the animator if it's still running, jumping to the end state. + */ + public void endAnimator() { + if (mAnimator != null) { + mAnimator.end(); + mAnimator = null; + } + } + + public void setActivated(Boolean isActivated) { + mIsActivated = isActivated; + } + + public boolean isActivated() { + return mIsActivated != null && mIsActivated; + } + + public boolean isActivatedStateNotSet() { + return mIsActivated == null; + } + + /** + * Dump debug information. + */ + public void dump(PrintWriter pw) { + } + + /** + * Set up any constants needed for computing the matrix. + */ + public abstract void setUp(Context context, boolean needsLinear); + + /** + * Sets the 4x4 matrix to apply. + */ + public abstract void setMatrix(int value); + + /** + * Get the 4x4 matrix to apply. + */ + public abstract float[] getMatrix(); + + /** + * Get the color transform level to apply the matrix. + */ + public abstract int getLevel(); + + /** + * Returns whether or not this transform type is available on this device. + */ + public abstract boolean isAvailable(Context context); +} diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java index 430203de8268..ed894ee0bee8 100644 --- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java +++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java @@ -131,14 +131,10 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem private final boolean mRefreshServiceOnPackageUpdate; /** - * Name of the service's package that was active but then was removed because its package - * update. - * - * <p>It's a temporary state set / used by the {@link PackageMonitor} implementation, but - * defined here so it can be dumped. + * Name of the service packages whose APK are being updated, keyed by user id. */ @GuardedBy("mLock") - private String mLastActivePackageName; + private SparseArray<String> mUpdatingPackageNames; /** * Default constructor. @@ -565,6 +561,20 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem } /** + * Called before the package that provides the service for the given user is being updated. + */ + protected void onServicePackageUpdatingLocked(@UserIdInt int userId) { + if (verbose) Slog.v(mTag, "onServicePackageUpdatingLocked(" + userId + ")"); + } + + /** + * Called after the package that provides the service for the given user is being updated. + */ + protected void onServicePackageUpdatedLocked(@UserIdInt int userId) { + if (verbose) Slog.v(mTag, "onServicePackageUpdated(" + userId + ")"); + } + + /** * Called after the service is removed from the cache. */ @SuppressWarnings("unused") @@ -602,8 +612,10 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem final int size = mServicesCache.size(); pw.print(prefix); pw.print("Debug: "); pw.print(realDebug); pw.print(" Verbose: "); pw.println(realVerbose); - pw.print(" Refresh on package update: "); pw.println(mRefreshServiceOnPackageUpdate); - pw.print(" Last active service on update: "); pw.println(mLastActivePackageName); + pw.print("Refresh on package update: "); pw.println(mRefreshServiceOnPackageUpdate); + if (mUpdatingPackageNames != null) { + pw.print("Packages being updated: "); pw.println(mUpdatingPackageNames); + } if (mServiceNameResolver != null) { pw.print(prefix); pw.print("Name resolver: "); mServiceNameResolver.dumpShort(pw); pw.println(); @@ -644,39 +656,49 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem final PackageMonitor monitor = new PackageMonitor() { @Override - public void onPackageUpdateStarted(String packageName, int uid) { + public void onPackageUpdateStarted(@NonNull String packageName, int uid) { + if (verbose) Slog.v(mTag, "onPackageUpdateStarted(): " + packageName); + final String activePackageName = getActiveServicePackageNameLocked(); + if (!packageName.equals(activePackageName)) return; + + final int userId = getChangingUserId(); synchronized (mLock) { - final String activePackageName = getActiveServicePackageNameLocked(); - if (packageName.equals(activePackageName)) { - final int userId = getChangingUserId(); - if (mRefreshServiceOnPackageUpdate) { - if (debug) { - Slog.d(mTag, "Removing service for user " + userId - + " because package " + activePackageName - + " is being updated"); - } - mLastActivePackageName = activePackageName; - removeCachedServiceLocked(userId); - } else { - if (debug) { - Slog.d(mTag, "Holding service for user " + userId - + " while package " + activePackageName - + " is being updated"); - } + if (mUpdatingPackageNames == null) { + mUpdatingPackageNames = new SparseArray<String>(mServicesCache.size()); + } + mUpdatingPackageNames.put(userId, packageName); + onServicePackageUpdatingLocked(userId); + if (mRefreshServiceOnPackageUpdate) { + if (debug) { + Slog.d(mTag, "Removing service for user " + userId + " because package " + + activePackageName + " is being updated"); + } + removeCachedServiceLocked(userId); + } else { + if (debug) { + Slog.d(mTag, "Holding service for user " + userId + " while package " + + activePackageName + " is being updated"); } } } } @Override - public void onPackageUpdateFinished(String packageName, int uid) { + public void onPackageUpdateFinished(@NonNull String packageName, int uid) { + if (verbose) Slog.v(mTag, "onPackageUpdateFinished(): " + packageName); + final int userId = getChangingUserId(); synchronized (mLock) { - String activePackageName = getActiveServicePackageNameLocked(); - if (activePackageName == null) { - activePackageName = mLastActivePackageName; - mLastActivePackageName = null; - } - if (!packageName.equals(activePackageName)) { + final String activePackageName = mUpdatingPackageNames == null ? null + : mUpdatingPackageNames.get(userId); + if (packageName.equals(activePackageName)) { + if (mUpdatingPackageNames != null) { + mUpdatingPackageNames.remove(userId); + if (mUpdatingPackageNames.size() == 0) { + mUpdatingPackageNames = null; + } + } + onServicePackageUpdatedLocked(userId); + } else { handlePackageUpdateLocked(packageName); } } diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index 293813add594..3e134b266a88 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -21,6 +21,9 @@ import static android.Manifest.permission.READ_CONTACTS; import static android.content.Context.KEYGUARD_SERVICE; import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE; +import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD; +import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN; import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback; import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_ENABLED_KEY; import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_HANDLE_KEY; @@ -106,6 +109,7 @@ import com.android.internal.util.Preconditions; import com.android.internal.widget.ICheckCredentialProgressCallback; import com.android.internal.widget.ILockSettings; import com.android.internal.widget.LockPatternUtils; +import com.android.internal.widget.LockPatternUtils.CredentialType; import com.android.internal.widget.LockSettingsInternal; import com.android.internal.widget.VerifyCredentialResponse; import com.android.server.LocalServices; @@ -319,8 +323,8 @@ public class LockSettingsService extends ILockSettings.Stub { } Arrays.fill(newPasswordChars, '\u0000'); final int quality = DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC; - setLockCredentialInternal(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, - managedUserPassword, quality, managedUserId); + setLockCredentialInternal(newPassword, CREDENTIAL_TYPE_PASSWORD, managedUserPassword, + quality, managedUserId, false); // We store a private credential for the managed user that's unlocked by the primary // account holder's credential. As such, the user will never be prompted to enter this // password directly, so we always store a password. @@ -1082,13 +1086,12 @@ public class LockSettingsService extends ILockSettings.Stub { } @Override - public boolean havePassword(int userId) throws RemoteException { + public boolean havePassword(int userId) { checkPasswordHavePermission(userId); synchronized (mSpManager) { if (isSyntheticPasswordBasedCredentialLocked(userId)) { - long handle = getSyntheticPasswordHandleLocked(userId); - return mSpManager.getCredentialType(handle, userId) == - LockPatternUtils.CREDENTIAL_TYPE_PASSWORD; + final long handle = getSyntheticPasswordHandleLocked(userId); + return mSpManager.getCredentialType(handle, userId) == CREDENTIAL_TYPE_PASSWORD; } } // Do we need a permissions check here? @@ -1096,13 +1099,12 @@ public class LockSettingsService extends ILockSettings.Stub { } @Override - public boolean havePattern(int userId) throws RemoteException { + public boolean havePattern(int userId) { checkPasswordHavePermission(userId); synchronized (mSpManager) { if (isSyntheticPasswordBasedCredentialLocked(userId)) { - long handle = getSyntheticPasswordHandleLocked(userId); - return mSpManager.getCredentialType(handle, userId) == - LockPatternUtils.CREDENTIAL_TYPE_PATTERN; + final long handle = getSyntheticPasswordHandleLocked(userId); + return mSpManager.getCredentialType(handle, userId) == CREDENTIAL_TYPE_PATTERN; } } // Do we need a permissions check here? @@ -1112,9 +1114,8 @@ public class LockSettingsService extends ILockSettings.Stub { private boolean isUserSecure(int userId) { synchronized (mSpManager) { if (isSyntheticPasswordBasedCredentialLocked(userId)) { - long handle = getSyntheticPasswordHandleLocked(userId); - return mSpManager.getCredentialType(handle, userId) != - LockPatternUtils.CREDENTIAL_TYPE_NONE; + final long handle = getSyntheticPasswordHandleLocked(userId); + return mSpManager.getCredentialType(handle, userId) != CREDENTIAL_TYPE_NONE; } } return mStorage.hasCredential(userId); @@ -1167,7 +1168,7 @@ public class LockSettingsService extends ILockSettings.Stub { throws RemoteException { try { doVerifyCredential(getDecryptedPasswordForTiedProfile(profileHandle), - LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, + CREDENTIAL_TYPE_PASSWORD, false, 0 /* no challenge */, profileHandle, null /* progressCallback */); } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException | NoSuchAlgorithmException | NoSuchPaddingException @@ -1299,14 +1300,16 @@ public class LockSettingsService extends ILockSettings.Stub { // We use cached work profile password computed before clearing the parent's // credential, otherwise they get lost if (profilePasswordMap != null && profilePasswordMap.containsKey(managedUserId)) { - setLockCredentialInternal(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, + setLockCredentialInternal(null, CREDENTIAL_TYPE_NONE, profilePasswordMap.get(managedUserId), - DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId); + DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId, + false); } else { Slog.wtf(TAG, "clear tied profile challenges, but no password supplied."); // Supplying null here would lead to untrusted credential change - setLockCredentialInternal(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, null, - DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId); + setLockCredentialInternal(null, CREDENTIAL_TYPE_NONE, null, + DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId, + true); } mStorage.removeChildProfileLock(managedUserId); removeKeystoreProfileKey(managedUserId); @@ -1329,8 +1332,8 @@ public class LockSettingsService extends ILockSettings.Stub { // should call setLockCredentialInternal. @Override public void setLockCredential(byte[] credential, int type, - byte[] savedCredential, int requestedQuality, int userId) - throws RemoteException { + byte[] savedCredential, int requestedQuality, int userId, + boolean allowUntrustedChange) throws RemoteException { if (!mLockPatternUtils.hasSecureLockScreen()) { throw new UnsupportedOperationException( @@ -1338,15 +1341,17 @@ public class LockSettingsService extends ILockSettings.Stub { } checkWritePermission(userId); synchronized (mSeparateChallengeLock) { - setLockCredentialInternal(credential, type, savedCredential, requestedQuality, userId); + setLockCredentialInternal(credential, type, savedCredential, requestedQuality, userId, + allowUntrustedChange); setSeparateProfileChallengeEnabledLocked(userId, true, null); notifyPasswordChanged(userId); } notifySeparateProfileChallengeChanged(userId); } - private void setLockCredentialInternal(byte[] credential, int credentialType, - byte[] savedCredential, int requestedQuality, int userId) throws RemoteException { + private void setLockCredentialInternal(byte[] credential, @CredentialType int credentialType, + byte[] savedCredential, int requestedQuality, int userId, + boolean allowUntrustedChange) throws RemoteException { // Normalize savedCredential and credential such that empty string is always represented // as null. if (savedCredential == null || savedCredential.length == 0) { @@ -1358,12 +1363,12 @@ public class LockSettingsService extends ILockSettings.Stub { synchronized (mSpManager) { if (isSyntheticPasswordBasedCredentialLocked(userId)) { spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential, - requestedQuality, userId); + requestedQuality, userId, allowUntrustedChange); return; } } - if (credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) { + if (credentialType == CREDENTIAL_TYPE_NONE) { if (credential != null) { Slog.wtf(TAG, "CredentialType is none, but credential is non-null."); } @@ -1373,7 +1378,7 @@ public class LockSettingsService extends ILockSettings.Stub { setKeystorePassword(null, userId); fixateNewestUserKeyAuth(userId); synchronizeUnifiedWorkChallengeForProfiles(userId, null); - notifyActivePasswordMetricsAvailable(null, userId); + notifyActivePasswordMetricsAvailable(CREDENTIAL_TYPE_NONE, null, userId); mRecoverableKeyStoreManager.lockScreenSecretChanged(credentialType, credential, userId); return; } @@ -1409,7 +1414,7 @@ public class LockSettingsService extends ILockSettings.Stub { initializeSyntheticPasswordLocked(currentHandle.hash, savedCredential, currentHandle.type, requestedQuality, userId); spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential, - requestedQuality, userId); + requestedQuality, userId, allowUntrustedChange); return; } } @@ -1431,8 +1436,7 @@ public class LockSettingsService extends ILockSettings.Stub { userId); } else { throw new RemoteException("Failed to enroll " + - (credentialType == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD ? "password" - : "pattern")); + (credentialType == CREDENTIAL_TYPE_PASSWORD ? "password" : "pattern")); } } @@ -1688,7 +1692,7 @@ public class LockSettingsService extends ILockSettings.Stub { return VerifyCredentialResponse.ERROR; } - boolean shouldReEnrollBaseZero = storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN + boolean shouldReEnrollBaseZero = storedHash.type == CREDENTIAL_TYPE_PATTERN && storedHash.isBaseZeroPattern; byte[] credentialToVerify; @@ -1705,7 +1709,7 @@ public class LockSettingsService extends ILockSettings.Stub { mStrongAuth.reportSuccessfulStrongAuthUnlock(userId); if (shouldReEnrollBaseZero) { setLockCredentialInternal(credential, storedHash.type, credentialToVerify, - DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId); + DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId, false); } } @@ -1736,7 +1740,7 @@ public class LockSettingsService extends ILockSettings.Stub { try { // Unlock work profile, and work profile with unified lock must use password only return doVerifyCredential(getDecryptedPasswordForTiedProfile(userId), - LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, + CREDENTIAL_TYPE_PASSWORD, true, challenge, userId, null /* progressCallback */); @@ -1773,14 +1777,14 @@ public class LockSettingsService extends ILockSettings.Stub { if (storedHash.version == CredentialHash.VERSION_LEGACY) { final byte[] hash; - if (storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) { + if (storedHash.type == CREDENTIAL_TYPE_PATTERN) { hash = LockPatternUtils.patternToHash( LockPatternUtils.byteArrayToPattern(credential)); } else { hash = mLockPatternUtils.legacyPasswordToHash(credential, userId).getBytes(); } if (Arrays.equals(hash, storedHash.hash)) { - if (storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) { + if (storedHash.type == CREDENTIAL_TYPE_PATTERN) { unlockKeystore(LockPatternUtils.patternByteArrayToBaseZero(credential), userId); } else { unlockKeystore(credential, userId); @@ -1793,12 +1797,12 @@ public class LockSettingsService extends ILockSettings.Stub { // migrate credential to GateKeeper setLockCredentialInternal(credential, storedHash.type, null, - storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN + storedHash.type == CREDENTIAL_TYPE_PATTERN ? DevicePolicyManager.PASSWORD_QUALITY_SOMETHING : DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC - /* TODO(roosa): keep the same password quality */, userId); + /* TODO(roosa): keep the same password quality */, userId, false); if (!hasChallenge) { - notifyActivePasswordMetricsAvailable(credential, userId); + notifyActivePasswordMetricsAvailable(storedHash.type, credential, userId); // Use credentials to create recoverable keystore snapshot. mRecoverableKeyStoreManager.lockScreenSecretAvailable( storedHash.type, credential, userId); @@ -1823,7 +1827,7 @@ public class LockSettingsService extends ILockSettings.Stub { if (progressCallback != null) { progressCallback.onCredentialVerified(); } - notifyActivePasswordMetricsAvailable(credential, userId); + notifyActivePasswordMetricsAvailable(storedHash.type, credential, userId); unlockKeystore(credential, userId); Slog.i(TAG, "Unlocking user " + userId + " with token length " @@ -1835,13 +1839,13 @@ public class LockSettingsService extends ILockSettings.Stub { (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE); trustManager.setDeviceLockedForUser(userId, false); } - int reEnrollQuality = storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN + int reEnrollQuality = storedHash.type == CREDENTIAL_TYPE_PATTERN ? DevicePolicyManager.PASSWORD_QUALITY_SOMETHING : DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC /* TODO(roosa): keep the same password quality */; if (shouldReEnroll) { setLockCredentialInternal(credential, storedHash.type, credential, - reEnrollQuality, userId); + reEnrollQuality, userId, false); } else { // Now that we've cleared of all required GK migration, let's do the final // migration to synthetic password. @@ -1871,18 +1875,14 @@ public class LockSettingsService extends ILockSettings.Stub { * Call this method to notify DPMS regarding the latest password metric. This should be called * when the user is authenticating or when a new password is being set. */ - private void notifyActivePasswordMetricsAvailable(byte[] password, @UserIdInt int userId) { - final PasswordMetrics metrics; - if (password == null) { - metrics = new PasswordMetrics(); - } else { - metrics = PasswordMetrics.computeForPassword(password); - metrics.quality = mLockPatternUtils.getKeyguardStoredPasswordQuality(userId); - } + private void notifyActivePasswordMetricsAvailable( + @CredentialType int credentialType, byte[] password, @UserIdInt int userId) { + final PasswordMetrics metrics = + PasswordMetrics.computeForCredential(credentialType, password); // Asynchronous to avoid dead lock mHandler.post(() -> { - DevicePolicyManager dpm = (DevicePolicyManager) + final DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); dpm.setActivePasswordState(metrics, userId); }); @@ -1935,7 +1935,7 @@ public class LockSettingsService extends ILockSettings.Stub { try { if (mLockPatternUtils.isLockPatternEnabled(userId)) { - if (checkCredential(password.getBytes(), LockPatternUtils.CREDENTIAL_TYPE_PATTERN, + if (checkCredential(password.getBytes(), CREDENTIAL_TYPE_PATTERN, userId, null /* progressCallback */) .getResponseCode() == GateKeeperResponse.RESPONSE_OK) { return true; @@ -1946,7 +1946,7 @@ public class LockSettingsService extends ILockSettings.Stub { try { if (mLockPatternUtils.isLockPasswordEnabled(userId)) { - if (checkCredential(password.getBytes(), LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, + if (checkCredential(password.getBytes(), CREDENTIAL_TYPE_PASSWORD, userId, null /* progressCallback */) .getResponseCode() == GateKeeperResponse.RESPONSE_OK) { return true; @@ -2392,11 +2392,11 @@ public class LockSettingsService extends ILockSettings.Stub { setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1, UserHandle.USER_SYSTEM); } - private VerifyCredentialResponse spBasedDoVerifyCredential(byte[] userCredential, int - credentialType, boolean hasChallenge, long challenge, int userId, + private VerifyCredentialResponse spBasedDoVerifyCredential(byte[] userCredential, + @CredentialType int credentialType, boolean hasChallenge, long challenge, int userId, ICheckCredentialProgressCallback progressCallback) throws RemoteException { if (DEBUG) Slog.d(TAG, "spBasedDoVerifyCredential: user=" + userId); - if (credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) { + if (credentialType == CREDENTIAL_TYPE_NONE) { userCredential = null; } @@ -2444,7 +2444,7 @@ public class LockSettingsService extends ILockSettings.Stub { } if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) { - notifyActivePasswordMetricsAvailable(userCredential, userId); + notifyActivePasswordMetricsAvailable(credentialType, userCredential, userId); unlockKeystore(authResult.authToken.deriveKeyStorePassword(), userId); // Reset lockout if (mInjector.hasBiometrics()) { @@ -2491,8 +2491,9 @@ public class LockSettingsService extends ILockSettings.Stub { * added back when new password is set in future. */ @GuardedBy("mSpManager") - private long setLockCredentialWithAuthTokenLocked(byte[] credential, int credentialType, - AuthenticationToken auth, int requestedQuality, int userId) throws RemoteException { + private long setLockCredentialWithAuthTokenLocked(byte[] credential, + @CredentialType int credentialType, AuthenticationToken auth, int requestedQuality, + int userId) throws RemoteException { if (DEBUG) Slog.d(TAG, "setLockCredentialWithAuthTokenLocked: user=" + userId); long newHandle = mSpManager.createPasswordBasedSyntheticPassword(getGateKeeperService(), credential, credentialType, auth, requestedQuality, userId); @@ -2534,7 +2535,7 @@ public class LockSettingsService extends ILockSettings.Stub { setLong(SYNTHETIC_PASSWORD_HANDLE_KEY, newHandle, userId); synchronizeUnifiedWorkChallengeForProfiles(userId, profilePasswords); - notifyActivePasswordMetricsAvailable(credential, userId); + notifyActivePasswordMetricsAvailable(credentialType, credential, userId); if (profilePasswords != null) { for (Map.Entry<Integer, byte[]> entry : profilePasswords.entrySet()) { @@ -2547,7 +2548,8 @@ public class LockSettingsService extends ILockSettings.Stub { @GuardedBy("mSpManager") private void spBasedSetLockCredentialInternalLocked(byte[] credential, int credentialType, - byte[] savedCredential, int requestedQuality, int userId) throws RemoteException { + byte[] savedCredential, int requestedQuality, int userId, + boolean allowUntrustedChange) throws RemoteException { if (DEBUG) Slog.d(TAG, "spBasedSetLockCredentialInternalLocked: user=" + userId); if (isManagedProfileWithUnifiedLock(userId)) { // get credential from keystore when managed profile has unified lock @@ -2568,28 +2570,31 @@ public class LockSettingsService extends ILockSettings.Stub { VerifyCredentialResponse response = authResult.gkResponse; AuthenticationToken auth = authResult.authToken; - // If existing credential is provided, then it must match. + // If existing credential is provided, the existing credential must match. if (savedCredential != null && auth == null) { - throw new RemoteException("Failed to enroll " + - (credentialType == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD ? "password" - : "pattern")); + throw new IllegalStateException("Failed to enroll " + + (credentialType == CREDENTIAL_TYPE_PASSWORD + ? "password" : "pattern")); } - boolean untrustedReset = false; if (auth != null) { onAuthTokenKnownForUser(userId, auth); - } else if (response != null - && response.getResponseCode() == VerifyCredentialResponse.RESPONSE_ERROR) { + } else if (response == null) { + throw new IllegalStateException("Password change failed."); + } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_ERROR) { // We are performing an untrusted credential change, by DevicePolicyManager or other // internal callers that don't provide the existing credential Slog.w(TAG, "Untrusted credential change invoked"); // Try to get a cached auth token, so we can keep SP unchanged. auth = mSpCache.get(userId); + if (!allowUntrustedChange) { + throw new IllegalStateException("Untrusted credential change was invoked but it was" + + " not allowed. This is likely a bug. Auth token is null: " + + Boolean.toString(auth == null)); + } untrustedReset = true; - } else /* response == null || responseCode == VerifyCredentialResponse.RESPONSE_RETRY */ { - Slog.w(TAG, "spBasedSetLockCredentialInternalLocked: " + - (response != null ? "rate limit exceeded" : "failed")); - return; + } else /* responseCode == VerifyCredentialResponse.RESPONSE_RETRY */ { + throw new IllegalStateException("Rate limit exceeded, so password was not changed."); } if (auth != null) { @@ -2660,7 +2665,7 @@ public class LockSettingsService extends ILockSettings.Stub { if (!isUserSecure(userId)) { if (shouldMigrateToSyntheticPasswordLocked(userId)) { auth = initializeSyntheticPasswordLocked(null, null, - LockPatternUtils.CREDENTIAL_TYPE_NONE, + CREDENTIAL_TYPE_NONE, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userId); } else /* isSyntheticPasswordBasedCredentialLocked(userId) */ { long pwdHandle = getSyntheticPasswordHandleLocked(userId); diff --git a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java index 2ede384f3edf..f0e431ee0354 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java @@ -37,6 +37,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.internal.util.Preconditions; import com.android.internal.widget.LockPatternUtils; +import com.android.internal.widget.LockPatternUtils.CredentialType; import com.android.server.LocalServices; import com.android.server.PersistentDataBlockManagerInternal; @@ -96,11 +97,12 @@ class LockSettingsStorage { static final int VERSION_LEGACY = 0; static final int VERSION_GATEKEEPER = 1; - private CredentialHash(byte[] hash, int type, int version) { + private CredentialHash(byte[] hash, @CredentialType int type, int version) { this(hash, type, version, false /* isBaseZeroPattern */); } - private CredentialHash(byte[] hash, int type, int version, boolean isBaseZeroPattern) { + private CredentialHash( + byte[] hash, @CredentialType int type, int version, boolean isBaseZeroPattern) { if (type != LockPatternUtils.CREDENTIAL_TYPE_NONE) { if (hash == null) { throw new RuntimeException("Empty hash for CredentialHash"); @@ -134,7 +136,7 @@ class LockSettingsStorage { } byte[] hash; - int type; + @CredentialType int type; int version; boolean isBaseZeroPattern; diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java index 7b691b411a99..e0fb9e7e679f 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecord.java +++ b/services/core/java/com/android/server/media/MediaSessionRecord.java @@ -29,13 +29,13 @@ import android.media.Rating; import android.media.VolumeProvider; import android.media.session.ControllerCallbackLink; import android.media.session.ISession; +import android.media.session.ISessionCallback; import android.media.session.ISessionController; import android.media.session.MediaController; import android.media.session.MediaController.PlaybackInfo; import android.media.session.MediaSession; import android.media.session.MediaSession.QueueItem; import android.media.session.PlaybackState; -import android.media.session.SessionCallbackLink; import android.net.Uri; import android.os.Binder; import android.os.Bundle; @@ -124,7 +124,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { private String mMetadataDescription; public MediaSessionRecord(int ownerPid, int ownerUid, int userId, String ownerPackageName, - SessionCallbackLink cb, String tag, Bundle sessionInfo, + ISessionCallback cb, String tag, Bundle sessionInfo, MediaSessionService.ServiceImpl service, Looper handlerLooper) { mOwnerPid = ownerPid; mOwnerUid = ownerUid; @@ -460,7 +460,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { } } - public SessionCallbackLink getCallback() { + public ISessionCallback getCallback() { return mSessionCb.mCb; } @@ -1003,9 +1003,9 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { } class SessionCb { - private final SessionCallbackLink mCb; + private final ISessionCallback mCb; - SessionCb(SessionCallbackLink cb) { + SessionCb(ISessionCallback cb) { mCb = cb; } @@ -1013,14 +1013,14 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { boolean asSystemService, KeyEvent keyEvent, int sequenceId, ResultReceiver cb) { try { if (asSystemService) { - mCb.notifyMediaButton(mContext.getPackageName(), Process.myPid(), + mCb.onMediaButton(mContext.getPackageName(), Process.myPid(), Process.SYSTEM_UID, createMediaButtonIntent(keyEvent), sequenceId, cb); } else { - mCb.notifyMediaButton(packageName, pid, uid, + mCb.onMediaButton(packageName, pid, uid, createMediaButtonIntent(keyEvent), sequenceId, cb); } return true; - } catch (RuntimeException e) { + } catch (RemoteException e) { Slog.e(TAG, "Remote failure in sendMediaRequest.", e); } return false; @@ -1031,14 +1031,14 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { KeyEvent keyEvent) { try { if (asSystemService) { - mCb.notifyMediaButton(mContext.getPackageName(), Process.myPid(), + mCb.onMediaButton(mContext.getPackageName(), Process.myPid(), Process.SYSTEM_UID, createMediaButtonIntent(keyEvent), 0, null); } else { - mCb.notifyMediaButtonFromController(packageName, pid, uid, caller, + mCb.onMediaButtonFromController(packageName, pid, uid, caller, createMediaButtonIntent(keyEvent)); } return true; - } catch (RuntimeException e) { + } catch (RemoteException e) { Slog.e(TAG, "Remote failure in sendMediaRequest.", e); } return false; @@ -1047,8 +1047,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { public void sendCommand(String packageName, int pid, int uid, ControllerCallbackLink caller, String command, Bundle args, ResultReceiver cb) { try { - mCb.notifyCommand(packageName, pid, uid, caller, command, args, cb); - } catch (RuntimeException e) { + mCb.onCommand(packageName, pid, uid, caller, command, args, cb); + } catch (RemoteException e) { Slog.e(TAG, "Remote failure in sendCommand.", e); } } @@ -1057,8 +1057,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { ControllerCallbackLink caller, String action, Bundle args) { try { - mCb.notifyCustomAction(packageName, pid, uid, caller, action, args); - } catch (RuntimeException e) { + mCb.onCustomAction(packageName, pid, uid, caller, action, args); + } catch (RemoteException e) { Slog.e(TAG, "Remote failure in sendCustomAction.", e); } } @@ -1066,8 +1066,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { public void prepare(String packageName, int pid, int uid, ControllerCallbackLink caller) { try { - mCb.notifyPrepare(packageName, pid, uid, caller); - } catch (RuntimeException e) { + mCb.onPrepare(packageName, pid, uid, caller); + } catch (RemoteException e) { Slog.e(TAG, "Remote failure in prepare.", e); } } @@ -1075,8 +1075,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { public void prepareFromMediaId(String packageName, int pid, int uid, ControllerCallbackLink caller, String mediaId, Bundle extras) { try { - mCb.notifyPrepareFromMediaId(packageName, pid, uid, caller, mediaId, extras); - } catch (RuntimeException e) { + mCb.onPrepareFromMediaId(packageName, pid, uid, caller, mediaId, extras); + } catch (RemoteException e) { Slog.e(TAG, "Remote failure in prepareFromMediaId.", e); } } @@ -1084,8 +1084,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { public void prepareFromSearch(String packageName, int pid, int uid, ControllerCallbackLink caller, String query, Bundle extras) { try { - mCb.notifyPrepareFromSearch(packageName, pid, uid, caller, query, extras); - } catch (RuntimeException e) { + mCb.onPrepareFromSearch(packageName, pid, uid, caller, query, extras); + } catch (RemoteException e) { Slog.e(TAG, "Remote failure in prepareFromSearch.", e); } } @@ -1093,16 +1093,16 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { public void prepareFromUri(String packageName, int pid, int uid, ControllerCallbackLink caller, Uri uri, Bundle extras) { try { - mCb.notifyPrepareFromUri(packageName, pid, uid, caller, uri, extras); - } catch (RuntimeException e) { + mCb.onPrepareFromUri(packageName, pid, uid, caller, uri, extras); + } catch (RemoteException e) { Slog.e(TAG, "Remote failure in prepareFromUri.", e); } } public void play(String packageName, int pid, int uid, ControllerCallbackLink caller) { try { - mCb.notifyPlay(packageName, pid, uid, caller); - } catch (RuntimeException e) { + mCb.onPlay(packageName, pid, uid, caller); + } catch (RemoteException e) { Slog.e(TAG, "Remote failure in play.", e); } } @@ -1110,8 +1110,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { public void playFromMediaId(String packageName, int pid, int uid, ControllerCallbackLink caller, String mediaId, Bundle extras) { try { - mCb.notifyPlayFromMediaId(packageName, pid, uid, caller, mediaId, extras); - } catch (RuntimeException e) { + mCb.onPlayFromMediaId(packageName, pid, uid, caller, mediaId, extras); + } catch (RemoteException e) { Slog.e(TAG, "Remote failure in playFromMediaId.", e); } } @@ -1119,8 +1119,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { public void playFromSearch(String packageName, int pid, int uid, ControllerCallbackLink caller, String query, Bundle extras) { try { - mCb.notifyPlayFromSearch(packageName, pid, uid, caller, query, extras); - } catch (RuntimeException e) { + mCb.onPlayFromSearch(packageName, pid, uid, caller, query, extras); + } catch (RemoteException e) { Slog.e(TAG, "Remote failure in playFromSearch.", e); } } @@ -1128,8 +1128,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { public void playFromUri(String packageName, int pid, int uid, ControllerCallbackLink caller, Uri uri, Bundle extras) { try { - mCb.notifyPlayFromUri(packageName, pid, uid, caller, uri, extras); - } catch (RuntimeException e) { + mCb.onPlayFromUri(packageName, pid, uid, caller, uri, extras); + } catch (RemoteException e) { Slog.e(TAG, "Remote failure in playFromUri.", e); } } @@ -1137,32 +1137,32 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { public void skipToTrack(String packageName, int pid, int uid, ControllerCallbackLink caller, long id) { try { - mCb.notifySkipToTrack(packageName, pid, uid, caller, id); - } catch (RuntimeException e) { + mCb.onSkipToTrack(packageName, pid, uid, caller, id); + } catch (RemoteException e) { Slog.e(TAG, "Remote failure in skipToTrack", e); } } public void pause(String packageName, int pid, int uid, ControllerCallbackLink caller) { try { - mCb.notifyPause(packageName, pid, uid, caller); - } catch (RuntimeException e) { + mCb.onPause(packageName, pid, uid, caller); + } catch (RemoteException e) { Slog.e(TAG, "Remote failure in pause.", e); } } public void stop(String packageName, int pid, int uid, ControllerCallbackLink caller) { try { - mCb.notifyStop(packageName, pid, uid, caller); - } catch (RuntimeException e) { + mCb.onStop(packageName, pid, uid, caller); + } catch (RemoteException e) { Slog.e(TAG, "Remote failure in stop.", e); } } public void next(String packageName, int pid, int uid, ControllerCallbackLink caller) { try { - mCb.notifyNext(packageName, pid, uid, caller); - } catch (RuntimeException e) { + mCb.onNext(packageName, pid, uid, caller); + } catch (RemoteException e) { Slog.e(TAG, "Remote failure in next.", e); } } @@ -1170,8 +1170,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { public void previous(String packageName, int pid, int uid, ControllerCallbackLink caller) { try { - mCb.notifyPrevious(packageName, pid, uid, caller); - } catch (RuntimeException e) { + mCb.onPrevious(packageName, pid, uid, caller); + } catch (RemoteException e) { Slog.e(TAG, "Remote failure in previous.", e); } } @@ -1179,8 +1179,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { public void fastForward(String packageName, int pid, int uid, ControllerCallbackLink caller) { try { - mCb.notifyFastForward(packageName, pid, uid, caller); - } catch (RuntimeException e) { + mCb.onFastForward(packageName, pid, uid, caller); + } catch (RemoteException e) { Slog.e(TAG, "Remote failure in fastForward.", e); } } @@ -1188,8 +1188,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { public void rewind(String packageName, int pid, int uid, ControllerCallbackLink caller) { try { - mCb.notifyRewind(packageName, pid, uid, caller); - } catch (RuntimeException e) { + mCb.onRewind(packageName, pid, uid, caller); + } catch (RemoteException e) { Slog.e(TAG, "Remote failure in rewind.", e); } } @@ -1197,8 +1197,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { public void seekTo(String packageName, int pid, int uid, ControllerCallbackLink caller, long pos) { try { - mCb.notifySeekTo(packageName, pid, uid, caller, pos); - } catch (RuntimeException e) { + mCb.onSeekTo(packageName, pid, uid, caller, pos); + } catch (RemoteException e) { Slog.e(TAG, "Remote failure in seekTo.", e); } } @@ -1206,8 +1206,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { public void rate(String packageName, int pid, int uid, ControllerCallbackLink caller, Rating rating) { try { - mCb.notifyRate(packageName, pid, uid, caller, rating); - } catch (RuntimeException e) { + mCb.onRate(packageName, pid, uid, caller, rating); + } catch (RemoteException e) { Slog.e(TAG, "Remote failure in rate.", e); } } @@ -1215,8 +1215,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { public void setPlaybackSpeed(String packageName, int pid, int uid, ControllerCallbackLink caller, float speed) { try { - mCb.notifySetPlaybackSpeed(packageName, pid, uid, caller, speed); - } catch (RuntimeException e) { + mCb.onSetPlaybackSpeed(packageName, pid, uid, caller, speed); + } catch (RemoteException e) { Slog.e(TAG, "Remote failure in setPlaybackSpeed.", e); } } @@ -1225,12 +1225,12 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { ControllerCallbackLink caller, boolean asSystemService, int direction) { try { if (asSystemService) { - mCb.notifyAdjustVolume(mContext.getPackageName(), Process.myPid(), + mCb.onAdjustVolume(mContext.getPackageName(), Process.myPid(), Process.SYSTEM_UID, null, direction); } else { - mCb.notifyAdjustVolume(packageName, pid, uid, caller, direction); + mCb.onAdjustVolume(packageName, pid, uid, caller, direction); } - } catch (RuntimeException e) { + } catch (RemoteException e) { Slog.e(TAG, "Remote failure in adjustVolume.", e); } } @@ -1238,8 +1238,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { public void setVolumeTo(String packageName, int pid, int uid, ControllerCallbackLink caller, int value) { try { - mCb.notifySetVolumeTo(packageName, pid, uid, caller, value); - } catch (RuntimeException e) { + mCb.onSetVolumeTo(packageName, pid, uid, caller, value); + } catch (RemoteException e) { Slog.e(TAG, "Remote failure in setVolumeTo.", e); } } diff --git a/services/core/java/com/android/server/media/MediaSessionServiceImpl.java b/services/core/java/com/android/server/media/MediaSessionServiceImpl.java index 7c8dc745f6f7..3acad7a9c70a 100644 --- a/services/core/java/com/android/server/media/MediaSessionServiceImpl.java +++ b/services/core/java/com/android/server/media/MediaSessionServiceImpl.java @@ -51,10 +51,10 @@ import android.media.session.IOnMediaKeyListener; import android.media.session.IOnVolumeKeyLongPressListener; import android.media.session.ISession; import android.media.session.ISession2TokensListener; +import android.media.session.ISessionCallback; import android.media.session.ISessionManager; import android.media.session.MediaSession; import android.media.session.MediaSessionManager; -import android.media.session.SessionCallbackLink; import android.net.Uri; import android.os.Binder; import android.os.Bundle; @@ -467,7 +467,7 @@ public class MediaSessionServiceImpl extends MediaSessionService.ServiceImpl { } try { - session.getCallback().getBinder().unlinkToDeath(session, 0); + session.getCallback().asBinder().unlinkToDeath(session, 0); } catch (Exception e) { // ignore exceptions while destroying a session. } @@ -553,7 +553,7 @@ public class MediaSessionServiceImpl extends MediaSessionService.ServiceImpl { } private MediaSessionRecord createSessionInternal(int callerPid, int callerUid, int userId, - String callerPackageName, SessionCallbackLink cb, String tag, Bundle sessionInfo) + String callerPackageName, ISessionCallback cb, String tag, Bundle sessionInfo) throws RemoteException { synchronized (mLock) { return createSessionLocked(callerPid, callerUid, userId, callerPackageName, cb, @@ -569,7 +569,7 @@ public class MediaSessionServiceImpl extends MediaSessionService.ServiceImpl { * 4. It needs to be added to the relevant user record. */ private MediaSessionRecord createSessionLocked(int callerPid, int callerUid, int userId, - String callerPackageName, SessionCallbackLink cb, String tag, Bundle sessionInfo) { + String callerPackageName, ISessionCallback cb, String tag, Bundle sessionInfo) { FullUserRecord user = getFullUserRecordLocked(userId); if (user == null) { Log.w(TAG, "Request from invalid user: " + userId + ", pkg=" + callerPackageName); @@ -579,7 +579,7 @@ public class MediaSessionServiceImpl extends MediaSessionService.ServiceImpl { final MediaSessionRecord session = new MediaSessionRecord(callerPid, callerUid, userId, callerPackageName, cb, tag, sessionInfo, this, mHandler.getLooper()); try { - cb.getBinder().linkToDeath(session, 0); + cb.asBinder().linkToDeath(session, 0); } catch (RemoteException e) { throw new RuntimeException("Media Session owner died prematurely.", e); } @@ -1001,7 +1001,7 @@ public class MediaSessionServiceImpl extends MediaSessionService.ServiceImpl { private boolean mVoiceButtonHandled = false; @Override - public ISession createSession(String packageName, SessionCallbackLink cb, String tag, + public ISession createSession(String packageName, ISessionCallback cb, String tag, Bundle sessionInfo, int userId) throws RemoteException { final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java index 3872523492a7..1f1ba203e716 100644 --- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java +++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java @@ -63,6 +63,7 @@ import java.util.Map; */ public final class MediaProjectionManagerService extends SystemService implements Watchdog.Monitor { + private static final boolean REQUIRE_FG_SERVICE_FOR_PROJECTION = false; private static final String TAG = "MediaProjectionManagerService"; private final Object mLock = new Object(); // Protects the list of media projections @@ -100,21 +101,23 @@ public final class MediaProjectionManagerService extends SystemService false /*allowIsolated*/); mMediaRouter.addCallback(MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY, mMediaRouterCallback, MediaRouter.CALLBACK_FLAG_PASSIVE_DISCOVERY); - mActivityManagerInternal.registerProcessObserver(new IProcessObserver.Stub() { - @Override - public void onForegroundActivitiesChanged(int pid, int uid, boolean fg) { - } + if (REQUIRE_FG_SERVICE_FOR_PROJECTION) { + mActivityManagerInternal.registerProcessObserver(new IProcessObserver.Stub() { + @Override + public void onForegroundActivitiesChanged(int pid, int uid, boolean fg) { + } - @Override - public void onForegroundServicesChanged(int pid, int uid, int serviceTypes) { - MediaProjectionManagerService.this.handleForegroundServicesChanged(pid, uid, - serviceTypes); - } + @Override + public void onForegroundServicesChanged(int pid, int uid, int serviceTypes) { + MediaProjectionManagerService.this.handleForegroundServicesChanged(pid, uid, + serviceTypes); + } - @Override - public void onProcessDied(int pid, int uid) { - } - }); + @Override + public void onProcessDied(int pid, int uid) { + } + }); + } } @Override @@ -462,7 +465,8 @@ public final class MediaProjectionManagerService extends SystemService return; } - if (targetSdkVersion >= Build.VERSION_CODES.Q + if (REQUIRE_FG_SERVICE_FOR_PROJECTION + && targetSdkVersion >= Build.VERSION_CODES.Q && !mActivityManagerInternal.hasRunningForegroundService( uid, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION)) { throw new SecurityException("Media projections require a foreground service" diff --git a/services/core/java/com/android/server/media/projection/OWNERS b/services/core/java/com/android/server/media/projection/OWNERS new file mode 100644 index 000000000000..7e7335d68d3b --- /dev/null +++ b/services/core/java/com/android/server/media/projection/OWNERS @@ -0,0 +1 @@ +michaelwr@google.com diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index ca3c826d77dd..dddb7efca50b 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -4107,7 +4107,17 @@ public class NotificationManagerService extends SystemService { return; } if (adjustment.getSignals() != null) { - Bundle.setDefusable(adjustment.getSignals(), true); + final Bundle adjustments = adjustment.getSignals(); + Bundle.setDefusable(adjustments, true); + List<String> toRemove = new ArrayList<>(); + for (String potentialKey : adjustments.keySet()) { + if (!mAssistants.isAdjustmentAllowed(potentialKey)) { + toRemove.add(potentialKey); + } + } + for (String removeKey : toRemove) { + adjustments.remove(removeKey); + } r.addAdjustment(adjustment); } } @@ -7313,6 +7323,12 @@ public class NotificationManagerService extends SystemService { } } + protected boolean isAdjustmentAllowed(String type) { + synchronized (mLock) { + return mAllowedAdjustments.contains(type); + } + } + protected void onNotificationsSeenLocked(ArrayList<NotificationRecord> records) { // There should be only one, but it's a list, so while we enforce // singularity elsewhere, we keep it general here, to avoid surprises. diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java index b0d2704196a6..15ed06311758 100644 --- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java +++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java @@ -83,6 +83,9 @@ final class OverlayManagerServiceImpl { if (!Objects.equals(theTruth.overlayTarget, oldSettings.targetPackageName)) { return true; } + if (!Objects.equals(theTruth.targetOverlayableName, oldSettings.targetOverlayableName)) { + return true; + } if (theTruth.isStaticOverlayPackage() != oldSettings.isStatic) { return true; } @@ -149,6 +152,7 @@ final class OverlayManagerServiceImpl { mSettings.init(overlayPackage.packageName, newUserId, overlayPackage.overlayTarget, + overlayPackage.targetOverlayableName, overlayPackage.applicationInfo.getBaseCodePath(), overlayPackage.isStaticOverlayPackage(), overlayPackage.overlayPriority, @@ -331,6 +335,7 @@ final class OverlayManagerServiceImpl { } mSettings.init(packageName, userId, overlayPackage.overlayTarget, + overlayPackage.targetOverlayableName, overlayPackage.applicationInfo.getBaseCodePath(), overlayPackage.isStaticOverlayPackage(), overlayPackage.overlayPriority, overlayPackage.overlayCategory); @@ -395,7 +400,7 @@ final class OverlayManagerServiceImpl { if (oldOi != null && !oldOi.targetPackageName.equals(pkg.overlayTarget)) { mListener.onOverlaysChanged(pkg.overlayTarget, userId); } - mSettings.init(packageName, userId, pkg.overlayTarget, + mSettings.init(packageName, userId, pkg.overlayTarget, pkg.targetOverlayableName, pkg.applicationInfo.getBaseCodePath(), pkg.isStaticOverlayPackage(), pkg.overlayPriority, pkg.overlayCategory); } diff --git a/services/core/java/com/android/server/om/OverlayManagerSettings.java b/services/core/java/com/android/server/om/OverlayManagerSettings.java index 2b4ec03b98fd..667dfa19af15 100644 --- a/services/core/java/com/android/server/om/OverlayManagerSettings.java +++ b/services/core/java/com/android/server/om/OverlayManagerSettings.java @@ -65,12 +65,13 @@ final class OverlayManagerSettings { private final ArrayList<SettingsItem> mItems = new ArrayList<>(); void init(@NonNull final String packageName, final int userId, - @NonNull final String targetPackageName, @NonNull final String baseCodePath, - boolean isStatic, int priority, String overlayCategory) { + @NonNull final String targetPackageName, @Nullable final String targetOverlayableName, + @NonNull final String baseCodePath, boolean isStatic, int priority, + @Nullable String overlayCategory) { remove(packageName, userId); final SettingsItem item = - new SettingsItem(packageName, userId, targetPackageName, baseCodePath, - isStatic, priority, overlayCategory); + new SettingsItem(packageName, userId, targetPackageName, targetOverlayableName, + baseCodePath, isStatic, priority, overlayCategory); if (isStatic) { // All static overlays are always enabled. item.setEnabled(true); @@ -302,16 +303,17 @@ final class OverlayManagerSettings { pw.println(item.mPackageName + ":" + item.getUserId() + " {"); pw.increaseIndent(); - pw.println("mPackageName.......: " + item.mPackageName); - pw.println("mUserId............: " + item.getUserId()); - pw.println("mTargetPackageName.: " + item.getTargetPackageName()); - pw.println("mBaseCodePath......: " + item.getBaseCodePath()); - pw.println("mState.............: " + OverlayInfo.stateToString(item.getState())); - pw.println("mState.............: " + OverlayInfo.stateToString(item.getState())); - pw.println("mIsEnabled.........: " + item.isEnabled()); - pw.println("mIsStatic..........: " + item.isStatic()); - pw.println("mPriority..........: " + item.mPriority); - pw.println("mCategory..........: " + item.mCategory); + pw.println("mPackageName...........: " + item.mPackageName); + pw.println("mUserId................: " + item.getUserId()); + pw.println("mTargetPackageName.....: " + item.getTargetPackageName()); + pw.println("mTargetOverlayableName.: " + item.getTargetOverlayableName()); + pw.println("mBaseCodePath..........: " + item.getBaseCodePath()); + pw.println("mState.................: " + OverlayInfo.stateToString(item.getState())); + pw.println("mState.................: " + OverlayInfo.stateToString(item.getState())); + pw.println("mIsEnabled.............: " + item.isEnabled()); + pw.println("mIsStatic..............: " + item.isStatic()); + pw.println("mPriority..............: " + item.mPriority); + pw.println("mCategory..............: " + item.mCategory); pw.decreaseIndent(); pw.println("}"); @@ -335,6 +337,7 @@ final class OverlayManagerSettings { private static final String ATTR_PACKAGE_NAME = "packageName"; private static final String ATTR_STATE = "state"; private static final String ATTR_TARGET_PACKAGE_NAME = "targetPackageName"; + private static final String ATTR_TARGET_OVERLAYABLE_NAME = "targetOverlayableName"; private static final String ATTR_IS_STATIC = "isStatic"; private static final String ATTR_PRIORITY = "priority"; private static final String ATTR_CATEGORY = "category"; @@ -387,6 +390,8 @@ final class OverlayManagerSettings { final int userId = XmlUtils.readIntAttribute(parser, ATTR_USER_ID); final String targetPackageName = XmlUtils.readStringAttribute(parser, ATTR_TARGET_PACKAGE_NAME); + final String targetOverlayableName = XmlUtils.readStringAttribute(parser, + ATTR_TARGET_OVERLAYABLE_NAME); final String baseCodePath = XmlUtils.readStringAttribute(parser, ATTR_BASE_CODE_PATH); final int state = XmlUtils.readIntAttribute(parser, ATTR_STATE); final boolean isEnabled = XmlUtils.readBooleanAttribute(parser, ATTR_IS_ENABLED); @@ -394,8 +399,8 @@ final class OverlayManagerSettings { final int priority = XmlUtils.readIntAttribute(parser, ATTR_PRIORITY); final String category = XmlUtils.readStringAttribute(parser, ATTR_CATEGORY); - return new SettingsItem(packageName, userId, targetPackageName, baseCodePath, - state, isEnabled, isStatic, priority, category); + return new SettingsItem(packageName, userId, targetPackageName, targetOverlayableName, + baseCodePath, state, isEnabled, isStatic, priority, category); } public static void persist(@NonNull final ArrayList<SettingsItem> table, @@ -422,6 +427,8 @@ final class OverlayManagerSettings { XmlUtils.writeStringAttribute(xml, ATTR_PACKAGE_NAME, item.mPackageName); XmlUtils.writeIntAttribute(xml, ATTR_USER_ID, item.mUserId); XmlUtils.writeStringAttribute(xml, ATTR_TARGET_PACKAGE_NAME, item.mTargetPackageName); + XmlUtils.writeStringAttribute(xml, ATTR_TARGET_OVERLAYABLE_NAME, + item.mTargetOverlayableName); XmlUtils.writeStringAttribute(xml, ATTR_BASE_CODE_PATH, item.mBaseCodePath); XmlUtils.writeIntAttribute(xml, ATTR_STATE, item.mState); XmlUtils.writeBooleanAttribute(xml, ATTR_IS_ENABLED, item.mIsEnabled); @@ -436,6 +443,7 @@ final class OverlayManagerSettings { private final int mUserId; private final String mPackageName; private final String mTargetPackageName; + private final String mTargetOverlayableName; private String mBaseCodePath; private @OverlayInfo.State int mState; private boolean mIsEnabled; @@ -445,12 +453,14 @@ final class OverlayManagerSettings { private String mCategory; SettingsItem(@NonNull final String packageName, final int userId, - @NonNull final String targetPackageName, @NonNull final String baseCodePath, + @NonNull final String targetPackageName, + @Nullable final String targetOverlayableName, @NonNull final String baseCodePath, final @OverlayInfo.State int state, final boolean isEnabled, final boolean isStatic, - final int priority, String category) { + final int priority, @Nullable String category) { mPackageName = packageName; mUserId = userId; mTargetPackageName = targetPackageName; + mTargetOverlayableName = targetOverlayableName; mBaseCodePath = baseCodePath; mState = state; mIsEnabled = isEnabled || isStatic; @@ -461,16 +471,21 @@ final class OverlayManagerSettings { } SettingsItem(@NonNull final String packageName, final int userId, - @NonNull final String targetPackageName, @NonNull final String baseCodePath, - final boolean isStatic, final int priority, String category) { - this(packageName, userId, targetPackageName, baseCodePath, OverlayInfo.STATE_UNKNOWN, - false, isStatic, priority, category); + @NonNull final String targetPackageName, + @Nullable final String targetOverlayableName, @NonNull final String baseCodePath, + final boolean isStatic, final int priority, @Nullable String category) { + this(packageName, userId, targetPackageName, targetOverlayableName, baseCodePath, + OverlayInfo.STATE_UNKNOWN, false, isStatic, priority, category); } private String getTargetPackageName() { return mTargetPackageName; } + private String getTargetOverlayableName() { + return mTargetOverlayableName; + } + private int getUserId() { return mUserId; } @@ -520,7 +535,7 @@ final class OverlayManagerSettings { private boolean setCategory(String category) { if (!Objects.equals(mCategory, category)) { - mCategory = category.intern(); + mCategory = (category == null) ? null : category.intern(); invalidateCache(); return true; } @@ -529,8 +544,8 @@ final class OverlayManagerSettings { private OverlayInfo getOverlayInfo() { if (mCache == null) { - mCache = new OverlayInfo(mPackageName, mTargetPackageName, mCategory, mBaseCodePath, - mState, mUserId, mPriority, mIsStatic); + mCache = new OverlayInfo(mPackageName, mTargetPackageName, mTargetOverlayableName, + mCategory, mBaseCodePath, mState, mUserId, mPriority, mIsStatic); } return mCache; } diff --git a/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java b/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java index 5c0874d7977a..c98a79ad4ed9 100644 --- a/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java +++ b/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java @@ -174,7 +174,11 @@ class BugreportManagerServiceImpl extends IDumpstate.Stub { ds.startBugreport(callingUid, callingPackage, bugreportFd, screenshotFd, bugreportMode, myListener); } catch (RemoteException e) { - reportError(listener, IDumpstateListener.BUGREPORT_ERROR_RUNTIME_ERROR); + // bugreportd service is already started now. We need to kill it to manage the + // lifecycle correctly. If we don't subsequent callers will get + // BUGREPORT_ERROR_ANOTHER_REPORT_IN_PROGRESS error. + // Note that listener will be notified by the death recipient below. + cancelBugreport(); } } diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java index 18cfa4a479f4..9b6333d7bef4 100644 --- a/services/core/java/com/android/server/pm/LauncherAppsService.java +++ b/services/core/java/com/android/server/pm/LauncherAppsService.java @@ -40,6 +40,7 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageInstaller.SessionInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; +import android.content.pm.PackageParser; import android.content.pm.ParceledListSlice; import android.content.pm.ResolveInfo; import android.content.pm.ShortcutInfo; @@ -66,6 +67,7 @@ import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.content.PackageMonitor; import com.android.internal.os.BackgroundThread; +import com.android.internal.util.ArrayUtils; import com.android.internal.util.Preconditions; import com.android.server.LocalServices; import com.android.server.SystemService; @@ -441,6 +443,44 @@ public class LauncherAppsService extends SystemService { if (isManagedProfileAdmin(user, appInfo.packageName)) { return false; } + // If app does not have any components or any permissions, the app can legitimately + // have no icon so we do not show the synthetic activity. + return hasComponentsAndRequestsPermissions(appInfo.packageName); + } + + private boolean hasComponentsAndRequestsPermissions(@NonNull String packageName) { + final PackageManagerInternal pmInt = + LocalServices.getService(PackageManagerInternal.class); + final PackageParser.Package pkg = pmInt.getPackage(packageName); + if (pkg == null) { + // Should not happen, but we shouldn't be failing if it does + return false; + } + if (ArrayUtils.isEmpty(pkg.requestedPermissions)) { + return false; + } + if (!hasApplicationDeclaredActivities(pkg) + && ArrayUtils.isEmpty(pkg.receivers) + && ArrayUtils.isEmpty(pkg.providers) + && ArrayUtils.isEmpty(pkg.services)) { + return false; + } + return true; + } + + private boolean hasApplicationDeclaredActivities(@NonNull PackageParser.Package pkg) { + if (pkg.activities == null) { + return false; + } + if (ArrayUtils.isEmpty(pkg.activities)) { + return false; + } + // If it only contains synthetic AppDetailsActivity only, it means application does + // not have actual activity declared in manifest. + if (pkg.activities.size() == 1 && PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals( + pkg.activities.get(0).className)) { + return false; + } return true; } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index ec2ff28b4a88..10c30e34ce1f 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -1141,11 +1141,22 @@ public class PackageManagerService extends IPackageManager.Stub switch (userStatus) { case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: if (!verified) { - // updatedStatus is already UNDEFINED - needUpdate = true; - - if (DEBUG_DOMAIN_VERIFICATION) { - Slog.d(TAG, "Formerly validated but now failing; demoting"); + // Don't demote if sysconfig says 'always' + SystemConfig systemConfig = SystemConfig.getInstance(); + ArraySet<String> packages = systemConfig.getLinkedApps(); + if (!packages.contains(packageName)) { + // updatedStatus is already UNDEFINED + needUpdate = true; + + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.d(TAG, "Formerly validated but now failing; demoting"); + } + } else { + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.d(TAG, "Updating bundled package " + packageName + + " failed autoVerify, but sysconfig supersedes"); + } + // leave needUpdate == false here intentionally } } break; @@ -2450,7 +2461,9 @@ public class PackageManagerService extends IPackageManager.Stub mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N; mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1; - mIsPreQUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.Q; + mIsPreQUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.Q + // STOPSHIP: Remove next line when API level for Q is defined. + && Build.VERSION.SDK_INT > Build.VERSION_CODES.P; int preUpgradeSdkVersion = ver.sdkVersion; @@ -4979,7 +4992,9 @@ public class PackageManagerService extends IPackageManager.Stub PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId, false /* throwIfPermNotDeclared*/) || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES) - == PERMISSION_GRANTED; + == PERMISSION_GRANTED + || mContext.checkCallingOrSelfPermission( + Manifest.permission.ACCESS_SHARED_LIBRARIES) == PERMISSION_GRANTED; synchronized (mPackages) { List<SharedLibraryInfo> result = null; @@ -5029,6 +5044,76 @@ public class PackageManagerService extends IPackageManager.Stub } } + @Nullable + @Override + public ParceledListSlice<SharedLibraryInfo> getDeclaredSharedLibraries( + @NonNull String packageName, int flags, @NonNull int userId) { + mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_SHARED_LIBRARIES, + "getDeclaredSharedLibraries"); + int callingUid = Binder.getCallingUid(); + mPermissionManager.enforceCrossUserPermission(callingUid, userId, + true /* requireFullPermission */, false /* checkShell */, + "getDeclaredSharedLibraries"); + + Preconditions.checkNotNull(packageName, "packageName cannot be null"); + Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0"); + if (!sUserManager.exists(userId)) { + return null; + } + + if (getInstantAppPackageName(callingUid) != null) { + return null; + } + + synchronized (mPackages) { + List<SharedLibraryInfo> result = null; + + int libraryCount = mSharedLibraries.size(); + for (int i = 0; i < libraryCount; i++) { + LongSparseArray<SharedLibraryInfo> versionedLibrary = mSharedLibraries.valueAt(i); + if (versionedLibrary == null) { + continue; + } + + int versionCount = versionedLibrary.size(); + for (int j = 0; j < versionCount; j++) { + SharedLibraryInfo libraryInfo = versionedLibrary.valueAt(j); + + VersionedPackage declaringPackage = libraryInfo.getDeclaringPackage(); + if (!Objects.equals(declaringPackage.getPackageName(), packageName)) { + continue; + } + + long identity = Binder.clearCallingIdentity(); + try { + PackageInfo packageInfo = getPackageInfoVersioned(declaringPackage, flags + | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId); + if (packageInfo == null) { + continue; + } + } finally { + Binder.restoreCallingIdentity(identity); + } + + SharedLibraryInfo resultLibraryInfo = new SharedLibraryInfo( + libraryInfo.getPath(), libraryInfo.getPackageName(), + libraryInfo.getAllCodePaths(), libraryInfo.getName(), + libraryInfo.getLongVersion(), libraryInfo.getType(), + libraryInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr( + libraryInfo, flags, userId), libraryInfo.getDependencies() == null + ? null : new ArrayList<>(libraryInfo.getDependencies())); + + if (result == null) { + result = new ArrayList<>(); + } + result.add(resultLibraryInfo); + } + } + + return result != null ? new ParceledListSlice<>(result) : null; + } + } + @GuardedBy("mPackages") private List<VersionedPackage> getPackagesUsingSharedLibraryLPr( SharedLibraryInfo libInfo, int flags, int userId) { diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index e36ac23d6473..3029f51d4e09 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -1552,13 +1552,13 @@ public class PermissionManagerService { oldPermAreModernStorageModel = false; } - boolean shouldBeRestricted; + boolean shouldBeHidden; boolean shouldBeFixed; boolean shouldBeGranted = false; boolean shouldBeRevoked = false; int userFlags = -1; if (useLegacyStoragePermissionModel) { - shouldBeRestricted = isModernStoragePermission; + shouldBeHidden = isModernStoragePermission; shouldBeFixed = isQApp || isModernStoragePermission; if (shouldBeFixed) { @@ -1576,7 +1576,7 @@ public class PermissionManagerService { shouldBeRevoked = !shouldBeGranted; } } else { - shouldBeRestricted = isLegacyStoragePermission; + shouldBeHidden = isLegacyStoragePermission; shouldBeFixed = isLegacyStoragePermission; if (shouldBeFixed) { @@ -1636,7 +1636,12 @@ public class PermissionManagerService { changed |= ps.updatePermissionFlags(mSettings.getPermissionLocked(perm), userId, FLAG_PERMISSION_HIDDEN, - shouldBeRestricted ? FLAG_PERMISSION_HIDDEN : 0); + shouldBeHidden ? FLAG_PERMISSION_HIDDEN : 0); + + if (shouldBeHidden) { + changed |= ps.updatePermissionFlags(mSettings.getPermissionLocked(perm), + userId, FLAG_PERMISSION_REVIEW_REQUIRED, 0); + } } if (changed) { @@ -1661,18 +1666,6 @@ public class PermissionManagerService { for (int i = 0; i < numPerms; i++) { String permission = pkg.requestedPermissions.get(i); - int op = permissionToOpCode(permission); - if (op == OP_NONE) { - continue; - } - - // Runtime permissions are per uid, not per package, hence per package app-op - // modes should never have been set. It is possible to set them via the shell - // though. Revert such settings during boot to get the device back into a good - // state. - LocalServices.getService(AppOpsManagerInternal.class).setAllPkgModesToDefault( - op, getUid(userId, getAppId(pkg.applicationInfo.uid))); - // For pre-M apps the runtime permission do not store the state if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { continue; diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 5a32aa0539ec..55af3571f63a 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -5126,7 +5126,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { // Start home. mActivityTaskManagerInternal.startHomeOnDisplay(mCurrentUserId, "startDockOrHome", - displayId, fromHomeKey); + displayId, true /* allowInstrumenting */, fromHomeKey); } /** @@ -5214,13 +5214,15 @@ public class PhoneWindowManager implements WindowManagerPolicy { private VibrationEffect getVibrationEffect(int effectId) { long[] pattern; switch (effectId) { - case HapticFeedbackConstants.CLOCK_TICK: case HapticFeedbackConstants.CONTEXT_CLICK: return VibrationEffect.get(VibrationEffect.EFFECT_TICK); case HapticFeedbackConstants.TEXT_HANDLE_MOVE: if (!mHapticTextHandleEnabled) { return null; } + // fallthrough + case HapticFeedbackConstants.CLOCK_TICK: + return VibrationEffect.get(VibrationEffect.EFFECT_TEXTURE_TICK); case HapticFeedbackConstants.KEYBOARD_RELEASE: case HapticFeedbackConstants.VIRTUAL_KEY_RELEASE: case HapticFeedbackConstants.ENTRY_BUMP: diff --git a/services/core/java/com/android/server/power/AttentionDetector.java b/services/core/java/com/android/server/power/AttentionDetector.java index 701e5af01290..d9d21babe210 100644 --- a/services/core/java/com/android/server/power/AttentionDetector.java +++ b/services/core/java/com/android/server/power/AttentionDetector.java @@ -34,6 +34,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.server.LocalServices; import java.io.PrintWriter; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; /** @@ -65,6 +66,11 @@ public class AttentionDetector { private final Object mLock; /** + * If we're currently waiting for an attention callback + */ + private final AtomicBoolean mRequested; + + /** * {@link android.service.attention.AttentionService} API timeout. */ private long mMaxAttentionApiTimeoutMillis; @@ -78,11 +84,6 @@ public class AttentionDetector { protected AttentionManagerInternal mAttentionManager; /** - * If we're currently waiting for an attention callback - */ - private boolean mRequested; - - /** * Current wakefulness of the device. {@see PowerManagerInternal} */ private int mWakefulness; @@ -94,14 +95,11 @@ public class AttentionDetector { @VisibleForTesting final AttentionCallbackInternal mCallback = new AttentionCallbackInternal() { - @Override - public void onSuccess(int requestCode, int result, long timestamp) { - Slog.v(TAG, "onSuccess: " + requestCode + ", " + result - + " - current requestCode: " + getRequestCode()); - synchronized (mLock) { - if (requestCode == getRequestCode() && mRequested) { - mRequested = false; + public void onSuccess(int result, long timestamp) { + Slog.v(TAG, "onSuccess: " + result); + if (mRequested.getAndSet(false)) { + synchronized (mLock) { if (mWakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE) { if (DEBUG) Slog.d(TAG, "Device slept before receiving callback."); return; @@ -116,19 +114,16 @@ public class AttentionDetector { } @Override - public void onFailure(int requestCode, int error) { + public void onFailure(int error) { Slog.i(TAG, "Failed to check attention: " + error); - synchronized (mLock) { - if (requestCode == getRequestCode()) { - mRequested = false; - } - } + mRequested.set(false); } }; public AttentionDetector(Runnable onUserAttention, Object lock) { mOnUserAttention = onUserAttention; mLock = lock; + mRequested = new AtomicBoolean(false); // Device starts with an awake state upon boot. mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE; @@ -181,9 +176,11 @@ public class AttentionDetector { + (whenToCheck - whenToStopExtending)); } return nextScreenDimming; - } else if (mRequested) { + } else if (mRequested.get()) { if (DEBUG) { - Slog.d(TAG, "Pending attention callback, wait. " + getRequestCode()); + // TODO(b/128134941): consider adding a member ID increasing counter in + // AttentionCallbackInternal to track this better. + Slog.d(TAG, "Pending attention callback, wait."); } return whenToCheck; } @@ -192,14 +189,13 @@ public class AttentionDetector { // callback might arrive before #checkAttention returns (if there are cached results.) // This means that we must assume that the request was successful, and then cancel it // afterwards if AttentionManager couldn't deliver it. - mRequested = true; - final boolean sent = mAttentionManager.checkAttention(getRequestCode(), - getAttentionTimeout(), mCallback); + mRequested.set(true); + final boolean sent = mAttentionManager.checkAttention(getAttentionTimeout(), mCallback); if (!sent) { - mRequested = false; + mRequested.set(false); } - Slog.v(TAG, "Checking user attention with request code: " + getRequestCode()); + Slog.v(TAG, "Checking user attention"); return whenToCheck; } @@ -241,9 +237,9 @@ public class AttentionDetector { } private void cancelCurrentRequestIfAny() { - if (mRequested) { - mAttentionManager.cancelAttentionCheck(getRequestCode()); - mRequested = false; + if (mRequested.get()) { + mAttentionManager.cancelAttentionCheck(mCallback); + mRequested.set(false); } } @@ -255,11 +251,6 @@ public class AttentionDetector { } @VisibleForTesting - int getRequestCode() { - return (int) (mLastUserActivityTime % Integer.MAX_VALUE); - } - - @VisibleForTesting long getAttentionTimeout() { return mMaxAttentionApiTimeoutMillis; } diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 9b427f5cfd5c..cfe11bfb4347 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -4489,8 +4489,7 @@ public final class PowerManagerService extends SystemService } @Override // Binder call - public boolean setDynamicPowerSavings(boolean dynamicPowerSavingsEnabled, - int disableThreshold) { + public boolean setDynamicPowerSaveHint(boolean powerSaveHint, int disableThreshold) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.POWER_SAVER, "updateDynamicPowerSavings"); final long ident = Binder.clearCallingIdentity(); @@ -4503,7 +4502,7 @@ public final class PowerManagerService extends SystemService // abort updating if we weren't able to succeed on the threshold success &= Settings.Global.putInt(resolver, Settings.Global.DYNAMIC_POWER_SAVINGS_ENABLED, - dynamicPowerSavingsEnabled ? 1 : 0); + powerSaveHint ? 1 : 0); } return success; } finally { @@ -4542,13 +4541,13 @@ public final class PowerManagerService extends SystemService } @Override // Binder call - public int getPowerSaveMode() { + public int getPowerSaveModeTrigger() { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.POWER_SAVER, null); final long ident = Binder.clearCallingIdentity(); try { return Settings.Global.getInt(mContext.getContentResolver(), - Settings.Global.AUTOMATIC_POWER_SAVER_MODE, - PowerManager.POWER_SAVER_MODE_PERCENTAGE); + Settings.Global.AUTOMATIC_POWER_SAVE_MODE, + PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE); } finally { Binder.restoreCallingIdentity(ident); } diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java index 61daca7c93bc..fe0b9a6acc85 100644 --- a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java +++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java @@ -45,6 +45,7 @@ import com.android.server.EventLogTags; import com.android.server.power.BatterySaverStateMachineProto; import java.io.PrintWriter; +import java.text.NumberFormat; /** * Decides when to enable / disable battery saver. @@ -188,7 +189,7 @@ public class BatterySaverStateMachine { @GuardedBy("mLock") private int mSettingBatterySaverTriggerThreshold; - /** Previously known value of Settings.Global.AUTOMATIC_POWER_SAVER_MODE. */ + /** Previously known value of Settings.Global.AUTOMATIC_POWER_SAVE_MODE. */ @GuardedBy("mLock") private int mSettingAutomaticBatterySaver; @@ -248,7 +249,7 @@ public class BatterySaverStateMachine { /** @return true if the automatic percentage based mode should be used */ private boolean isAutomaticModeActiveLocked() { - return mSettingAutomaticBatterySaver == PowerManager.POWER_SAVER_MODE_PERCENTAGE + return mSettingAutomaticBatterySaver == PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE && mSettingBatterySaverTriggerThreshold > 0; } @@ -264,7 +265,7 @@ public class BatterySaverStateMachine { /** @return true if the dynamic mode should be used */ private boolean isDynamicModeActiveLocked() { - return mSettingAutomaticBatterySaver == PowerManager.POWER_SAVER_MODE_DYNAMIC + return mSettingAutomaticBatterySaver == PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC && mDynamicPowerSavingsBatterySaver; } @@ -304,7 +305,7 @@ public class BatterySaverStateMachine { Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL), false, mSettingsObserver, UserHandle.USER_SYSTEM); cr.registerContentObserver(Settings.Global.getUriFor( - Settings.Global.AUTOMATIC_POWER_SAVER_MODE), + Settings.Global.AUTOMATIC_POWER_SAVE_MODE), false, mSettingsObserver, UserHandle.USER_SYSTEM); cr.registerContentObserver(Settings.Global.getUriFor( Settings.Global.DYNAMIC_POWER_SAVINGS_ENABLED), @@ -367,8 +368,8 @@ public class BatterySaverStateMachine { final int lowPowerModeTriggerLevel = getGlobalSetting( Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0); final int automaticBatterySaverMode = getGlobalSetting( - Settings.Global.AUTOMATIC_POWER_SAVER_MODE, - PowerManager.POWER_SAVER_MODE_PERCENTAGE); + Settings.Global.AUTOMATIC_POWER_SAVE_MODE, + PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE); final int dynamicPowerSavingsDisableThreshold = getGlobalSetting( Settings.Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, mDynamicPowerSavingsDefaultDisableThreshold); @@ -791,7 +792,7 @@ public class BatterySaverStateMachine { manager.notify(DYNAMIC_MODE_NOTIFICATION_ID, buildNotification(DYNAMIC_MODE_NOTIF_CHANNEL_ID, - R.string.dynamic_mode_notification_title, + mContext.getResources().getString(R.string.dynamic_mode_notification_title), R.string.dynamic_mode_notification_summary, Intent.ACTION_POWER_USAGE_SUMMARY)); } @@ -801,10 +802,13 @@ public class BatterySaverStateMachine { ensureNotificationChannelExists(manager, BATTERY_SAVER_NOTIF_CHANNEL_ID, R.string.battery_saver_notification_channel_name); + final String percentage = NumberFormat.getPercentInstance() + .format((double) mBatteryLevel / 100.0); manager.notify(STICKY_AUTO_DISABLED_NOTIFICATION_ID, buildNotification(BATTERY_SAVER_NOTIF_CHANNEL_ID, - R.string.battery_saver_sticky_disabled_notification_title, - R.string.battery_saver_sticky_disabled_notification_summary, + mContext.getResources().getString( + R.string.battery_saver_charged_notification_title, percentage), + R.string.battery_saver_off_notification_summary, Settings.ACTION_BATTERY_SAVER_SETTINGS)); } @@ -816,7 +820,7 @@ public class BatterySaverStateMachine { manager.createNotificationChannel(channel); } - private Notification buildNotification(@NonNull String channelId, @StringRes int titleId, + private Notification buildNotification(@NonNull String channelId, @NonNull String title, @StringRes int summaryId, @NonNull String intentAction) { Resources res = mContext.getResources(); Intent intent = new Intent(intentAction); @@ -827,11 +831,12 @@ public class BatterySaverStateMachine { return new Notification.Builder(mContext, channelId) .setSmallIcon(R.drawable.ic_battery) - .setContentTitle(res.getString(titleId)) + .setContentTitle(title) .setContentText(summary) .setContentIntent(batterySaverIntent) .setStyle(new Notification.BigTextStyle().bigText(summary)) .setOnlyAlertOnce(true) + .setAutoCancel(true) .build(); } diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 4706930928f4..5bbabfceda47 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -17,6 +17,7 @@ package com.android.server.wm; import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; +import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; import static android.app.ActivityManager.TaskDescription.ATTR_TASKDESCRIPTION_PREFIX; import static android.app.ActivityOptions.ANIM_CLIP_REVEAL; import static android.app.ActivityOptions.ANIM_CUSTOM; @@ -2159,8 +2160,7 @@ final class ActivityRecord extends ConfigurationContainer { } if (nowVisible) { - // We won't get a call to reportActivityVisibleLocked() so dismiss lockscreen now. - mStackSupervisor.reportActivityVisibleLocked(this); + mStackSupervisor.stopWaitingForActivityVisible(this); } // Schedule an idle timeout in case the app doesn't do it for us. @@ -2349,7 +2349,7 @@ final class ActivityRecord extends ConfigurationContainer { final @LaunchState int launchState = info != null ? info.getLaunchState() : -1; mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this, windowsDrawnDelayMs, launchState); - mStackSupervisor.sendWaitingVisibleReportLocked(this); + mStackSupervisor.stopWaitingForActivityVisible(this); finishLaunchTickingLocked(); if (task != null) { task.hasBeenVisible = true; @@ -2360,7 +2360,7 @@ final class ActivityRecord extends ConfigurationContainer { /** Called when the windows associated app window container are visible. */ public void onWindowsVisible() { synchronized (mAtmService.mGlobalLock) { - mStackSupervisor.reportActivityVisibleLocked(this); + mStackSupervisor.stopWaitingForActivityVisible(this); if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsVisibleLocked(): " + this); if (!nowVisible) { nowVisible = true; @@ -2710,22 +2710,50 @@ final class ActivityRecord extends ConfigurationContainer { if (!shouldUseSizeCompatMode()) { return false; } - final Configuration parentConfig = getParent().getConfiguration(); final Configuration resolvedConfig = getResolvedOverrideConfiguration(); + final Rect resolvedAppBounds = resolvedConfig.windowConfiguration.getAppBounds(); + if (resolvedAppBounds == null) { + // The override configuration has not been resolved yet. + return false; + } + + final Configuration parentConfig = getParent().getConfiguration(); // Although colorMode, screenLayout, smallestScreenWidthDp are also fixed, generally these // fields should be changed with density and bounds, so here only compares the most // significant field. if (parentConfig.densityDpi != resolvedConfig.densityDpi) { return true; } + final Rect parentAppBounds = parentConfig.windowConfiguration.getAppBounds(); - final Rect parentBounds = parentAppBounds != null - ? parentAppBounds : parentConfig.windowConfiguration.getBounds(); - final Rect overrideBounds = resolvedConfig.windowConfiguration.getBounds(); + final int appWidth = resolvedAppBounds.width(); + final int appHeight = resolvedAppBounds.height(); + final int parentAppWidth = parentAppBounds.width(); + final int parentAppHeight = parentAppBounds.height(); + if (parentAppWidth < appWidth || parentAppHeight < appHeight) { + // One side is larger than the parent. + return true; + } + + if (info.hasFixedAspectRatio()) { + final float aspectRatio = (0.5f + Math.max(appWidth, appHeight)) + / Math.min(appWidth, appHeight); + final float parentAspectRatio = (0.5f + Math.max(parentAppWidth, parentAppHeight)) + / Math.min(parentAppWidth, parentAppHeight); + // Check if the parent still has available space in long side. + if (aspectRatio < parentAspectRatio + && (aspectRatio < info.maxAspectRatio || info.minAspectRatio > 0)) { + return true; + } + } + + final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds(); // If the width or height is the same as parent, it is already the best fit of the override - // bounds, therefore this condition is considered as not size compatibility mode. - return parentBounds.width() != overrideBounds.width() - && parentBounds.height() != overrideBounds.height(); + // bounds, therefore this condition is considered as not size compatibility mode. Here uses + // right and bottom as width and height of parent because the bounds may contain decor + // insets which has been accounted in override bounds. See {@link #computeBounds}. + return parentAppBounds.right != resolvedBounds.width() + && parentAppBounds.bottom != resolvedBounds.height(); } /** @@ -2778,15 +2806,18 @@ final class ActivityRecord extends ConfigurationContainer { // are relative to bounds and density, they will be calculated in // {@link TaskRecord#computeConfigResourceOverrides} and the result will also be // relatively fixed. - final Configuration srcConfig = task.getConfiguration(); - overrideConfig.colorMode = srcConfig.colorMode; - overrideConfig.densityDpi = srcConfig.densityDpi; - overrideConfig.screenLayout = srcConfig.screenLayout + final Configuration parentConfig = task.getConfiguration(); + // Don't account decor insets into app bounds. + mTmpBounds.intersect(parentConfig.windowConfiguration.getAppBounds()); + overrideConfig.windowConfiguration.setAppBounds(mTmpBounds); + overrideConfig.colorMode = parentConfig.colorMode; + overrideConfig.densityDpi = parentConfig.densityDpi; + overrideConfig.screenLayout = parentConfig.screenLayout & (Configuration.SCREENLAYOUT_LONG_MASK | Configuration.SCREENLAYOUT_SIZE_MASK); // The smallest screen width is the short side of screen bounds. Because the bounds // and density won't be changed, smallestScreenWidthDp is also fixed. - overrideConfig.smallestScreenWidthDp = srcConfig.smallestScreenWidthDp; + overrideConfig.smallestScreenWidthDp = parentConfig.smallestScreenWidthDp; } } onRequestedOverrideConfigurationChanged(overrideConfig); @@ -2794,33 +2825,38 @@ final class ActivityRecord extends ConfigurationContainer { @Override void resolveOverrideConfiguration(Configuration newParentConfiguration) { - super.resolveOverrideConfiguration(newParentConfiguration); + // If the activity has override bounds, the relative configuration (e.g. screen size, + // layout) needs to be resolved according to the bounds. + final boolean hasOverrideBounds = !matchParentBounds(); + if (hasOverrideBounds && shouldUseSizeCompatMode()) { + resolveSizeCompatModeConfiguration(newParentConfiguration); + } else { + super.resolveOverrideConfiguration(newParentConfiguration); + if (hasOverrideBounds) { + task.computeConfigResourceOverrides(getResolvedOverrideConfiguration(), + newParentConfiguration, true /* insideParentBounds */); + } + } // Assign configuration sequence number into hierarchy because there is a different way than // ensureActivityConfiguration() in this class that uses configuration in WindowState during // layout traversals. mConfigurationSeq = Math.max(++mConfigurationSeq, 1); getResolvedOverrideConfiguration().seq = mConfigurationSeq; + } - if (matchParentBounds()) { - return; - } - + private void resolveSizeCompatModeConfiguration(Configuration newParentConfiguration) { final Configuration resolvedConfig = getResolvedOverrideConfiguration(); - if (!shouldUseSizeCompatMode()) { - computeConfigResourceOverrides(resolvedConfig, newParentConfiguration, - ORIENTATION_UNDEFINED, true /* insideParentBounds */); - return; - } + final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds(); - final Configuration displayConfig = getDisplay().getConfiguration(); int orientation = getConfiguration().orientation; - if (orientation != displayConfig.orientation && isConfigurationCompatible(displayConfig)) { + if (orientation != newParentConfiguration.orientation + && isConfigurationCompatible(newParentConfiguration)) { // The activity is compatible to apply the orientation change or it requests different // fixed orientation. - orientation = displayConfig.orientation; + orientation = newParentConfiguration.orientation; } else { - if (resolvedConfig.windowConfiguration.getAppBounds() != null) { + if (!resolvedBounds.isEmpty()) { // Keep the computed resolved override configuration. return; } @@ -2830,35 +2866,55 @@ final class ActivityRecord extends ConfigurationContainer { } } - // Adjust the bounds to match the current orientation. - if (orientation != ORIENTATION_UNDEFINED) { - final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds(); - final int longSide = Math.max(resolvedBounds.height(), resolvedBounds.width()); - final int shortSide = Math.min(resolvedBounds.height(), resolvedBounds.width()); - final boolean toBeLandscape = orientation == ORIENTATION_LANDSCAPE; - final int width = toBeLandscape ? longSide : shortSide; - final int height = toBeLandscape ? shortSide : longSide; - // Assume the bounds is always started from zero because the size may be bigger than its + // The requested override bounds will set to the resolved bounds. + super.resolveOverrideConfiguration(newParentConfiguration); + + boolean shouldSwapAppBounds = false; + int width = resolvedBounds.width(); + int height = resolvedBounds.height(); + if ((orientation == ORIENTATION_LANDSCAPE && height > width) + || (orientation == ORIENTATION_PORTRAIT && width > height)) { + // Swap width and height because they are opposite to the orientation. + width = resolvedBounds.height(); + height = resolvedBounds.width(); + // Assume the bounds always starts from zero because the size may be larger than its // parent (task ~ display). The actual letterboxing will be done by surface offset. resolvedBounds.set(0, 0, width, height); - } - - // In size compatible mode, activity is allowed to have larger bounds than its parent. - computeConfigResourceOverrides(resolvedConfig, newParentConfiguration, orientation, + shouldSwapAppBounds = true; + } else if (width == height) { + // The bounds may contain decor insets, then its app bounds may not be 1:1 and need to + // be adjusted according to the orientation. + final int appWidth = resolvedConfig.windowConfiguration.getAppBounds().width(); + final int appHeight = resolvedConfig.windowConfiguration.getAppBounds().height(); + shouldSwapAppBounds = (orientation == ORIENTATION_LANDSCAPE && appHeight > appWidth) + || (orientation == ORIENTATION_PORTRAIT && appWidth > appHeight); + } + + final Rect resolvedAppBounds = resolvedConfig.windowConfiguration.getAppBounds(); + final Rect parentAppBounds = newParentConfiguration.windowConfiguration.getAppBounds(); + if (shouldSwapAppBounds) { + // Preserve the original decor insets (the left and top of the resolved app bounds) if + // the parent also has the insets at the corresponding side. + final int left = parentAppBounds.left > 0 ? resolvedAppBounds.top : 0; + final int top = parentAppBounds.top > 0 ? resolvedAppBounds.left : 0; + final int appWidth = resolvedAppBounds.height(); + final int appHeight = resolvedAppBounds.width(); + resolvedAppBounds.set(left, top, appWidth + left, appHeight + top); + } + // The horizontal inset included in width is not needed if the activity cannot fill the + // parent, because the offset will be applied by {@link AppWindowToken#mSizeCompatBounds}. + if (resolvedBounds.width() < parentAppBounds.width()) { + resolvedBounds.right -= resolvedAppBounds.left; + } + + // In size compatibility mode, activity is allowed to have larger bounds than its parent. + task.computeConfigResourceOverrides(resolvedConfig, newParentConfiguration, false /* insideParentBounds */); - } - - private void computeConfigResourceOverrides(Configuration inOutConfig, - Configuration parentConfig, int orientation, boolean insideParentBounds) { - // Set the real orientation or undefined value to ensure the output orientation won't be the - // old value. Also reset app bounds so it will be updated according to bounds. - inOutConfig.orientation = orientation; - final Rect outAppBounds = inOutConfig.windowConfiguration.getAppBounds(); - if (outAppBounds != null) { - outAppBounds.setEmpty(); + // Use parent orientation if it cannot be decided by bounds, so the activity can fit inside + // the parent bounds appropriately. + if (resolvedConfig.screenWidthDp == resolvedConfig.screenHeightDp) { + resolvedConfig.orientation = newParentConfiguration.orientation; } - - task.computeConfigResourceOverrides(inOutConfig, parentConfig, insideParentBounds); } @Override @@ -2889,8 +2945,27 @@ final class ActivityRecord extends ConfigurationContainer { } final ActivityDisplay display = getDisplay(); - if (display != null) { + if (display == null) { + return; + } + if (visible) { + // It may toggle the UI for user to restart the size compatibility mode activity. display.handleActivitySizeCompatModeIfNeeded(this); + } else if (shouldUseSizeCompatMode()) { + // The override changes can only be obtained from display, because we don't have the + // difference of full configuration in each hierarchy. + final int displayChanges = display.getLastOverrideConfigurationChanges(); + final int orientationChanges = CONFIG_WINDOW_CONFIGURATION + | CONFIG_SCREEN_SIZE | CONFIG_ORIENTATION; + final boolean hasNonOrienSizeChanged = hasResizeChange(displayChanges) + // Filter out the case of simple orientation change. + && (displayChanges & orientationChanges) != orientationChanges; + // For background activity that uses size compatibility mode, if the size or density of + // the display is changed, then reset the override configuration and kill the activity's + // process if its process state is not important to user. + if (hasNonOrienSizeChanged || (displayChanges & ActivityInfo.CONFIG_DENSITY) != 0) { + restartProcessIfVisible(); + } } } @@ -2990,14 +3065,14 @@ final class ActivityRecord extends ConfigurationContainer { // {@link #getRequestedOverrideBounds()} will be empty (representing no override). If // the method has run before, then effect of {@link #getRequestedOverrideBounds()} will // already have been applied to the value returned from {@link getConfiguration}. Refer - // to {@link TaskRecord#computeOverrideConfiguration}. + // to {@link TaskRecord#computeConfigResourceOverrides()}. outBounds.set(getRequestedOverrideBounds()); return; } // Compute configuration based on max supported width and height. // Also account for the left / top insets (e.g. from display cutouts), which will be clipped - // away later in StackWindowController.adjustConfigurationForBounds(). Otherwise, the app + // away later in {@link TaskRecord#computeConfigResourceOverrides()}. Otherwise, the app // bounds would end up too small. outBounds.set(0, 0, activityWidth + appBounds.left, activityHeight + appBounds.top); } @@ -3357,7 +3432,8 @@ final class ActivityRecord extends ConfigurationContainer { void restartProcessIfVisible() { Slog.i(TAG, "Request to restart process of " + this); - // Reset the existing override configuration to the latest configuration. + // Reset the existing override configuration so it can be updated according to the latest + // configuration. getRequestedOverrideConfiguration().setToDefaults(); getResolvedOverrideConfiguration().setToDefaults(); if (visible) { @@ -3377,8 +3453,17 @@ final class ActivityRecord extends ConfigurationContainer { // Kill its process immediately because the activity should be in background. // The activity state will be update to {@link #DESTROYED} in // {@link ActivityStack#cleanUpActivityLocked} when handling process died. - mAtmService.mH.post(() -> mAtmService.mAmInternal.killProcess( - app.mName, app.mUid, "restartActivityProcess")); + mAtmService.mH.post(() -> { + final WindowProcessController wpc; + synchronized (mAtmService.mGlobalLock) { + if (!hasProcess() + || app.getReportedProcState() <= PROCESS_STATE_IMPORTANT_FOREGROUND) { + return; + } + wpc = app; + } + mAtmService.mAmInternal.killProcess(wpc.mName, wpc.mUid, "resetConfig"); + }); return; } diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java index d7c9bc78e72f..53dc1df5a46a 100644 --- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java @@ -553,18 +553,10 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { // down to the max limit while they are still waiting to finish. mFinishingActivities.remove(r); - for (int i = mWaitingForActivityVisible.size() - 1; i >= 0; --i) { - if (mWaitingForActivityVisible.get(i).matches(r.mActivityComponent)) { - mWaitingForActivityVisible.remove(i); - } - } - } - - void reportActivityVisibleLocked(ActivityRecord r) { - sendWaitingVisibleReportLocked(r); + stopWaitingForActivityVisible(r); } - void sendWaitingVisibleReportLocked(ActivityRecord r) { + void stopWaitingForActivityVisible(ActivityRecord r) { boolean changed = false; for (int i = mWaitingForActivityVisible.size() - 1; i >= 0; --i) { final WaitInfo w = mWaitingForActivityVisible.get(i); diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 2b23ff084391..3acd4e7fc746 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -1538,10 +1538,13 @@ class ActivityStarter { if (!mAddingToTask && mReuseTask == null) { // We didn't do anything... but it was needed (a.k.a., client don't use that // intent!) And for paranoia, make sure we have correctly resumed the top activity. - resumeTargetStackIfNeeded(); if (outActivity != null && outActivity.length > 0) { - outActivity[0] = reusedActivity; + // The reusedActivity could be finishing, for example of starting an + // activity with FLAG_ACTIVITY_CLEAR_TOP flag. In that case, return the + // top running activity in the task instead. + outActivity[0] = reusedActivity.finishing + ? reusedActivity.getTaskRecord().getTopActivity() : reusedActivity; } return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP; diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java index b262a006a545..fc7646f8ae4e 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java @@ -364,7 +364,7 @@ public abstract class ActivityTaskManagerInternal { * - Use the secondary home defined in the config. */ public abstract boolean startHomeOnDisplay(int userId, String reason, int displayId, - boolean fromHomeKey); + boolean allowInstrumenting, boolean fromHomeKey); /** Start home activities on all displays that support system decorations. */ public abstract boolean startHomeOnAllDisplays(int userId, String reason); /** @return true if the given process is the factory test process. */ diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index c91ee8e2f286..7ea7cf1cd015 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -5209,7 +5209,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { // the ATMS lock held. final Message msg = PooledLambda.obtainMessage( ActivityManagerInternal::killAllBackgroundProcessesExcept, mAmInternal, - N, ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE); + N, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND); mH.sendMessage(msg); } } @@ -6492,10 +6492,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public boolean startHomeOnDisplay(int userId, String reason, int displayId, - boolean fromHomeKey) { + boolean allowInstrumenting, boolean fromHomeKey) { synchronized (mGlobalLock) { return mRootActivityContainer.startHomeOnDisplay(userId, reason, displayId, - fromHomeKey); + allowInstrumenting, fromHomeKey); } } diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index 955f2e9ce050..1e1c482bdce3 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -1627,7 +1627,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree // If the changes come from change-listener, the incoming parent configuration is // still the old one. Make sure their orientations are the same to reduce computing // the compatibility bounds for the intermediate state. - && getResolvedOverrideConfiguration().orientation == newParentConfig.orientation) { + && (task.mTaskRecord == null || task.mTaskRecord + .getConfiguration().orientation == newParentConfig.orientation)) { final Rect taskBounds = task.getBounds(); // Since we only center the activity horizontally, if only the fixed height is smaller // than its container, the override bounds don't need to take effect. @@ -1763,7 +1764,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree final Rect parentAppBounds = newParentConfig.windowConfiguration.getAppBounds(); final Rect viewportBounds = parentAppBounds != null ? parentAppBounds : newParentConfig.windowConfiguration.getBounds(); - final Rect contentBounds = getResolvedOverrideBounds(); + final Rect appBounds = getWindowConfiguration().getAppBounds(); + final Rect contentBounds = appBounds != null ? appBounds : getResolvedOverrideBounds(); final float contentW = contentBounds.width(); final float contentH = contentBounds.height(); final float viewportW = viewportBounds.width(); @@ -1780,6 +1782,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree mSizeCompatBounds.set(contentBounds); mSizeCompatBounds.offsetTo(0, 0); mSizeCompatBounds.scale(mSizeCompatScale); + // The decor inset is included in height. + mSizeCompatBounds.bottom += viewportBounds.top; mSizeCompatBounds.left += offsetX; mSizeCompatBounds.right += offsetX; } diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java index 5c528c7f6047..3886ae1635cc 100644 --- a/services/core/java/com/android/server/wm/ConfigurationContainer.java +++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java @@ -77,6 +77,9 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> { */ private Configuration mFullConfiguration = new Configuration(); + /** The bit mask of the last override fields of full configuration. */ + private int mLastOverrideConfigurationChanges; + /** * Contains merged override configuration settings from the top of the hierarchy down to this * particular instance. It is different from {@link #mFullConfiguration} because it starts from @@ -108,6 +111,11 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> { return mFullConfiguration; } + /** Returns the last changes from applying override configuration. */ + int getLastOverrideConfigurationChanges() { + return mLastOverrideConfigurationChanges; + } + /** * Notify that parent config changed and we need to update full configuration. * @see #mFullConfiguration @@ -116,7 +124,8 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> { mTmpConfig.setTo(mResolvedOverrideConfiguration); resolveOverrideConfiguration(newParentConfig); mFullConfiguration.setTo(newParentConfig); - mFullConfiguration.updateFrom(mResolvedOverrideConfiguration); + mLastOverrideConfigurationChanges = + mFullConfiguration.updateFrom(mResolvedOverrideConfiguration); if (!mTmpConfig.equals(mResolvedOverrideConfiguration)) { onMergedOverrideConfigurationChanged(); // This depends on the assumption that change-listeners don't do diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index ff4e2564a696..6605f3c605ed 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -334,6 +334,11 @@ public class DisplayPolicy { private int mForcingShowNavBarLayer; private boolean mForceShowSystemBars; + /** + * Force the display of system bars regardless of other settings. + */ + private boolean mForceShowSystemBarsFromExternal; + private boolean mShowingDream; private boolean mLastShowingDream; private boolean mDreamingLockscreen; @@ -409,6 +414,7 @@ public class DisplayPolicy { mCarDockEnablesAccelerometer = r.getBoolean(R.bool.config_carDockEnablesAccelerometer); mDeskDockEnablesAccelerometer = r.getBoolean(R.bool.config_deskDockEnablesAccelerometer); mTranslucentDecorEnabled = r.getBoolean(R.bool.config_enableTranslucentDecor); + mForceShowSystemBarsFromExternal = r.getBoolean(R.bool.config_forceShowSystemBars); updateConfigurationDependentBehaviors(); mAccessibilityManager = (AccessibilityManager) mContext.getSystemService( @@ -613,6 +619,13 @@ public class DisplayPolicy { return mDockMode; } + /** + * @see WindowManagerService.setForceShowSystemBars + */ + void setForceShowSystemBars(boolean forceShowSystemBars) { + mForceShowSystemBarsFromExternal = forceShowSystemBars; + } + public boolean hasNavigationBar() { return mHasNavigationBar; } @@ -1119,9 +1132,9 @@ public class DisplayPolicy { } /** - * @return true if the navigation bar is forced to stay visible + * @return true if the system bars are forced to stay visible */ - public boolean isNavBarForcedShownLw(WindowState windowState) { + public boolean areSystemBarsForcedShownLw(WindowState windowState) { return mForceShowSystemBars; } @@ -1141,8 +1154,8 @@ public class DisplayPolicy { * current visibility. Expressed as positive insets. * @param outOutsets The areas that are not real display, but we would like to treat as such. * @param outDisplayCutout The area that has been cut away from the display. - * @return Whether to always consume the navigation bar. - * See {@link #isNavBarForcedShownLw(WindowState)}. + * @return Whether to always consume the system bars. + * See {@link #areSystemBarsForcedShownLw(WindowState)}. */ public boolean getLayoutHintLw(LayoutParams attrs, Rect taskBounds, DisplayFrames displayFrames, boolean floatingStack, Rect outFrame, @@ -3048,7 +3061,8 @@ public class DisplayPolicy { // We need to force system bars when the docked stack is visible, when the freeform stack // is visible but also when we are resizing for the transitions when docked stack // visibility changes. - mForceShowSystemBars = dockedStackVisible || freeformStackVisible || resizing; + mForceShowSystemBars = dockedStackVisible || freeformStackVisible || resizing + || mForceShowSystemBarsFromExternal; final boolean forceOpaqueStatusBar = mForceShowSystemBars && !mForceStatusBarFromKeyguard; // apply translucent bar vis flags @@ -3420,6 +3434,8 @@ public class DisplayPolicy { pw.print(prefix); pw.print("mTopIsFullscreen="); pw.print(mTopIsFullscreen); pw.print(prefix); pw.print("mForceStatusBar="); pw.print(mForceStatusBar); pw.print(" mForceStatusBarFromKeyguard="); pw.println(mForceStatusBarFromKeyguard); + pw.print(" mForceShowSystemBarsFromExternal="); + pw.println(mForceShowSystemBarsFromExternal); pw.print(prefix); pw.print("mAllowLockscreenWhenOn="); pw.println(mAllowLockscreenWhenOn); mStatusBarController.dump(pw, prefix); mNavigationBarController.dump(pw, prefix); diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java index 72a1a2f0cac2..432d75e9a4e3 100644 --- a/services/core/java/com/android/server/wm/KeyguardController.java +++ b/services/core/java/com/android/server/wm/KeyguardController.java @@ -95,13 +95,15 @@ class KeyguardController { } /** - * @return {@code true} if 1) Keyguard is showing, not going away, and not being occluded on the - * given display, or 2) AOD is showing, {@code false} otherwise. + * @return {@code true} for default display when AOD is showing. Otherwise, same as + * {@link #isKeyguardOrAodShowing(int)} * TODO(b/125198167): Replace isKeyguardOrAodShowing() by this logic. */ boolean isKeyguardUnoccludedOrAodShowing(int displayId) { - return (mKeyguardShowing && !mKeyguardGoingAway && !isDisplayOccluded(displayId)) - || mAodShowing; + if (displayId == DEFAULT_DISPLAY && mAodShowing) { + return true; + } + return isKeyguardOrAodShowing(displayId); } /** diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java index d69ae3d5c3c0..24b02133ff3c 100644 --- a/services/core/java/com/android/server/wm/RecentTasks.java +++ b/services/core/java/com/android/server/wm/RecentTasks.java @@ -845,6 +845,11 @@ class RecentTasks { return mService.mAmInternal.getCurrentProfileIds(); } + @VisibleForTesting + boolean isUserRunning(int userId, int flags) { + return mService.mAmInternal.isUserRunning(userId, flags); + } + /** * @return the list of recent tasks for presentation. */ @@ -861,7 +866,7 @@ class RecentTasks { boolean getTasksAllowed, boolean getDetailedTasks, int userId, int callingUid) { final boolean withExcluded = (flags & RECENT_WITH_EXCLUDED) != 0; - if (!mService.mAmInternal.isUserRunning(userId, FLAG_AND_UNLOCKED)) { + if (!isUserRunning(userId, FLAG_AND_UNLOCKED)) { Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents"); return new ArrayList<>(); } @@ -881,7 +886,7 @@ class RecentTasks { if (isVisibleRecentTask(tr)) { numVisibleTasks++; - if (isInVisibleRange(tr, numVisibleTasks)) { + if (isInVisibleRange(tr, numVisibleTasks, withExcluded)) { // Fall through } else { // Not in visible range @@ -908,51 +913,43 @@ class RecentTasks { continue; } - // Return the entry if desired by the caller. We always return - // the first entry, because callers always expect this to be the - // foreground app. We may filter others if the caller has - // not supplied RECENT_WITH_EXCLUDED and there is some reason - // we should exclude the entry. - - if (i == 0 - || withExcluded - || (tr.intent == null) - || ((tr.intent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) - == 0)) { - if (!getTasksAllowed) { - // If the caller doesn't have the GET_TASKS permission, then only - // allow them to see a small subset of tasks -- their own and home. - if (!tr.isActivityTypeHome() && tr.effectiveUid != callingUid) { - if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr); - continue; - } - } - if (tr.autoRemoveRecents && tr.getTopActivity() == null) { - // Don't include auto remove tasks that are finished or finishing. - if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, - "Skipping, auto-remove without activity: " + tr); - continue; - } - if ((flags & RECENT_IGNORE_UNAVAILABLE) != 0 && !tr.isAvailable) { - if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, - "Skipping, unavail real act: " + tr); + if (!getTasksAllowed) { + // If the caller doesn't have the GET_TASKS permission, then only + // allow them to see a small subset of tasks -- their own and home. + if (!tr.isActivityTypeHome() && tr.effectiveUid != callingUid) { + if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr); continue; } + } - if (!tr.mUserSetupComplete) { - // Don't include task launched while user is not done setting-up. - if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, - "Skipping, user setup not complete: " + tr); - continue; + if (tr.autoRemoveRecents && tr.getTopActivity() == null) { + // Don't include auto remove tasks that are finished or finishing. + if (DEBUG_RECENTS) { + Slog.d(TAG_RECENTS, "Skipping, auto-remove without activity: " + tr); + } + continue; + } + if ((flags & RECENT_IGNORE_UNAVAILABLE) != 0 && !tr.isAvailable) { + if (DEBUG_RECENTS) { + Slog.d(TAG_RECENTS, "Skipping, unavail real act: " + tr); } + continue; + } - final ActivityManager.RecentTaskInfo rti = createRecentTaskInfo(tr); - if (!getDetailedTasks) { - rti.baseIntent.replaceExtras((Bundle)null); + if (!tr.mUserSetupComplete) { + // Don't include task launched while user is not done setting-up. + if (DEBUG_RECENTS) { + Slog.d(TAG_RECENTS, "Skipping, user setup not complete: " + tr); } + continue; + } - res.add(rti); + final ActivityManager.RecentTaskInfo rti = createRecentTaskInfo(tr); + if (!getDetailedTasks) { + rti.baseIntent.replaceExtras((Bundle) null); } + + res.add(rti); } return res; } @@ -994,7 +991,7 @@ class RecentTasks { final TaskRecord tr = mTasks.get(i); if (isVisibleRecentTask(tr)) { numVisibleTasks++; - if (isInVisibleRange(tr, numVisibleTasks)) { + if (isInVisibleRange(tr, numVisibleTasks, false /* skipExcludedCheck */)) { res.put(tr.taskId, true); } } @@ -1215,7 +1212,8 @@ class RecentTasks { continue; } else { numVisibleTasks++; - if (isInVisibleRange(task, numVisibleTasks) || !isTrimmable(task)) { + if (isInVisibleRange(task, numVisibleTasks, false /* skipExcludedCheck */) + || !isTrimmable(task)) { // Keep visible tasks in range i++; continue; @@ -1329,14 +1327,17 @@ class RecentTasks { /** * @return whether the given visible task is within the policy range. */ - private boolean isInVisibleRange(TaskRecord task, int numVisibleTasks) { - // Keep the last most task even if it is excluded from recents - final boolean isExcludeFromRecents = - (task.getBaseIntent().getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) - == FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; - if (isExcludeFromRecents) { - if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "\texcludeFromRecents=true"); - return numVisibleTasks == 1; + private boolean isInVisibleRange(TaskRecord task, int numVisibleTasks, + boolean skipExcludedCheck) { + if (!skipExcludedCheck) { + // Keep the most recent task even if it is excluded from recents + final boolean isExcludeFromRecents = + (task.getBaseIntent().getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) + == FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; + if (isExcludeFromRecents) { + if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "\texcludeFromRecents=true"); + return numVisibleTasks == 1; + } } if (mMinNumVisibleTasks >= 0 && numVisibleTasks <= mMinNumVisibleTasks) { diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index 26df832bf316..381366995dd5 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimationController.java +++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java @@ -208,7 +208,10 @@ public class RecentsAnimationController implements DeathRecipient { try { synchronized (mService.getWindowManagerLock()) { for (int i = mPendingAnimations.size() - 1; i >= 0; i--) { - mPendingAnimations.get(i).mTask.setCanAffectSystemUiFlags(behindSystemBars); + final Task task = mPendingAnimations.get(i).mTask; + if (task.getActivityType() != mTargetActivityType) { + task.setCanAffectSystemUiFlags(behindSystemBars); + } } mService.mWindowPlacerLocked.requestTraversal(); } diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java index 24cf7f127e18..46b5f3ab38f9 100644 --- a/services/core/java/com/android/server/wm/RootActivityContainer.java +++ b/services/core/java/com/android/server/wm/RootActivityContainer.java @@ -347,7 +347,8 @@ class RootActivityContainer extends ConfigurationContainer } boolean startHomeOnDisplay(int userId, String reason, int displayId) { - return startHomeOnDisplay(userId, reason, displayId, false /*fromHomeKey*/); + return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */, + false /* fromHomeKey */); } /** @@ -361,7 +362,8 @@ class RootActivityContainer extends ConfigurationContainer * If there are multiple activities matched, use first one. * - Use the secondary home defined in the config. */ - boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean fromHomeKey) { + boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting, + boolean fromHomeKey) { // Fallback to top focused display if the displayId is invalid. if (displayId == INVALID_DISPLAY) { displayId = getTopDisplayFocusedStack().mDisplayId; @@ -383,7 +385,7 @@ class RootActivityContainer extends ConfigurationContainer return false; } - if (!canStartHomeOnDisplay(aInfo, displayId, false /* allowInstrumenting */)) { + if (!canStartHomeOnDisplay(aInfo, displayId, allowInstrumenting)) { return false; } diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java index 4fd84896e101..714c2274af8e 100644 --- a/services/core/java/com/android/server/wm/TaskRecord.java +++ b/services/core/java/com/android/server/wm/TaskRecord.java @@ -2115,8 +2115,9 @@ class TaskRecord extends ConfigurationContainer { // {@link WindowManagerPolicy#getNonDecorInsetsLw}. calculateInsetFrames(mTmpNonDecorBounds, mTmpStableBounds, bounds, di); } else { - mTmpNonDecorBounds.set(bounds); - mTmpStableBounds.set(bounds); + // Set to app bounds because it excludes decor insets. + mTmpNonDecorBounds.set(outAppBounds); + mTmpStableBounds.set(outAppBounds); } if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED) { diff --git a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java b/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java index e0d85e876476..4379b7cdace6 100644 --- a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java +++ b/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java @@ -41,7 +41,7 @@ class TaskScreenshotAnimatable implements SurfaceAnimator.Animatable { return new TaskScreenshotAnimatable(task, getBufferFromTask(task)); } - private static GraphicBuffer getBufferFromTask(Task task) { + private static SurfaceControl.ScreenshotGraphicBuffer getBufferFromTask(Task task) { if (task == null) { return null; } @@ -51,7 +51,10 @@ class TaskScreenshotAnimatable implements SurfaceAnimator.Animatable { task.getSurfaceControl().getHandle(), tmpRect, 1f); } - private TaskScreenshotAnimatable(Task task, GraphicBuffer buffer) { + private TaskScreenshotAnimatable(Task task, + SurfaceControl.ScreenshotGraphicBuffer screenshotBuffer) { + GraphicBuffer buffer = screenshotBuffer == null + ? null : screenshotBuffer.getGraphicBuffer(); mTask = task; mWidth = (buffer != null) ? buffer.getWidth() : 1; mHeight = (buffer != null) ? buffer.getHeight() : 1; diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java index beb3d82c05fb..6fe8b43db139 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotController.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java @@ -279,8 +279,11 @@ class TaskSnapshotController { Slog.w(TAG_WM, "Failed to take screenshot. No main window for " + task); return null; } - final GraphicBuffer buffer = SurfaceControl.captureLayers( - task.getSurfaceControl().getHandle(), mTmpRect, scaleFraction); + final SurfaceControl.ScreenshotGraphicBuffer screenshotBuffer = + SurfaceControl.captureLayers( + task.getSurfaceControl().getHandle(), mTmpRect, scaleFraction); + final GraphicBuffer buffer = screenshotBuffer != null ? screenshotBuffer.getGraphicBuffer() + : null; if (buffer == null || buffer.getWidth() <= 1 || buffer.getHeight() <= 1) { if (DEBUG_SCREENSHOT) { Slog.w(TAG_WM, "Failed to take screenshot for " + task); diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java index 938c8b452e29..dafed9ed919a 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java @@ -454,7 +454,7 @@ class TaskSnapshotSurface implements StartingSurface { public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout, - boolean alwaysConsumeNavBar, int displayId, + boolean alwaysConsumeSystemBars, int displayId, DisplayCutout.ParcelableWrapper displayCutout) { if (mergedConfiguration != null && mOuter != null && mOuter.mOrientationOnCreation diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java index dddc6b755db0..166a33d7a560 100644 --- a/services/core/java/com/android/server/wm/WallpaperController.java +++ b/services/core/java/com/android/server/wm/WallpaperController.java @@ -34,8 +34,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.H.WALLPAPER_DRAW_PENDING_TIMEOUT; import android.graphics.Bitmap; -import android.graphics.ColorSpace; -import android.graphics.GraphicBuffer; import android.graphics.Rect; import android.hardware.HardwareBuffer; import android.os.Bundle; @@ -738,17 +736,16 @@ class WallpaperController { final Rect bounds = wallpaperWindowState.getBounds(); bounds.offsetTo(0, 0); - GraphicBuffer wallpaperBuffer = SurfaceControl.captureLayers( + SurfaceControl.ScreenshotGraphicBuffer wallpaperBuffer = SurfaceControl.captureLayers( wallpaperWindowState.getSurfaceControl().getHandle(), bounds, 1 /* frameScale */); if (wallpaperBuffer == null) { Slog.w(TAG_WM, "Failed to screenshot wallpaper"); return null; } - // TODO(b/116112787) Now that hardware bitmap creation can take color space, we - // should continue to fix screenshot. - return Bitmap.wrapHardwareBuffer(HardwareBuffer.createFromGraphicBuffer(wallpaperBuffer), - ColorSpace.get(ColorSpace.Named.SRGB)); + return Bitmap.wrapHardwareBuffer( + HardwareBuffer.createFromGraphicBuffer(wallpaperBuffer.getGraphicBuffer()), + wallpaperBuffer.getColorSpace()); } private WindowState getTopVisibleWallpaper() { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 7751560203e7..4aa844ff4f49 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1534,7 +1534,7 @@ public class WindowManagerService extends IWindowManager.Stub } if (displayPolicy.getLayoutHintLw(win.mAttrs, taskBounds, displayFrames, floatingStack, outFrame, outContentInsets, outStableInsets, outOutsets, outDisplayCutout)) { - res |= WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_NAV_BAR; + res |= WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_SYSTEM_BARS; } outInsetsState.set(displayContent.getInsetsStateController().getInsetsForDispatch(win)); @@ -2206,8 +2206,8 @@ public class WindowManagerService extends IWindowManager.Stub winAnimator.mReportSurfaceResized = false; result |= WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED; } - if (displayPolicy.isNavBarForcedShownLw(win)) { - result |= WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_NAV_BAR; + if (displayPolicy.areSystemBarsForcedShownLw(win)) { + result |= WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS; } if (!win.isGoneForLayoutLw()) { win.mResizedWhileGone = false; @@ -5638,6 +5638,19 @@ public class WindowManagerService extends IWindowManager.Stub } } + @Override + public void setForceShowSystemBars(boolean show) { + if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR) + != PackageManager.PERMISSION_GRANTED) { + throw new SecurityException("Caller does not hold permission " + + android.Manifest.permission.STATUS_BAR); + } + synchronized (mGlobalLock) { + mRoot.forAllDisplayPolicies(PooledLambda.obtainConsumer( + DisplayPolicy::setForceShowSystemBars, PooledLambda.__(), show)); + } + } + public void setNavBarVirtualKeyHapticFeedbackEnabled(boolean enabled) { if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR) != PackageManager.PERMISSION_GRANTED) { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 600178fa3276..6a21327d8bb9 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -3117,7 +3117,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mClient.resized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets, outsets, reportDraw, mergedConfiguration, getBackdropFrame(frame), forceRelayout, - getDisplayContent().getDisplayPolicy().isNavBarForcedShownLw(this), displayId, + getDisplayContent().getDisplayPolicy().areSystemBarsForcedShownLw(this), displayId, new DisplayCutout.ParcelableWrapper(displayCutout)); mDragResizingChangeReported = true; } diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index 00b815ae1bfa..a7423ea40bf0 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -50,6 +50,7 @@ cc_library_static { "com_android_server_VibratorService.cpp", "com_android_server_PersistentDataBlockService.cpp", "com_android_server_GraphicsStatsService.cpp", + "com_android_server_am_AppCompactor.cpp", "onload.cpp", ], diff --git a/services/core/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_VibratorService.cpp index 63dca62104a1..d5fbd2b316e7 100644 --- a/services/core/jni/com_android_server_VibratorService.cpp +++ b/services/core/jni/com_android_server_VibratorService.cpp @@ -96,7 +96,7 @@ bool isValidEffect(jlong effect) { } R val = static_cast<R>(effect); auto iter = hardware::hidl_enum_range<R>(); - return val >= *iter.begin() && val < *std::prev(iter.end()); + return val >= *iter.begin() && val <= *std::prev(iter.end()); } static void vibratorInit(JNIEnv /* env */, jobject /* clazz */) @@ -170,6 +170,9 @@ static jlong vibratorPerformEffect(JNIEnv*, jobject, jlong effect, jint strength } else if (isValidEffect<V1_2::Effect>(effect)) { ret = halCall(&V1_2::IVibrator::perform_1_2, static_cast<V1_2::Effect>(effect), effectStrength, callback); + } else if (isValidEffect<V1_3::Effect>(effect)) { + ret = halCall(&V1_3::IVibrator::perform_1_3, static_cast<V1_3::Effect>(effect), + effectStrength, callback); } else { ALOGW("Unable to perform haptic effect, invalid effect ID (%" PRId32 ")", static_cast<int32_t>(effect)); diff --git a/services/core/jni/com_android_server_am_AppCompactor.cpp b/services/core/jni/com_android_server_am_AppCompactor.cpp new file mode 100644 index 000000000000..de6aa8b3266b --- /dev/null +++ b/services/core/jni/com_android_server_am_AppCompactor.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "AppCompactor" +//#define LOG_NDEBUG 0 + +#include <dirent.h> +#include <stddef.h> +#include <stdio.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +#include <android-base/stringprintf.h> +#include <android-base/file.h> + +#include <nativehelper/JNIHelp.h> +#include <android_runtime/AndroidRuntime.h> +#include <jni.h> + +using android::base::StringPrintf; +using android::base::WriteStringToFile; + +namespace android { + +// This performs per-process reclaim on all processes belonging to non-app UIDs. +// For the most part, these are non-zygote processes like Treble HALs, but it +// also includes zygote-derived processes that run in system UIDs, like bluetooth +// or potentially some mainline modules. The only process that should definitely +// not be compacted is system_server, since compacting system_server around the +// time of BOOT_COMPLETE could result in perceptible issues. +static void com_android_server_am_AppCompactor_compactSystem(JNIEnv *, jobject) { + std::unique_ptr<DIR, decltype(&closedir)> proc(opendir("/proc"), closedir); + struct dirent* current; + while ((current = readdir(proc.get()))) { + if (current->d_type != DT_DIR) { + continue; + } + + // don't compact system_server, rely on persistent compaction during screen off + // in order to avoid mmap_sem-related stalls + if (atoi(current->d_name) == getpid()) { + continue; + } + + std::string status_name = StringPrintf("/proc/%s/status", current->d_name); + struct stat status_info; + + if (stat(status_name.c_str(), &status_info) != 0) { + // must be some other directory that isn't a pid + continue; + } + + // android.os.Process.FIRST_APPLICATION_UID + if (status_info.st_uid >= 10000) { + continue; + } + + std::string reclaim_path = StringPrintf("/proc/%s/reclaim", current->d_name); + WriteStringToFile(std::string("all"), reclaim_path); + } +} + +static const JNINativeMethod sMethods[] = { + /* name, signature, funcPtr */ + {"compactSystem", "()V", (void*)com_android_server_am_AppCompactor_compactSystem}, +}; + +int register_android_server_am_AppCompactor(JNIEnv* env) +{ + return jniRegisterNativeMethods(env, "com/android/server/am/AppCompactor", + sMethods, NELEM(sMethods)); +} + +} diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index 65a7eec60f63..7df7ef3bae87 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -998,8 +998,9 @@ struct GnssMeasurementCallback : public IGnssMeasurementCallback_V2_0 { template<class T> size_t getMeasurementCount(const T& data); - jobject translateGnssClock( - JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssClock* clock); + template<class T> + void translateGnssClock(JavaObject& object, const T& data); + void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray); }; @@ -1025,12 +1026,12 @@ template<class T> void GnssMeasurementCallback::translateAndSetGnssData(const T& data) { JNIEnv* env = getJniEnv(); - jobject clock; - jobjectArray measurementArray; + JavaObject gnssClockJavaObject(env, "android/location/GnssClock"); + translateGnssClock(gnssClockJavaObject, data); + jobject clock = gnssClockJavaObject.get(); - clock = translateGnssClock(env, &data.clock); size_t count = getMeasurementCount(data); - measurementArray = translateAllGnssMeasurements(env, data.measurements.data(), count); + jobjectArray measurementArray = translateAllGnssMeasurements(env, data.measurements.data(), count); setMeasurementData(env, clock, measurementArray); env->DeleteLocalRef(clock); @@ -1124,43 +1125,59 @@ void GnssMeasurementCallback::translateSingleGnssMeasurement SET(ConstellationType, static_cast<int32_t>(measurement_V2_0->constellation)); } -jobject GnssMeasurementCallback::translateGnssClock( - JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssClock* clock) { - JavaObject object(env, "android/location/GnssClock"); +template<class T> +void GnssMeasurementCallback::translateGnssClock(JavaObject& object, const T& data) { + translateGnssClock(object, data.clock); +} - uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags); +template<> +void GnssMeasurementCallback::translateGnssClock( + JavaObject& object, const IGnssMeasurementCallback_V1_0::GnssClock& clock) { + uint32_t flags = static_cast<uint32_t>(clock.gnssClockFlags); if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) { - SET(LeapSecond, static_cast<int32_t>(clock->leapSecond)); + SET(LeapSecond, static_cast<int32_t>(clock.leapSecond)); } if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) { - SET(TimeUncertaintyNanos, clock->timeUncertaintyNs); + SET(TimeUncertaintyNanos, clock.timeUncertaintyNs); } if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) { - SET(FullBiasNanos, clock->fullBiasNs); + SET(FullBiasNanos, clock.fullBiasNs); } if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) { - SET(BiasNanos, clock->biasNs); + SET(BiasNanos, clock.biasNs); } if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) { - SET(BiasUncertaintyNanos, clock->biasUncertaintyNs); + SET(BiasUncertaintyNanos, clock.biasUncertaintyNs); } if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) { - SET(DriftNanosPerSecond, clock->driftNsps); + SET(DriftNanosPerSecond, clock.driftNsps); } if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) { - SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps); + SET(DriftUncertaintyNanosPerSecond, clock.driftUncertaintyNsps); } - SET(TimeNanos, clock->timeNs); - SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount); + SET(TimeNanos, clock.timeNs); + SET(HardwareClockDiscontinuityCount, clock.hwClockDiscontinuityCount); +} - return object.get(); +template<> +void GnssMeasurementCallback::translateGnssClock( + JavaObject& object, const IGnssMeasurementCallback_V2_0::GnssData& data) { + auto elapsedRealtime = data.elapsedRealtime; + uint16_t flags = static_cast<uint16_t>(elapsedRealtime.flags); + if (flags & ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) { + SET(ElapsedRealtimeNanos, static_cast<uint64_t>(elapsedRealtime.timestampNs)); + } + if (flags & ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS) { + SET(ElapsedRealtimeUncertaintyNanos, static_cast<uint64_t>(elapsedRealtime.timeUncertaintyNs)); + } + translateGnssClock(object, data.clock); } template<class T> diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp index 5ffed03c86ae..2cfaebf4632e 100644 --- a/services/core/jni/onload.cpp +++ b/services/core/jni/onload.cpp @@ -54,6 +54,7 @@ int register_android_server_GraphicsStatsService(JNIEnv* env); int register_android_hardware_display_DisplayViewport(JNIEnv* env); int register_android_server_net_NetworkStatsService(JNIEnv* env); int register_android_server_security_VerityUtils(JNIEnv* env); +int register_android_server_am_AppCompactor(JNIEnv* env); }; using namespace android; @@ -101,5 +102,6 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) register_android_hardware_display_DisplayViewport(env); register_android_server_net_NetworkStatsService(env); register_android_server_security_VerityUtils(env); + register_android_server_am_AppCompactor(env); return JNI_VERSION_1_4; } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index f6de82d8e237..633367ab2fe8 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -58,7 +58,14 @@ import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_HOME; import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS; import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW; import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE; +import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC; +import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC; +import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX; +import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_MANAGED; +import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; +import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX; +import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; import static android.app.admin.DevicePolicyManager.PRIVATE_DNS_MODE_OFF; import static android.app.admin.DevicePolicyManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; @@ -3475,15 +3482,15 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { static void validateQualityConstant(int quality) { switch (quality) { - case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED: - case DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK: - case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING: - case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC: - case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX: - case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC: - case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC: - case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX: - case DevicePolicyManager.PASSWORD_QUALITY_MANAGED: + case PASSWORD_QUALITY_UNSPECIFIED: + case PASSWORD_QUALITY_BIOMETRIC_WEAK: + case PASSWORD_QUALITY_SOMETHING: + case PASSWORD_QUALITY_NUMERIC: + case PASSWORD_QUALITY_NUMERIC_COMPLEX: + case PASSWORD_QUALITY_ALPHABETIC: + case PASSWORD_QUALITY_ALPHANUMERIC: + case PASSWORD_QUALITY_COMPLEX: + case PASSWORD_QUALITY_MANAGED: return; } throw new IllegalArgumentException("Invalid quality constant: 0x" @@ -4747,41 +4754,36 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { // setActivePasswordState has never been called for it. metrics = new PasswordMetrics(); } + return isPasswordSufficientForUserWithoutCheckpointLocked(metrics, userHandle, parent); } /** - * Returns {@code true} if the password represented by the {@code passwordMetrics} argument + * Returns {@code true} if the password represented by the {@code metrics} argument * sufficiently fulfills the password requirements for the user corresponding to - * {@code userHandle} (or its parent, if {@code parent} is set to {@code true}). + * {@code userId} (or its parent, if {@code parent} is set to {@code true}). */ private boolean isPasswordSufficientForUserWithoutCheckpointLocked( - PasswordMetrics passwordMetrics, int userHandle, boolean parent) { - final int requiredPasswordQuality = getPasswordQuality(null, userHandle, parent); + PasswordMetrics metrics, @UserIdInt int userId, boolean parent) { + final int requiredQuality = getPasswordQuality(null, userId, parent); - if (passwordMetrics.quality < requiredPasswordQuality) { - return false; - } - if (requiredPasswordQuality >= DevicePolicyManager.PASSWORD_QUALITY_NUMERIC - && passwordMetrics.length < getPasswordMinimumLength( - null, userHandle, parent)) { + if (requiredQuality >= PASSWORD_QUALITY_NUMERIC + && metrics.length < getPasswordMinimumLength(null, userId, parent)) { return false; } - if (requiredPasswordQuality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) { - return true; + + // PASSWORD_QUALITY_COMPLEX doesn't represent actual password quality, it means that number + // of characters of each class should be checked instead of quality itself. + if (requiredQuality == PASSWORD_QUALITY_COMPLEX) { + return metrics.upperCase >= getPasswordMinimumUpperCase(null, userId, parent) + && metrics.lowerCase >= getPasswordMinimumLowerCase(null, userId, parent) + && metrics.letters >= getPasswordMinimumLetters(null, userId, parent) + && metrics.numeric >= getPasswordMinimumNumeric(null, userId, parent) + && metrics.symbols >= getPasswordMinimumSymbols(null, userId, parent) + && metrics.nonLetter >= getPasswordMinimumNonLetter(null, userId, parent); + } else { + return metrics.quality >= requiredQuality; } - return passwordMetrics.upperCase >= getPasswordMinimumUpperCase( - null, userHandle, parent) - && passwordMetrics.lowerCase >= getPasswordMinimumLowerCase( - null, userHandle, parent) - && passwordMetrics.letters >= getPasswordMinimumLetters( - null, userHandle, parent) - && passwordMetrics.numeric >= getPasswordMinimumNumeric( - null, userHandle, parent) - && passwordMetrics.symbols >= getPasswordMinimumSymbols( - null, userHandle, parent) - && passwordMetrics.nonLetter >= getPasswordMinimumNonLetter( - null, userHandle, parent); } @Override @@ -5042,14 +5044,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { int quality; synchronized (getLockObject()) { quality = getPasswordQuality(null, userHandle, /* parent */ false); - if (quality == DevicePolicyManager.PASSWORD_QUALITY_MANAGED) { + if (quality == PASSWORD_QUALITY_MANAGED) { quality = PASSWORD_QUALITY_UNSPECIFIED; } // TODO(b/120484642): remove getBytes() below final PasswordMetrics metrics = PasswordMetrics.computeForPassword(password.getBytes()); final int realQuality = metrics.quality; - if (realQuality < quality - && quality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) { + if (realQuality < quality && quality != PASSWORD_QUALITY_COMPLEX) { Slog.w(LOG_TAG, "resetPassword: password quality 0x" + Integer.toHexString(realQuality) + " does not meet required quality 0x" @@ -5063,7 +5064,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { + " does not meet required length " + length); return false; } - if (quality == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) { + if (quality == PASSWORD_QUALITY_COMPLEX) { int neededLetters = getPasswordMinimumLetters(null, userHandle, /* parent */ false); if(metrics.letters < neededLetters) { Slog.w(LOG_TAG, "resetPassword: number of letters " + metrics.letters @@ -5132,11 +5133,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final boolean result; try { if (token == null) { + // This is the legacy reset password for DPM. Here we want to be able to override + // the old device password without necessarily knowing it. if (!TextUtils.isEmpty(password)) { mLockPatternUtils.saveLockPassword(password.getBytes(), null, quality, - userHandle); + userHandle, /*allowUntrustedChange */true); } else { - mLockPatternUtils.clearLock(null, userHandle); + mLockPatternUtils.clearLock(null, userHandle, + /*allowUntrustedChange */ true); } result = true; } else { @@ -5245,12 +5249,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { // would allow bypassing of the maximum time to lock. mInjector.settingsGlobalPutInt(Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0); } + getPowerManagerInternal().setMaximumScreenOffTimeoutFromDeviceAdmin( + UserHandle.USER_SYSTEM, timeMs); } finally { mInjector.binderRestoreCallingIdentity(ident); } - - getPowerManagerInternal().setMaximumScreenOffTimeoutFromDeviceAdmin( - UserHandle.USER_SYSTEM, timeMs); } private void updateProfileLockTimeoutLocked(@UserIdInt int userId) { @@ -5268,8 +5271,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } policy.mLastMaximumTimeToLock = timeMs; - getPowerManagerInternal().setMaximumScreenOffTimeoutFromDeviceAdmin( - userId, policy.mLastMaximumTimeToLock); + final long ident = mInjector.binderClearCallingIdentity(); + try { + getPowerManagerInternal().setMaximumScreenOffTimeoutFromDeviceAdmin( + userId, policy.mLastMaximumTimeToLock); + } finally { + mInjector.binderRestoreCallingIdentity(ident); + } } @Override diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 419f52cff578..d4ccb0b77bca 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -849,7 +849,7 @@ public final class SystemServer { private void startOtherServices() { final Context context = mSystemContext; VibratorService vibrator = null; - DynamicAndroidService dynamicAndroid = null; + DynamicSystemService dynamicSystem = null; IStorageManager storageManager = null; NetworkManagementService networkManagement = null; IpSecService ipSecService = null; @@ -968,9 +968,9 @@ public final class SystemServer { ServiceManager.addService("vibrator", vibrator); traceEnd(); - traceBeginAndSlog("StartDynamicAndroidService"); - dynamicAndroid = new DynamicAndroidService(context); - ServiceManager.addService("dynamic_android", dynamicAndroid); + traceBeginAndSlog("StartDynamicSystemService"); + dynamicSystem = new DynamicSystemService(context); + ServiceManager.addService("dynamic_system", dynamicSystem); traceEnd(); if (!isWatch) { diff --git a/services/net/Android.bp b/services/net/Android.bp index 486d15d918bf..9e1d44b9faff 100644 --- a/services/net/Android.bp +++ b/services/net/Android.bp @@ -1,3 +1,61 @@ +// AIDL interfaces between the core system and the networking mainline module. +aidl_interface { + name: "ipmemorystore-aidl-interfaces", + local_include_dir: "java", + srcs: [ + // TODO: Define and use a filegroup for these files, since they're also used in + // networkstack-aidl-interfaces. This does not appear to work at the moment. + "java/android/net/IIpMemoryStore.aidl", + "java/android/net/IIpMemoryStoreCallbacks.aidl", + "java/android/net/ipmemorystore/**/*.aidl", + ], + backend: { + ndk: { + enabled: false, + }, + cpp: { + enabled: false, + }, + }, + api_dir: "aidl/networkstack", +} + +aidl_interface { + name: "networkstack-aidl-interfaces", + local_include_dir: "java", + include_dirs: ["frameworks/base/core/java"], // For framework parcelables. + srcs: [ + "java/android/net/ApfCapabilitiesParcelable.aidl", + "java/android/net/DhcpResultsParcelable.aidl", + "java/android/net/IIpMemoryStore.aidl", + "java/android/net/IIpMemoryStoreCallbacks.aidl", + "java/android/net/INetworkMonitor.aidl", + "java/android/net/INetworkMonitorCallbacks.aidl", + "java/android/net/INetworkStackConnector.aidl", + "java/android/net/INetworkStackStatusCallback.aidl", + "java/android/net/InitialConfigurationParcelable.aidl", + "java/android/net/PrivateDnsConfigParcel.aidl", + "java/android/net/ProvisioningConfigurationParcelable.aidl", + "java/android/net/StaticIpConfigurationParcelable.aidl", + "java/android/net/TcpKeepalivePacketDataParcelable.aidl", + "java/android/net/dhcp/DhcpServingParamsParcel.aidl", + "java/android/net/dhcp/IDhcpServer.aidl", + "java/android/net/dhcp/IDhcpServerCallbacks.aidl", + "java/android/net/ip/IIpClient.aidl", + "java/android/net/ip/IIpClientCallbacks.aidl", + "java/android/net/ipmemorystore/**/*.aidl", + ], + backend: { + ndk: { + enabled: false, + }, + cpp: { + enabled: false, + }, + }, + api_dir: "aidl/networkstack", +} + java_library_static { name: "services.net", srcs: ["java/**/*.java"], diff --git a/core/java/android/net/ApfCapabilitiesParcelable.aidl b/services/net/java/android/net/ApfCapabilitiesParcelable.aidl index f0645d2782d2..f0645d2782d2 100644 --- a/core/java/android/net/ApfCapabilitiesParcelable.aidl +++ b/services/net/java/android/net/ApfCapabilitiesParcelable.aidl diff --git a/core/java/android/net/DhcpResultsParcelable.aidl b/services/net/java/android/net/DhcpResultsParcelable.aidl index cf5629b6f792..cf5629b6f792 100644 --- a/core/java/android/net/DhcpResultsParcelable.aidl +++ b/services/net/java/android/net/DhcpResultsParcelable.aidl diff --git a/core/java/android/net/IIpMemoryStore.aidl b/services/net/java/android/net/IIpMemoryStore.aidl index 6f88dec8dee9..6f88dec8dee9 100644 --- a/core/java/android/net/IIpMemoryStore.aidl +++ b/services/net/java/android/net/IIpMemoryStore.aidl diff --git a/core/java/android/net/IIpMemoryStoreCallbacks.aidl b/services/net/java/android/net/IIpMemoryStoreCallbacks.aidl index 53108dbca097..53108dbca097 100644 --- a/core/java/android/net/IIpMemoryStoreCallbacks.aidl +++ b/services/net/java/android/net/IIpMemoryStoreCallbacks.aidl diff --git a/core/java/android/net/INetworkMonitor.aidl b/services/net/java/android/net/INetworkMonitor.aidl index 1b0e1d788ff3..1b0e1d788ff3 100644 --- a/core/java/android/net/INetworkMonitor.aidl +++ b/services/net/java/android/net/INetworkMonitor.aidl diff --git a/core/java/android/net/INetworkMonitorCallbacks.aidl b/services/net/java/android/net/INetworkMonitorCallbacks.aidl index 2c61511feb72..2c61511feb72 100644 --- a/core/java/android/net/INetworkMonitorCallbacks.aidl +++ b/services/net/java/android/net/INetworkMonitorCallbacks.aidl diff --git a/core/java/android/net/INetworkStackConnector.aidl b/services/net/java/android/net/INetworkStackConnector.aidl index 3751c36d6ee9..3751c36d6ee9 100644 --- a/core/java/android/net/INetworkStackConnector.aidl +++ b/services/net/java/android/net/INetworkStackConnector.aidl diff --git a/core/java/android/net/INetworkStackStatusCallback.aidl b/services/net/java/android/net/INetworkStackStatusCallback.aidl index 51032d80a172..51032d80a172 100644 --- a/core/java/android/net/INetworkStackStatusCallback.aidl +++ b/services/net/java/android/net/INetworkStackStatusCallback.aidl diff --git a/core/java/android/net/InitialConfigurationParcelable.aidl b/services/net/java/android/net/InitialConfigurationParcelable.aidl index 3fa88c377a64..3fa88c377a64 100644 --- a/core/java/android/net/InitialConfigurationParcelable.aidl +++ b/services/net/java/android/net/InitialConfigurationParcelable.aidl diff --git a/core/java/android/net/PrivateDnsConfigParcel.aidl b/services/net/java/android/net/PrivateDnsConfigParcel.aidl index b52fce643302..b52fce643302 100644 --- a/core/java/android/net/PrivateDnsConfigParcel.aidl +++ b/services/net/java/android/net/PrivateDnsConfigParcel.aidl diff --git a/core/java/android/net/ProvisioningConfigurationParcelable.aidl b/services/net/java/android/net/ProvisioningConfigurationParcelable.aidl index 5b46d7f55ee3..5b46d7f55ee3 100644 --- a/core/java/android/net/ProvisioningConfigurationParcelable.aidl +++ b/services/net/java/android/net/ProvisioningConfigurationParcelable.aidl diff --git a/core/java/android/net/StaticIpConfigurationParcelable.aidl b/services/net/java/android/net/StaticIpConfigurationParcelable.aidl index 6fffb423edb5..6fffb423edb5 100644 --- a/core/java/android/net/StaticIpConfigurationParcelable.aidl +++ b/services/net/java/android/net/StaticIpConfigurationParcelable.aidl diff --git a/services/net/java/android/net/TcpKeepalivePacketData.java b/services/net/java/android/net/TcpKeepalivePacketData.java index d79ad1fe41a9..7f2f499ab21f 100644 --- a/services/net/java/android/net/TcpKeepalivePacketData.java +++ b/services/net/java/android/net/TcpKeepalivePacketData.java @@ -38,7 +38,7 @@ import java.util.Objects; public class TcpKeepalivePacketData extends KeepalivePacketData implements Parcelable { private static final String TAG = "TcpKeepalivePacketData"; - /** TCP sequence number. */ + /** TCP sequence number. */ public final int tcpSeq; /** TCP ACK number. */ @@ -50,6 +50,12 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce /** TCP RCV window scale. */ public final int tcpWndScale; + /** IP TOS. */ + public final int ipTos; + + /** IP TTL. */ + public final int ipTtl; + private static final int IPV4_HEADER_LENGTH = 20; private static final int IPV6_HEADER_LENGTH = 40; private static final int TCP_HEADER_LENGTH = 20; @@ -65,6 +71,8 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce // In the packet, the window is shifted right by the window scale. tcpWnd = tcpDetails.rcvWnd; tcpWndScale = tcpDetails.rcvWndScale; + ipTos = tcpDetails.tos; + ipTtl = tcpDetails.ttl; } /** @@ -98,12 +106,11 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce final int length = IPV4_HEADER_LENGTH + TCP_HEADER_LENGTH; ByteBuffer buf = ByteBuffer.allocate(length); buf.order(ByteOrder.BIG_ENDIAN); - // IP version and TOS. TODO : fetch this from getsockopt(SOL_IP, IP_TOS) - buf.putShort((short) 0x4500); + buf.put((byte) 0x45); // IP version and IHL + buf.put((byte) tcpDetails.tos); // TOS buf.putShort((short) length); - buf.putInt(0x4000); // ID, flags=DF, offset - // TODO : fetch TTL from getsockopt(SOL_IP, IP_TTL) - buf.put((byte) 64); + buf.putInt(0x00004000); // ID, flags=DF, offset + buf.put((byte) tcpDetails.ttl); // TTL buf.put((byte) OsConstants.IPPROTO_TCP); final int ipChecksumOffset = buf.position(); buf.putShort((short) 0); // IP checksum @@ -117,7 +124,9 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce buf.putShort((short) (tcpDetails.rcvWnd >> tcpDetails.rcvWndScale)); // Window size final int tcpChecksumOffset = buf.position(); buf.putShort((short) 0); // TCP checksum - // URG is not set therefore the urgent pointer is not included + // URG is not set therefore the urgent pointer is zero. + buf.putShort((short) 0); // Urgent pointer + buf.putShort(ipChecksumOffset, IpUtils.ipChecksum(buf, 0)); buf.putShort(tcpChecksumOffset, IpUtils.tcpChecksum( buf, 0, IPV4_HEADER_LENGTH, TCP_HEADER_LENGTH)); @@ -138,13 +147,15 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce && this.tcpAck == other.tcpAck && this.tcpSeq == other.tcpSeq && this.tcpWnd == other.tcpWnd - && this.tcpWndScale == other.tcpWndScale; + && this.tcpWndScale == other.tcpWndScale + && this.ipTos == other.ipTos + && this.ipTtl == other.ipTtl; } @Override public int hashCode() { return Objects.hash(srcAddress, dstAddress, srcPort, dstPort, tcpAck, tcpSeq, tcpWnd, - tcpWndScale); + tcpWndScale, ipTos, ipTtl); } /** @@ -164,6 +175,8 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce out.writeInt(tcpAck); out.writeInt(tcpWnd); out.writeInt(tcpWndScale); + out.writeInt(ipTos); + out.writeInt(ipTtl); } private TcpKeepalivePacketData(Parcel in) { @@ -172,6 +185,8 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce tcpAck = in.readInt(); tcpWnd = in.readInt(); tcpWndScale = in.readInt(); + ipTos = in.readInt(); + ipTtl = in.readInt(); } /** Parcelable Creator. */ @@ -200,6 +215,8 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce parcel.ack = tcpAck; parcel.rcvWnd = tcpWnd; parcel.rcvWndScale = tcpWndScale; + parcel.tos = ipTos; + parcel.ttl = ipTtl; return parcel; } @@ -212,6 +229,8 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce + " seq: " + tcpSeq + " ack: " + tcpAck + " wnd: " + tcpWnd - + " wndScale: " + tcpWndScale; + + " wndScale: " + tcpWndScale + + " tos: " + ipTos + + " ttl: " + ipTtl; } } diff --git a/core/java/android/net/TcpKeepalivePacketDataParcelable.aidl b/services/net/java/android/net/TcpKeepalivePacketDataParcelable.aidl index d66b6ae3ab54..e25168d588e7 100644 --- a/core/java/android/net/TcpKeepalivePacketDataParcelable.aidl +++ b/services/net/java/android/net/TcpKeepalivePacketDataParcelable.aidl @@ -25,4 +25,6 @@ parcelable TcpKeepalivePacketDataParcelable { int ack; int rcvWnd; int rcvWndScale; + int tos; + int ttl; } diff --git a/core/java/android/net/dhcp/DhcpServingParamsParcel.aidl b/services/net/java/android/net/dhcp/DhcpServingParamsParcel.aidl index 7b8b9ee324bc..7b8b9ee324bc 100644 --- a/core/java/android/net/dhcp/DhcpServingParamsParcel.aidl +++ b/services/net/java/android/net/dhcp/DhcpServingParamsParcel.aidl diff --git a/core/java/android/net/dhcp/IDhcpServer.aidl b/services/net/java/android/net/dhcp/IDhcpServer.aidl index 559433b13962..559433b13962 100644 --- a/core/java/android/net/dhcp/IDhcpServer.aidl +++ b/services/net/java/android/net/dhcp/IDhcpServer.aidl diff --git a/core/java/android/net/dhcp/IDhcpServerCallbacks.aidl b/services/net/java/android/net/dhcp/IDhcpServerCallbacks.aidl index 7ab4dcdbe584..7ab4dcdbe584 100644 --- a/core/java/android/net/dhcp/IDhcpServerCallbacks.aidl +++ b/services/net/java/android/net/dhcp/IDhcpServerCallbacks.aidl diff --git a/core/java/android/net/ip/IIpClient.aidl b/services/net/java/android/net/ip/IIpClient.aidl index b834e45c6852..b834e45c6852 100644 --- a/core/java/android/net/ip/IIpClient.aidl +++ b/services/net/java/android/net/ip/IIpClient.aidl diff --git a/core/java/android/net/ip/IIpClientCallbacks.aidl b/services/net/java/android/net/ip/IIpClientCallbacks.aidl index 3681416611a9..3681416611a9 100644 --- a/core/java/android/net/ip/IIpClientCallbacks.aidl +++ b/services/net/java/android/net/ip/IIpClientCallbacks.aidl diff --git a/core/java/android/net/ipmemorystore/Blob.aidl b/services/net/java/android/net/ipmemorystore/Blob.aidl index 9dbef117f8a4..9dbef117f8a4 100644 --- a/core/java/android/net/ipmemorystore/Blob.aidl +++ b/services/net/java/android/net/ipmemorystore/Blob.aidl diff --git a/core/java/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl b/services/net/java/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl index 4926feb06e55..4926feb06e55 100644 --- a/core/java/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl +++ b/services/net/java/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl diff --git a/core/java/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl b/services/net/java/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl index dea0cc4e2586..dea0cc4e2586 100644 --- a/core/java/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl +++ b/services/net/java/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl diff --git a/core/java/android/net/ipmemorystore/IOnNetworkAttributesRetrieved.aidl b/services/net/java/android/net/ipmemorystore/IOnNetworkAttributesRetrieved.aidl index fb4ca3b97895..fb4ca3b97895 100644 --- a/core/java/android/net/ipmemorystore/IOnNetworkAttributesRetrieved.aidl +++ b/services/net/java/android/net/ipmemorystore/IOnNetworkAttributesRetrieved.aidl diff --git a/core/java/android/net/ipmemorystore/IOnSameNetworkResponseListener.aidl b/services/net/java/android/net/ipmemorystore/IOnSameNetworkResponseListener.aidl index 294bd3bd4012..294bd3bd4012 100644 --- a/core/java/android/net/ipmemorystore/IOnSameNetworkResponseListener.aidl +++ b/services/net/java/android/net/ipmemorystore/IOnSameNetworkResponseListener.aidl diff --git a/core/java/android/net/ipmemorystore/IOnStatusListener.aidl b/services/net/java/android/net/ipmemorystore/IOnStatusListener.aidl index 5d0750449ec5..5d0750449ec5 100644 --- a/core/java/android/net/ipmemorystore/IOnStatusListener.aidl +++ b/services/net/java/android/net/ipmemorystore/IOnStatusListener.aidl diff --git a/core/java/android/net/ipmemorystore/NetworkAttributesParcelable.aidl b/services/net/java/android/net/ipmemorystore/NetworkAttributesParcelable.aidl index 0894d7260915..0894d7260915 100644 --- a/core/java/android/net/ipmemorystore/NetworkAttributesParcelable.aidl +++ b/services/net/java/android/net/ipmemorystore/NetworkAttributesParcelable.aidl diff --git a/core/java/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl b/services/net/java/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl index 71966998a68a..71966998a68a 100644 --- a/core/java/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl +++ b/services/net/java/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl diff --git a/core/java/android/net/ipmemorystore/StatusParcelable.aidl b/services/net/java/android/net/ipmemorystore/StatusParcelable.aidl index fb36ef4a56ff..fb36ef4a56ff 100644 --- a/core/java/android/net/ipmemorystore/StatusParcelable.aidl +++ b/services/net/java/android/net/ipmemorystore/StatusParcelable.aidl diff --git a/services/net/java/android/net/shared/NetworkMonitorUtils.java b/services/net/java/android/net/shared/NetworkMonitorUtils.java index 3d2a2de45539..a17cb4647158 100644 --- a/services/net/java/android/net/shared/NetworkMonitorUtils.java +++ b/services/net/java/android/net/shared/NetworkMonitorUtils.java @@ -44,18 +44,14 @@ public class NetworkMonitorUtils { public static final String PERMISSION_ACCESS_NETWORK_CONDITIONS = "android.permission.ACCESS_NETWORK_CONDITIONS"; - // TODO: once the URL is a resource overlay, remove and have the resource define the default - private static final String DEFAULT_HTTP_URL = - "http://connectivitycheck.gstatic.com/generate_204"; - /** * Get the captive portal server HTTP URL that is configured on the device. */ - public static String getCaptivePortalServerHttpUrl(Context context) { + public static String getCaptivePortalServerHttpUrl(Context context, String defaultUrl) { final String settingUrl = Settings.Global.getString( context.getContentResolver(), Settings.Global.CAPTIVE_PORTAL_HTTP_URL); - return settingUrl != null ? settingUrl : DEFAULT_HTTP_URL; + return settingUrl != null ? settingUrl : defaultUrl; } /** diff --git a/services/tests/mockingservicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java b/services/tests/mockingservicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java index 2e5efbd1deef..212d2a845254 100644 --- a/services/tests/mockingservicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java @@ -112,7 +112,7 @@ public class BatterySaverStateMachineTest { Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED, 0) != 0, mPersistedState.global.getOrDefault( Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_LEVEL, 90), - mPersistedState.global.getOrDefault(Global.AUTOMATIC_POWER_SAVER_MODE, 0), + mPersistedState.global.getOrDefault(Global.AUTOMATIC_POWER_SAVE_MODE, 0), mPersistedState.global.getOrDefault( Global.DYNAMIC_POWER_SAVINGS_ENABLED, 0) != 0, mPersistedState.global.getOrDefault( @@ -321,7 +321,7 @@ public class BatterySaverStateMachineTest { @Test public void testAutoBatterySaver() { mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 50); - mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVER_MODE, 0); + mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVE_MODE, 0); assertEquals(false, mDevice.batterySaverEnabled); assertEquals(100, mPersistedState.batteryLevel); @@ -789,7 +789,7 @@ public class BatterySaverStateMachineTest { .thenReturn(true); initDevice(); mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 50); - mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVER_MODE, 0); + mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVE_MODE, 0); mTarget.setBatterySaverEnabledManually(true); @@ -906,8 +906,8 @@ public class BatterySaverStateMachineTest { @Test public void testAutoBatterySaver_smartBatterySaverEnabled() { mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 50); - mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVER_MODE, - PowerManager.POWER_SAVER_MODE_DYNAMIC); + mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVE_MODE, + PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC); mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_ENABLED, 0); assertEquals(false, mDevice.batterySaverEnabled); @@ -1029,8 +1029,8 @@ public class BatterySaverStateMachineTest { // Test dynamic threshold higher than automatic to make sure it doesn't interfere when it's // not enabled. mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 50); - mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVER_MODE, - PowerManager.POWER_SAVER_MODE_PERCENTAGE); + mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVE_MODE, + PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE); mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_ENABLED, 0); assertEquals(false, mDevice.batterySaverEnabled); @@ -1138,8 +1138,8 @@ public class BatterySaverStateMachineTest { // not enabled. mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 50); mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 30); - mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVER_MODE, - PowerManager.POWER_SAVER_MODE_DYNAMIC); + mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVE_MODE, + PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC); mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_ENABLED, 1); assertEquals(false, mDevice.batterySaverEnabled); diff --git a/services/tests/servicestests/src/com/android/server/DynamicAndroidServiceTest.java b/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java index 149428443fa1..4a9dd9776a1b 100644 --- a/services/tests/servicestests/src/com/android/server/DynamicAndroidServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java @@ -16,28 +16,28 @@ package com.android.server; -import android.os.IDynamicAndroidService; import android.os.ServiceManager; +import android.os.image.IDynamicSystemService; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.LargeTest; -public class DynamicAndroidServiceTest extends AndroidTestCase { - private static final String TAG = "DynamicAndroidServiceTests"; - private IDynamicAndroidService mService; +public class DynamicSystemServiceTest extends AndroidTestCase { + private static final String TAG = "DynamicSystemServiceTests"; + private IDynamicSystemService mService; @Override protected void setUp() throws Exception { mService = - IDynamicAndroidService.Stub.asInterface( - ServiceManager.getService("dynamic_android")); + IDynamicSystemService.Stub.asInterface( + ServiceManager.getService("dynamic_system")); } @LargeTest public void test1() { - assertTrue("dynamic_android service available", mService != null); + assertTrue("dynamic_system service available", mService != null); try { mService.startInstallation(1 << 20, 8 << 30); - fail("DynamicAndroidService did not throw SecurityException as expected"); + fail("DynamicSystemService did not throw SecurityException as expected"); } catch (SecurityException e) { // expected } catch (Exception e) { diff --git a/services/tests/servicestests/src/com/android/server/backup/testutils/IPackageManagerStub.java b/services/tests/servicestests/src/com/android/server/backup/testutils/IPackageManagerStub.java index caf6c9cac509..4b3d9cf59487 100644 --- a/services/tests/servicestests/src/com/android/server/backup/testutils/IPackageManagerStub.java +++ b/services/tests/servicestests/src/com/android/server/backup/testutils/IPackageManagerStub.java @@ -1068,6 +1068,12 @@ public class IPackageManagerStub implements IPackageManager { } @Override + public ParceledListSlice getDeclaredSharedLibraries(String packageName, int flags, int userId) + throws RemoteException { + return null; + } + + @Override public boolean canRequestPackageInstalls(String packageName, int userId) throws RemoteException { return false; diff --git a/services/tests/servicestests/src/com/android/server/display/color/GlobalSaturationTintControllerTest.java b/services/tests/servicestests/src/com/android/server/display/color/GlobalSaturationTintControllerTest.java new file mode 100644 index 000000000000..7b88a0e012de --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/display/color/GlobalSaturationTintControllerTest.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.display.color; + +import static com.google.common.truth.Truth.assertThat; + +import android.opengl.Matrix; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class GlobalSaturationTintControllerTest { + + @Test + public void setAndGetMatrix() { + final GlobalSaturationTintController tintController = new GlobalSaturationTintController(); + tintController.setMatrix(50); + assertThat(tintController.getMatrix()).hasValuesWithin(0.00001f) + .of(new float[]{0.6155f, 0.1155f, 0.1155f, 0.0f, 0.3575f, 0.85749996f, 0.3575f, + 0.0f, 0.036f, 0.036f, 0.536f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}); + } + + @Test + public void resetMatrix() { + final GlobalSaturationTintController tintController = new GlobalSaturationTintController(); + tintController.setMatrix(100); + final float[] matrix = new float[16]; + Matrix.setIdentityM(matrix, 0); + assertThat(tintController.getMatrix()).hasValuesWithin(0.00001f).of(matrix); + } +} diff --git a/services/tests/servicestests/src/com/android/server/locksettings/CachedSyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/CachedSyntheticPasswordTests.java index 94d21ddeaa2b..ca4330fa7a5d 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/CachedSyntheticPasswordTests.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/CachedSyntheticPasswordTests.java @@ -61,12 +61,12 @@ public class CachedSyntheticPasswordTests extends SyntheticPasswordTests { long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID); // clear password mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, null, - PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID); + PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID, true); assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID)); // set a new password mService.setLockCredential(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, - PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID); + PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false); assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID) .getResponseCode()); @@ -81,7 +81,7 @@ public class CachedSyntheticPasswordTests extends SyntheticPasswordTests { long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID); // Untrusted change password mService.setLockCredential(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, - PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID); + PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, true); assertNotEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID)); assertNotEquals(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID)); @@ -99,7 +99,7 @@ public class CachedSyntheticPasswordTests extends SyntheticPasswordTests { initializeCredentialUnderSP(password, PRIMARY_USER_ID); // Untrusted change password mService.setLockCredential(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, - PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID); + PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, true); // Verify the password assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(newPassword, @@ -124,10 +124,12 @@ public class CachedSyntheticPasswordTests extends SyntheticPasswordTests { initializeCredentialUnderSP(password, PRIMARY_USER_ID); long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID); // Untrusted change password - assertExpectException(IllegalStateException.class, /* messageRegex= */ null, + assertExpectException( + IllegalStateException.class, + /* messageRegex= */ "Untrusted credential reset not possible without cached SP", () -> mService.setLockCredential(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, - PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID)); + PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, true)); assertEquals(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID)); // Verify the new password doesn't work but the old one still does diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java index 6e0ba3cb366c..255e694bffaf 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java @@ -85,9 +85,9 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { try { mService.setLockCredential("newpwd".getBytes(), CREDENTIAL_TYPE_PASSWORD, - "badpwd".getBytes(), PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID); + "badpwd".getBytes(), PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false); fail("Did not fail when enrolling using incorrect credential"); - } catch (RemoteException expected) { + } catch (IllegalStateException expected) { assertTrue(expected.getMessage().equals(FAILED_MESSAGE)); } assertVerifyCredentials(PRIMARY_USER_ID, "password", CREDENTIAL_TYPE_PASSWORD, sid); @@ -97,7 +97,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { final String PASSWORD = "password"; initializeStorageWithCredential(PRIMARY_USER_ID, PASSWORD, CREDENTIAL_TYPE_PASSWORD, 1234); mService.setLockCredential(null, CREDENTIAL_TYPE_NONE, PASSWORD.getBytes(), - PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID); + PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID, false); assertFalse(mService.havePassword(PRIMARY_USER_ID)); assertFalse(mService.havePattern(PRIMARY_USER_ID)); assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID)); @@ -108,7 +108,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { final String secondUnifiedPassword = "testManagedProfileUnifiedChallenge-pwd-2"; mService.setLockCredential(firstUnifiedPassword.getBytes(), LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, - null, PASSWORD_QUALITY_COMPLEX, PRIMARY_USER_ID); + null, PASSWORD_QUALITY_COMPLEX, PRIMARY_USER_ID, false); mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null); final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID); final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID); @@ -143,15 +143,16 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { mStorageManager.setIgnoreBadUnlock(true); // Change primary password and verify that profile SID remains mService.setLockCredential(secondUnifiedPassword.getBytes(), - LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, - firstUnifiedPassword.getBytes(), PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID); + LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, firstUnifiedPassword.getBytes(), + PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false); mStorageManager.setIgnoreBadUnlock(false); assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID)); assertNull(mGateKeeperService.getAuthToken(TURNED_OFF_PROFILE_USER_ID)); // Clear unified challenge mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, - secondUnifiedPassword.getBytes(), PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID); + secondUnifiedPassword.getBytes(), PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID, + false); assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID)); assertEquals(0, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID)); assertEquals(0, mGateKeeperService.getSecureUserId(TURNED_OFF_PROFILE_USER_ID)); @@ -162,7 +163,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { final String profilePassword = "testManagedProfileSeparateChallenge-profile"; mService.setLockCredential(primaryPassword.getBytes(), LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, - PASSWORD_QUALITY_COMPLEX, PRIMARY_USER_ID); + PASSWORD_QUALITY_COMPLEX, PRIMARY_USER_ID, false); /* Currently in LockSettingsService.setLockCredential, unlockUser() is called with the new * credential as part of verifyCredential() before the new credential is committed in * StorageManager. So we relax the check in our mock StorageManager to allow that. @@ -170,7 +171,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { mStorageManager.setIgnoreBadUnlock(true); mService.setLockCredential(profilePassword.getBytes(), LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, - PASSWORD_QUALITY_COMPLEX, MANAGED_PROFILE_USER_ID); + PASSWORD_QUALITY_COMPLEX, MANAGED_PROFILE_USER_ID, false); mStorageManager.setIgnoreBadUnlock(false); final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID); @@ -197,7 +198,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { // Change primary credential and make sure we don't affect profile mStorageManager.setIgnoreBadUnlock(true); mService.setLockCredential("pwd".getBytes(), LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, - primaryPassword.getBytes(), PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID); + primaryPassword.getBytes(), PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false); mStorageManager.setIgnoreBadUnlock(false); assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential( profilePassword.getBytes(), LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, @@ -208,7 +209,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { private void testCreateCredential(int userId, String credential, int type, int quality) throws RemoteException { mService.setLockCredential(credential.getBytes(), type, null, quality, - userId); + userId, false); assertVerifyCredentials(userId, credential, type, -1); } @@ -218,7 +219,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { try { mService.setLockCredential(credential.getBytes(), type, null, quality, - userId); + userId, false); fail("An exception should have been thrown."); } catch (UnsupportedOperationException e) { // Success - the exception was expected. @@ -233,7 +234,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { final long sid = 1234; initializeStorageWithCredential(userId, oldCredential, oldType, sid); mService.setLockCredential(newCredential.getBytes(), newType, oldCredential.getBytes(), - quality, userId); + quality, userId, false); assertVerifyCredentials(userId, newCredential, newType, sid); } diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java index 6a07a45ed360..5a9ca0f88287 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java @@ -102,7 +102,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { disableSyntheticPassword(); mService.setLockCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, - PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID); + PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false); long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID); final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID); enableSyntheticPassword(); @@ -127,7 +127,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { : PASSWORD_QUALITY_UNSPECIFIED; int type = password != null ? LockPatternUtils.CREDENTIAL_TYPE_PASSWORD : LockPatternUtils.CREDENTIAL_TYPE_NONE; - mService.setLockCredential(password, type, null, quality, userId); + mService.setLockCredential(password, type, null, quality, userId, false); } public void testSyntheticPasswordChangeCredential() throws RemoteException { @@ -137,7 +137,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { initializeCredentialUnderSP(password, PRIMARY_USER_ID); long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID); mService.setLockCredential(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, password, - PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID); + PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false); assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential( newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID) .getResponseCode()); @@ -166,12 +166,12 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID); // clear password mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, password, - PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID); + PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID, false); assertEquals(0 ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID)); // set a new password mService.setLockCredential(badPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, - PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID); + PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false); assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential( badPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID) .getResponseCode()); @@ -186,7 +186,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { initializeCredentialUnderSP(password, PRIMARY_USER_ID); mService.setLockCredential(badPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, password, - PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID); + PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false); assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential( badPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID) .getResponseCode()); @@ -245,7 +245,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { final byte[] password = "getASyntheticPassword".getBytes(); initializeCredentialUnderSP(password, PRIMARY_USER_ID); mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, password, - PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID); + PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID, false); reset(mAuthSecretService); mService.onUnlockUser(PRIMARY_USER_ID); @@ -257,7 +257,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { final byte[] UnifiedPassword = "testManagedProfileUnifiedChallengeMigration-pwd".getBytes(); disableSyntheticPassword(); mService.setLockCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, - PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID); + PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false); mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null); final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID); final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID); @@ -294,9 +294,9 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { "testManagedProfileSeparateChallengeMigration-profile".getBytes(); disableSyntheticPassword(); mService.setLockCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, - PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID); + PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false); mService.setLockCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, - PASSWORD_QUALITY_ALPHABETIC, MANAGED_PROFILE_USER_ID); + PASSWORD_QUALITY_ALPHABETIC, MANAGED_PROFILE_USER_ID, false); final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID); final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID); final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID); @@ -353,8 +353,8 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { // Verify DPM gets notified about new device lock mService.mHandler.runWithScissors(() -> {}, 0 /*now*/); // Flush runnables on handler - PasswordMetrics metric = PasswordMetrics.computeForPassword(pattern); - metric.quality = PASSWORD_QUALITY_SOMETHING; + final PasswordMetrics metric = PasswordMetrics.computeForCredential( + LockPatternUtils.CREDENTIAL_TYPE_PATTERN, pattern); verify(mDevicePolicyManager).setActivePasswordState(metric, PRIMARY_USER_ID); assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential( @@ -404,7 +404,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID)); mService.setLockCredential(pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, password, - PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID); + PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID, false); mLocalService.setLockCredentialWithToken(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, handle, token, @@ -443,7 +443,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { // Set up pre-SP user password disableSyntheticPassword(); mService.setLockCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, - PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID); + PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false); enableSyntheticPassword(); long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID, null); @@ -491,12 +491,12 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { public void testgetHashFactorPrimaryUser() throws RemoteException { final byte[] password = "password".getBytes(); mService.setLockCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, - PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID); + PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false); final byte[] hashFactor = mService.getHashFactor(password, PRIMARY_USER_ID); assertNotNull(hashFactor); mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, - password, PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID); + password, PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID, false); final byte[] newHashFactor = mService.getHashFactor(null, PRIMARY_USER_ID); assertNotNull(newHashFactor); // Hash factor should never change after password change/removal @@ -506,7 +506,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { public void testgetHashFactorManagedProfileUnifiedChallenge() throws RemoteException { final byte[] pattern = "1236".getBytes(); mService.setLockCredential(pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, - null, PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID); + null, PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID, false); mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null); assertNotNull(mService.getHashFactor(null, MANAGED_PROFILE_USER_ID)); } @@ -515,9 +515,9 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { final byte[] primaryPassword = "primary".getBytes(); final byte[] profilePassword = "profile".getBytes(); mService.setLockCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, - PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID); + PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false); mService.setLockCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, - PASSWORD_QUALITY_ALPHABETIC, MANAGED_PROFILE_USER_ID); + PASSWORD_QUALITY_ALPHABETIC, MANAGED_PROFILE_USER_ID, false); assertNotNull(mService.getHashFactor(profilePassword, MANAGED_PROFILE_USER_ID)); } diff --git a/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java b/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java index a1a58b49329f..5de41ea5e7d1 100644 --- a/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java +++ b/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java @@ -21,7 +21,6 @@ import static android.os.BatteryStats.Uid.NUM_USER_ACTIVITY_TYPES; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; @@ -29,6 +28,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.attention.AttentionManagerInternal; +import android.attention.AttentionManagerInternal.AttentionCallbackInternal; import android.os.PowerManager; import android.os.PowerManagerInternal; import android.os.SystemClock; @@ -41,14 +41,17 @@ import android.test.suitebuilder.annotation.SmallTest; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @SmallTest public class AttentionDetectorTest extends AndroidTestCase { - private @Mock AttentionManagerInternal mAttentionManagerInternal; - private @Mock Runnable mOnUserAttention; + @Mock + private AttentionManagerInternal mAttentionManagerInternal; + @Mock + private Runnable mOnUserAttention; private TestableAttentionDetector mAttentionDetector; private long mAttentionTimeout; private long mNextDimming; @@ -57,7 +60,7 @@ public class AttentionDetectorTest extends AndroidTestCase { @Before public void setUp() { MockitoAnnotations.initMocks(this); - when(mAttentionManagerInternal.checkAttention(anyInt(), anyLong(), any())) + when(mAttentionManagerInternal.checkAttention(anyLong(), any())) .thenReturn(true); mAttentionDetector = new TestableAttentionDetector(); mAttentionDetector.onWakefulnessChangeStarted(PowerManagerInternal.WAKEFULNESS_AWAKE); @@ -82,7 +85,7 @@ public class AttentionDetectorTest extends AndroidTestCase { @Test public void testOnUserActivity_checksAttention() { long when = registerAttention(); - verify(mAttentionManagerInternal).checkAttention(anyInt(), anyLong(), any()); + verify(mAttentionManagerInternal).checkAttention(anyLong(), any()); assertThat(when).isLessThan(mNextDimming); } @@ -92,7 +95,7 @@ public class AttentionDetectorTest extends AndroidTestCase { Settings.System.ADAPTIVE_SLEEP, 0, UserHandle.USER_CURRENT); mAttentionDetector.updateEnabledFromSettings(getContext()); long when = registerAttention(); - verify(mAttentionManagerInternal, never()).checkAttention(anyInt(), anyLong(), any()); + verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any()); assertThat(mNextDimming).isEqualTo(when); } @@ -100,7 +103,7 @@ public class AttentionDetectorTest extends AndroidTestCase { public void testOnUserActivity_doesntCheckIfNotSupported() { mAttentionDetector.setAttentionServiceSupported(false); long when = registerAttention(); - verify(mAttentionManagerInternal, never()).checkAttention(anyInt(), anyLong(), any()); + verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any()); assertThat(mNextDimming).isEqualTo(when); } @@ -129,7 +132,7 @@ public class AttentionDetectorTest extends AndroidTestCase { mNextDimming = now; mAttentionDetector.onUserActivity(now, PowerManager.USER_ACTIVITY_EVENT_TOUCH); mAttentionDetector.updateUserActivity(mNextDimming + 5000L); - verify(mAttentionManagerInternal, never()).checkAttention(anyInt(), anyLong(), any()); + verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any()); } @Test @@ -146,7 +149,7 @@ public class AttentionDetectorTest extends AndroidTestCase { long now = SystemClock.uptimeMillis(); mAttentionDetector.onUserActivity(now - 15000L, PowerManager.USER_ACTIVITY_EVENT_TOUCH); mAttentionDetector.updateUserActivity(now + 2000L); - verify(mAttentionManagerInternal, never()).checkAttention(anyInt(), anyLong(), any()); + verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any()); } @Test @@ -154,7 +157,7 @@ public class AttentionDetectorTest extends AndroidTestCase { registerAttention(); reset(mAttentionManagerInternal); long when = mAttentionDetector.updateUserActivity(mNextDimming); - verify(mAttentionManagerInternal, never()).checkAttention(anyInt(), anyLong(), any()); + verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any()); assertThat(when).isLessThan(mNextDimming); } @@ -162,32 +165,35 @@ public class AttentionDetectorTest extends AndroidTestCase { public void testOnWakefulnessChangeStarted_cancelsRequestWhenNotAwake() { registerAttention(); mAttentionDetector.onWakefulnessChangeStarted(PowerManagerInternal.WAKEFULNESS_ASLEEP); - verify(mAttentionManagerInternal).cancelAttentionCheck(anyInt()); + + ArgumentCaptor<AttentionCallbackInternal> callbackCaptor = ArgumentCaptor.forClass( + AttentionCallbackInternal.class); + verify(mAttentionManagerInternal).cancelAttentionCheck(callbackCaptor.capture()); + assertEquals(callbackCaptor.getValue(), mAttentionDetector.mCallback); } @Test public void testCallbackOnSuccess_ignoresIfNoAttention() { registerAttention(); - mAttentionDetector.mCallback.onSuccess(mAttentionDetector.getRequestCode(), - AttentionService.ATTENTION_SUCCESS_ABSENT, SystemClock.uptimeMillis()); + mAttentionDetector.mCallback.onSuccess(AttentionService.ATTENTION_SUCCESS_ABSENT, + SystemClock.uptimeMillis()); verify(mOnUserAttention, never()).run(); } @Test public void testCallbackOnSuccess_callsCallback() { registerAttention(); - mAttentionDetector.mCallback.onSuccess(mAttentionDetector.getRequestCode(), - AttentionService.ATTENTION_SUCCESS_PRESENT, SystemClock.uptimeMillis()); + mAttentionDetector.mCallback.onSuccess(AttentionService.ATTENTION_SUCCESS_PRESENT, + SystemClock.uptimeMillis()); verify(mOnUserAttention).run(); } @Test public void testCallbackOnFailure_unregistersCurrentRequestCode() { registerAttention(); - mAttentionDetector.mCallback.onFailure(mAttentionDetector.getRequestCode(), - AttentionService.ATTENTION_FAILURE_UNKNOWN); - mAttentionDetector.mCallback.onSuccess(mAttentionDetector.getRequestCode(), - AttentionService.ATTENTION_SUCCESS_PRESENT, SystemClock.uptimeMillis()); + mAttentionDetector.mCallback.onFailure(AttentionService.ATTENTION_FAILURE_UNKNOWN); + mAttentionDetector.mCallback.onSuccess(AttentionService.ATTENTION_SUCCESS_PRESENT, + SystemClock.uptimeMillis()); verify(mOnUserAttention, never()).run(); } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index a8da80efa35f..987d46a697c2 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -40,6 +40,8 @@ import static android.content.pm.PackageManager.PERMISSION_DENIED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.Build.VERSION_CODES.O_MR1; import static android.os.Build.VERSION_CODES.P; +import static android.service.notification.Adjustment.KEY_IMPORTANCE; +import static android.service.notification.Adjustment.KEY_USER_SENTIMENT; import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE; import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL; @@ -353,7 +355,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { FileOutputStream fos = mPolicyFile.startWrite(); fos.write(preupgradeXml.getBytes()); mPolicyFile.finishWrite(fos); - FileInputStream fStream = new FileInputStream(mFile); // Setup managed services mListener = mListeners.new ManagedServiceInfo( @@ -369,6 +370,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { dndConfig.xmlTag = ConditionProviders.TAG_ENABLED_DND_APPS; when(mConditionProviders.getConfig()).thenReturn(dndConfig); + when(mAssistants.isAdjustmentAllowed(anyString())).thenReturn(true); + try { mService.init(mTestableLooper.getLooper(), mPackageManager, mPackageManagerClient, mockLightsManager, @@ -491,6 +494,19 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { return answers; } + private void clearDeviceConfig() { + DeviceConfig.resetToDefaults( + Settings.RESET_MODE_PACKAGE_DEFAULTS, DeviceConfig.NAMESPACE_SYSTEMUI); + } + + private void setDefaultAssistantInDeviceConfig(String componentName) { + DeviceConfig.setProperty( + DeviceConfig.NAMESPACE_SYSTEMUI, + SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE, + componentName, + false); + } + @Test public void testCreateNotificationChannels_SingleChannel() throws Exception { final NotificationChannel channel = @@ -830,7 +846,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mService.addEnqueuedNotification(r); Bundle bundle = new Bundle(); - bundle.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_NONE); + bundle.putInt(KEY_IMPORTANCE, IMPORTANCE_NONE); Adjustment adjustment = new Adjustment( r.sbn.getPackageName(), r.getKey(), bundle, "", r.getUser().getIdentifier()); mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment); @@ -2825,7 +2841,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mService.setHandler(handler); Bundle signals = new Bundle(); - signals.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_NONE); + signals.putInt(KEY_IMPORTANCE, IMPORTANCE_NONE); Adjustment adjustment = new Adjustment( r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier()); when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); @@ -2866,7 +2882,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true); Bundle signals = new Bundle(); - signals.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_LOW); + signals.putInt(KEY_IMPORTANCE, IMPORTANCE_LOW); Adjustment adjustment = new Adjustment( r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier()); mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment); @@ -2884,13 +2900,13 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true); Bundle signals = new Bundle(); - signals.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_LOW); + signals.putInt(KEY_IMPORTANCE, IMPORTANCE_LOW); Adjustment adjustment = new Adjustment( r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier()); mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment); assertEquals(IMPORTANCE_DEFAULT, r.getImportance()); - assertFalse(r.hasAdjustment(Adjustment.KEY_IMPORTANCE)); + assertFalse(r.hasAdjustment(KEY_IMPORTANCE)); } @Test @@ -4274,18 +4290,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { .onGranted(eq(xmlConfig), eq(0), eq(true)); } - private void clearDeviceConfig() { - DeviceConfig.resetToDefaults( - Settings.RESET_MODE_PACKAGE_DEFAULTS, DeviceConfig.NAMESPACE_SYSTEMUI); - } - private void setDefaultAssistantInDeviceConfig(String componentName) { - DeviceConfig.setProperty( - DeviceConfig.NAMESPACE_SYSTEMUI, - SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE, - componentName, - false); - } public void testGetAllowedAssistantCapabilities() throws Exception { List<String> capabilities = mBinderService.getAllowedAssistantCapabilities(null); @@ -4300,4 +4305,23 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertFalse(currentCapabilities.contains(capability)); } } + + public void testAdjustRestrictedKey() throws Exception { + NotificationRecord r = generateNotificationRecord(mTestNotificationChannel); + + when(mAssistants.isAdjustmentAllowed(KEY_IMPORTANCE)).thenReturn(true); + when(mAssistants.isAdjustmentAllowed(KEY_USER_SENTIMENT)).thenReturn(false); + + Bundle signals = new Bundle(); + signals.putInt(KEY_IMPORTANCE, IMPORTANCE_LOW); + signals.putInt(KEY_USER_SENTIMENT, USER_SENTIMENT_NEGATIVE); + Adjustment adjustment = new Adjustment(r.sbn.getPackageName(), r.getKey(), signals, + "", r.getUser().getIdentifier()); + + mBinderService.applyAdjustmentFromAssistant(null, adjustment); + r.applyAdjustments(); + + assertEquals(IMPORTANCE_LOW, r.getAssistantImportance()); + assertEquals(USER_SENTIMENT_NEUTRAL, r.getUserSentiment()); + } } diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java index 85e8a1453e6f..63b9198bda90 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java @@ -350,7 +350,7 @@ public class ActivityDisplayTests extends ActivityTestsBase { activity.setState(ActivityStack.ActivityState.RESUMED, "testHandleActivitySizeCompatMode"); activity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE; activity.info.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; - activity.getTaskRecord().getConfiguration().windowConfiguration.getBounds().set( + activity.getTaskRecord().getConfiguration().windowConfiguration.setAppBounds( 0, 0, 1000, 2000); final ArrayList<CompletableFuture<IBinder>> resultWrapper = new ArrayList<>(); @@ -363,15 +363,15 @@ public class ActivityDisplayTests extends ActivityTestsBase { } }); - // Expect the exact component name when the activity is in size compatible mode. - activity.getResolvedOverrideConfiguration().windowConfiguration.getBounds().set( + // Expect the exact token when the activity is in size compatibility mode. + activity.getResolvedOverrideConfiguration().windowConfiguration.setAppBounds( 0, 0, 800, 1600); resultWrapper.add(new CompletableFuture<>()); display.handleActivitySizeCompatModeIfNeeded(activity); assertEquals(activity.appToken, resultWrapper.get(0).get(2, TimeUnit.SECONDS)); - // Expect null component name when switching to non-size-compat mode activity. + // Expect null token when switching to non-size-compat mode activity. activity.info.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE; resultWrapper.set(0, new CompletableFuture<>()); display.handleActivitySizeCompatModeIfNeeded(activity); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java index 23bae8881aa1..de4fb9855bc4 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java @@ -37,6 +37,7 @@ import android.os.SystemClock; import android.platform.test.annotations.Presubmit; import android.util.SparseIntArray; +import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; import com.android.server.wm.ActivityMetricsLaunchObserver.ActivityRecordProto; @@ -118,6 +119,7 @@ public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase { } @Test + @FlakyTest(bugId = 129138370) public void testOnIntentStarted() throws Exception { Intent intent = new Intent("action 1"); @@ -128,6 +130,7 @@ public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase { } @Test + @FlakyTest(bugId = 129138370) public void testOnIntentFailed() throws Exception { testOnIntentStarted(); @@ -143,6 +146,7 @@ public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase { } @Test + @FlakyTest(bugId = 129138370) public void testOnActivityLaunched() throws Exception { testOnIntentStarted(); @@ -154,6 +158,7 @@ public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase { } @Test + @FlakyTest(bugId = 129138370) public void testOnActivityLaunchFinished() throws Exception { testOnActivityLaunched(); @@ -168,6 +173,7 @@ public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase { } @Test + @FlakyTest(bugId = 129138370) public void testOnActivityLaunchCancelled() throws Exception { testOnActivityLaunched(); @@ -181,6 +187,7 @@ public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase { } @Test + @FlakyTest(bugId = 129138370) public void testOnActivityLaunchedTrampoline() throws Exception { testOnIntentStarted(); @@ -197,6 +204,7 @@ public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase { } @Test + @FlakyTest(bugId = 129138370) public void testOnActivityLaunchFinishedTrampoline() throws Exception { testOnActivityLaunchedTrampoline(); @@ -211,6 +219,7 @@ public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase { } @Test + @FlakyTest(bugId = 129138370) public void testOnActivityLaunchCancelledTrampoline() throws Exception { testOnActivityLaunchedTrampoline(); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index 457d9c0f2dee..d580557638cf 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -43,7 +43,10 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyString; +import android.app.ActivityManager; +import android.app.ActivityManagerInternal; import android.app.ActivityOptions; import android.app.servertransaction.ActivityConfigurationChangeItem; import android.app.servertransaction.ClientTransaction; @@ -61,6 +64,8 @@ import org.junit.Before; import org.junit.Test; import org.mockito.invocation.InvocationOnMock; +import java.util.concurrent.TimeUnit; + /** * Tests for the {@link ActivityRecord} class. * @@ -175,15 +180,14 @@ public class ActivityRecordTests extends ActivityTestsBase { @Test public void testRestartProcessIfVisible() { doNothing().when(mSupervisor).scheduleRestartTimeout(mActivity); - mActivity.getParent().getWindowConfiguration().setAppBounds(0, 0, 500, 1000); mActivity.visible = true; mActivity.haveState = false; - mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE; - mActivity.info.maxAspectRatio = 1.5f; mActivity.setState(ActivityStack.ActivityState.RESUMED, "testRestart"); - final Rect originalOverrideBounds = new Rect(0, 0, 400, 600); - mActivity.setBounds(originalOverrideBounds); + prepareFixedAspectRatioUnresizableActivity(); + final Rect originalOverrideBounds = new Rect(mActivity.getBounds()); + mTask.getWindowConfiguration().setAppBounds(0, 0, 600, 1200); + // The visible activity should recompute configuration according to the last parent bounds. mService.restartActivityProcessIfVisible(mActivity.appToken); assertEquals(ActivityStack.ActivityState.RESTARTING_PROCESS, mActivity.getState()); @@ -426,19 +430,41 @@ public class ActivityRecordTests extends ActivityTestsBase { } @Test + public void testSizeCompatMode_FixedAspectRatioBoundsWithDecor() { + final int decorHeight = 200; // e.g. The device has cutout. + final Rect parentAppBounds = new Rect(0, decorHeight, 600, 1000); + mTask.getWindowConfiguration().setAppBounds(parentAppBounds); + mTask.getConfiguration().orientation = Configuration.ORIENTATION_PORTRAIT; + doReturn(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) + .when(mActivity.mAppWindowToken).getOrientationIgnoreVisibility(); + mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE; + mActivity.info.maxAspectRatio = 1; + ensureActivityConfiguration(); + + final Rect appBounds = mActivity.getWindowConfiguration().getAppBounds(); + // Ensure the app bounds keep the declared aspect ratio. + assertEquals(appBounds.width(), appBounds.height()); + // The decor height should be a part of the effective bounds. + assertEquals(mActivity.getBounds().height(), appBounds.height() + decorHeight); + + mTask.getConfiguration().orientation = Configuration.ORIENTATION_LANDSCAPE; + mActivity.onConfigurationChanged(mTask.getConfiguration()); + // After changing orientation, the aspect ratio should be the same. + assertEquals(appBounds.width(), appBounds.height()); + // The decor height will be included in width. + assertEquals(mActivity.getBounds().width(), appBounds.width() + decorHeight); + } + + @Test public void testSizeCompatMode_FixedScreenConfigurationWhenMovingToDisplay() { // Initialize different bounds on a new display. final ActivityDisplay newDisplay = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP); - newDisplay.setBounds(0, 0, 1000, 2000); + newDisplay.getWindowConfiguration().setAppBounds(new Rect(0, 0, 1000, 2000)); newDisplay.getConfiguration().densityDpi = 300; - mTask.getWindowConfiguration().setAppBounds(mStack.getDisplay().getBounds()); mTask.getConfiguration().densityDpi = 200; - when(mActivity.mAppWindowToken.getOrientationIgnoreVisibility()).thenReturn( - ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); - mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE; - mActivity.info.maxAspectRatio = 1.5f; - ensureActivityConfiguration(); + prepareFixedAspectRatioUnresizableActivity(); + final Rect originalBounds = new Rect(mActivity.getBounds()); final int originalDpi = mActivity.getConfiguration().densityDpi; @@ -448,14 +474,16 @@ public class ActivityRecordTests extends ActivityTestsBase { assertEquals(originalBounds, mActivity.getBounds()); assertEquals(originalDpi, mActivity.getConfiguration().densityDpi); + assertTrue(mActivity.inSizeCompatMode()); } @Test public void testSizeCompatMode_FixedScreenBoundsWhenDisplaySizeChanged() { when(mActivity.mAppWindowToken.getOrientationIgnoreVisibility()).thenReturn( - ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); mTask.getWindowConfiguration().setAppBounds(mStack.getDisplay().getBounds()); - mActivity.info.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; + mTask.getConfiguration().orientation = Configuration.ORIENTATION_PORTRAIT; + mActivity.info.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE; ensureActivityConfiguration(); final Rect originalBounds = new Rect(mActivity.getBounds()); @@ -465,6 +493,7 @@ public class ActivityRecordTests extends ActivityTestsBase { ensureActivityConfiguration(); assertEquals(originalBounds, mActivity.getBounds()); + assertTrue(mActivity.inSizeCompatMode()); } @Test @@ -473,10 +502,7 @@ public class ActivityRecordTests extends ActivityTestsBase { | Configuration.SCREENLAYOUT_SIZE_NORMAL; mTask.getConfiguration().screenLayout = fixedScreenLayout | Configuration.SCREENLAYOUT_LAYOUTDIR_LTR; - mTask.getWindowConfiguration().setAppBounds(mStack.getDisplay().getBounds()); - mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE; - mActivity.info.maxAspectRatio = 1.5f; - ensureActivityConfiguration(); + prepareFixedAspectRatioUnresizableActivity(); // The initial configuration should inherit from parent. assertEquals(mTask.getConfiguration().screenLayout, @@ -490,4 +516,46 @@ public class ActivityRecordTests extends ActivityTestsBase { assertEquals(fixedScreenLayout | Configuration.SCREENLAYOUT_LAYOUTDIR_RTL, mActivity.getConfiguration().screenLayout); } + + @Test + public void testSizeCompatMode_ResetNonVisibleActivity() { + final ActivityDisplay display = mStack.getDisplay(); + spyOn(display); + + prepareFixedAspectRatioUnresizableActivity(); + mActivity.setState(STOPPED, "testSizeCompatMode"); + mActivity.visible = false; + mActivity.app.setReportedProcState(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY); + // Make the parent bounds to be different so the activity is in size compatibility mode. + mTask.getWindowConfiguration().setAppBounds(new Rect(0, 0, 600, 1200)); + + // Simulate the display changes orientation. + doReturn(ActivityInfo.CONFIG_SCREEN_SIZE | ActivityInfo.CONFIG_ORIENTATION + | ActivityInfo.CONFIG_WINDOW_CONFIGURATION) + .when(display).getLastOverrideConfigurationChanges(); + mActivity.onConfigurationChanged(mTask.getConfiguration()); + // The override configuration should not change so it is still in size compatibility mode. + assertTrue(mActivity.inSizeCompatMode()); + + // Simulate the display changes density. + doReturn(ActivityInfo.CONFIG_DENSITY).when(display).getLastOverrideConfigurationChanges(); + mService.mAmInternal = mock(ActivityManagerInternal.class); + mActivity.onConfigurationChanged(mTask.getConfiguration()); + // The override configuration should be reset and the activity's process will be killed. + assertFalse(mActivity.inSizeCompatMode()); + verify(mActivity).restartProcessIfVisible(); + mService.mH.runWithScissors(() -> { }, TimeUnit.SECONDS.toMillis(3)); + verify(mService.mAmInternal).killProcess( + eq(mActivity.app.mName), eq(mActivity.app.mUid), anyString()); + } + + /** Setup {@link #mActivity} as a size-compat-mode-able activity without fixed orientation. */ + private void prepareFixedAspectRatioUnresizableActivity() { + when(mActivity.mAppWindowToken.getOrientationIgnoreVisibility()).thenReturn( + ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); + mTask.getWindowConfiguration().setAppBounds(mStack.getDisplay().getBounds()); + mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE; + mActivity.info.maxAspectRatio = 1.5f; + ensureActivityConfiguration(); + } } diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java index d17e5c3f5359..c4009df27c1f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java @@ -218,6 +218,7 @@ public class AppWindowTokenTests extends WindowTestsBase { final Rect fixedBounds = mToken.getRequestedOverrideConfiguration().windowConfiguration .getBounds(); fixedBounds.set(0, 0, 1200, 1600); + mToken.getRequestedOverrideConfiguration().windowConfiguration.setAppBounds(fixedBounds); final Configuration newParentConfig = mTask.getConfiguration(); // Change the size of the container to two times smaller with insets. diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java index 4279c4152836..03969dad67c5 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java @@ -50,6 +50,7 @@ import android.view.WindowManager; import androidx.test.filters.SmallTest; +import com.android.server.policy.WindowManagerPolicy; import com.android.server.wm.utils.WmDisplayCutout; import org.junit.Before; @@ -476,6 +477,28 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase { } } + @Test + public void forceShowSystemBars_clearsSystemUIFlags() { + synchronized (mWm.mGlobalLock) { + mDisplayPolicy.mLastSystemUiFlags |= SYSTEM_UI_FLAG_FULLSCREEN; + mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; + mWindow.mAttrs.flags |= FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; + mWindow.mSystemUiVisibility = SYSTEM_UI_FLAG_FULLSCREEN; + mDisplayPolicy.setForceShowSystemBars(true); + addWindow(mWindow); + + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); + // triggers updateSystemUiVisibilityLw which will reset the flags as needed + int finishPostLayoutPolicyLw = mDisplayPolicy.focusChangedLw(mWindow, mWindow); + + assertEquals(WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT, finishPostLayoutPolicyLw); + assertEquals(0, mDisplayPolicy.mLastSystemUiFlags); + assertEquals(0, mWindow.mAttrs.systemUiVisibility); + assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + } + } + /** * Asserts that {@code actual} is inset by the given amounts from the full display rect. * diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java index 68e7470b8763..08e6ce4287a5 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java @@ -16,6 +16,7 @@ package com.android.server.wm; +import static android.app.ActivityManager.RECENT_WITH_EXCLUDED; import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; @@ -29,7 +30,9 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.view.Display.DEFAULT_DISPLAY; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; @@ -512,6 +515,52 @@ public class RecentTasksTest extends ActivityTestsBase { } @Test + public void testVisibleTasks_excludedFromRecents_firstTaskNotVisible() { + // Create some set of tasks, some of which are visible and some are not + TaskRecord homeTask = setTaskActivityType( + createTaskBuilder("com.android.pkg1", ".HomeTask").build(), + ACTIVITY_TYPE_HOME); + homeTask.mUserSetupComplete = true; + mRecentTasks.add(homeTask); + TaskRecord excludedTask1 = createTaskBuilder(".ExcludedTask1") + .setFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) + .build(); + excludedTask1.mUserSetupComplete = true; + mRecentTasks.add(excludedTask1); + + // Expect that the first visible excluded-from-recents task is visible + assertGetRecentTasksOrder(0 /* flags */, excludedTask1); + } + + @Test + public void testVisibleTasks_excludedFromRecents_withExcluded() { + // Create some set of tasks, some of which are visible and some are not + TaskRecord t1 = createTaskBuilder("com.android.pkg1", ".Task1").build(); + t1.mUserSetupComplete = true; + mRecentTasks.add(t1); + TaskRecord homeTask = setTaskActivityType( + createTaskBuilder("com.android.pkg1", ".HomeTask").build(), + ACTIVITY_TYPE_HOME); + homeTask.mUserSetupComplete = true; + mRecentTasks.add(homeTask); + TaskRecord excludedTask1 = createTaskBuilder(".ExcludedTask1") + .setFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) + .build(); + excludedTask1.mUserSetupComplete = true; + mRecentTasks.add(excludedTask1); + TaskRecord excludedTask2 = createTaskBuilder(".ExcludedTask2") + .setFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) + .build(); + excludedTask2.mUserSetupComplete = true; + mRecentTasks.add(excludedTask2); + TaskRecord t2 = createTaskBuilder("com.android.pkg2", ".Task1").build(); + t2.mUserSetupComplete = true; + mRecentTasks.add(t2); + + assertGetRecentTasksOrder(RECENT_WITH_EXCLUDED, t2, excludedTask2, excludedTask1, t1); + } + + @Test public void testVisibleTasks_minNum() { mRecentTasks.setOnlyTestVisibleRange(); mRecentTasks.setParameters(5 /* min */, -1 /* max */, 25 /* ms */); @@ -830,7 +879,7 @@ public class RecentTasksTest extends ActivityTestsBase { } /** - * Ensures that the recent tasks list is in the provided order. Note that the expected tasks + * Ensures that the raw recent tasks list is in the provided order. Note that the expected tasks * should be ordered from least to most recent. */ private void assertRecentTasksOrder(TaskRecord... expectedTasks) { @@ -841,6 +890,22 @@ public class RecentTasksTest extends ActivityTestsBase { } } + /** + * Ensures that the recent tasks list is in the provided order. Note that the expected tasks + * should be ordered from least to most recent. + */ + private void assertGetRecentTasksOrder(int getRecentTaskFlags, TaskRecord... expectedTasks) { + doNothing().when(mRecentTasks).loadUserRecentsLocked(anyInt()); + doReturn(true).when(mRecentTasks).isUserRunning(anyInt(), anyInt()); + List<RecentTaskInfo> infos = mRecentTasks.getRecentTasks(MAX_VALUE, getRecentTaskFlags, + true /* getTasksAllowed */, false /* getDetailedTasks */, + TEST_USER_0_ID, 0).getList(); + assertTrue(expectedTasks.length == infos.size()); + for (int i = 0; i < infos.size(); i++) { + assertTrue(expectedTasks[i].taskId == infos.get(i).taskId); + } + } + private void assertNotRestoreTask(Runnable action) { // Verify stack count doesn't change because task with fullscreen mode and standard type // would have its own stack. @@ -1018,7 +1083,7 @@ public class RecentTasksTest extends ActivityTestsBase { @Override protected RecentTasks createRecentTasks() { - return new TestRecentTasks(this, mTaskPersister); + return spy(new TestRecentTasks(this, mTaskPersister)); } @Override diff --git a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java index c5df85c554f4..83aa620b9573 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java +++ b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java @@ -38,7 +38,7 @@ public class TestIWindow extends IWindow.Stub { @Override public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, MergedConfiguration mergedConfig, - Rect backDropFrame, boolean forceLayout, boolean alwaysConsumeNavBar, int displayId, + Rect backDropFrame, boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId, DisplayCutout.ParcelableWrapper displayCutout) throws RemoteException { } diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java index ae05750eed9f..96e12ce837ca 100644 --- a/services/usb/java/com/android/server/usb/UsbPortManager.java +++ b/services/usb/java/com/android/server/usb/UsbPortManager.java @@ -150,8 +150,8 @@ public class UsbPortManager { private NotificationManager mNotificationManager; /** - * If there currently is a notification about contaminated USB port shown the id of the - * notification, or 0 if there is none. + * If there currently is a notification related to contaminated USB port management + * shown the id of the notification, or 0 if there is none. */ private int mIsPortContaminatedNotificationId; @@ -191,18 +191,24 @@ public class UsbPortManager { private void updateContaminantNotification() { PortInfo currentPortInfo = null; Resources r = mContext.getResources(); + int contaminantStatus = UsbPortStatus.CONTAMINANT_DETECTION_NOT_DETECTED; // Not handling multiple ports here. Showing the notification // for the first port that returns CONTAMINANT_PRESENCE_DETECTED. for (PortInfo portInfo : mPorts.values()) { - if (portInfo.mUsbPortStatus.getContaminantDetectionStatus() - == UsbPortStatus.CONTAMINANT_DETECTION_DETECTED) { + contaminantStatus = portInfo.mUsbPortStatus.getContaminantDetectionStatus(); + if (contaminantStatus == UsbPortStatus.CONTAMINANT_DETECTION_DETECTED + || contaminantStatus == UsbPortStatus.CONTAMINANT_DETECTION_DISABLED) { currentPortInfo = portInfo; break; } } - if (currentPortInfo != null && mIsPortContaminatedNotificationId + // Current contminant status is detected while "safe to use usb port" + // notification is displayed. Remove safe to use usb port notification + // and push contaminant detected notification. + if (contaminantStatus == UsbPortStatus.CONTAMINANT_DETECTION_DETECTED + && mIsPortContaminatedNotificationId != SystemMessage.NOTE_USB_CONTAMINANT_DETECTED) { if (mIsPortContaminatedNotificationId == SystemMessage.NOTE_USB_CONTAMINANT_NOT_DETECTED) { @@ -242,32 +248,41 @@ public class UsbPortManager { Notification notification = builder.build(); mNotificationManager.notifyAsUser(null, mIsPortContaminatedNotificationId, notification, UserHandle.ALL); - } else if (currentPortInfo == null && mIsPortContaminatedNotificationId + // No contaminant is detected but contaminant detection notification is displayed. + // Remove contaminant detection notification and push safe to use USB port notification. + } else if (contaminantStatus != UsbPortStatus.CONTAMINANT_DETECTION_DETECTED + && mIsPortContaminatedNotificationId == SystemMessage.NOTE_USB_CONTAMINANT_DETECTED) { mNotificationManager.cancelAsUser(null, mIsPortContaminatedNotificationId, UserHandle.ALL); - - mIsPortContaminatedNotificationId = SystemMessage.NOTE_USB_CONTAMINANT_NOT_DETECTED; - int titleRes = com.android.internal.R.string.usb_contaminant_not_detected_title; - CharSequence title = r.getText(titleRes); - String channel = SystemNotificationChannels.ALERTS; - CharSequence message = r.getText( - com.android.internal.R.string.usb_contaminant_not_detected_message); - - Notification.Builder builder = new Notification.Builder(mContext, channel) - .setSmallIcon(com.android.internal.R.drawable.ic_usb_48dp) - .setTicker(title) - .setColor(mContext.getColor( - com.android.internal.R.color - .system_notification_accent_color)) - .setContentTitle(title) - .setContentText(message) - .setVisibility(Notification.VISIBILITY_PUBLIC) - .setStyle(new Notification.BigTextStyle() - .bigText(message)); - Notification notification = builder.build(); - mNotificationManager.notifyAsUser(null, mIsPortContaminatedNotificationId, notification, - UserHandle.ALL); + mIsPortContaminatedNotificationId = 0; + + // Dont show safe to use notification when contaminant detection is disabled. + // Show only when the status is changing from detected to not detected. + if (contaminantStatus == UsbPortStatus.CONTAMINANT_DETECTION_NOT_DETECTED) { + mIsPortContaminatedNotificationId = + SystemMessage.NOTE_USB_CONTAMINANT_NOT_DETECTED; + int titleRes = com.android.internal.R.string.usb_contaminant_not_detected_title; + CharSequence title = r.getText(titleRes); + String channel = SystemNotificationChannels.ALERTS; + CharSequence message = r.getText( + com.android.internal.R.string.usb_contaminant_not_detected_message); + + Notification.Builder builder = new Notification.Builder(mContext, channel) + .setSmallIcon(com.android.internal.R.drawable.ic_usb_48dp) + .setTicker(title) + .setColor(mContext.getColor( + com.android.internal.R.color + .system_notification_accent_color)) + .setContentTitle(title) + .setContentText(message) + .setVisibility(Notification.VISIBILITY_PUBLIC) + .setStyle(new Notification.BigTextStyle() + .bigText(message)); + Notification notification = builder.build(); + mNotificationManager.notifyAsUser(null, mIsPortContaminatedNotificationId, + notification, UserHandle.ALL); + } } } @@ -319,8 +334,8 @@ public class UsbPortManager { } try { - // Oneway call into the hal - android.hardware.usb.V1_2.IUsb proxy = (android.hardware.usb.V1_2.IUsb) mProxy; + // Oneway call into the hal. Use the castFrom method from HIDL. + android.hardware.usb.V1_2.IUsb proxy = android.hardware.usb.V1_2.IUsb.castFrom(mProxy); proxy.enableContaminantPresenceDetection(portId, enable); } catch (RemoteException e) { logAndPrintException(pw, "Failed to set contaminant detection", e); @@ -948,22 +963,26 @@ public class UsbPortManager { } } - private void handlePortAddedLocked(PortInfo portInfo, IndentingPrintWriter pw) { - logAndPrint(Log.INFO, pw, "USB port added: " + portInfo); + private void handlePortLocked(PortInfo portInfo, IndentingPrintWriter pw) { sendPortChangedBroadcastLocked(portInfo); + enableContaminantDetectionIfNeeded(portInfo, pw); + logToStatsd(portInfo, pw); updateContaminantNotification(); } + private void handlePortAddedLocked(PortInfo portInfo, IndentingPrintWriter pw) { + logAndPrint(Log.INFO, pw, "USB port added: " + portInfo); + handlePortLocked(portInfo, pw); + } + private void handlePortChangedLocked(PortInfo portInfo, IndentingPrintWriter pw) { logAndPrint(Log.INFO, pw, "USB port changed: " + portInfo); - sendPortChangedBroadcastLocked(portInfo); - updateContaminantNotification(); + handlePortLocked(portInfo, pw); } private void handlePortRemovedLocked(PortInfo portInfo, IndentingPrintWriter pw) { logAndPrint(Log.INFO, pw, "USB port removed: " + portInfo); - sendPortChangedBroadcastLocked(portInfo); - updateContaminantNotification(); + handlePortLocked(portInfo, pw); } // Constants have to be converted between USB HAL V1.2 ContaminantDetectionStatus @@ -996,9 +1015,25 @@ public class UsbPortManager { // instead of from within the critical section. mHandler.post(() -> mContext.sendBroadcastAsUser(intent, UserHandle.ALL, Manifest.permission.MANAGE_USB)); + } - // Log to statsd + private void enableContaminantDetectionIfNeeded(PortInfo portInfo, IndentingPrintWriter pw) { + if (!mConnected.containsKey(portInfo.mUsbPort.getId())) { + return; + } + + if (mConnected.get(portInfo.mUsbPort.getId()) + && !portInfo.mUsbPortStatus.isConnected() + && portInfo.mUsbPortStatus.getContaminantDetectionStatus() + == UsbPortStatus.CONTAMINANT_DETECTION_DISABLED) { + // Contaminant detection might have been temporarily disabled by the user + // through SystemUI. + // Re-enable contaminant detection when the accessory is unplugged. + enableContaminantDetection(portInfo.mUsbPort.getId(), true, pw); + } + } + private void logToStatsd(PortInfo portInfo, IndentingPrintWriter pw) { // Port is removed if (portInfo.mUsbPortStatus == null) { if (mConnected.containsKey(portInfo.mUsbPort.getId())) { diff --git a/telephony/java/android/telephony/AccessNetworkConstants.java b/telephony/java/android/telephony/AccessNetworkConstants.java index 81553a3bc0f8..afa35b4d4de3 100644 --- a/telephony/java/android/telephony/AccessNetworkConstants.java +++ b/telephony/java/android/telephony/AccessNetworkConstants.java @@ -18,6 +18,7 @@ package android.telephony; import android.annotation.IntDef; import android.annotation.SystemApi; +import android.annotation.TestApi; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -51,6 +52,7 @@ public final class AccessNetworkConstants { * @hide */ @SystemApi + @TestApi public static final int TRANSPORT_TYPE_WWAN = 1; /** @@ -58,6 +60,7 @@ public final class AccessNetworkConstants { * @hide */ @SystemApi + @TestApi public static final int TRANSPORT_TYPE_WLAN = 2; /** @hide */ diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 5f9ef3c0c601..0a9b90465a48 100755 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -1543,6 +1543,21 @@ public class CarrierConfigManager { "allow_non_emergency_calls_in_ecm_bool"; /** + * Time that the telephony framework stays in "emergency SMS mode" after an emergency SMS is + * sent to the network. This is used by carriers to configure the time + * {@link TelephonyManager#isInEmergencySmsMode()} will be true after an emergency SMS is sent. + * This is used by GNSS to override user location permissions so that the carrier network can + * get the user's location for emergency services. + * + * The default is 0, which means that this feature is disabled. The maximum value for this timer + * is 300000 mS (5 minutes). + * + * @hide + */ + public static final String KEY_EMERGENCY_SMS_MODE_TIMER_MS_INT = + "emergency_sms_mode_timer_ms_int"; + + /** * Flag indicating whether to allow carrier video calls to emergency numbers. * When {@code true}, video calls to emergency numbers will be allowed. When {@code false}, * video calls to emergency numbers will be initiated as audio-only calls instead. @@ -1847,12 +1862,32 @@ public class CarrierConfigManager { "use_wfc_home_network_mode_in_roaming_network_bool"; /** + * Flag specifying whether the carrier is allowed to use metered network to download a + * certificate of Carrier-WiFi. + * {@code false} - default value. + * + * @hide + */ + public static final String KEY_ALLOW_METERED_NETWORK_FOR_CERT_DOWNLOAD_BOOL = + "allow_metered_network_for_cert_download_bool"; + + /** * Carrier specified WiFi networks. * @hide */ public static final String KEY_CARRIER_WIFI_STRING_ARRAY = "carrier_wifi_string_array"; /** + * Base64 Encoding method the carrier will use for encoding encrypted IMSI and SSID. + * The value set as below: + * 2045 - RFC2045 (default value) + * 4648 - RFC4648 + * + * @hide + */ + public static final String KEY_IMSI_ENCODING_METHOD_INT = "imsi_encoding_method_int"; + + /** * Time delay (in ms) after which we show the notification to switch the preferred * network. * @hide @@ -2667,6 +2702,14 @@ public class CarrierConfigManager { "cdma_enhanced_roaming_indicator_for_home_network_int_array"; /** + * Determines whether wifi calling location privacy policy is shown. + * + * @hide + */ + public static final String KEY_SHOW_WFC_LOCATION_PRIVACY_POLICY_BOOL = + "show_wfc_location_privacy_policy_bool"; + + /** * Indicates use 3GPP application to replace 3GPP2 application even if it's a CDMA/CDMA-LTE * phone, becasue some carriers's CSIM application is present but not supported. * @hide @@ -2917,6 +2960,7 @@ public class CarrierConfigManager { sDefaults.putString(KEY_MMS_UA_PROF_URL_STRING, ""); sDefaults.putString(KEY_MMS_USER_AGENT_STRING, ""); sDefaults.putBoolean(KEY_ALLOW_NON_EMERGENCY_CALLS_IN_ECM_BOOL, true); + sDefaults.putInt(KEY_EMERGENCY_SMS_MODE_TIMER_MS_INT, 0); sDefaults.putBoolean(KEY_USE_RCS_PRESENCE_BOOL, false); sDefaults.putBoolean(KEY_FORCE_IMEI_BOOL, false); sDefaults.putInt( @@ -2982,7 +3026,9 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_EDITABLE_WFC_ROAMING_MODE_BOOL, false); sDefaults.putBoolean(KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL, false); sDefaults.putBoolean(KEY_STK_DISABLE_LAUNCH_BROWSER_BOOL, false); + sDefaults.putBoolean(KEY_ALLOW_METERED_NETWORK_FOR_CERT_DOWNLOAD_BOOL, false); sDefaults.putStringArray(KEY_CARRIER_WIFI_STRING_ARRAY, null); + sDefaults.putInt(KEY_IMSI_ENCODING_METHOD_INT, 2045); sDefaults.putInt(KEY_PREF_NETWORK_NOTIFICATION_DELAY_INT, -1); sDefaults.putInt(KEY_EMERGENCY_NOTIFICATION_DELAY_INT, -1); sDefaults.putBoolean(KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL, true); @@ -3073,6 +3119,7 @@ public class CarrierConfigManager { }); sDefaults.putStringArray(KEY_EMERGENCY_NUMBER_PREFIX_STRING_ARRAY, new String[0]); sDefaults.putBoolean(KEY_USE_USIM_BOOL, false); + sDefaults.putBoolean(KEY_SHOW_WFC_LOCATION_PRIVACY_POLICY_BOOL, true); sDefaults.putBoolean(KEY_AUTO_CANCEL_CS_REJECT_NOTIFICATION, false); sDefaults.putBoolean(KEY_ALWAYS_SHOW_PRIMARY_SIGNAL_BAR_IN_OPPORTUNISTIC_NETWORK_BOOLEAN, false); diff --git a/telephony/java/android/telephony/DataSpecificRegistrationStates.java b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java index 8eb345ac258a..fbf488e590fd 100644 --- a/telephony/java/android/telephony/DataSpecificRegistrationStates.java +++ b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java @@ -1,7 +1,24 @@ +/* + * Copyright 2018 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.telephony; import android.annotation.NonNull; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; @@ -13,7 +30,8 @@ import java.util.Objects; * @hide */ @SystemApi -public final class DataSpecificRegistrationStates implements Parcelable{ +@TestApi +public final class DataSpecificRegistrationInfo implements Parcelable { /** * @hide * The maximum number of simultaneous Data Calls that @@ -53,27 +71,27 @@ public final class DataSpecificRegistrationStates implements Parcelable{ /** * Provides network support info for LTE VoPS and LTE Emergency bearer support */ - private final LteVopsSupportInfo lteVopsSupportInfo; + private final LteVopsSupportInfo mLteVopsSupportInfo; /** * @hide */ - DataSpecificRegistrationStates( + DataSpecificRegistrationInfo( int maxDataCalls, boolean isDcNrRestricted, boolean isNrAvailable, boolean isEnDcAvailable, LteVopsSupportInfo lteVops) { this.maxDataCalls = maxDataCalls; this.isDcNrRestricted = isDcNrRestricted; this.isNrAvailable = isNrAvailable; this.isEnDcAvailable = isEnDcAvailable; - this.lteVopsSupportInfo = lteVops; + this.mLteVopsSupportInfo = lteVops; } - private DataSpecificRegistrationStates(Parcel source) { + private DataSpecificRegistrationInfo(Parcel source) { maxDataCalls = source.readInt(); isDcNrRestricted = source.readBoolean(); isNrAvailable = source.readBoolean(); isEnDcAvailable = source.readBoolean(); - lteVopsSupportInfo = LteVopsSupportInfo.CREATOR.createFromParcel(source); + mLteVopsSupportInfo = LteVopsSupportInfo.CREATOR.createFromParcel(source); } @Override @@ -82,7 +100,7 @@ public final class DataSpecificRegistrationStates implements Parcelable{ dest.writeBoolean(isDcNrRestricted); dest.writeBoolean(isNrAvailable); dest.writeBoolean(isEnDcAvailable); - lteVopsSupportInfo.writeToParcel(dest, flags); + mLteVopsSupportInfo.writeToParcel(dest, flags); } @Override @@ -98,7 +116,7 @@ public final class DataSpecificRegistrationStates implements Parcelable{ .append(" isDcNrRestricted = " + isDcNrRestricted) .append(" isNrAvailable = " + isNrAvailable) .append(" isEnDcAvailable = " + isEnDcAvailable) - .append(lteVopsSupportInfo.toString()) + .append(mLteVopsSupportInfo.toString()) .append(" }") .toString(); } @@ -106,41 +124,41 @@ public final class DataSpecificRegistrationStates implements Parcelable{ @Override public int hashCode() { return Objects.hash(maxDataCalls, isDcNrRestricted, isNrAvailable, isEnDcAvailable, - lteVopsSupportInfo); + mLteVopsSupportInfo); } @Override public boolean equals(Object o) { if (this == o) return true; - if (!(o instanceof DataSpecificRegistrationStates)) return false; + if (!(o instanceof DataSpecificRegistrationInfo)) return false; - DataSpecificRegistrationStates other = (DataSpecificRegistrationStates) o; + DataSpecificRegistrationInfo other = (DataSpecificRegistrationInfo) o; return this.maxDataCalls == other.maxDataCalls && this.isDcNrRestricted == other.isDcNrRestricted && this.isNrAvailable == other.isNrAvailable && this.isEnDcAvailable == other.isEnDcAvailable - && this.lteVopsSupportInfo.equals(other.lteVopsSupportInfo); + && this.mLteVopsSupportInfo.equals(other.mLteVopsSupportInfo); } - public static final @android.annotation.NonNull Parcelable.Creator<DataSpecificRegistrationStates> CREATOR = - new Parcelable.Creator<DataSpecificRegistrationStates>() { + public static final @NonNull Parcelable.Creator<DataSpecificRegistrationInfo> CREATOR = + new Parcelable.Creator<DataSpecificRegistrationInfo>() { @Override - public DataSpecificRegistrationStates createFromParcel(Parcel source) { - return new DataSpecificRegistrationStates(source); + public DataSpecificRegistrationInfo createFromParcel(Parcel source) { + return new DataSpecificRegistrationInfo(source); } @Override - public DataSpecificRegistrationStates[] newArray(int size) { - return new DataSpecificRegistrationStates[size]; + public DataSpecificRegistrationInfo[] newArray(int size) { + return new DataSpecificRegistrationInfo[size]; } }; /** - * @return LteVopsSupportInfo + * @return The LTE VOPS (Voice over Packet Switched) support information */ @NonNull public LteVopsSupportInfo getLteVopsSupportInfo() { - return lteVopsSupportInfo; + return mLteVopsSupportInfo; } } diff --git a/telephony/java/android/telephony/LteVopsSupportInfo.java b/telephony/java/android/telephony/LteVopsSupportInfo.java index ee45f0761e0b..ec9f078367b8 100644 --- a/telephony/java/android/telephony/LteVopsSupportInfo.java +++ b/telephony/java/android/telephony/LteVopsSupportInfo.java @@ -18,6 +18,7 @@ package android.telephony; import android.annotation.IntDef; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; @@ -30,6 +31,7 @@ import java.util.Objects; * @hide */ @SystemApi +@TestApi public final class LteVopsSupportInfo implements Parcelable { /**@hide*/ diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java index 9145b2532817..1dc29979dc61 100644 --- a/telephony/java/android/telephony/NetworkRegistrationInfo.java +++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java @@ -20,6 +20,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; import android.telephony.AccessNetworkConstants.TransportType; @@ -38,6 +39,7 @@ import java.util.stream.Collectors; * @hide */ @SystemApi +@TestApi public final class NetworkRegistrationInfo implements Parcelable { /** * Network domain @@ -174,10 +176,10 @@ public final class NetworkRegistrationInfo implements Parcelable { private CellIdentity mCellIdentity; @Nullable - private VoiceSpecificRegistrationStates mVoiceSpecificStates; + private VoiceSpecificRegistrationInfo mVoiceSpecificInfo; @Nullable - private DataSpecificRegistrationStates mDataSpecificStates; + private DataSpecificRegistrationInfo mDataSpecificInfo; /** * @param domain Network domain. Must be a {@link Domain}. For transport type @@ -234,7 +236,7 @@ public final class NetworkRegistrationInfo implements Parcelable { this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause, emergencyOnly, availableServices, cellIdentity); - mVoiceSpecificStates = new VoiceSpecificRegistrationStates(cssSupported, roamingIndicator, + mVoiceSpecificInfo = new VoiceSpecificRegistrationInfo(cssSupported, roamingIndicator, systemIsInPrl, defaultRoamingIndicator); } @@ -253,9 +255,9 @@ public final class NetworkRegistrationInfo implements Parcelable { this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause, emergencyOnly, availableServices, cellIdentity); - mDataSpecificStates = new DataSpecificRegistrationStates( + mDataSpecificInfo = new DataSpecificRegistrationInfo( maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, lteVopsSupportInfo); - updateNrState(mDataSpecificStates); + updateNrState(mDataSpecificInfo); } private NetworkRegistrationInfo(Parcel source) { @@ -269,10 +271,10 @@ public final class NetworkRegistrationInfo implements Parcelable { mAvailableServices = new ArrayList<>(); source.readList(mAvailableServices, Integer.class.getClassLoader()); mCellIdentity = source.readParcelable(CellIdentity.class.getClassLoader()); - mVoiceSpecificStates = source.readParcelable( - VoiceSpecificRegistrationStates.class.getClassLoader()); - mDataSpecificStates = source.readParcelable( - DataSpecificRegistrationStates.class.getClassLoader()); + mVoiceSpecificInfo = source.readParcelable( + VoiceSpecificRegistrationInfo.class.getClassLoader()); + mDataSpecificInfo = source.readParcelable( + DataSpecificRegistrationInfo.class.getClassLoader()); mNrState = source.readInt(); } @@ -389,16 +391,16 @@ public final class NetworkRegistrationInfo implements Parcelable { * @hide */ @Nullable - public VoiceSpecificRegistrationStates getVoiceSpecificStates() { - return mVoiceSpecificStates; + public VoiceSpecificRegistrationInfo getVoiceSpecificInfo() { + return mVoiceSpecificInfo; } /** * @return Data registration related info */ @Nullable - public DataSpecificRegistrationStates getDataSpecificStates() { - return mDataSpecificStates; + public DataSpecificRegistrationInfo getDataSpecificInfo() { + return mDataSpecificInfo; } @Override @@ -474,8 +476,8 @@ public final class NetworkRegistrationInfo implements Parcelable { ? mAvailableServices.stream().map(type -> serviceTypeToString(type)) .collect(Collectors.joining(",")) : null) + "]") .append(" cellIdentity=").append(mCellIdentity) - .append(" voiceSpecificStates=").append(mVoiceSpecificStates) - .append(" dataSpecificStates=").append(mDataSpecificStates) + .append(" voiceSpecificInfo=").append(mVoiceSpecificInfo) + .append(" dataSpecificInfo=").append(mDataSpecificInfo) .append(" nrState=").append(nrStateToString(mNrState)) .append("}").toString(); } @@ -484,7 +486,7 @@ public final class NetworkRegistrationInfo implements Parcelable { public int hashCode() { return Objects.hash(mDomain, mTransportType, mRegistrationState, mRoamingType, mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices, - mCellIdentity, mVoiceSpecificStates, mDataSpecificStates, mNrState); + mCellIdentity, mVoiceSpecificInfo, mDataSpecificInfo, mNrState); } @Override @@ -505,8 +507,8 @@ public final class NetworkRegistrationInfo implements Parcelable { && mEmergencyOnly == other.mEmergencyOnly && mAvailableServices.equals(other.mAvailableServices) && Objects.equals(mCellIdentity, other.mCellIdentity) - && Objects.equals(mVoiceSpecificStates, other.mVoiceSpecificStates) - && Objects.equals(mDataSpecificStates, other.mDataSpecificStates) + && Objects.equals(mVoiceSpecificInfo, other.mVoiceSpecificInfo) + && Objects.equals(mDataSpecificInfo, other.mDataSpecificInfo) && mNrState == other.mNrState; } @@ -521,8 +523,8 @@ public final class NetworkRegistrationInfo implements Parcelable { dest.writeBoolean(mEmergencyOnly); dest.writeList(mAvailableServices); dest.writeParcelable(mCellIdentity, 0); - dest.writeParcelable(mVoiceSpecificStates, 0); - dest.writeParcelable(mDataSpecificStates, 0); + dest.writeParcelable(mVoiceSpecificInfo, 0); + dest.writeParcelable(mDataSpecificInfo, 0); dest.writeInt(mNrState); } @@ -543,7 +545,7 @@ public final class NetworkRegistrationInfo implements Parcelable { * * @param state data specific registration state contains the 5G NR indicators. */ - private void updateNrState(DataSpecificRegistrationStates state) { + private void updateNrState(DataSpecificRegistrationInfo state) { mNrState = NR_STATE_NONE; if (state.isEnDcAvailable) { if (!state.isDcNrRestricted && state.isNrAvailable) { diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index df31f50d28a4..a794ba12f202 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -1132,7 +1132,7 @@ public class ServiceState implements Parcelable { } /** @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) + @TestApi public void setVoiceRoamingType(@RoamingType int type) { NetworkRegistrationInfo regState = getNetworkRegistrationInfo( NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); @@ -1153,7 +1153,7 @@ public class ServiceState implements Parcelable { } /** @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) + @TestApi public void setDataRoamingType(@RoamingType int type) { NetworkRegistrationInfo regState = getNetworkRegistrationInfo( NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); @@ -1855,6 +1855,7 @@ public class ServiceState implements Parcelable { /** * @hide */ + @TestApi public void addNetworkRegistrationInfo(NetworkRegistrationInfo regState) { if (regState == null) return; diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java index ac1194089758..ee28ca23be35 100644 --- a/telephony/java/android/telephony/SubscriptionInfo.java +++ b/telephony/java/android/telephony/SubscriptionInfo.java @@ -32,6 +32,7 @@ import android.graphics.Rect; import android.graphics.Typeface; import android.os.Build; import android.os.Parcel; +import android.os.ParcelUuid; import android.os.Parcelable; import android.text.TextUtils; import android.util.DisplayMetrics; @@ -154,11 +155,11 @@ public class SubscriptionInfo implements Parcelable { private boolean mIsOpportunistic; /** - * A UUID assigned to the subscription group. It returns - * null if not assigned. + * A UUID assigned to the subscription group. It returns null if not assigned. + * Check {@link SubscriptionManager#createSubscriptionGroup(List)} for more details. */ @Nullable - private String mGroupUUID; + private ParcelUuid mGroupUUID; /** * Whether group of the subscription is disabled. @@ -237,7 +238,7 @@ public class SubscriptionInfo implements Parcelable { this.mCardString = cardString; this.mCardId = cardId; this.mIsOpportunistic = isOpportunistic; - this.mGroupUUID = groupUUID; + this.mGroupUUID = groupUUID == null ? null : ParcelUuid.fromString(groupUUID); this.mIsGroupDisabled = isGroupDisabled; this.mCarrierId = carrierId; this.mProfileClass = profileClass; @@ -461,7 +462,7 @@ public class SubscriptionInfo implements Parcelable { * @return group UUID a String of group UUID if it belongs to a group. Otherwise * it will return null. */ - public @Nullable String getGroupUuid() { + public @Nullable ParcelUuid getGroupUuid() { return mGroupUUID; } @@ -643,7 +644,7 @@ public class SubscriptionInfo implements Parcelable { dest.writeString(mCardString); dest.writeInt(mCardId); dest.writeBoolean(mIsOpportunistic); - dest.writeString(mGroupUUID); + dest.writeString(mGroupUUID == null ? null : mGroupUUID.toString()); dest.writeBoolean(mIsGroupDisabled); dest.writeInt(mCarrierId); dest.writeInt(mProfileClass); diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 2edef838ff28..14eac87f1575 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -50,11 +50,12 @@ import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Message; +import android.os.ParcelUuid; +import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.telephony.euicc.EuiccManager; import android.telephony.ims.ImsMmTelManager; -import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Log; @@ -1752,6 +1753,10 @@ public class SubscriptionManager { Rlog.d(LOG_TAG, msg); } + private static void loge(String msg) { + Rlog.e(LOG_TAG, msg); + } + /** * Returns the system's default subscription id. * @@ -1991,24 +1996,6 @@ public class SubscriptionManager { } /** - * If a default is set to subscription which is not active, this will reset that default back to - * an invalid subscription id, i.e. < 0. - * @hide - */ - @UnsupportedAppUsage - public void clearDefaultsForInactiveSubIds() { - if (VDBG) logd("clearDefaultsForInactiveSubIds"); - try { - ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); - if (iSub != null) { - iSub.clearDefaultsForInactiveSubIds(); - } - } catch (RemoteException ex) { - // ignore it - } - } - - /** * Check if the supplied subscription ID is valid. * * <p>A valid subscription ID is not necessarily an active subscription ID @@ -2740,11 +2727,20 @@ public class SubscriptionManager { /** * Inform SubscriptionManager that subscriptions in the list are bundled - * as a group. Typically it's a primary subscription and an opportunistic - * subscription. It should only affect multi-SIM scenarios where primary - * and opportunistic subscriptions can be activated together. - * Being in the same group means they might be activated or deactivated - * together, some of them may be invisible to the users, etc. + * as a group. It can be multiple primary (non-opportunistic) subscriptions, + * or one or more primary plus one or more opportunistic subscriptions. + * + * This API will always create a new immutable group and assign group UUID to all the + * subscriptions, regardless whether they are in a group already or not. + * + * Grouped subscriptions will have below behaviors: + * 1) They will share the same user settings. + * 2) The opportunistic subscriptions in the group is considered invisible and will not + * return from {@link #getActiveSubscriptionInfoList()}, unless caller has carrier + * privilege permission of the subscriptions. + * 3) The opportunistic subscriptions in the group can't be active by itself. If all other + * non-opportunistic ones are deactivated (unplugged or disabled in Settings), + * the opportunistic ones will be deactivated automatically. * * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE} * permission or had carrier privilege permission on the subscriptions: @@ -2755,34 +2751,94 @@ public class SubscriptionManager { * outlined above. * * @param subIdList list of subId that will be in the same group - * @return groupUUID a UUID assigned to the subscription group. It returns - * null if fails. + * @return groupUUID a UUID assigned to the subscription group. * */ @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) - public @Nullable String setSubscriptionGroup(@NonNull int[] subIdList) { + public @NonNull ParcelUuid createSubscriptionGroup(@NonNull List<Integer> subIdList) { + Preconditions.checkNotNull(subIdList, "can't create group for null subId list"); String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; if (VDBG) { - logd("[setSubscriptionGroup]+ subIdList:" + Arrays.toString(subIdList)); + logd("[createSubscriptionGroup]"); } - String groupUUID = null; + ParcelUuid groupUuid = null; + int[] subIdArray = subIdList.stream().mapToInt(i->i).toArray(); try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); if (iSub != null) { - groupUUID = iSub.setSubscriptionGroup(subIdList, pkgForDebug); + groupUuid = iSub.createSubscriptionGroup(subIdArray, pkgForDebug); + } else { + if (!isSystemProcess()) { + throw new IllegalStateException("telephony service is null."); + } } } catch (RemoteException ex) { - // ignore it + loge("createSubscriptionGroup RemoteException " + ex); + if (!isSystemProcess()) { + ex.rethrowAsRuntimeException(); + } + } + + return groupUuid; + } + + /** + * Add a list of subscriptions into a group. + * See {@link #createSubscriptionGroup(List)} for more details. + * + * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE} + * permission or had carrier privilege permission on the subscriptions: + * {@link TelephonyManager#hasCarrierPrivileges()} or + * {@link #canManageSubscription(SubscriptionInfo)} + * + * @throws SecurityException if the caller doesn't meet the requirements + * outlined above. + * @throws IllegalArgumentException if the some subscriptions in the list doesn't exist, + * or the groupUuid doesn't exist. + * + * @param subIdList list of subId that need adding into the group + * @param groupUuid the groupUuid the subscriptions are being added to. + * + */ + @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges + @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) + public void addSubscriptionsIntoGroup(@NonNull List<Integer> subIdList, + @NonNull ParcelUuid groupUuid) { + Preconditions.checkNotNull(subIdList, "subIdList can't be null."); + Preconditions.checkNotNull(groupUuid, "groupUuid can't be null."); + String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; + if (VDBG) { + logd("[addSubscriptionsIntoGroup]"); + } + + int[] subIdArray = subIdList.stream().mapToInt(i->i).toArray(); + + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + iSub.addSubscriptionsIntoGroup(subIdArray, groupUuid, pkgForDebug); + } else { + if (!isSystemProcess()) { + throw new IllegalStateException("telephony service is null."); + } + } + } catch (RemoteException ex) { + loge("addSubscriptionsIntoGroup RemoteException " + ex); + if (!isSystemProcess()) { + ex.rethrowAsRuntimeException(); + } } + } - return groupUUID; + private boolean isSystemProcess() { + return Process.myUid() == Process.SYSTEM_UID; } /** * Remove a list of subscriptions from their subscription group. - * See {@link #setSubscriptionGroup(int[])} for more details. + * See {@link #createSubscriptionGroup(List)} for more details. * * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE} * permission or had carrier privilege permission on the subscriptions: @@ -2791,34 +2847,45 @@ public class SubscriptionManager { * * @throws SecurityException if the caller doesn't meet the requirements * outlined above. + * @throws IllegalArgumentException if the some subscriptions in the list doesn't belong + * the specified group. * * @param subIdList list of subId that need removing from their groups. - * @return whether the operation succeeds. * */ @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) - public boolean removeSubscriptionsFromGroup(@NonNull int[] subIdList) { + public void removeSubscriptionsFromGroup(@NonNull List<Integer> subIdList, + @NonNull ParcelUuid groupUuid) { + Preconditions.checkNotNull(subIdList, "subIdList can't be null."); + Preconditions.checkNotNull(groupUuid, "groupUuid can't be null."); String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; if (VDBG) { - logd("[removeSubscriptionsFromGroup]+ subIdList:" + Arrays.toString(subIdList)); + logd("[removeSubscriptionsFromGroup]"); } + int[] subIdArray = subIdList.stream().mapToInt(i->i).toArray(); + try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); if (iSub != null) { - return iSub.removeSubscriptionsFromGroup(subIdList, pkgForDebug); + iSub.removeSubscriptionsFromGroup(subIdArray, groupUuid, pkgForDebug); + } else { + if (!isSystemProcess()) { + throw new IllegalStateException("telephony service is null."); + } } } catch (RemoteException ex) { - // ignore it + loge("removeSubscriptionsFromGroup RemoteException " + ex); + if (!isSystemProcess()) { + ex.rethrowAsRuntimeException(); + } } - - return false; } /** * Get subscriptionInfo list of subscriptions that are in the same group of given subId. - * See {@link #setSubscriptionGroup(int[])} for more details. + * See {@link #createSubscriptionGroup(List)} for more details. * * Caller will either have {@link android.Manifest.permission#READ_PHONE_STATE} * permission or had carrier privilege permission on the subscription. @@ -2827,28 +2894,35 @@ public class SubscriptionManager { * @throws SecurityException if the caller doesn't meet the requirements * outlined above. * - * @param subId of which list of subInfo from the same group will be returned. + * @param groupUuid of which list of subInfo will be returned. * @return list of subscriptionInfo that belong to the same group, including the given - * subscription itself. It will return null if the subscription doesn't exist or it - * doesn't belong to any group. + * subscription itself. It will return an empty list if no subscription belongs to the group. * */ @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges @RequiresPermission(Manifest.permission.READ_PHONE_STATE) - public @Nullable List<SubscriptionInfo> getSubscriptionsInGroup(int subId) { + public @NonNull List<SubscriptionInfo> getSubscriptionsInGroup(@NonNull ParcelUuid groupUuid) { + Preconditions.checkNotNull(groupUuid, "groupUuid can't be null"); String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; if (VDBG) { - logd("[getSubscriptionsInGroup]+ subId:" + subId); + logd("[getSubscriptionsInGroup]+ groupUuid:" + groupUuid); } List<SubscriptionInfo> result = null; try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); if (iSub != null) { - result = iSub.getSubscriptionsInGroup(subId, pkgForDebug); + result = iSub.getSubscriptionsInGroup(groupUuid, pkgForDebug); + } else { + if (!isSystemProcess()) { + throw new IllegalStateException("telephony service is null."); + } } } catch (RemoteException ex) { - // ignore it + loge("removeSubscriptionsFromGroup RemoteException " + ex); + if (!isSystemProcess()) { + ex.rethrowAsRuntimeException(); + } } return result; @@ -2868,7 +2942,7 @@ public class SubscriptionManager { if (info == null) return false; // If subscription is NOT grouped opportunistic subscription, it's visible. - if (TextUtils.isEmpty(info.getGroupUuid()) || !info.isOpportunistic()) return true; + if (info.getGroupUuid() == null || !info.isOpportunistic()) return true; // If the caller is the carrier app and owns the subscription, it should be visible // to the caller. @@ -2898,14 +2972,14 @@ public class SubscriptionManager { // It should be the current active primary subscription if any, or any // primary subscription. List<SubscriptionInfo> selectableList = new ArrayList<>(); - Map<String, SubscriptionInfo> groupMap = new HashMap<>(); + Map<ParcelUuid, SubscriptionInfo> groupMap = new HashMap<>(); for (SubscriptionInfo info : availableList) { // Opportunistic subscriptions are considered invisible // to users so they should never be returned. if (!isSubscriptionVisible(info)) continue; - String groupUuid = info.getGroupUuid(); + ParcelUuid groupUuid = info.getGroupUuid(); if (groupUuid == null) { // Doesn't belong to any group. Add in the list. selectableList.add(info); diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 244d622930bb..5df7bf717aed 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -1428,6 +1428,70 @@ public class TelephonyManager { public static final String EXTRA_ANOMALY_DESCRIPTION = "android.telephony.extra.ANOMALY_DESCRIPTION"; + /** + * Broadcast intent sent to indicate primary (non-opportunistic) subscription list has changed. + * + * @hide + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED = + "android.telephony.action.PRIMARY_SUBSCRIPTION_LIST_CHANGED"; + + /** + * Integer intent extra to be used with {@link #ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED} + * to indicate whether a SIM selection is needed to choose default subscription. + * + * @hide + */ + public static final String EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE = + "android.telephony.extra.DEFAULT_SUBSCRIPTION_SELECT_TYPE"; + + /** + * Used as an int value for {@link #EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE} + * to indicate there's no need to re-select any default subscription. + * @hide + */ + public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE = 0; + + /** + * Used as an int value for {@link #EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE} + * to indicate there's a need to select default data subscription. + * @hide + */ + public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA = 1; + + /** + * Used as an int value for {@link #EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE} + * to indicate there's a need to select default voice call subscription. + * @hide + */ + public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_VOICE = 2; + + /** + * Used as an int value for {@link #EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE} + * to indicate there's a need to select default sms subscription. + * @hide + */ + public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_SMS = 3; + + /** + * Used as an int value for {@link #EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE} + * to indicate user to decide whether current SIM should be preferred for all + * data / voice / sms. + * @hide + */ + public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_FOR_ALL_TYPES = 4; + + /** + * Integer intent extra to be used with + * {@link #EXTRA_DEFAULT_SUBSCRIPTION_SELECT_FOR_ALL_TYPES} + * to indicate which SIM is being selected. + * + * @hide + */ + public static final String EXTRA_DEFAULT_SUBSCRIPTION_ID = + "android.telephony.extra.DEFAULT_SUBSCRIPTION_ID"; + // // // Device Info @@ -7018,6 +7082,35 @@ public class TelephonyManager { } /** + * Query Telephony to see if there has recently been an emergency SMS sent to the network by the + * user and we are still within the time interval after the emergency SMS was sent that we are + * considered in Emergency SMS mode. + * + * <p>This mode is used by other applications to allow them to perform special functionality, + * such as allow the GNSS service to provide user location to the carrier network for emergency + * when an emergency SMS is sent. This interval is set by + * {@link CarrierConfigManager#KEY_EMERGENCY_SMS_MODE_TIMER_MS_INT}. If + * the carrier does not support this mode, this function will always return false. + * + * @return true if this device is in emergency SMS mode, false otherwise. + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public boolean isInEmergencySmsMode() { + + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + return telephony.isInEmergencySmsMode(); + } + } catch (RemoteException ex) { + Rlog.e(TAG, "getNetworkSelectionMode RemoteException", ex); + } + return false; + } + + /** * Set the preferred network type. * * <p>Requires Permission: @@ -10192,6 +10285,24 @@ public class TelephonyManager { } /** + * Determine whether the emergency assistance feature is available on the device. + * <p> + * Requires permission: {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} + * + * @return whether the emergency assistance feature is available on the device + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + @SystemApi + public boolean isEmergencyAssistanceEnabled() { + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, + "isEmergencyAssistanceEnabled"); + return EMERGENCY_ASSISTANCE_ENABLED; + } + + /** * Get the emergency number list based on current locale, sim, default, modem and network. * * <p>In each returned list, the emergency number {@link EmergencyNumber} coming from higher diff --git a/telephony/java/android/telephony/VoiceSpecificRegistrationStates.java b/telephony/java/android/telephony/VoiceSpecificRegistrationInfo.java index d8ce5b43e4d6..18a533a46273 100644 --- a/telephony/java/android/telephony/VoiceSpecificRegistrationStates.java +++ b/telephony/java/android/telephony/VoiceSpecificRegistrationInfo.java @@ -1,5 +1,22 @@ +/* + * Copyright 2018 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.telephony; +import android.annotation.NonNull; import android.os.Parcel; import android.os.Parcelable; @@ -10,14 +27,14 @@ import java.util.Objects; * Class that stores information specific to voice network registration. * @hide */ -public class VoiceSpecificRegistrationStates implements Parcelable{ +public class VoiceSpecificRegistrationInfo implements Parcelable{ /** * oncurrent services support indicator. if * registered on a CDMA system. * false - Concurrent services not supported, * true - Concurrent services supported */ - public final boolean cssSupported; + public final boolean cssSupported; /** * TSB-58 Roaming Indicator if registered @@ -40,15 +57,15 @@ public class VoiceSpecificRegistrationStates implements Parcelable{ */ public final int defaultRoamingIndicator; - VoiceSpecificRegistrationStates(boolean cssSupported, int roamingIndicator, int systemIsInPrl, - int defaultRoamingIndicator) { + VoiceSpecificRegistrationInfo(boolean cssSupported, int roamingIndicator, int systemIsInPrl, + int defaultRoamingIndicator) { this.cssSupported = cssSupported; this.roamingIndicator = roamingIndicator; this.systemIsInPrl = systemIsInPrl; this.defaultRoamingIndicator = defaultRoamingIndicator; } - private VoiceSpecificRegistrationStates(Parcel source) { + private VoiceSpecificRegistrationInfo(Parcel source) { this.cssSupported = source.readBoolean(); this.roamingIndicator = source.readInt(); this.systemIsInPrl = source.readInt(); @@ -70,7 +87,7 @@ public class VoiceSpecificRegistrationStates implements Parcelable{ @Override public String toString() { - return "VoiceSpecificRegistrationStates {" + return "VoiceSpecificRegistrationInfo {" + " mCssSupported=" + cssSupported + " mRoamingIndicator=" + roamingIndicator + " mSystemIsInPrl=" + systemIsInPrl @@ -87,11 +104,11 @@ public class VoiceSpecificRegistrationStates implements Parcelable{ public boolean equals(Object o) { if (this == o) return true; - if (o == null || !(o instanceof VoiceSpecificRegistrationStates)) { + if (o == null || !(o instanceof VoiceSpecificRegistrationInfo)) { return false; } - VoiceSpecificRegistrationStates other = (VoiceSpecificRegistrationStates) o; + VoiceSpecificRegistrationInfo other = (VoiceSpecificRegistrationInfo) o; return this.cssSupported == other.cssSupported && this.roamingIndicator == other.roamingIndicator && this.systemIsInPrl == other.systemIsInPrl @@ -99,16 +116,16 @@ public class VoiceSpecificRegistrationStates implements Parcelable{ } - public static final @android.annotation.NonNull Parcelable.Creator<VoiceSpecificRegistrationStates> CREATOR = - new Parcelable.Creator<VoiceSpecificRegistrationStates>() { + public static final @NonNull Parcelable.Creator<VoiceSpecificRegistrationInfo> CREATOR = + new Parcelable.Creator<VoiceSpecificRegistrationInfo>() { @Override - public VoiceSpecificRegistrationStates createFromParcel(Parcel source) { - return new VoiceSpecificRegistrationStates(source); + public VoiceSpecificRegistrationInfo createFromParcel(Parcel source) { + return new VoiceSpecificRegistrationInfo(source); } @Override - public VoiceSpecificRegistrationStates[] newArray(int size) { - return new VoiceSpecificRegistrationStates[size]; + public VoiceSpecificRegistrationInfo[] newArray(int size) { + return new VoiceSpecificRegistrationInfo[size]; } }; -}
\ No newline at end of file +} diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java index d0b52c9085a5..7eea21860bce 100644 --- a/telephony/java/android/telephony/data/ApnSetting.java +++ b/telephony/java/android/telephony/data/ApnSetting.java @@ -17,6 +17,7 @@ package android.telephony.data; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; import android.content.ContentValues; import android.database.Cursor; import android.hardware.radio.V1_4.ApnTypes; @@ -1620,7 +1621,7 @@ public class ApnSetting implements Parcelable { * @param mvnoMatchData the MVNO match data for the APN * @hide */ - public Builder setMvnoMatchData(String mvnoMatchData) { + public Builder setMvnoMatchData(@Nullable String mvnoMatchData) { this.mMvnoMatchData = mvnoMatchData; return this; } @@ -1642,7 +1643,7 @@ public class ApnSetting implements Parcelable { * @param entryName the entry name to set for the APN */ @NonNull - public Builder setEntryName(String entryName) { + public Builder setEntryName(@Nullable String entryName) { this.mEntryName = entryName; return this; } @@ -1653,7 +1654,7 @@ public class ApnSetting implements Parcelable { * @param apnName the name to set for the APN */ @NonNull - public Builder setApnName(String apnName) { + public Builder setApnName(@Nullable String apnName) { this.mApnName = apnName; return this; } @@ -1684,7 +1685,7 @@ public class ApnSetting implements Parcelable { * @param proxy the proxy address to set for the APN */ @NonNull - public Builder setProxyAddress(String proxy) { + public Builder setProxyAddress(@Nullable String proxy) { this.mProxyAddress = proxy; return this; } @@ -1706,7 +1707,7 @@ public class ApnSetting implements Parcelable { * @param mmsc the MMSC Uri to set for the APN */ @NonNull - public Builder setMmsc(Uri mmsc) { + public Builder setMmsc(@Nullable Uri mmsc) { this.mMmsc = mmsc; return this; } @@ -1738,7 +1739,7 @@ public class ApnSetting implements Parcelable { * @param mmsProxy the MMS proxy address to set for the APN */ @NonNull - public Builder setMmsProxyAddress(String mmsProxy) { + public Builder setMmsProxyAddress(@Nullable String mmsProxy) { this.mMmsProxyAddress = mmsProxy; return this; } @@ -1760,7 +1761,7 @@ public class ApnSetting implements Parcelable { * @param user the APN username to set for the APN */ @NonNull - public Builder setUser(String user) { + public Builder setUser(@Nullable String user) { this.mUser = user; return this; } @@ -1772,7 +1773,7 @@ public class ApnSetting implements Parcelable { * @param password the APN password to set for the APN */ @NonNull - public Builder setPassword(String password) { + public Builder setPassword(@Nullable String password) { this.mPassword = password; return this; } @@ -1813,7 +1814,7 @@ public class ApnSetting implements Parcelable { * @param operatorNumeric the numeric operator ID to set for this entry */ @NonNull - public Builder setOperatorNumeric(String operatorNumeric) { + public Builder setOperatorNumeric(@Nullable String operatorNumeric) { this.mOperatorNumeric = operatorNumeric; return this; } diff --git a/telephony/java/android/telephony/ims/feature/ImsFeature.java b/telephony/java/android/telephony/ims/feature/ImsFeature.java index d2b41337e100..5e3f3983b0a1 100644 --- a/telephony/java/android/telephony/ims/feature/ImsFeature.java +++ b/telephony/java/android/telephony/ims/feature/ImsFeature.java @@ -210,7 +210,7 @@ public abstract class ImsFeature { /** * Contains the capabilities defined and supported by an ImsFeature in the form of a bit mask. * @hide - * @deprecated + * @deprecated Use {@link MmTelFeature.MmTelCapabilities} instead. */ @SystemApi // SystemApi only because it was leaked through type usage in a previous release. public static class Capabilities { diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl index 3bbf7a41eebf..01fdae800972 100755 --- a/telephony/java/com/android/internal/telephony/ISub.aidl +++ b/telephony/java/com/android/internal/telephony/ISub.aidl @@ -17,6 +17,7 @@ package com.android.internal.telephony; import android.telephony.SubscriptionInfo; +import android.os.ParcelUuid; import com.android.internal.telephony.ISetOpportunisticDataCallback; interface ISub { @@ -202,7 +203,7 @@ interface ISub { * null if fails. * */ - String setSubscriptionGroup(in int[] subIdList, String callingPackage); + ParcelUuid createSubscriptionGroup(in int[] subIdList, String callingPackage); /** * Set which subscription is preferred for cellular data. It's @@ -234,9 +235,13 @@ interface ISub { */ List<SubscriptionInfo> getOpportunisticSubscriptions(String callingPackage); - boolean removeSubscriptionsFromGroup(in int[] subIdList, String callingPackage); + void removeSubscriptionsFromGroup(in int[] subIdList, in ParcelUuid groupUuid, + String callingPackage); - List<SubscriptionInfo> getSubscriptionsInGroup(int subId, String callingPackage); + void addSubscriptionsIntoGroup(in int[] subIdList, in ParcelUuid groupUuid, + String callingPackage); + + List<SubscriptionInfo> getSubscriptionsInGroup(in ParcelUuid groupUuid, String callingPackage); int getSlotIndex(int subId); @@ -264,8 +269,6 @@ interface ISub { void setDefaultSmsSubId(int subId); - void clearDefaultsForInactiveSubIds(); - int[] getActiveSubIdList(boolean visibleOnly); int setSubscriptionProperty(int subId, String propKey, String propValue); diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 10cc99e3e98e..d98f8d832166 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -1707,6 +1707,11 @@ interface ITelephony { */ int getNetworkSelectionMode(int subId); + /** + * Return true if the device is in emergency sms mode, false otherwise. + */ + boolean isInEmergencySmsMode(); + /** * Get a list of SMS apps on a user. */ diff --git a/test-mock/api/test-current.txt b/test-mock/api/test-current.txt index 6765316a304b..a87e2f57bb5f 100644 --- a/test-mock/api/test-current.txt +++ b/test-mock/api/test-current.txt @@ -3,6 +3,7 @@ package android.test.mock { public class MockContext extends android.content.Context { method public android.view.Display getDisplay(); + method public int getDisplayId(); } @Deprecated public class MockPackageManager extends android.content.pm.PackageManager { diff --git a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java index 372ffcd057b4..e0b722761c34 100644 --- a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java +++ b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java @@ -48,6 +48,8 @@ public final class TcpKeepalivePacketDataTest { final int ack = 0x22222222; final int wnd = 8000; final int wndScale = 2; + final int tos = 4; + final int ttl = 64; TcpKeepalivePacketData resultData = null; final TcpKeepalivePacketDataParcelable testInfo = new TcpKeepalivePacketDataParcelable(); testInfo.srcAddress = IPV4_KEEPALIVE_SRC_ADDR; @@ -58,6 +60,8 @@ public final class TcpKeepalivePacketDataTest { testInfo.ack = ack; testInfo.rcvWnd = wnd; testInfo.rcvWndScale = wndScale; + testInfo.tos = tos; + testInfo.ttl = ttl; try { resultData = TcpKeepalivePacketData.tcpKeepalivePacket(testInfo); } catch (InvalidPacketException e) { @@ -72,16 +76,21 @@ public final class TcpKeepalivePacketDataTest { assertEquals(testInfo.ack, resultData.tcpAck); assertEquals(testInfo.rcvWnd, resultData.tcpWnd); assertEquals(testInfo.rcvWndScale, resultData.tcpWndScale); + assertEquals(testInfo.tos, resultData.ipTos); + assertEquals(testInfo.ttl, resultData.ipTtl); TestUtils.assertParcelingIsLossless(resultData, TcpKeepalivePacketData.CREATOR); final byte[] packet = resultData.getPacket(); - // IP version and TOS. - ByteBuffer buf = ByteBuffer.wrap(packet); - assertEquals(buf.getShort(), 0x4500); + // IP version and IHL + assertEquals(packet[0], 0x45); + // TOS + assertEquals(packet[1], tos); + // TTL + assertEquals(packet[8], ttl); // Source IP address. byte[] ip = new byte[4]; - buf = ByteBuffer.wrap(packet, 12, 4); + ByteBuffer buf = ByteBuffer.wrap(packet, 12, 4); buf.get(ip); assertArrayEquals(ip, IPV4_KEEPALIVE_SRC_ADDR); // Destination IP address. @@ -113,6 +122,8 @@ public final class TcpKeepalivePacketDataTest { final int ack = 0x22222222; final int wnd = 48_000; final int wndScale = 2; + final int tos = 4; + final int ttl = 64; final TcpKeepalivePacketDataParcelable testInfo = new TcpKeepalivePacketDataParcelable(); testInfo.srcAddress = IPV4_KEEPALIVE_SRC_ADDR; testInfo.srcPort = srcPort; @@ -122,6 +133,8 @@ public final class TcpKeepalivePacketDataTest { testInfo.ack = ack; testInfo.rcvWnd = wnd; testInfo.rcvWndScale = wndScale; + testInfo.tos = tos; + testInfo.ttl = ttl; TcpKeepalivePacketData testData = null; TcpKeepalivePacketDataParcelable resultData = null; testData = TcpKeepalivePacketData.tcpKeepalivePacket(testInfo); @@ -134,5 +147,7 @@ public final class TcpKeepalivePacketDataTest { assertEquals(resultData.ack, ack); assertEquals(resultData.rcvWnd, wnd); assertEquals(resultData.rcvWndScale, wndScale); + assertEquals(resultData.tos, tos); + assertEquals(resultData.ttl, ttl); } } diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 9dfe4362e838..1151214418df 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -144,12 +144,14 @@ import android.os.INetworkManagementService; import android.os.Looper; import android.os.Message; import android.os.Parcel; +import android.os.ParcelFileDescriptor; import android.os.Parcelable; import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; +import android.system.Os; import android.test.mock.MockContentResolver; import android.text.TextUtils; import android.util.ArraySet; @@ -188,6 +190,8 @@ import org.mockito.MockitoAnnotations; import org.mockito.Spy; import org.mockito.stubbing.Answer; +import java.io.IOException; +import java.net.DatagramSocket; import java.net.Inet4Address; import java.net.InetAddress; import java.net.InetSocketAddress; @@ -421,7 +425,7 @@ public class ConnectivityServiceTest { private final ConditionVariable mPreventReconnectReceived = new ConditionVariable(); private int mScore; private NetworkAgent mNetworkAgent; - private int mStartKeepaliveError = SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED; + private int mStartKeepaliveError = SocketKeepalive.ERROR_UNSUPPORTED; private int mStopKeepaliveError = SocketKeepalive.NO_KEEPALIVE; private Integer mExpectedKeepaliveSlot = null; // Contains the redirectUrl from networkStatus(). Before reading, wait for @@ -4032,6 +4036,7 @@ public class ConnectivityServiceTest { runTestWithSerialExecutors(executor -> { try { doTestNattSocketKeepalivesWithExecutor(executor); + doTestNattSocketKeepalivesFdWithExecutor(executor); } catch (Exception e) { fail(e.getMessage()); } @@ -4041,6 +4046,8 @@ public class ConnectivityServiceTest { private void doTestNattSocketKeepalivesWithExecutor(Executor executor) throws Exception { // TODO: 1. Move this outside of ConnectivityServiceTest. // 2. Make test to verify that Nat-T keepalive socket is created by IpSecService. + // 3. Mock ipsec service. + // 4. Find a free port instead of a fixed port. final int srcPort = 12345; final InetAddress myIPv4 = InetAddress.getByName("192.0.2.129"); final InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35"); @@ -4065,89 +4072,106 @@ public class ConnectivityServiceTest { Network myNet = connectKeepaliveNetwork(lp); TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor); - SocketKeepalive ka; // Attempt to start keepalives with invalid parameters and check for errors. // Invalid network. - ka = mCm.createSocketKeepalive(notMyNet, testSocket, myIPv4, dstIPv4, executor, callback); - ka.start(validKaInterval); - callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); + try (SocketKeepalive ka = mCm.createSocketKeepalive( + notMyNet, testSocket, myIPv4, dstIPv4, executor, callback)) { + ka.start(validKaInterval); + callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); + } // Invalid interval. - ka = mCm.createSocketKeepalive(myNet, testSocket, myIPv4, dstIPv4, executor, callback); - ka.start(invalidKaInterval); - callback.expectError(SocketKeepalive.ERROR_INVALID_INTERVAL); + try (SocketKeepalive ka = mCm.createSocketKeepalive( + myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { + ka.start(invalidKaInterval); + callback.expectError(SocketKeepalive.ERROR_INVALID_INTERVAL); + } // Invalid destination. - ka = mCm.createSocketKeepalive(myNet, testSocket, myIPv4, dstIPv6, executor, callback); - ka.start(validKaInterval); - callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); + try (SocketKeepalive ka = mCm.createSocketKeepalive( + myNet, testSocket, myIPv4, dstIPv6, executor, callback)) { + ka.start(validKaInterval); + callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); + } // Invalid source; - ka = mCm.createSocketKeepalive(myNet, testSocket, myIPv6, dstIPv4, executor, callback); - ka.start(validKaInterval); - callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); + try (SocketKeepalive ka = mCm.createSocketKeepalive( + myNet, testSocket, myIPv6, dstIPv4, executor, callback)) { + ka.start(validKaInterval); + callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); + } // NAT-T is only supported for IPv4. - ka = mCm.createSocketKeepalive(myNet, testSocket, myIPv6, dstIPv6, executor, callback); - ka.start(validKaInterval); - callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); + try (SocketKeepalive ka = mCm.createSocketKeepalive( + myNet, testSocket, myIPv6, dstIPv6, executor, callback)) { + ka.start(validKaInterval); + callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); + } // Sanity check before testing started keepalive. - ka = mCm.createSocketKeepalive(myNet, testSocket, myIPv4, dstIPv4, executor, callback); - ka.start(validKaInterval); - callback.expectError(SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED); + try (SocketKeepalive ka = mCm.createSocketKeepalive( + myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { + ka.start(validKaInterval); + callback.expectError(SocketKeepalive.ERROR_UNSUPPORTED); + } // Check that a started keepalive can be stopped. mWiFiNetworkAgent.setStartKeepaliveError(SocketKeepalive.SUCCESS); - ka = mCm.createSocketKeepalive(myNet, testSocket, myIPv4, dstIPv4, executor, callback); - ka.start(validKaInterval); - callback.expectStarted(); - mWiFiNetworkAgent.setStopKeepaliveError(SocketKeepalive.SUCCESS); - ka.stop(); - callback.expectStopped(); - - // Check that keepalive could be restarted. - ka.start(validKaInterval); - callback.expectStarted(); - ka.stop(); - callback.expectStopped(); - - // Check that keepalive can be restarted without waiting for callback. - ka.start(validKaInterval); - callback.expectStarted(); - ka.stop(); - ka.start(validKaInterval); - callback.expectStopped(); - callback.expectStarted(); - ka.stop(); - callback.expectStopped(); + try (SocketKeepalive ka = mCm.createSocketKeepalive( + myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { + ka.start(validKaInterval); + callback.expectStarted(); + mWiFiNetworkAgent.setStopKeepaliveError(SocketKeepalive.SUCCESS); + ka.stop(); + callback.expectStopped(); + + // Check that keepalive could be restarted. + ka.start(validKaInterval); + callback.expectStarted(); + ka.stop(); + callback.expectStopped(); + + // Check that keepalive can be restarted without waiting for callback. + ka.start(validKaInterval); + callback.expectStarted(); + ka.stop(); + ka.start(validKaInterval); + callback.expectStopped(); + callback.expectStarted(); + ka.stop(); + callback.expectStopped(); + } // Check that deleting the IP address stops the keepalive. LinkProperties bogusLp = new LinkProperties(lp); - ka = mCm.createSocketKeepalive(myNet, testSocket, myIPv4, dstIPv4, executor, callback); - ka.start(validKaInterval); - callback.expectStarted(); - bogusLp.removeLinkAddress(new LinkAddress(myIPv4, 25)); - bogusLp.addLinkAddress(new LinkAddress(notMyIPv4, 25)); - mWiFiNetworkAgent.sendLinkProperties(bogusLp); - callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); - mWiFiNetworkAgent.sendLinkProperties(lp); + try (SocketKeepalive ka = mCm.createSocketKeepalive( + myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { + ka.start(validKaInterval); + callback.expectStarted(); + bogusLp.removeLinkAddress(new LinkAddress(myIPv4, 25)); + bogusLp.addLinkAddress(new LinkAddress(notMyIPv4, 25)); + mWiFiNetworkAgent.sendLinkProperties(bogusLp); + callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); + mWiFiNetworkAgent.sendLinkProperties(lp); + } // Check that a started keepalive is stopped correctly when the network disconnects. - ka = mCm.createSocketKeepalive(myNet, testSocket, myIPv4, dstIPv4, executor, callback); - ka.start(validKaInterval); - callback.expectStarted(); - mWiFiNetworkAgent.disconnect(); - waitFor(mWiFiNetworkAgent.getDisconnectedCV()); - callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); + try (SocketKeepalive ka = mCm.createSocketKeepalive( + myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { + ka.start(validKaInterval); + callback.expectStarted(); + mWiFiNetworkAgent.disconnect(); + waitFor(mWiFiNetworkAgent.getDisconnectedCV()); + callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); - // ... and that stopping it after that has no adverse effects. - waitForIdle(); - final Network myNetAlias = myNet; - assertNull(mCm.getNetworkCapabilities(myNetAlias)); - ka.stop(); - callback.assertNoCallback(); + // ... and that stopping it after that has no adverse effects. + waitForIdle(); + final Network myNetAlias = myNet; + assertNull(mCm.getNetworkCapabilities(myNetAlias)); + ka.stop(); + callback.assertNoCallback(); + } // Reconnect. myNet = connectKeepaliveNetwork(lp); @@ -4155,27 +4179,30 @@ public class ConnectivityServiceTest { // Check that keepalive slots start from 1 and increment. The first one gets slot 1. mWiFiNetworkAgent.setExpectedKeepaliveSlot(1); - ka = mCm.createSocketKeepalive(myNet, testSocket, myIPv4, dstIPv4, executor, callback); - ka.start(validKaInterval); - callback.expectStarted(); - - // The second one gets slot 2. - mWiFiNetworkAgent.setExpectedKeepaliveSlot(2); - final UdpEncapsulationSocket testSocket2 = mIpSec.openUdpEncapsulationSocket(6789); - TestSocketKeepaliveCallback callback2 = new TestSocketKeepaliveCallback(executor); - SocketKeepalive ka2 = - mCm.createSocketKeepalive(myNet, testSocket2, myIPv4, dstIPv4, executor, callback2); - ka2.start(validKaInterval); - callback2.expectStarted(); - - ka.stop(); - callback.expectStopped(); - - ka2.stop(); - callback2.expectStopped(); - - testSocket.close(); - testSocket2.close(); + try (SocketKeepalive ka = mCm.createSocketKeepalive( + myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { + ka.start(validKaInterval); + callback.expectStarted(); + + // The second one gets slot 2. + mWiFiNetworkAgent.setExpectedKeepaliveSlot(2); + final UdpEncapsulationSocket testSocket2 = mIpSec.openUdpEncapsulationSocket(6789); + TestSocketKeepaliveCallback callback2 = new TestSocketKeepaliveCallback(executor); + try (SocketKeepalive ka2 = mCm.createSocketKeepalive( + myNet, testSocket2, myIPv4, dstIPv4, executor, callback2)) { + ka2.start(validKaInterval); + callback2.expectStarted(); + + ka.stop(); + callback.expectStopped(); + + ka2.stop(); + callback2.expectStopped(); + + testSocket.close(); + testSocket2.close(); + } + } mWiFiNetworkAgent.disconnect(); waitFor(mWiFiNetworkAgent.getDisconnectedCV()); @@ -4200,7 +4227,6 @@ public class ConnectivityServiceTest { final InetAddress myIPv6 = InetAddress.getByName("::1"); final int validKaInterval = 15; - final int invalidKaInterval = 9; final LinkProperties lp = new LinkProperties(); lp.setInterfaceName("wlan12"); @@ -4216,37 +4242,46 @@ public class ConnectivityServiceTest { final Socket testSocketV6 = new Socket(); TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor); - SocketKeepalive ka; // Attempt to start Tcp keepalives with invalid parameters and check for errors. // Invalid network. - ka = mCm.createSocketKeepalive(notMyNet, testSocketV4, executor, callback); - ka.start(validKaInterval); - callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); + try (SocketKeepalive ka = mCm.createSocketKeepalive( + notMyNet, testSocketV4, executor, callback)) { + ka.start(validKaInterval); + callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); + } // Invalid Socket (socket is not bound with IPv4 address). - ka = mCm.createSocketKeepalive(myNet, testSocketV4, executor, callback); - ka.start(validKaInterval); - callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); + try (SocketKeepalive ka = mCm.createSocketKeepalive( + myNet, testSocketV4, executor, callback)) { + ka.start(validKaInterval); + callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); + } // Invalid Socket (socket is not bound with IPv6 address). - ka = mCm.createSocketKeepalive(myNet, testSocketV6, executor, callback); - ka.start(validKaInterval); - callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); + try (SocketKeepalive ka = mCm.createSocketKeepalive( + myNet, testSocketV6, executor, callback)) { + ka.start(validKaInterval); + callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); + } // Bind the socket address testSocketV4.bind(new InetSocketAddress(myIPv4, srcPortV4)); testSocketV6.bind(new InetSocketAddress(myIPv6, srcPortV6)); // Invalid Socket (socket is bound with IPv4 address). - ka = mCm.createSocketKeepalive(myNet, testSocketV4, executor, callback); - ka.start(validKaInterval); - callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); + try (SocketKeepalive ka = mCm.createSocketKeepalive( + myNet, testSocketV4, executor, callback)) { + ka.start(validKaInterval); + callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); + } // Invalid Socket (socket is bound with IPv6 address). - ka = mCm.createSocketKeepalive(myNet, testSocketV6, executor, callback); - ka.start(validKaInterval); - callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); + try (SocketKeepalive ka = mCm.createSocketKeepalive( + myNet, testSocketV6, executor, callback)) { + ka.start(validKaInterval); + callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); + } testSocketV4.close(); testSocketV6.close(); @@ -4256,6 +4291,66 @@ public class ConnectivityServiceTest { mWiFiNetworkAgent = null; } + private void doTestNattSocketKeepalivesFdWithExecutor(Executor executor) throws Exception { + final int srcPort = 12345; + final InetAddress myIPv4 = InetAddress.getByName("192.0.2.129"); + final InetAddress anyIPv4 = InetAddress.getByName("0.0.0.0"); + final InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8"); + final int validKaInterval = 15; + + // Prepare the target network. + LinkProperties lp = new LinkProperties(); + lp.setInterfaceName("wlan12"); + lp.addLinkAddress(new LinkAddress(myIPv4, 25)); + lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); + Network myNet = connectKeepaliveNetwork(lp); + mWiFiNetworkAgent.setStartKeepaliveError(SocketKeepalive.SUCCESS); + mWiFiNetworkAgent.setStopKeepaliveError(SocketKeepalive.SUCCESS); + + TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor); + + // Prepare the target file descriptor, keep only one instance. + final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE); + final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket(srcPort); + final ParcelFileDescriptor testPfd = + ParcelFileDescriptor.dup(testSocket.getFileDescriptor()); + testSocket.close(); + assertTrue(isUdpPortInUse(srcPort)); + + // Start keepalive and explicit make the variable goes out of scope with try-with-resources + // block. + try (SocketKeepalive ka = mCm.createNattKeepalive( + myNet, testPfd, myIPv4, dstIPv4, executor, callback)) { + ka.start(validKaInterval); + callback.expectStarted(); + ka.stop(); + callback.expectStopped(); + } + + // Check that the ParcelFileDescriptor is still valid after keepalive stopped, + // ErrnoException with EBADF will be thrown if the socket is closed when checking local + // address. + assertTrue(isUdpPortInUse(srcPort)); + final InetSocketAddress sa = + (InetSocketAddress) Os.getsockname(testPfd.getFileDescriptor()); + assertEquals(anyIPv4, sa.getAddress()); + + testPfd.close(); + assertFalse(isUdpPortInUse(srcPort)); + + mWiFiNetworkAgent.disconnect(); + waitFor(mWiFiNetworkAgent.getDisconnectedCV()); + mWiFiNetworkAgent = null; + } + + private static boolean isUdpPortInUse(int port) { + try (DatagramSocket ignored = new DatagramSocket(port)) { + return false; + } catch (IOException ignored) { + return true; + } + } + @Test public void testGetCaptivePortalServerUrl() throws Exception { String url = mCm.getCaptivePortalServerUrl(); diff --git a/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java b/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java index 3944fad2ac9e..bac509802258 100644 --- a/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java +++ b/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java @@ -166,6 +166,7 @@ public final class EntitlementManagerTest { .thenReturn(mCarrierConfigManager); when(mCarrierConfigManager.getConfig()).thenReturn(mCarrierConfig); mCarrierConfig.putBoolean(CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, true); + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true); } @Test @@ -199,6 +200,16 @@ public final class EntitlementManagerTest { } @Test + public void toleratesCarrierConfigNotLoaded() { + setupForRequiredProvisioning(); + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, false); + mEnMgr.updateConfiguration( + new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID)); + // We still have a provisioning app configured, so still require provisioning. + assertTrue(mEnMgr.isTetherProvisioningRequired()); + } + + @Test public void provisioningNotRequiredWhenAppNotFound() { setupForRequiredProvisioning(); when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app)) diff --git a/tests/utils/testutils/Android.bp b/tests/utils/testutils/Android.bp index 0a9e964d8d8d..f71be7b0b7d3 100644 --- a/tests/utils/testutils/Android.bp +++ b/tests/utils/testutils/Android.bp @@ -19,7 +19,10 @@ java_library { srcs: ["java/**/*.java"], - static_libs: ["junit"], + static_libs: [ + "junit", + "hamcrest-library", + ], libs: [ "android.test.runner", diff --git a/core/tests/coretests/src/com/android/server/wm/test/filters/CoreTestsFilter.java b/tests/utils/testutils/java/com/android/server/wm/test/filters/CoreTestsFilter.java index 1a81c2c9fd41..1a81c2c9fd41 100644 --- a/core/tests/coretests/src/com/android/server/wm/test/filters/CoreTestsFilter.java +++ b/tests/utils/testutils/java/com/android/server/wm/test/filters/CoreTestsFilter.java diff --git a/tests/utils/testutils/java/com/android/test/filters/SelectTest.java b/tests/utils/testutils/java/com/android/test/filters/SelectTest.java index d0350aff5ef5..d5b14c58512e 100644 --- a/tests/utils/testutils/java/com/android/test/filters/SelectTest.java +++ b/tests/utils/testutils/java/com/android/test/filters/SelectTest.java @@ -26,10 +26,12 @@ import com.android.internal.annotations.VisibleForTesting; import org.junit.runner.Description; import org.junit.runner.manipulation.Filter; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.LinkedHashMap; import java.util.LinkedHashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.StringJoiner; @@ -131,7 +133,8 @@ public class SelectTest extends Filter { * * @param testArgs instrumentation test arguments. * @param selectTests array of class name to be selected to run. - * @return modified instrumentation test arguments. + * @return modified instrumentation test arguments. if {@link #OPTION_SELECT_TEST} argument + * already exists in {@code testArgs}, those are prepended before {@code selectTests}. */ @NonNull protected static Bundle addSelectTest( @@ -139,7 +142,13 @@ public class SelectTest extends Filter { if (selectTests.length == 0) { return testArgs; } - testArgs.putString(OPTION_SELECT_TEST, join(Arrays.asList(selectTests))); + final List<String> selectedTestList = new ArrayList<>(); + final String selectTestArgs = testArgs.getString(OPTION_SELECT_TEST); + if (selectTestArgs != null) { + selectedTestList.addAll(Arrays.asList(selectTestArgs.split(ARGUMENT_ITEM_SEPARATOR))); + } + selectedTestList.addAll(Arrays.asList(selectTests)); + testArgs.putString(OPTION_SELECT_TEST, join(selectedTestList)); return testArgs; } diff --git a/tests/utils/testutils/java/com/android/test/filters/SelectTestTests.java b/tests/utils/testutils/java/com/android/test/filters/SelectTestTests.java index 163b00abafcd..df18985f77bf 100644 --- a/tests/utils/testutils/java/com/android/test/filters/SelectTestTests.java +++ b/tests/utils/testutils/java/com/android/test/filters/SelectTestTests.java @@ -19,7 +19,11 @@ package com.android.test.filters; import static com.android.test.filters.SelectTest.OPTION_SELECT_TEST; import static com.android.test.filters.SelectTest.OPTION_SELECT_TEST_VERBOSE; +import static org.hamcrest.collection.IsArrayContaining.hasItemInArray; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import android.os.Bundle; @@ -146,6 +150,45 @@ public class SelectTestTests { } @Test + public void testAddSelectTest() { + final Bundle testArgs = new Bundle(); + + final Bundle modifiedTestArgs = + SelectTest.addSelectTest(testArgs, PACKAGE_A, CLASS_B3, METHOD_C5X); + assertSame(testArgs, modifiedTestArgs); + + final String selectTestArgs = modifiedTestArgs.getString(OPTION_SELECT_TEST); + assertNotNull(selectTestArgs); + final String[] selectedTests = selectTestArgs.split(","); + assertThat(selectedTests, hasItemInArray(PACKAGE_A)); + assertThat(selectedTests, hasItemInArray(CLASS_B3)); + assertThat(selectedTests, hasItemInArray(METHOD_C5X)); + } + + @Test + public void testAddSelectTest_prependExistingTestArg() { + final Bundle testArgs = new Bundle(); + testArgs.putString(OPTION_SELECT_TEST, new StringJoiner(",") + .add(PACKAGE_A) + .add(CLASS_B3) + .add(METHOD_C5X) + .toString()); + + final Bundle modifiedTestArgs = + SelectTest.addSelectTest(testArgs, PACKAGE_B, CLASS_B4, METHOD_C6Y); + + final String selectTestArgs = modifiedTestArgs.getString(OPTION_SELECT_TEST); + assertNotNull(selectTestArgs); + final String[] selectedTests = selectTestArgs.split(","); + assertThat(selectedTests, hasItemInArray(PACKAGE_A)); + assertThat(selectedTests, hasItemInArray(CLASS_B3)); + assertThat(selectedTests, hasItemInArray(METHOD_C5X)); + assertThat(selectedTests, hasItemInArray(PACKAGE_B)); + assertThat(selectedTests, hasItemInArray(CLASS_B4)); + assertThat(selectedTests, hasItemInArray(METHOD_C6Y)); + } + + @Test public void testFilterDisabled() { final Filter filter = mBuilder.build(); acceptTests(filter, TEST_ALL); diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp index 42dc74c6db55..2ec1ab31a58c 100644 --- a/tools/aapt2/cmd/Compile.cpp +++ b/tools/aapt2/cmd/Compile.cpp @@ -678,7 +678,7 @@ int Compile(IAaptContext* context, io::IFileCollection* inputs, IArchiveWriter* } else if (const ResourceType* type = ParseResourceType(path_data.resource_dir)) { if (*type != ResourceType::kRaw) { - if (path_data.extension == "xml") { + if (*type == ResourceType::kXml || path_data.extension == "xml") { compile_func = &CompileXml; } else if ((!options.no_png_crunch && path_data.extension == "png") || path_data.extension == "9.png") { diff --git a/tools/bit/main.cpp b/tools/bit/main.cpp index 082ccf38299b..0f555b11d30f 100644 --- a/tools/bit/main.cpp +++ b/tools/bit/main.cpp @@ -78,6 +78,9 @@ struct Options { // For help bool runHelp; + // For refreshing module-info.json + bool runRefresh; + // For tab completion bool runTab; string tabPattern; @@ -93,6 +96,7 @@ struct Options { Options::Options() :runHelp(false), + runRefresh(false), runTab(false), noRestart(false), reboot(false), @@ -418,6 +422,10 @@ print_usage(FILE* out) { fprintf(out, " com.android.statusbartest/.NotificationBuilderTest activity.\n"); fprintf(out, "\n"); fprintf(out, "\n"); + fprintf(out, "usage: bit --refresh\n"); + fprintf(out, "\n"); + fprintf(out, " Update module-info.json, the cache of make goals that can be built.\n"); + fprintf(out, "\n"); fprintf(out, "usage: bit --tab ...\n"); fprintf(out, "\n"); fprintf(out, " Lists the targets in a format for tab completion. To get tab\n"); @@ -450,6 +458,12 @@ parse_args(Options* options, int argc, const char** argv) return; } + // Refresh + if (argc == 2 && strcmp(argv[1], "--refresh") == 0) { + options->runRefresh = true; + return; + } + // Tab if (argc >= 4 && strcmp(argv[1], "--tab") == 0) { options->runTab = true; @@ -669,6 +683,9 @@ run_phases(vector<Target*> targets, const Options& options) target->module = mod->second; } else { print_error("Error: Could not find module: %s", target->name.c_str()); + fprintf(stderr, "Try running %sbit --refresh%s if you recently added %s%s%s.\n", + g_escapeBold, g_escapeEndColor, + g_escapeBold, target->name.c_str(), g_escapeEndColor); err = 1; } } @@ -1146,6 +1163,34 @@ run_phases(vector<Target*> targets, const Options& options) } /** + * Refresh module-info. + */ +void +run_refresh() +{ + int err; + + print_status("Initializing"); + const string buildTop = get_required_env("ANDROID_BUILD_TOP", false); + const string buildProduct = get_required_env("TARGET_PRODUCT", false); + const string buildVariant = get_required_env("TARGET_BUILD_VARIANT", false); + const string buildType = get_required_env("TARGET_BUILD_TYPE", false); + const string buildOut = get_out_dir(); + chdir_or_exit(buildTop.c_str()); + + BuildVars buildVars(buildOut, buildProduct, buildVariant, buildType); + + string buildDevice = buildVars.GetBuildVar("TARGET_DEVICE", false); + + vector<string> goals; + goals.push_back(buildOut + "/target/product/" + buildDevice + "/module-info.json"); + + print_status("Refreshing module-info.json"); + err = build_goals(goals); + check_error(err); +} + +/** * Implement tab completion of the target names from the all modules file. */ void @@ -1188,6 +1233,9 @@ main(int argc, const char** argv) // Help print_usage(stdout); exit(0); + } else if (options.runRefresh) { + run_refresh(); + exit(0); } else if (options.runTab) { run_tab_completion(options.tabPattern); exit(0); diff --git a/tools/stats_log_api_gen/Android.bp b/tools/stats_log_api_gen/Android.bp index 5725f0cdae6e..4ce4406211ce 100644 --- a/tools/stats_log_api_gen/Android.bp +++ b/tools/stats_log_api_gen/Android.bp @@ -31,6 +31,7 @@ cc_binary_host { shared_libs: [ "libstats_proto_host", "libprotobuf-cpp-full", + "libbase", ], proto: { diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp index a8d970edaa85..e66ead7ec340 100644 --- a/tools/stats_log_api_gen/Collation.cpp +++ b/tools/stats_log_api_gen/Collation.cpp @@ -49,7 +49,9 @@ AtomDecl::AtomDecl(const AtomDecl& that) exclusiveField(that.exclusiveField), uidField(that.uidField), whitelisted(that.whitelisted), - binaryFields(that.binaryFields) {} + binaryFields(that.binaryFields), + hasModule(that.hasModule), + moduleName(that.moduleName) {} AtomDecl::AtomDecl(int c, const string& n, const string& m) :code(c), @@ -391,7 +393,12 @@ int collate_atoms(const Descriptor *descriptor, Atoms *atoms) { AtomDecl atomDecl(atomField->number(), atomField->name(), atom->name()); if (atomField->options().GetExtension(os::statsd::allow_from_any_uid) == true) { - atomDecl.whitelisted = true; + atomDecl.whitelisted = true; + } + + if (atomField->options().HasExtension(os::statsd::log_from_module)) { + atomDecl.hasModule = true; + atomDecl.moduleName = atomField->options().GetExtension(os::statsd::log_from_module); } vector<java_type_t> signature; @@ -399,25 +406,49 @@ int collate_atoms(const Descriptor *descriptor, Atoms *atoms) { if (atomDecl.primaryFields.size() != 0 && atomDecl.exclusiveField == 0) { errorCount++; } - atoms->signatures.insert(signature); + + // Add the signature if does not already exist. + auto signature_to_modules_it = atoms->signatures_to_modules.find(signature); + if (signature_to_modules_it == atoms->signatures_to_modules.end()) { + set<string> modules; + if (atomDecl.hasModule) { + modules.insert(atomDecl.moduleName); + } + atoms->signatures_to_modules[signature] = modules; + } else { + if (atomDecl.hasModule) { + signature_to_modules_it->second.insert(atomDecl.moduleName); + } + } atoms->decls.insert(atomDecl); AtomDecl nonChainedAtomDecl(atomField->number(), atomField->name(), atom->name()); vector<java_type_t> nonChainedSignature; if (get_non_chained_node(atom, &nonChainedAtomDecl, &nonChainedSignature)) { - atoms->non_chained_signatures.insert(nonChainedSignature); + auto it = atoms->non_chained_signatures_to_modules.find(signature); + if (it == atoms->non_chained_signatures_to_modules.end()) { + set<string> modules_non_chained; + if (atomDecl.hasModule) { + modules_non_chained.insert(atomDecl.moduleName); + } + atoms->non_chained_signatures_to_modules[nonChainedSignature] = modules_non_chained; + } else { + if (atomDecl.hasModule) { + it->second.insert(atomDecl.moduleName); + } + } atoms->non_chained_decls.insert(nonChainedAtomDecl); } } if (dbg) { printf("signatures = [\n"); - for (set<vector<java_type_t>>::const_iterator it = - atoms->signatures.begin(); - it != atoms->signatures.end(); it++) { + for (map<vector<java_type_t>, set<string>>::const_iterator it = + atoms->signatures_to_modules.begin(); + it != atoms->signatures_to_modules.end(); it++) { printf(" "); - for (vector<java_type_t>::const_iterator jt = it->begin(); - jt != it->end(); jt++) { + for (vector<java_type_t>::const_iterator jt = it->first.begin(); + jt != it->first.end(); jt++) { printf(" %d", (int)*jt); } printf("\n"); diff --git a/tools/stats_log_api_gen/Collation.h b/tools/stats_log_api_gen/Collation.h index 6b86b862dfad..44746c96df1b 100644 --- a/tools/stats_log_api_gen/Collation.h +++ b/tools/stats_log_api_gen/Collation.h @@ -93,6 +93,9 @@ struct AtomDecl { vector<int> binaryFields; + bool hasModule = false; + string moduleName; + AtomDecl(); AtomDecl(const AtomDecl& that); AtomDecl(int code, const string& name, const string& message); @@ -104,10 +107,10 @@ struct AtomDecl { }; struct Atoms { - set<vector<java_type_t>> signatures; + map<vector<java_type_t>, set<string>> signatures_to_modules; set<AtomDecl> decls; set<AtomDecl> non_chained_decls; - set<vector<java_type_t>> non_chained_signatures; + map<vector<java_type_t>, set<string>> non_chained_signatures_to_modules; }; /** diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp index 0270c72ff240..daee6d6be048 100644 --- a/tools/stats_log_api_gen/main.cpp +++ b/tools/stats_log_api_gen/main.cpp @@ -12,6 +12,8 @@ #include <stdlib.h> #include <string.h> +#include "android-base/strings.h" + using namespace google::protobuf; using namespace std; @@ -20,6 +22,10 @@ namespace stats_log_api_gen { int maxPushedAtomId = 2; +const string DEFAULT_MODULE_NAME = "DEFAULT"; +const string DEFAULT_CPP_NAMESPACE = "android,util"; +const string DEFAULT_CPP_HEADER_IMPORT = "statslog.h"; + using android::os::statsd::Atom; /** @@ -97,40 +103,27 @@ java_type_name(java_type_t type) } } -static int write_stats_log_cpp(FILE *out, const Atoms &atoms, - const AtomDecl &attributionDecl) { - // Print prelude - fprintf(out, "// This file is autogenerated\n"); - fprintf(out, "\n"); - - fprintf(out, "#include <mutex>\n"); - fprintf(out, "#include <chrono>\n"); - fprintf(out, "#include <thread>\n"); - fprintf(out, "#ifdef __ANDROID__\n"); - fprintf(out, "#include <cutils/properties.h>\n"); - fprintf(out, "#endif\n"); - fprintf(out, "#include <stats_event_list.h>\n"); - fprintf(out, "#include <log/log.h>\n"); - fprintf(out, "#include <statslog.h>\n"); - fprintf(out, "#include <utils/SystemClock.h>\n"); - fprintf(out, "\n"); +static bool atom_needed_for_module(const AtomDecl& atomDecl, const string& moduleName) { + if (moduleName == DEFAULT_MODULE_NAME) { + return true; + } + return atomDecl.hasModule && (moduleName == atomDecl.moduleName); +} - fprintf(out, "namespace android {\n"); - fprintf(out, "namespace util {\n"); - fprintf(out, "// the single event tag id for all stats logs\n"); - fprintf(out, "const static int kStatsEventTag = 1937006964;\n"); - fprintf(out, "#ifdef __ANDROID__\n"); - fprintf(out, "const static bool kStatsdEnabled = property_get_bool(\"ro.statsd.enable\", true);\n"); - fprintf(out, "#else\n"); - fprintf(out, "const static bool kStatsdEnabled = false;\n"); - fprintf(out, "#endif\n"); +static bool signature_needed_for_module(const set<string>& modules, const string& moduleName) { + if (moduleName == DEFAULT_MODULE_NAME) { + return true; + } + return modules.find(moduleName) != modules.end(); +} +static void write_atoms_info_cpp(FILE *out, const Atoms &atoms) { std::set<string> kTruncatingAtomNames = {"mobile_radio_power_state_changed", - "audio_state_changed", - "call_state_changed", - "phone_signal_strength_changed", - "mobile_bytes_transfer_by_fg_bg", - "mobile_bytes_transfer"}; + "audio_state_changed", + "call_state_changed", + "phone_signal_strength_changed", + "mobile_bytes_transfer_by_fg_bg", + "mobile_bytes_transfer"}; fprintf(out, "const std::set<int> " "AtomsInfo::kNotTruncatingTimestampAtomWhiteList = {\n"); @@ -256,6 +249,56 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, "const std::map<int, std::vector<int>> " "AtomsInfo::kBytesFieldAtoms = " "getBinaryFieldAtoms();\n"); +} + +// Writes namespaces for the cpp and header files, returning the number of namespaces written. +void write_namespace(FILE* out, const string& cppNamespaces) { + vector<string> cppNamespaceVec = android::base::Split(cppNamespaces, ","); + for (string cppNamespace : cppNamespaceVec) { + fprintf(out, "namespace %s {\n", cppNamespace.c_str()); + } +} + +// Writes namespace closing brackets for cpp and header files. +void write_closing_namespace(FILE* out, const string& cppNamespaces) { + vector<string> cppNamespaceVec = android::base::Split(cppNamespaces, ","); + for (auto it = cppNamespaceVec.rbegin(); it != cppNamespaceVec.rend(); ++it) { + fprintf(out, "} // namespace %s\n", it->c_str()); + } +} + +static int write_stats_log_cpp(FILE *out, const Atoms &atoms, const AtomDecl &attributionDecl, + const string& moduleName, const string& cppNamespace, + const string& importHeader) { + // Print prelude + fprintf(out, "// This file is autogenerated\n"); + fprintf(out, "\n"); + + fprintf(out, "#include <mutex>\n"); + fprintf(out, "#include <chrono>\n"); + fprintf(out, "#include <thread>\n"); + fprintf(out, "#ifdef __ANDROID__\n"); + fprintf(out, "#include <cutils/properties.h>\n"); + fprintf(out, "#endif\n"); + fprintf(out, "#include <stats_event_list.h>\n"); + fprintf(out, "#include <log/log.h>\n"); + fprintf(out, "#include <%s>\n", importHeader.c_str()); + fprintf(out, "#include <utils/SystemClock.h>\n"); + fprintf(out, "\n"); + + write_namespace(out, cppNamespace); + fprintf(out, "// the single event tag id for all stats logs\n"); + fprintf(out, "const static int kStatsEventTag = 1937006964;\n"); + fprintf(out, "#ifdef __ANDROID__\n"); + fprintf(out, "const static bool kStatsdEnabled = property_get_bool(\"ro.statsd.enable\", true);\n"); + fprintf(out, "#else\n"); + fprintf(out, "const static bool kStatsdEnabled = false;\n"); + fprintf(out, "#endif\n"); + + // AtomsInfo is only used by statsd internally and is not needed for other modules. + if (moduleName == DEFAULT_MODULE_NAME) { + write_atoms_info_cpp(out, atoms); + } fprintf(out, "int64_t lastRetryTimestampNs = -1;\n"); fprintf(out, "const int64_t kMinRetryIntervalNs = NS_PER_SEC * 60 * 20; // 20 minutes\n"); @@ -263,15 +306,19 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, // Print write methods fprintf(out, "\n"); - for (set<vector<java_type_t>>::const_iterator signature = atoms.signatures.begin(); - signature != atoms.signatures.end(); signature++) { + for (auto signature_to_modules_it = atoms.signatures_to_modules.begin(); + signature_to_modules_it != atoms.signatures_to_modules.end(); signature_to_modules_it++) { + if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { + continue; + } + vector<java_type_t> signature = signature_to_modules_it->first; int argIndex; fprintf(out, "int\n"); fprintf(out, "try_stats_write(int32_t code"); argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { for (auto chainField : attributionDecl.fields) { if (chainField.javaType == JAVA_TYPE_STRING) { @@ -303,8 +350,8 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, fprintf(out, " stats_event_list event(kStatsEventTag);\n"); fprintf(out, " event << android::elapsedRealtimeNano();\n\n"); fprintf(out, " event << code;\n\n"); - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { for (const auto &chainField : attributionDecl.fields) { if (chainField.javaType == JAVA_TYPE_STRING) { @@ -387,15 +434,19 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, fprintf(out, "\n"); } - for (set<vector<java_type_t>>::const_iterator signature = atoms.signatures.begin(); - signature != atoms.signatures.end(); signature++) { + for (auto signature_to_modules_it = atoms.signatures_to_modules.begin(); + signature_to_modules_it != atoms.signatures_to_modules.end(); signature_to_modules_it++) { + if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { + continue; + } + vector<java_type_t> signature = signature_to_modules_it->first; int argIndex; fprintf(out, "int\n"); fprintf(out, "stats_write(int32_t code"); argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { for (auto chainField : attributionDecl.fields) { if (chainField.javaType == JAVA_TYPE_STRING) { @@ -429,8 +480,8 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, fprintf(out, " ret = try_stats_write(code"); argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { for (auto chainField : attributionDecl.fields) { if (chainField.javaType == JAVA_TYPE_STRING) { @@ -468,15 +519,19 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, fprintf(out, "\n"); } - for (set<vector<java_type_t>>::const_iterator signature = atoms.non_chained_signatures.begin(); - signature != atoms.non_chained_signatures.end(); signature++) { + for (auto signature_it = atoms.non_chained_signatures_to_modules.begin(); + signature_it != atoms.non_chained_signatures_to_modules.end(); signature_it++) { + if (!signature_needed_for_module(signature_it->second, moduleName)) { + continue; + } + vector<java_type_t> signature = signature_it->first; int argIndex; fprintf(out, "int\n"); fprintf(out, "try_stats_write_non_chained(int32_t code"); argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex); argIndex++; } @@ -488,8 +543,8 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, fprintf(out, " stats_event_list event(kStatsEventTag);\n"); fprintf(out, " event << android::elapsedRealtimeNano();\n\n"); fprintf(out, " event << code;\n\n"); - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { if (argIndex == 1) { fprintf(out, " event.begin();\n\n"); fprintf(out, " event.begin();\n"); @@ -522,15 +577,19 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, fprintf(out, "\n"); } - for (set<vector<java_type_t>>::const_iterator signature = atoms.non_chained_signatures.begin(); - signature != atoms.non_chained_signatures.end(); signature++) { + for (auto signature_it = atoms.non_chained_signatures_to_modules.begin(); + signature_it != atoms.non_chained_signatures_to_modules.end(); signature_it++) { + if (!signature_needed_for_module(signature_it->second, moduleName)) { + continue; + } + vector<java_type_t> signature = signature_it->first; int argIndex; fprintf(out, "int\n"); fprintf(out, "stats_write_non_chained(int32_t code"); argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex); argIndex++; } @@ -543,8 +602,8 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, fprintf(out, " ret = try_stats_write_non_chained(code"); argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { fprintf(out, ", arg%d", argIndex); argIndex++; } @@ -572,8 +631,7 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, // Print footer fprintf(out, "\n"); - fprintf(out, "} // namespace util\n"); - fprintf(out, "} // namespace android\n"); + write_closing_namespace(out, cppNamespace); return 0; } @@ -623,14 +681,23 @@ static void write_cpp_usage( } static void write_cpp_method_header( - FILE* out, const string& method_name, const set<vector<java_type_t>>& signatures, - const AtomDecl &attributionDecl) { - for (set<vector<java_type_t>>::const_iterator signature = signatures.begin(); - signature != signatures.end(); signature++) { + FILE* out, + const string& method_name, + const map<vector<java_type_t>, set<string>>& signatures_to_modules, + const AtomDecl &attributionDecl, const string& moduleName) { + + for (auto signature_to_modules_it = signatures_to_modules.begin(); + signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { + // Skip if this signature is not needed for the module. + if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { + continue; + } + + vector<java_type_t> signature = signature_to_modules_it->first; fprintf(out, "int %s(int32_t code", method_name.c_str()); int argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { for (auto chainField : attributionDecl.fields) { if (chainField.javaType == JAVA_TYPE_STRING) { @@ -659,7 +726,8 @@ static void write_cpp_method_header( } static int -write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl) +write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl, + const string& moduleName, const string& cppNamespace) { // Print prelude fprintf(out, "// This file is autogenerated\n"); @@ -672,8 +740,7 @@ write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributio fprintf(out, "#include <set>\n"); fprintf(out, "\n"); - fprintf(out, "namespace android {\n"); - fprintf(out, "namespace util {\n"); + write_namespace(out, cppNamespace); fprintf(out, "\n"); fprintf(out, "/*\n"); fprintf(out, " * API For logging statistics events.\n"); @@ -691,6 +758,10 @@ write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributio // Print atom constants for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); atom != atoms.decls.end(); atom++) { + // Skip if the atom is not needed for the module. + if (!atom_needed_for_module(*atom, moduleName)) { + continue; + } string constant = make_constant_name(atom->name); fprintf(out, "\n"); fprintf(out, " /**\n"); @@ -720,6 +791,11 @@ write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributio fprintf(out, "//\n\n"); for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); atom != atoms.decls.end(); atom++) { + // Skip if the atom is not needed for the module. + if (!atom_needed_for_module(*atom, moduleName)) { + continue; + } + for (vector<AtomField>::const_iterator field = atom->fields.begin(); field != atom->fields.end(); field++) { if (field->javaType == JAVA_TYPE_ENUM) { @@ -747,47 +823,51 @@ write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributio fprintf(out, "};\n"); fprintf(out, "\n"); - fprintf(out, "struct StateAtomFieldOptions {\n"); - fprintf(out, " std::vector<int> primaryFields;\n"); - fprintf(out, " int exclusiveField;\n"); - fprintf(out, "};\n"); - fprintf(out, "\n"); + // This metadata is only used by statsd, which uses the default libstatslog. + if (moduleName == DEFAULT_MODULE_NAME) { - fprintf(out, "struct AtomsInfo {\n"); - fprintf(out, - " const static std::set<int> " - "kNotTruncatingTimestampAtomWhiteList;\n"); - fprintf(out, " const static std::map<int, int> kAtomsWithUidField;\n"); - fprintf(out, - " const static std::set<int> kAtomsWithAttributionChain;\n"); - fprintf(out, - " const static std::map<int, StateAtomFieldOptions> " - "kStateAtomsFieldOptions;\n"); - fprintf(out, - " const static std::map<int, std::vector<int>> " - "kBytesFieldAtoms;"); - fprintf(out, - " const static std::set<int> kWhitelistedAtoms;\n"); - fprintf(out, "};\n"); + fprintf(out, "struct StateAtomFieldOptions {\n"); + fprintf(out, " std::vector<int> primaryFields;\n"); + fprintf(out, " int exclusiveField;\n"); + fprintf(out, "};\n"); + fprintf(out, "\n"); - fprintf(out, "const static int kMaxPushedAtomId = %d;\n\n", - maxPushedAtomId); + fprintf(out, "struct AtomsInfo {\n"); + fprintf(out, + " const static std::set<int> " + "kNotTruncatingTimestampAtomWhiteList;\n"); + fprintf(out, " const static std::map<int, int> kAtomsWithUidField;\n"); + fprintf(out, + " const static std::set<int> kAtomsWithAttributionChain;\n"); + fprintf(out, + " const static std::map<int, StateAtomFieldOptions> " + "kStateAtomsFieldOptions;\n"); + fprintf(out, + " const static std::map<int, std::vector<int>> " + "kBytesFieldAtoms;"); + fprintf(out, + " const static std::set<int> kWhitelistedAtoms;\n"); + fprintf(out, "};\n"); + + fprintf(out, "const static int kMaxPushedAtomId = %d;\n\n", + maxPushedAtomId); + } // Print write methods fprintf(out, "//\n"); fprintf(out, "// Write methods\n"); fprintf(out, "//\n"); - write_cpp_method_header(out, "stats_write", atoms.signatures, attributionDecl); + write_cpp_method_header(out, "stats_write", atoms.signatures_to_modules, attributionDecl, + moduleName); fprintf(out, "//\n"); fprintf(out, "// Write flattened methods\n"); fprintf(out, "//\n"); - write_cpp_method_header(out, "stats_write_non_chained", atoms.non_chained_signatures, - attributionDecl); + write_cpp_method_header(out, "stats_write_non_chained", atoms.non_chained_signatures_to_modules, + attributionDecl, moduleName); fprintf(out, "\n"); - fprintf(out, "} // namespace util\n"); - fprintf(out, "} // namespace android\n"); + write_closing_namespace(out, cppNamespace); return 0; } @@ -812,15 +892,19 @@ static void write_java_usage(FILE* out, const string& method_name, const string& } static void write_java_method( - FILE* out, const string& method_name, const set<vector<java_type_t>>& signatures, - const AtomDecl &attributionDecl) { - for (set<vector<java_type_t>>::const_iterator signature = signatures.begin(); - signature != signatures.end(); signature++) { + FILE* out, + const string& method_name, + const map<vector<java_type_t>, set<string>>& signatures_to_modules, + const AtomDecl &attributionDecl) { + + for (auto signature_to_modules_it = signatures_to_modules.begin(); + signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { + vector<java_type_t> signature = signature_to_modules_it->first; fprintf(out, " /** @hide */\n"); fprintf(out, " public static native int %s(int code", method_name.c_str()); int argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { for (auto chainField : attributionDecl.fields) { fprintf(out, ", %s[] %s", @@ -837,15 +921,17 @@ static void write_java_method( } } -static void write_java_work_source_method(FILE* out, const set<vector<java_type_t>>& signatures) { +static void write_java_work_source_method(FILE* out, + const map<vector<java_type_t>, set<string>>& signatures_to_modules) { fprintf(out, "\n // WorkSource methods.\n"); - for (set<vector<java_type_t>>::const_iterator signature = signatures.begin(); - signature != signatures.end(); signature++) { + for (auto signature_to_modules_it = signatures_to_modules.begin(); + signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { + vector<java_type_t> signature = signature_to_modules_it->first; // Determine if there is Attribution in this signature. int attributionArg = -1; int argIndexMax = 0; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { argIndexMax++; if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { if (attributionArg > -1) { @@ -865,8 +951,8 @@ static void write_java_work_source_method(FILE* out, const set<vector<java_type_ fprintf(out, " /** @hide */\n"); fprintf(out, " public static void write(int code"); int argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { fprintf(out, ", WorkSource ws"); } else { @@ -974,9 +1060,10 @@ write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl &attributionD // Print write methods fprintf(out, " // Write methods\n"); - write_java_method(out, "write", atoms.signatures, attributionDecl); - write_java_method(out, "write_non_chained", atoms.non_chained_signatures, attributionDecl); - write_java_work_source_method(out, atoms.signatures); + write_java_method(out, "write", atoms.signatures_to_modules, attributionDecl); + write_java_method(out, "write_non_chained", atoms.non_chained_signatures_to_modules, + attributionDecl); + write_java_work_source_method(out, atoms.signatures_to_modules); fprintf(out, "}\n"); @@ -1154,19 +1241,20 @@ static void write_key_value_map_jni(FILE* out) { static int write_stats_log_jni(FILE* out, const string& java_method_name, const string& cpp_method_name, - const set<vector<java_type_t>>& signatures, const AtomDecl &attributionDecl) -{ + const map<vector<java_type_t>, set<string>>& signatures_to_modules, + const AtomDecl &attributionDecl) { // Print write methods - for (set<vector<java_type_t>>::const_iterator signature = signatures.begin(); - signature != signatures.end(); signature++) { + for (auto signature_to_modules_it = signatures_to_modules.begin(); + signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { + vector<java_type_t> signature = signature_to_modules_it->first; int argIndex; fprintf(out, "static int\n"); fprintf(out, "%s(JNIEnv* env, jobject clazz UNUSED, jint code", - jni_function_name(java_method_name, *signature).c_str()); + jni_function_name(java_method_name, signature).c_str()); argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { for (auto chainField : attributionDecl.fields) { fprintf(out, ", %s %s", jni_array_type_name(chainField.javaType), @@ -1187,8 +1275,8 @@ write_stats_log_jni(FILE* out, const string& java_method_name, const string& cpp argIndex = 1; bool hadStringOrChain = false; bool isKeyValuePairAtom = false; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { if (*arg == JAVA_TYPE_STRING) { hadStringOrChain = true; fprintf(out, " const char* str%d;\n", argIndex); @@ -1288,8 +1376,8 @@ write_stats_log_jni(FILE* out, const string& java_method_name, const string& cpp argIndex = 1; fprintf(out, "\n int ret = android::util::%s(code", cpp_method_name.c_str()); - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { for (auto chainField : attributionDecl.fields) { if (chainField.javaType == JAVA_TYPE_INT) { @@ -1316,8 +1404,8 @@ write_stats_log_jni(FILE* out, const string& java_method_name, const string& cpp // Clean up strings argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { if (*arg == JAVA_TYPE_STRING) { fprintf(out, " if (str%d != NULL) {\n", argIndex); fprintf(out, " env->ReleaseStringUTFChars(arg%d, str%d);\n", @@ -1357,13 +1445,15 @@ write_stats_log_jni(FILE* out, const string& java_method_name, const string& cpp } void write_jni_registration(FILE* out, const string& java_method_name, - const set<vector<java_type_t>>& signatures, const AtomDecl &attributionDecl) { - for (set<vector<java_type_t>>::const_iterator signature = signatures.begin(); - signature != signatures.end(); signature++) { + const map<vector<java_type_t>, set<string>>& signatures_to_modules, + const AtomDecl &attributionDecl) { + for (auto signature_to_modules_it = signatures_to_modules.begin(); + signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { + vector<java_type_t> signature = signature_to_modules_it->first; fprintf(out, " { \"%s\", \"%s\", (void*)%s },\n", java_method_name.c_str(), - jni_function_signature(*signature, attributionDecl).c_str(), - jni_function_name(java_method_name, *signature).c_str()); + jni_function_signature(signature, attributionDecl).c_str(), + jni_function_name(java_method_name, signature).c_str()); } } @@ -1388,25 +1478,26 @@ write_stats_log_jni(FILE* out, const Atoms& atoms, const AtomDecl &attributionDe fprintf(out, "namespace android {\n"); fprintf(out, "\n"); - write_stats_log_jni(out, "write", "stats_write", atoms.signatures, attributionDecl); + write_stats_log_jni(out, "write", "stats_write", atoms.signatures_to_modules, attributionDecl); write_stats_log_jni(out, "write_non_chained", "stats_write_non_chained", - atoms.non_chained_signatures, attributionDecl); + atoms.non_chained_signatures_to_modules, attributionDecl); // Print registration function table fprintf(out, "/*\n"); fprintf(out, " * JNI registration.\n"); fprintf(out, " */\n"); fprintf(out, "static const JNINativeMethod gRegisterMethods[] = {\n"); - write_jni_registration(out, "write", atoms.signatures, attributionDecl); - write_jni_registration(out, "write_non_chained", atoms.non_chained_signatures, attributionDecl); + write_jni_registration(out, "write", atoms.signatures_to_modules, attributionDecl); + write_jni_registration(out, "write_non_chained", atoms.non_chained_signatures_to_modules, + attributionDecl); fprintf(out, "};\n"); fprintf(out, "\n"); // Print registration function - fprintf(out, "int register_android_util_StatsLog(JNIEnv* env) {\n"); + fprintf(out, "int register_android_util_StatsLogInternal(JNIEnv* env) {\n"); fprintf(out, " return RegisterMethodsOrDie(\n"); fprintf(out, " env,\n"); - fprintf(out, " \"android/util/StatsLog\",\n"); + fprintf(out, " \"android/util/StatsLogInternal\",\n"); fprintf(out, " gRegisterMethods, NELEM(gRegisterMethods));\n"); fprintf(out, "}\n"); @@ -1426,6 +1517,10 @@ print_usage() fprintf(stderr, " --help this message\n"); fprintf(stderr, " --java FILENAME the java file to output\n"); fprintf(stderr, " --jni FILENAME the jni file to output\n"); + fprintf(stderr, " --module NAME optional, module name to generate outputs for\n"); + fprintf(stderr, " --namespace COMMA,SEP,NAMESPACE required for cpp/header with module\n"); + fprintf(stderr, " comma separated namespace of the files\n"); + fprintf(stderr, " --importHeader NAME required for cpp/jni to say which header to import\n"); } /** @@ -1439,6 +1534,10 @@ run(int argc, char const*const* argv) string javaFilename; string jniFilename; + string moduleName = DEFAULT_MODULE_NAME; + string cppNamespace = DEFAULT_CPP_NAMESPACE; + string cppHeaderImport = DEFAULT_CPP_HEADER_IMPORT; + int index = 1; while (index < argc) { if (0 == strcmp("--help", argv[index])) { @@ -1472,6 +1571,27 @@ run(int argc, char const*const* argv) return 1; } jniFilename = argv[index]; + } else if (0 == strcmp("--module", argv[index])) { + index++; + if (index >= argc) { + print_usage(); + return 1; + } + moduleName = argv[index]; + } else if (0 == strcmp("--namespace", argv[index])) { + index++; + if (index >= argc) { + print_usage(); + return 1; + } + cppNamespace = argv[index]; + } else if (0 == strcmp("--importHeader", argv[index])) { + index++; + if (index >= argc) { + print_usage(); + return 1; + } + cppHeaderImport = argv[index]; } index++; } @@ -1503,8 +1623,18 @@ run(int argc, char const*const* argv) fprintf(stderr, "Unable to open file for write: %s\n", cppFilename.c_str()); return 1; } + // If this is for a specific module, the namespace must also be provided. + if (moduleName != DEFAULT_MODULE_NAME && cppNamespace == DEFAULT_CPP_NAMESPACE) { + fprintf(stderr, "Must supply --namespace if supplying a specific module\n"); + return 1; + } + // If this is for a specific module, the header file to import must also be provided. + if (moduleName != DEFAULT_MODULE_NAME && cppHeaderImport == DEFAULT_CPP_HEADER_IMPORT) { + fprintf(stderr, "Must supply --headerImport if supplying a specific module\n"); + return 1; + } errorCount = android::stats_log_api_gen::write_stats_log_cpp( - out, atoms, attributionDecl); + out, atoms, attributionDecl, moduleName, cppNamespace, cppHeaderImport); fclose(out); } @@ -1515,8 +1645,12 @@ run(int argc, char const*const* argv) fprintf(stderr, "Unable to open file for write: %s\n", headerFilename.c_str()); return 1; } + // If this is for a specific module, the namespace must also be provided. + if (moduleName != DEFAULT_MODULE_NAME && cppNamespace == DEFAULT_CPP_NAMESPACE) { + fprintf(stderr, "Must supply --namespace if supplying a specific module\n"); + } errorCount = android::stats_log_api_gen::write_stats_log_header( - out, atoms, attributionDecl); + out, atoms, attributionDecl, moduleName, cppNamespace); fclose(out); } diff --git a/tools/stats_log_api_gen/test.proto b/tools/stats_log_api_gen/test.proto index 24ebf4de031a..c3e703826be5 100644 --- a/tools/stats_log_api_gen/test.proto +++ b/tools/stats_log_api_gen/test.proto @@ -213,4 +213,24 @@ message ListedAtoms { // by whitelisted sources NonWhitelistedAtom non_whitelisted_atom = 2; } +} + +message ModuleOneAtom { + optional int32 field = 1; +} + +message ModuleTwoAtom { + optional int32 field = 1; +} + +message NoModuleAtom { + optional string field = 1; +} + +message ModuleAtoms { + oneof event { + ModuleOneAtom module_one_atom = 1 [(android.os.statsd.log_from_module) = "module1"]; + ModuleTwoAtom module_two_atom = 2 [(android.os.statsd.log_from_module) = "module2"]; + NoModuleAtom no_module_atom = 3; + } }
\ No newline at end of file diff --git a/tools/stats_log_api_gen/test_collation.cpp b/tools/stats_log_api_gen/test_collation.cpp index dc585c1c5dd1..bcf18ae8bf19 100644 --- a/tools/stats_log_api_gen/test_collation.cpp +++ b/tools/stats_log_api_gen/test_collation.cpp @@ -32,7 +32,7 @@ using std::vector; * Return whether the set contains a vector of the elements provided. */ static bool -set_contains_vector(const set<vector<java_type_t>>& s, int count, ...) +set_contains_vector(const map<vector<java_type_t>, set<string>>& s, int count, ...) { va_list args; vector<java_type_t> v; @@ -86,17 +86,17 @@ TEST(CollationTest, CollateStats) { int errorCount = collate_atoms(Event::descriptor(), &atoms); EXPECT_EQ(0, errorCount); - EXPECT_EQ(3ul, atoms.signatures.size()); + EXPECT_EQ(3ul, atoms.signatures_to_modules.size()); // IntAtom, AnotherIntAtom - EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures, JAVA_TYPE_INT); + EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures_to_modules, JAVA_TYPE_INT); // OutOfOrderAtom - EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures, JAVA_TYPE_INT, JAVA_TYPE_INT); + EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures_to_modules, JAVA_TYPE_INT, JAVA_TYPE_INT); // AllTypesAtom EXPECT_SET_CONTAINS_SIGNATURE( - atoms.signatures, + atoms.signatures_to_modules, JAVA_TYPE_ATTRIBUTION_CHAIN, // AttributionChain JAVA_TYPE_DOUBLE, // double JAVA_TYPE_FLOAT, // float @@ -228,8 +228,7 @@ TEST(CollationTest, FailOnBadBinaryFieldAtom) { TEST(CollationTest, PassOnWhitelistedAtom) { Atoms atoms; - int errorCount = - collate_atoms(ListedAtoms::descriptor(), &atoms); + int errorCount = collate_atoms(ListedAtoms::descriptor(), &atoms); EXPECT_EQ(errorCount, 0); EXPECT_EQ(atoms.decls.size(), 2ul); } @@ -246,5 +245,46 @@ TEST(CollationTest, RecogniseWhitelistedAtom) { } } +TEST(CollationTest, PassOnLogFromModuleAtom) { + Atoms atoms; + int errorCount = collate_atoms(ModuleAtoms::descriptor(), &atoms); + EXPECT_EQ(errorCount, 0); + EXPECT_EQ(atoms.decls.size(), 3ul); +} + +TEST(CollationTest, RecognizeModuleAtom) { + Atoms atoms; + int errorCount = collate_atoms(ModuleAtoms::descriptor(), &atoms); + EXPECT_EQ(errorCount, 0); + EXPECT_EQ(atoms.decls.size(), 3ul); + for (const auto& atomDecl: atoms.decls) { + if (atomDecl.code == 1) { + EXPECT_TRUE(atomDecl.hasModule); + EXPECT_EQ(atomDecl.moduleName, "module1"); + } else if (atomDecl.code == 2) { + EXPECT_TRUE(atomDecl.hasModule); + EXPECT_EQ(atomDecl.moduleName, "module2"); + } else { + EXPECT_FALSE(atomDecl.hasModule); + } + } + + EXPECT_EQ(atoms.signatures_to_modules.size(), 2u); + EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures_to_modules, JAVA_TYPE_INT); + EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures_to_modules, JAVA_TYPE_STRING); + for (auto signature_to_modules_it : atoms.signatures_to_modules) { + vector<java_type_t> signature = signature_to_modules_it.first; + if (signature[0] == JAVA_TYPE_STRING) { + EXPECT_EQ(signature_to_modules_it.second.size(), 0u); + } else if (signature[0] == JAVA_TYPE_INT) { + set<string> modules = signature_to_modules_it.second; + EXPECT_EQ(modules.size(), 2u); + // Assert that the set contains "module1" and "module2". + EXPECT_NE(modules.find("module1"), modules.end()); + EXPECT_NE(modules.find("module2"), modules.end()); + } + } +} + } // namespace stats_log_api_gen } // namespace android
\ No newline at end of file diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 476330052dcf..78967e4a4a9f 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -413,8 +413,8 @@ public class WifiConfiguration implements Parcelable { allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SUITE_B_192); allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256); allowedGroupManagementCiphers.set(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256); - allowedSuiteBCiphers.set(WifiConfiguration.SuiteBCipher.ECDHE_ECDSA); - allowedSuiteBCiphers.set(WifiConfiguration.SuiteBCipher.ECDHE_RSA); + // Note: allowedSuiteBCiphers bitset will be set by the service once the + // certificates are attached to this profile requirePMF = true; break; case SECURITY_TYPE_OWE: @@ -1171,49 +1171,39 @@ public class WifiConfiguration implements Parcelable { * This network is disabled because EAP-TLS failure */ public static final int DISABLED_TLS_VERSION_MISMATCH = 8; - /** - * This network is disabled due to WifiManager.disconnect() call. - */ - public static final int DISABLED_BY_WIFI_MANAGER_DISCONNECT = 9; - // Values above are for temporary disablement; values below are for permanent disablement. /** - * The starting index for permanent network selection disabled reasons - */ - public static final int NETWORK_SELECTION_DISABLED_PERMANENT_STARTING_INDEX = 10; - /** * This network is disabled due to absence of user credentials */ - public static final int DISABLED_AUTHENTICATION_NO_CREDENTIALS = 10; + public static final int DISABLED_AUTHENTICATION_NO_CREDENTIALS = 9; /** * This network is permanently disabled because it has no Internet access and user does not * want to stay connected. */ - public static final int DISABLED_NO_INTERNET_PERMANENT = 11; + public static final int DISABLED_NO_INTERNET_PERMANENT = 10; /** - * This network is disabled due to WifiManager.disable() call. + * This network is disabled due to WifiManager disable it explicitly */ - public static final int DISABLED_BY_WIFI_MANAGER = 12; + public static final int DISABLED_BY_WIFI_MANAGER = 11; /** * This network is disabled due to user switching */ - public static final int DISABLED_DUE_TO_USER_SWITCH = 13; + public static final int DISABLED_DUE_TO_USER_SWITCH = 12; /** * This network is disabled due to wrong password */ - public static final int DISABLED_BY_WRONG_PASSWORD = 14; + public static final int DISABLED_BY_WRONG_PASSWORD = 13; /** * This network is disabled because service is not subscribed */ - public static final int DISABLED_AUTHENTICATION_NO_SUBSCRIPTION = 15; + public static final int DISABLED_AUTHENTICATION_NO_SUBSCRIPTION = 14; /** * This Maximum disable reason value */ - public static final int NETWORK_SELECTION_DISABLED_MAX = 16; + public static final int NETWORK_SELECTION_DISABLED_MAX = 15; /** - * Quality network selection disable reason String (for debug purposes & configuration - * storage) + * Quality network selection disable reason String (for debug purpose) */ public static final String[] QUALITY_NETWORK_SELECTION_DISABLE_REASON = { "NETWORK_SELECTION_ENABLE", @@ -1225,7 +1215,6 @@ public class WifiConfiguration implements Parcelable { "NETWORK_SELECTION_DISABLED_NO_INTERNET_TEMPORARY", "NETWORK_SELECTION_DISABLED_WPS_START", "NETWORK_SELECTION_DISABLED_TLS_VERSION", - "NETWORK_SELECTION_DISABLED_BY_WIFI_MANAGER_DISCONNECT", "NETWORK_SELECTION_DISABLED_AUTHENTICATION_NO_CREDENTIALS", "NETWORK_SELECTION_DISABLED_NO_INTERNET_PERMANENT", "NETWORK_SELECTION_DISABLED_BY_WIFI_MANAGER", diff --git a/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java b/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java index 01176f223fe2..e59516485112 100644 --- a/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java +++ b/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java @@ -345,7 +345,7 @@ public final class WifiUsabilityStatsEntry implements Parcelable { } /** Whether the primary registered cell of current entry is same as that of previous entry */ - public boolean getIsSameRegisteredCell() { + public boolean isSameRegisteredCell() { return mIsSameRegisteredCell; } } diff --git a/wifi/java/android/net/wifi/rtt/ResponderLocation.java b/wifi/java/android/net/wifi/rtt/ResponderLocation.java index 37d5f0ac1a8b..e1d82f8d3a09 100644 --- a/wifi/java/android/net/wifi/rtt/ResponderLocation.java +++ b/wifi/java/android/net/wifi/rtt/ResponderLocation.java @@ -1169,6 +1169,8 @@ public final class ResponderLocation implements Parcelable { * (see 802.11REVmc Section 11.12.3 - Registered STA Operation). * <p> * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception. + * + * @hide */ public boolean getRegisteredLocationDseIndication() { if (!mIsLciValid) { @@ -1185,6 +1187,8 @@ public final class ResponderLocation implements Parcelable { * (see 802.11REVmc Section 11.12.3 - Registered STA Operation). * <p> * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception. + * + * @hide */ public boolean getDependentStationIndication() { if (!mIsLciValid) { diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java index 2b0c7732e7ae..4dfa96b8c606 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java @@ -179,12 +179,10 @@ public class WifiNetworkSuggestionTest { .get(WifiConfiguration.GroupCipher.GCMP_256)); assertTrue(suggestion.wifiConfiguration.allowedGroupManagementCiphers .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256)); - assertTrue(suggestion.wifiConfiguration.allowedSuiteBCiphers - .get(WifiConfiguration.SuiteBCipher.ECDHE_ECDSA)); - assertTrue(suggestion.wifiConfiguration.allowedSuiteBCiphers - .get(WifiConfiguration.SuiteBCipher.ECDHE_RSA)); assertTrue(suggestion.wifiConfiguration.requirePMF); assertNull(suggestion.wifiConfiguration.preSharedKey); + // allowedSuiteBCiphers are set according to the loaded certificate and cannot be tested + // here. } /** diff --git a/wifi/tests/src/android/net/wifi/WifiUsabilityStatsEntryTest.java b/wifi/tests/src/android/net/wifi/WifiUsabilityStatsEntryTest.java index cd60f029dcce..5184152bce34 100644 --- a/wifi/tests/src/android/net/wifi/WifiUsabilityStatsEntryTest.java +++ b/wifi/tests/src/android/net/wifi/WifiUsabilityStatsEntryTest.java @@ -116,6 +116,6 @@ public class WifiUsabilityStatsEntryTest { assertEquals(expected.getCellularSignalStrengthDbm(), actual.getCellularSignalStrengthDbm()); assertEquals(expected.getCellularSignalStrengthDb(), actual.getCellularSignalStrengthDb()); - assertEquals(expected.getIsSameRegisteredCell(), actual.getIsSameRegisteredCell()); + assertEquals(expected.isSameRegisteredCell(), actual.isSameRegisteredCell()); } } |